mirror of
https://git.alee14.me/shiftos-archive/ShiftOS_TheReturn.git
synced 2025-01-22 18:02:16 +00:00
WHOA HACKING
This commit is contained in:
parent
c64333d0f5
commit
2a747334bd
14 changed files with 939 additions and 85 deletions
57
ShiftOS.WinForms/Applications/TutorialBox.Designer.cs
generated
Normal file
57
ShiftOS.WinForms/Applications/TutorialBox.Designer.cs
generated
Normal file
|
@ -0,0 +1,57 @@
|
|||
namespace ShiftOS.WinForms.Applications
|
||||
{
|
||||
partial class TutorialBox
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.lbltuttext = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lbltuttext
|
||||
//
|
||||
this.lbltuttext.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lbltuttext.Location = new System.Drawing.Point(0, 0);
|
||||
this.lbltuttext.Name = "lbltuttext";
|
||||
this.lbltuttext.Size = new System.Drawing.Size(401, 134);
|
||||
this.lbltuttext.TabIndex = 0;
|
||||
//
|
||||
// TutorialBox
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.lbltuttext);
|
||||
this.Name = "TutorialBox";
|
||||
this.Size = new System.Drawing.Size(401, 134);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label lbltuttext;
|
||||
}
|
||||
}
|
73
ShiftOS.WinForms/Applications/TutorialBox.cs
Normal file
73
ShiftOS.WinForms/Applications/TutorialBox.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using ShiftOS.Engine;
|
||||
using System.Threading;
|
||||
|
||||
namespace ShiftOS.WinForms.Applications
|
||||
{
|
||||
|
||||
[DefaultTitle("Tutorial objective")]
|
||||
public partial class TutorialBox : UserControl, IShiftOSWindow
|
||||
{
|
||||
public TutorialBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
IsComplete = false;
|
||||
lbltuttext.Text = "";
|
||||
}
|
||||
|
||||
bool stillTyping = false;
|
||||
|
||||
public void SetObjective(string text)
|
||||
{
|
||||
while (stillTyping == true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
new Thread(() =>
|
||||
{
|
||||
stillTyping = true;
|
||||
this.Invoke(new Action(() =>
|
||||
{
|
||||
lbltuttext.Text = "";
|
||||
}));
|
||||
foreach(var c in text.ToCharArray())
|
||||
{
|
||||
this.Invoke(new Action(() =>
|
||||
{
|
||||
lbltuttext.Text += c;
|
||||
}));
|
||||
Thread.Sleep(75);
|
||||
}
|
||||
stillTyping = false;
|
||||
}).Start();
|
||||
}
|
||||
|
||||
public void OnLoad()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSkinLoad()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsComplete { get; set; }
|
||||
|
||||
public bool OnUnload()
|
||||
{
|
||||
return IsComplete;
|
||||
}
|
||||
|
||||
public void OnUpgrade()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
120
ShiftOS.WinForms/Applications/TutorialBox.resx
Normal file
120
ShiftOS.WinForms/Applications/TutorialBox.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
|
@ -52,7 +52,9 @@ namespace ShiftOS.WinForms.Controls
|
|||
|
||||
public void Write(string text)
|
||||
{
|
||||
this.HideSelection = true;
|
||||
this.AppendText(Localization.Parse(text));
|
||||
this.HideSelection = false;
|
||||
}
|
||||
|
||||
public void WriteLine(string text)
|
||||
|
|
|
@ -1,27 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using ShiftOS.Engine;
|
||||
using ShiftOS.Objects;
|
||||
using ShiftOS.WinForms.Applications;
|
||||
using static ShiftOS.Objects.ShiftFS.Utils;
|
||||
|
||||
namespace ShiftOS.WinForms
|
||||
{
|
||||
[Namespace("l337")]
|
||||
[Namespace("puppy")]
|
||||
[RequiresUpgrade("hacker101_deadaccts")]
|
||||
[KernelMode]
|
||||
public static class KernelPuppyCommands
|
||||
{
|
||||
[Command("clear", true)]
|
||||
public static bool ClearLogs()
|
||||
{
|
||||
WriteAllText("0:/system/data/kernel.log", "");
|
||||
Console.WriteLine("<watchdog> logs cleared successfully.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Namespace("krnl")]
|
||||
public static class KernelCommands
|
||||
{
|
||||
[Command("control", true)]
|
||||
[RequiresArgument("pass")]
|
||||
public static bool Control(Dictionary<string, object> args)
|
||||
{
|
||||
if(args["pass"].ToString() == ServerManager.thisGuid.ToString())
|
||||
{
|
||||
KernelWatchdog.Log("warn", "User has breached the kernel.");
|
||||
KernelWatchdog.EnterKernelMode();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("lock_session")]
|
||||
[KernelMode]
|
||||
public static bool LeaveControl()
|
||||
{
|
||||
KernelWatchdog.Log("inf", "User has left the kernel-mode session.");
|
||||
KernelWatchdog.LeaveKernelMode();
|
||||
KernelWatchdog.MudConnected = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Namespace("hacker101")]
|
||||
[RequiresUpgrade("hacker101_deadaccts")]
|
||||
public static class HackerCommands
|
||||
{
|
||||
private static void writeSlow(string text)
|
||||
{
|
||||
Console.Write("[hacker101@undisclosed]: ");
|
||||
foreach(var c in text.ToCharArray())
|
||||
{
|
||||
Console.Write(c);
|
||||
Thread.Sleep(125);
|
||||
}
|
||||
Console.WriteLine();
|
||||
Thread.Sleep(200);
|
||||
Console.WriteLine(text);
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
|
@ -88,9 +128,217 @@ namespace ShiftOS.WinForms
|
|||
|
||||
internal static void StartHackerTutorial()
|
||||
{
|
||||
//nyi
|
||||
Desktop.InvokeOnWorkerThread(() =>
|
||||
{
|
||||
var tut = new TutorialBox();
|
||||
AppearanceManager.SetupWindow(tut);
|
||||
|
||||
new Thread(() =>
|
||||
{
|
||||
|
||||
|
||||
int tutPos = 0;
|
||||
Action ondec = () =>
|
||||
{
|
||||
if (tutPos == 2)
|
||||
tutPos++;
|
||||
};
|
||||
TerminalBackend.CommandProcessed += (o, a) =>
|
||||
{
|
||||
switch (tutPos)
|
||||
{
|
||||
|
||||
case 0:
|
||||
case 10:
|
||||
if (o.ToLower().StartsWith("mud.disconnect"))
|
||||
{
|
||||
tutPos++;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (o.ToLower().StartsWith("krnl.lock_session"))
|
||||
tutPos++;
|
||||
break;
|
||||
case 1:
|
||||
if (o.ToLower().StartsWith("hacker101.brute_decrypt"))
|
||||
{
|
||||
if (a.Contains("0:/system/data/kernel.log"))
|
||||
{
|
||||
tutPos++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (o.ToLower().StartsWith("krnl.control"))
|
||||
{
|
||||
tutPos++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (o.ToLower().StartsWith("puppy.clear"))
|
||||
tutPos++;
|
||||
break;
|
||||
case 5:
|
||||
if (o.ToLower().StartsWith("mud.reconnect"))
|
||||
tutPos++;
|
||||
break;
|
||||
case 6:
|
||||
if (o.ToLower().StartsWith("mud.sendmsg"))
|
||||
{
|
||||
var msg = JsonConvert.DeserializeObject<dynamic>(a);
|
||||
try
|
||||
{
|
||||
if (msg.header == "getusers" && msg.body == "dead")
|
||||
tutPos++;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (o.ToLower().StartsWith("hacker101.breach_user_password"))
|
||||
tutPos++;
|
||||
break;
|
||||
case 8:
|
||||
if (o.ToLower().StartsWith("hacker101.print_user_info"))
|
||||
tutPos++;
|
||||
break;
|
||||
case 9:
|
||||
if (o.ToLower().StartsWith("hacker101.steal_codepoints"))
|
||||
tutPos++;
|
||||
break;
|
||||
}
|
||||
};
|
||||
tut.SetObjective("Welcome to the dead account exploitation tutorial. In this tutorial you will learn the basics of hacking within the multi-user domain.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("We will start with a simple system exploit - gaining kernel-level access to ShiftOS. This can help you perform actions not ever possible in the user level.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("To gain root access, you will first need to breach the system watchdog to keep it from dialing home to DevX.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("The watchdog can only function when it has a successful connection to the multi-user domain. You will need to use the MUD Control Centre to disconnect yourself from the MUD. This will lock you out of most features. To disconnect from the multi-user domain, simply run the 'mud.disconnect' command.");
|
||||
while(tutPos == 0)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("As you can see, the kernel watchdog has shut down temporarily, however before the disconnect it was able to tell DevX that it has gone offline.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("You'll also notice that commands like the shiftorium, MUD control centre and various applications that utilize these system components no longer function.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("The watchdog, however, is still watching. DevX was smart and programmed the kernel to log all events to a local file in 0:/system/data/kernel.log.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("You will need to empty out this file before you can connect to the multi-user domain, as the watchdog will send the contents of this file straight to DevX.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("Or, you can do what we're about to do and attempt to decrypt the log and sniff out the kernel-mode access password.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("This will allow us to gain kernel-level access to our system using the krnl.control{pass:} command.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("Let's start decrypting the log file using the hacker101.brute_decrypt{file:} script. The file: argument is a string and should point to a .log file. When the script succeeds, you will see a TextPad open with the decrypted contents.");
|
||||
while(tutPos == 1)
|
||||
{
|
||||
|
||||
}
|
||||
onCompleteDecrypt += ondec;
|
||||
tut.SetObjective("This script isn't the most agile script ever, but it'll get the job done.");
|
||||
while(tutPos == 2)
|
||||
{
|
||||
|
||||
}
|
||||
onCompleteDecrypt -= ondec;
|
||||
tut.SetObjective("Alright - it's done. Here's how it's laid out. In each log entry, you have the timestamp, then the event name, then the event description.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("Look for the most recent 'mudhandshake' event. This contains the kernel access code.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("Once you have it, run 'krnl.control{pass:\"the-kernel-code-here\"}. This will allow you to gain access to the kernel.");
|
||||
while(tutPos == 3)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("You are now in kernel mode. Every command you enter will run on the kernel. Now, let's clear the watchdog's logfile and reconnect to the multi-user domain.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("To clear the log, simply run 'puppy.clear'.");
|
||||
while(tutPos == 4)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("Who's a good dog... You are, ShiftOS. Now, we can connect back to the MUD using 'mud.reconnect'.");
|
||||
Thread.Sleep(1000);
|
||||
while(tutPos == 5)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("We have now snuck by the watchdog and DevX has no idea. With kernel-level access, everything you do is not logged, however if you perform too much in one shot, you'll get kicked off and locked out of the multi-user domain temporarily.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("So, let's focus on the job. You want to get into one of those fancy dead accounts, don't ya? Well, first, we need to talk with the MUD to get a list of these accounts.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("Simply run the `mud.sendmsg` command, specifying a 'header' of \"getusers\", and a body of \"dead\".");
|
||||
while(tutPos == 6)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("Great. We now have the usernames and sysnames of all dead accounts on the MUD. Now let's use the hacker101.breach_user_password{user:,sys:} command to breach one of these accounts' passwords.");
|
||||
while(tutPos == 7)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("There - you now have access to that account. Use its password, username and sysname and run the hacker101.print_user_info{user:,pass:,sys:} command to print the entirety of this user's information.");
|
||||
while(tutPos == 8)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("Now you can see a list of the user's Codepoints among other things. Now you can steal their codepoints by using the hacker101.steal_codepoints{user:,pass:,sys;,amount:} command. Be careful. This may alert DevX.");
|
||||
while(tutPos == 9)
|
||||
{
|
||||
|
||||
}
|
||||
if(devx_alerted == true)
|
||||
{
|
||||
tut.SetObjective("Alright... enough fun and games. DevX just found out we were doing this.");
|
||||
Thread.Sleep(500);
|
||||
tut.SetObjective("Quick! Disconnect from the MUD!!");
|
||||
while(tutPos == 10)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("Now, get out of kernel mode! To do that, run krnl.lock_session.");
|
||||
while(tutPos == 11)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
tut.SetObjective("OK, that was risky, but we pulled it off. Treat yourself! But first, let's get you out of kernel mode.");
|
||||
Thread.Sleep(500);
|
||||
tut.SetObjective("First we need to get you off the MUD. Simply run mud.disconnect again.");
|
||||
while (tutPos == 10)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("Now, let's run krnl.lock_session. This will lock you back into the user mode, and reconnect you to the MUD.");
|
||||
while (tutPos == 11)
|
||||
{
|
||||
|
||||
}
|
||||
tut.SetObjective("If, for some reason, DevX DOES find out, you have to be QUICK to get off of kernel mode. You don't want to make him mad.");
|
||||
}
|
||||
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("So that's all for now. Whenever you're in kernel mode again, and you have access to a user account, try breaching their filesystem next time. You can use sos.help{ns:} to show commands from a specific namespace to help you find more commands easily.");
|
||||
Thread.Sleep(1000);
|
||||
tut.SetObjective("You can now close this window.");
|
||||
tut.IsComplete = true;
|
||||
|
||||
}).Start();
|
||||
});
|
||||
}
|
||||
|
||||
private static bool devx_alerted = false;
|
||||
|
||||
private static event Action onCompleteDecrypt;
|
||||
|
||||
private static bool terminalIsOpen()
|
||||
{
|
||||
foreach(var win in AppearanceManager.OpenForms)
|
||||
|
@ -100,6 +348,226 @@ namespace ShiftOS.WinForms
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-_";
|
||||
|
||||
[Command("breach_user_password")]
|
||||
[KernelMode]
|
||||
[RequiresArgument("user")]
|
||||
[RequiresArgument("sys")]
|
||||
[RequiresUpgrade("hacker101_deadaccts")]
|
||||
public static bool BreachUserPassword(Dictionary<string, object> args)
|
||||
{
|
||||
string usr = args["user"].ToString();
|
||||
string sys = args["sys"].ToString();
|
||||
|
||||
ServerMessageReceived msgReceived = null;
|
||||
|
||||
Console.WriteLine("--hooking system thread...");
|
||||
|
||||
msgReceived = (msg) =>
|
||||
{
|
||||
if(msg.Name == "user_data")
|
||||
{
|
||||
var sve = JsonConvert.DeserializeObject<Save>(msg.Contents);
|
||||
var rnd = new Random();
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
string pass = "";
|
||||
for(int i = 0; i < sve.Password.Length; i++)
|
||||
{
|
||||
char c = '\0';
|
||||
while (c != sve.Password[i])
|
||||
c = chars[rnd.Next(0, chars.Length)];
|
||||
pass += c;
|
||||
Thread.Sleep(rnd.Next(25,75));
|
||||
}
|
||||
sw.Stop();
|
||||
Console.WriteLine(pass);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("--password breached. Operation took " + sw.ElapsedMilliseconds + " milliseconds.");
|
||||
}
|
||||
else if(msg.Name == "user_data_not_found")
|
||||
{
|
||||
Console.WriteLine("--access denied.");
|
||||
}
|
||||
ServerManager.MessageReceived -= msgReceived;
|
||||
};
|
||||
|
||||
Console.WriteLine("--beginning brute-force attack on " + usr + "@" + sys + "...");
|
||||
Thread.Sleep(500);
|
||||
ServerManager.MessageReceived += msgReceived;
|
||||
|
||||
ServerManager.SendMessage("get_user_data", JsonConvert.SerializeObject(new
|
||||
{
|
||||
user = usr,
|
||||
sysname = sys
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("print_user_info")]
|
||||
[KernelMode]
|
||||
[RequiresArgument("pass")]
|
||||
[RequiresArgument("user")]
|
||||
[RequiresArgument("sys")]
|
||||
[RequiresUpgrade("hacker101_deadaccts")]
|
||||
public static bool PrintUserInfo(Dictionary<string, object> args)
|
||||
{
|
||||
string usr = args["user"].ToString();
|
||||
string sys = args["sys"].ToString();
|
||||
string pass = args["pass"].ToString();
|
||||
|
||||
ServerMessageReceived msgReceived = null;
|
||||
|
||||
Console.WriteLine("--hooking multi-user domain response call...");
|
||||
|
||||
msgReceived = (msg) =>
|
||||
{
|
||||
if (msg.Name == "user_data")
|
||||
{
|
||||
var sve = JsonConvert.DeserializeObject<Save>(msg.Contents);
|
||||
if(sve.Password == pass)
|
||||
{
|
||||
Console.WriteLine("Username: " + sve.Username);
|
||||
Console.WriteLine("Password: " + sve.Password);
|
||||
Console.WriteLine("System name: " + sve.SystemName);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Codepoints: " + sve.Codepoints.ToString());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("--access denied.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (msg.Name == "user_data_not_found")
|
||||
{
|
||||
Console.WriteLine("--access denied.");
|
||||
}
|
||||
ServerManager.MessageReceived -= msgReceived;
|
||||
};
|
||||
|
||||
Console.WriteLine("--contacting multi-user domain...");
|
||||
Thread.Sleep(500);
|
||||
ServerManager.MessageReceived += msgReceived;
|
||||
|
||||
ServerManager.SendMessage("get_user_data", JsonConvert.SerializeObject(new
|
||||
{
|
||||
user = usr,
|
||||
sysname = sys
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("steal_codepoints")]
|
||||
[KernelMode]
|
||||
[RequiresArgument("amount")]
|
||||
[RequiresArgument("pass")]
|
||||
[RequiresArgument("user")]
|
||||
[RequiresArgument("sys")]
|
||||
[RequiresUpgrade("hacker101_deadaccts")]
|
||||
public static bool StealCodepoints(Dictionary<string, object> args)
|
||||
{
|
||||
string usr = args["user"].ToString();
|
||||
string sys = args["sys"].ToString();
|
||||
string pass = args["pass"].ToString();
|
||||
long amount = (long)args["amount"];
|
||||
|
||||
if(amount < 0)
|
||||
{
|
||||
Console.WriteLine("--invalid codepoint amount - halting...");
|
||||
return true;
|
||||
}
|
||||
|
||||
ServerMessageReceived msgReceived = null;
|
||||
|
||||
Console.WriteLine("--hooking multi-user domain response call...");
|
||||
|
||||
msgReceived = (msg) =>
|
||||
{
|
||||
if (msg.Name == "user_data")
|
||||
{
|
||||
var sve = JsonConvert.DeserializeObject<Save>(msg.Contents);
|
||||
if (sve.Password == pass)
|
||||
{
|
||||
if(amount > sve.Codepoints)
|
||||
{
|
||||
Console.WriteLine("--can't steal this many codepoints from user.");
|
||||
return;
|
||||
}
|
||||
|
||||
sve.Codepoints -= amount;
|
||||
SaveSystem.TransferCodepointsFrom(sve.Username, amount);
|
||||
ServerManager.SendMessage("mud_save_allow_dead", JsonConvert.SerializeObject(sve));
|
||||
SaveSystem.SaveGame();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("--access denied.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (msg.Name == "user_data_not_found")
|
||||
{
|
||||
Console.WriteLine("--access denied.");
|
||||
}
|
||||
ServerManager.MessageReceived -= msgReceived;
|
||||
};
|
||||
|
||||
Console.WriteLine("--contacting multi-user domain...");
|
||||
Thread.Sleep(500);
|
||||
ServerManager.MessageReceived += msgReceived;
|
||||
|
||||
ServerManager.SendMessage("get_user_data", JsonConvert.SerializeObject(new
|
||||
{
|
||||
user = usr,
|
||||
sysname = sys
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Command("brute_decrypt", true)]
|
||||
[RequiresArgument("file")]
|
||||
public static bool BruteDecrypt(Dictionary<string, object> args)
|
||||
{
|
||||
if (FileExists(args["file"].ToString()))
|
||||
{
|
||||
string pass = new Random().Next(1000, 10000).ToString();
|
||||
string fake = "";
|
||||
Console.WriteLine("Beginning brute-force attack on password.");
|
||||
var s = new Stopwatch();
|
||||
s.Start();
|
||||
for(int i = 0; i < pass.Length; i++)
|
||||
{
|
||||
for(int num = 0; num < 10; num++)
|
||||
{
|
||||
if(pass[i].ToString() == num.ToString())
|
||||
{
|
||||
fake += num.ToString();
|
||||
Console.Write(num);
|
||||
}
|
||||
}
|
||||
}
|
||||
s.Stop();
|
||||
|
||||
Console.WriteLine("...password cracked - operation took " + s.ElapsedMilliseconds + " milliseconds.");
|
||||
var tp = new TextPad();
|
||||
AppearanceManager.SetupWindow(tp);
|
||||
WriteAllText("0:/temp.txt", ReadAllText(args["file"].ToString()));
|
||||
tp.LoadFile("0:/temp.txt");
|
||||
Delete("0:/temp.txt");
|
||||
onCompleteDecrypt?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("brute_decrypt: file not found");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Namespace("storydev")]
|
||||
|
|
|
@ -208,6 +208,12 @@
|
|||
<Compile Include="Applications\Terminal.Designer.cs">
|
||||
<DependentUpon>Terminal.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Applications\TutorialBox.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Applications\TutorialBox.Designer.cs">
|
||||
<DependentUpon>TutorialBox.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="AudioManager.cs" />
|
||||
<Compile Include="Commands.cs" />
|
||||
<Compile Include="Controls\ColorControl.cs">
|
||||
|
@ -350,6 +356,9 @@
|
|||
<EmbeddedResource Include="Applications\Terminal.resx">
|
||||
<DependentUpon>Terminal.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Applications\TutorialBox.resx">
|
||||
<DependentUpon>TutorialBox.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="DownloadControl.resx">
|
||||
<DependentUpon>DownloadControl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -30,6 +30,12 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace ShiftOS.Engine
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
|
||||
public class KernelModeAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class Command : Attribute
|
||||
{
|
||||
public string name;
|
||||
|
|
|
@ -164,7 +164,35 @@ namespace ShiftOS.Engine
|
|||
}
|
||||
}
|
||||
|
||||
[Command("reconnect")]
|
||||
[RequiresUpgrade("hacker101_deadaccts")]
|
||||
public static bool Reconnect()
|
||||
{
|
||||
Console.WriteLine("--reconnecting to multi-user domain...");
|
||||
KernelWatchdog.MudConnected = true;
|
||||
Console.WriteLine("--done.");
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("disconnect")]
|
||||
[RequiresUpgrade("hacker101_deadaccts")]
|
||||
public static bool Disconnect()
|
||||
{
|
||||
Console.WriteLine("--connection to multi-user domain severed...");
|
||||
KernelWatchdog.MudConnected = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("sendmsg")]
|
||||
[KernelMode]
|
||||
[RequiresUpgrade("hacker101_deadaccts")]
|
||||
[RequiresArgument("header")]
|
||||
[RequiresArgument("body")]
|
||||
public static bool SendMessage(Dictionary<string, object> args)
|
||||
{
|
||||
ServerManager.SendMessage(args["header"].ToString(), args["body"].ToString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[RequiresUpgrade("mud_fundamentals")]
|
||||
|
|
70
ShiftOS_TheReturn/KernelWatchdog.cs
Normal file
70
ShiftOS_TheReturn/KernelWatchdog.cs
Normal file
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static ShiftOS.Objects.ShiftFS.Utils;
|
||||
|
||||
namespace ShiftOS.Engine
|
||||
{
|
||||
public static class KernelWatchdog
|
||||
{
|
||||
public static void Log(string e, string desc)
|
||||
{
|
||||
string line = $"[{DateTime.Now}] <{e}> {desc}";
|
||||
if (FileExists("0:/system/data/kernel.log"))
|
||||
{
|
||||
string contents = ReadAllText("0:/system/data/kernel.log");
|
||||
contents += Environment.NewLine + line;
|
||||
WriteAllText("0:/system/data/kernel.log", contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteAllText("0:/system/data/kernel.log", line);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool InKernelMode { get; private set; }
|
||||
public static bool MudConnected { get; set; }
|
||||
|
||||
public static bool IsSafe(Type type)
|
||||
{
|
||||
if (InKernelMode == true)
|
||||
return true;
|
||||
|
||||
foreach (var attrib in type.GetCustomAttributes(false))
|
||||
{
|
||||
if (attrib is KernelModeAttribute)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsSafe(MethodInfo type)
|
||||
{
|
||||
if (InKernelMode == true)
|
||||
return true;
|
||||
|
||||
foreach (var attrib in type.GetCustomAttributes(false))
|
||||
{
|
||||
if (attrib is KernelModeAttribute)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static void EnterKernelMode()
|
||||
{
|
||||
InKernelMode = true;
|
||||
Console.WriteLine("<kernel> Watchdog deactivated, system-level access granted.");
|
||||
}
|
||||
|
||||
public static void LeaveKernelMode()
|
||||
{
|
||||
InKernelMode = false;
|
||||
Console.WriteLine("<kernel> Kernel mode disabled.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -155,6 +155,8 @@ namespace ShiftOS.Engine
|
|||
|
||||
public static void FinishBootstrap()
|
||||
{
|
||||
KernelWatchdog.Log("mud_handshake", "handshake successful: kernel watchdog access code is \"" + ServerManager.thisGuid.ToString() + "\"");
|
||||
|
||||
ServerManager.MessageReceived += (msg) =>
|
||||
{
|
||||
if (msg.Name == "mud_savefile")
|
||||
|
@ -313,7 +315,7 @@ namespace ShiftOS.Engine
|
|||
System.IO.File.WriteAllText(Paths.SaveFile, Utils.ExportMount(0));
|
||||
}
|
||||
|
||||
public static void TransferCodepointsFrom(string who, int amount)
|
||||
public static void TransferCodepointsFrom(string who, long amount)
|
||||
{
|
||||
NotificationDaemon.AddNotification(NotificationType.CodepointsReceived, amount);
|
||||
CurrentSave.Codepoints += amount;
|
||||
|
|
|
@ -126,6 +126,13 @@ namespace ShiftOS.Engine
|
|||
thisGuid = new Guid(msg.Contents);
|
||||
GUIDReceived?.Invoke(msg.Contents);
|
||||
}
|
||||
else if(msg.Name == "allusers")
|
||||
{
|
||||
foreach(var acc in JsonConvert.DeserializeObject<string[]>(msg.Contents))
|
||||
{
|
||||
Console.WriteLine(acc);
|
||||
}
|
||||
}
|
||||
else if(msg.Name == "update_your_cp")
|
||||
{
|
||||
var args = JsonConvert.DeserializeObject<Dictionary<string, object>>(msg.Contents);
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
<Compile Include="FileSkimmerBackend.cs" />
|
||||
<Compile Include="Infobox.cs" />
|
||||
<Compile Include="IShiftOSWindow.cs" />
|
||||
<Compile Include="KernelWatchdog.cs" />
|
||||
<Compile Include="Localization.cs" />
|
||||
<Compile Include="NotificationDaemon.cs" />
|
||||
<Compile Include="OutOfBoxExperience.cs" />
|
||||
|
|
|
@ -210,9 +210,12 @@ namespace ShiftOS.Engine
|
|||
if (SaveSystem.CurrentSave.StoriesExperienced == null)
|
||||
SaveSystem.CurrentSave.StoriesExperienced = new List<string>();
|
||||
|
||||
if (!SaveSystem.CurrentSave.StoriesExperienced.Contains(id))
|
||||
return SaveSystem.CurrentSave.Upgrades[id];
|
||||
bool upgInstalled = false;
|
||||
if(SaveSystem.CurrentSave.Upgrades.ContainsKey(id))
|
||||
upgInstalled = SaveSystem.CurrentSave.Upgrades[id];
|
||||
|
||||
if(upgInstalled == false)
|
||||
return SaveSystem.CurrentSave.StoriesExperienced.Contains(id);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
|
|
|
@ -139,121 +139,129 @@ namespace ShiftOS.Engine
|
|||
{
|
||||
if (Shiftorium.UpgradeAttributesUnlocked(type))
|
||||
{
|
||||
foreach (var a in type.GetCustomAttributes(false))
|
||||
if (KernelWatchdog.IsSafe(type))
|
||||
{
|
||||
if (a is Namespace)
|
||||
foreach (var a in type.GetCustomAttributes(false))
|
||||
{
|
||||
var ns = a as Namespace;
|
||||
if (text.Split('.')[0] == ns.name)
|
||||
if (a is Namespace)
|
||||
{
|
||||
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
|
||||
var ns = a as Namespace;
|
||||
if (text.Split('.')[0] == ns.name)
|
||||
{
|
||||
if (Shiftorium.UpgradeAttributesUnlocked(method))
|
||||
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
|
||||
{
|
||||
if (CanRunRemotely(method, isRemote))
|
||||
if (Shiftorium.UpgradeAttributesUnlocked(method))
|
||||
{
|
||||
foreach (var ma in method.GetCustomAttributes(false))
|
||||
if (KernelWatchdog.IsSafe(method))
|
||||
{
|
||||
if (ma is Command)
|
||||
if (CanRunRemotely(method, isRemote))
|
||||
{
|
||||
var cmd = ma as Command;
|
||||
if (text.Split('.')[1] == cmd.name)
|
||||
foreach (var ma in method.GetCustomAttributes(false))
|
||||
{
|
||||
|
||||
var attr = method.GetCustomAttribute<CommandObsolete>();
|
||||
|
||||
if (attr != null)
|
||||
if (ma is Command)
|
||||
{
|
||||
string newcommand = attr.newcommand;
|
||||
if (attr.warn)
|
||||
var cmd = ma as Command;
|
||||
if (text.Split('.')[1] == cmd.name)
|
||||
{
|
||||
Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary<string, string>() {
|
||||
|
||||
var attr = method.GetCustomAttribute<CommandObsolete>();
|
||||
|
||||
if (attr != null)
|
||||
{
|
||||
string newcommand = attr.newcommand;
|
||||
if (attr.warn)
|
||||
{
|
||||
Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary<string, string>() {
|
||||
{"%newcommand", newcommand}
|
||||
}));
|
||||
}
|
||||
if (newcommand != "")
|
||||
{
|
||||
// redo the entire process running newcommand
|
||||
}
|
||||
if (newcommand != "")
|
||||
{
|
||||
// redo the entire process running newcommand
|
||||
|
||||
return RunClient(newcommand, args);
|
||||
}
|
||||
}
|
||||
return RunClient(newcommand, args);
|
||||
}
|
||||
}
|
||||
|
||||
var requiresArgs = method.GetCustomAttributes<RequiresArgument>();
|
||||
var requiresArgs = method.GetCustomAttributes<RequiresArgument>();
|
||||
|
||||
bool error = false;
|
||||
bool providedusage = false;
|
||||
bool error = false;
|
||||
bool providedusage = false;
|
||||
|
||||
foreach (RequiresArgument argument in requiresArgs)
|
||||
{
|
||||
if (!args.ContainsKey(argument.argument))
|
||||
{
|
||||
|
||||
if (!providedusage)
|
||||
foreach (RequiresArgument argument in requiresArgs)
|
||||
{
|
||||
string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}";
|
||||
if (usageparse == Localization.Parse(usageparse))
|
||||
usageparse = "";
|
||||
else
|
||||
usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{ERROR}{USAGE}" + usageparse, new Dictionary<string, string>() {
|
||||
if (!args.ContainsKey(argument.argument))
|
||||
{
|
||||
|
||||
if (!providedusage)
|
||||
{
|
||||
string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}";
|
||||
if (usageparse == Localization.Parse(usageparse))
|
||||
usageparse = "";
|
||||
else
|
||||
usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{ERROR}{USAGE}" + usageparse, new Dictionary<string, string>() {
|
||||
{"%ns", ns.name},
|
||||
{"%cmd", cmd.name}
|
||||
}) : "";
|
||||
|
||||
Console.WriteLine(usageparse);
|
||||
Console.WriteLine(usageparse);
|
||||
|
||||
providedusage = true;
|
||||
}
|
||||
providedusage = true;
|
||||
}
|
||||
|
||||
if (Shiftorium.UpgradeInstalled("help_usage"))
|
||||
{
|
||||
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary<string, string>() {
|
||||
if (Shiftorium.UpgradeInstalled("help_usage"))
|
||||
{
|
||||
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary<string, string>() {
|
||||
{"%argument", argument.argument}
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}"));
|
||||
}
|
||||
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (error)
|
||||
{
|
||||
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}"));
|
||||
throw new Exception("{ERROR_COMMAND_WRONG}");
|
||||
}
|
||||
|
||||
error = true;
|
||||
try
|
||||
{
|
||||
return (bool)method.Invoke(null, new[] { args });
|
||||
}
|
||||
catch (TargetInvocationException e)
|
||||
{
|
||||
Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}"));
|
||||
Console.WriteLine(e.InnerException.Message);
|
||||
Console.WriteLine(e.InnerException.StackTrace);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return (bool)method.Invoke(null, new object[] { });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
throw new Exception("{ERROR_COMMAND_WRONG}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return (bool)method.Invoke(null, new[] { args });
|
||||
}
|
||||
catch (TargetInvocationException e)
|
||||
{
|
||||
Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}"));
|
||||
Console.WriteLine(e.InnerException.Message);
|
||||
Console.WriteLine(e.InnerException.StackTrace);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return (bool)method.Invoke(null, new object[] { });
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(text + " cannot be ran in a remote session");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(text + " cannot be ran in a remote session");
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue