Skip to content

Commit

Permalink
Added token decryptor (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
SychicBoy committed Nov 22, 2021
1 parent 2c5cddf commit 8bb4f3e
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 16 deletions.
4 changes: 2 additions & 2 deletions NetReactorSlayer-x64/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyVersion("2.1.0.0")]
[assembly: AssemblyFileVersion("2.1.0.0")]
1 change: 1 addition & 0 deletions NetReactorSlayer.Core/NetReactorSlayer.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<Compile Include="Protections\ControlFlow.cs" />
<Compile Include="Protections\EmbeddedAsm.cs" />
<Compile Include="Protections\HideCall.cs" />
<Compile Include="Protections\Token.cs" />
<Compile Include="Protections\Native.cs" />
<Compile Include="Protections\NecroBit.cs" />
<Compile Include="Program.cs" />
Expand Down
12 changes: 10 additions & 2 deletions NetReactorSlayer.Core/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace NetReactorSlayer.Core
{
public class Program
{
static void onExit(object sender, EventArgs e)
static void OnExit(object sender, EventArgs e)
{
if (!Context.IsNative) return;
Process.Start(new ProcessStartInfo("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del \"" + Context.FilePath + "\"") { WindowStyle = ProcessWindowStyle.Hidden }).Dispose();
Expand All @@ -30,7 +30,7 @@ static void onExit(object sender, EventArgs e)

public static void Main(string[] args)
{
AppDomain.CurrentDomain.ProcessExit += new EventHandler(onExit);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnExit);
Console.Title = ".NET Reactor Slayer v" + Variables.version + " by CS-RET";
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
Expand Down Expand Up @@ -105,6 +105,14 @@ public static void Main(string[] args)
Logger.Error("Failed to dump embedded assemblies. " + ex.Message);
}
try
{
if (Variables.options["decrypttoken"]) Token.Execute();
}
catch (Exception ex)
{
Logger.Error("Failed decrypt tokens. " + ex.Message);
}
try
{
if (Variables.options["remove"]) Remover.Execute();
}
Expand Down
4 changes: 2 additions & 2 deletions NetReactorSlayer.Core/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyVersion("2.1.0.0")]
[assembly: AssemblyFileVersion("2.1.0.0")]
83 changes: 83 additions & 0 deletions NetReactorSlayer.Core/Protections/Token.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using de4dot.blocks;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using NETReactorSlayer.Core.Utils;
using System.Linq;

namespace NETReactorSlayer.Core.Protections
{
class Token
{
private static TypeDef typeDef;
private static MethodDef typeMethod;
private static MethodDef fieldMethod;

public static void Execute()
{
float count = 0L;
Find();
if (typeDef == null || typeMethod == null || fieldMethod == null)
{
Logger.Warn("Couldn't found any encrypted token.");
return;
}
foreach (TypeDef type in Context.Module.GetTypes())
{
foreach (MethodDef method in (from x in type.Methods where x.HasBody && x.Body.HasInstructions select x))
count += Deobfuscate(method);
}
if (count == 0L)
Logger.Warn("Couldn't found any encrypted token.");
else
Logger.Info($"{(int)count} Tokens decrypted.");
}

private static void Find()
{
foreach (TypeDef type in (from x in Context.Module.GetTypes() where !x.HasProperties && !x.HasEvents && x.Fields.Count != 0 select x))
{
foreach (FieldDef field in (from x in type.Fields where x.FieldType.FullName.Equals("System.ModuleHandle") select x))
{
MethodDef FieldMethod = null;
MethodDef TypeMethod = null;
foreach (MethodDef method in (from x in type.Methods where x.MethodSig != null && x.MethodSig.Params.Count.Equals(1) && x.MethodSig.Params[0].GetElementType() == ElementType.I4 select x).ToArray<MethodDef>())
{
if (method.MethodSig.RetType.GetFullName().Equals("System.RuntimeTypeHandle"))
TypeMethod = method;
else if (method.MethodSig.RetType.GetFullName().Equals("System.RuntimeFieldHandle"))
FieldMethod = method;
}
if (TypeMethod == null || FieldMethod == null) continue;
typeDef = type;
typeMethod = TypeMethod;
fieldMethod = FieldMethod;
break;
}
}
}

public static long Deobfuscate(MethodDef myMethod)
{
long count = 0L;
if (typeDef == null) return 0L;
GenericParamContext gpContext = GenericParamContext.Create(myMethod);
for (int i = 0; i < myMethod.Body.Instructions.Count; i++)
{
if (myMethod.Body.Instructions[i].OpCode.Code.Equals(Code.Ldc_I4) && myMethod.Body.Instructions[i + 1].OpCode.Code == Code.Call)
{
if (!(myMethod.Body.Instructions[i + 1].Operand is IMethod method) || !default(SigComparer).Equals(typeDef, method.DeclaringType)) continue;
MethodDef methodDef = DotNetUtils.GetMethod(Context.Module, method);
if (methodDef == null) continue;
if (methodDef == typeMethod || methodDef == fieldMethod)
{
uint token = (uint)((int)myMethod.Body.Instructions[i].Operand);
myMethod.Body.Instructions[i] = OpCodes.Nop.ToInstruction();
myMethod.Body.Instructions[i + 1] = new Instruction(OpCodes.Ldtoken, Context.Module.ResolveToken(token, gpContext) as ITokenOperand);
count += 1L;
}
}
}
return count;
}
}
}
14 changes: 10 additions & 4 deletions NetReactorSlayer.Core/Utils/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,20 @@ public static void Save()
{
if (Module.IsILOnly)
{
ModuleWriterOptions options = new ModuleWriterOptions(Module);
options.Logger = DummyLogger.NoThrowInstance;
ModuleWriterOptions options = new ModuleWriterOptions(Module) { Logger = DummyLogger.NoThrowInstance };
if (Logger.Prompt("Do you want to preserve all MD tokens? (Y/n): "))
options.MetadataOptions.Flags = MetadataFlags.PreserveAll;
if (Logger.Prompt("Do you want to keep old MaxStack value? (Y/n): "))
options.MetadataOptions.Flags |= MetadataFlags.KeepOldMaxStack;
Module.Write(DestPath, options);
}
else
{
NativeModuleWriterOptions options = new NativeModuleWriterOptions(Module, false);
options.Logger = DummyLogger.NoThrowInstance;
NativeModuleWriterOptions options = new NativeModuleWriterOptions(Module, false) { Logger = DummyLogger.NoThrowInstance };
if (Logger.Prompt("Do you want to preserve all MD tokens? (Y/n): "))
options.MetadataOptions.Flags = MetadataFlags.PreserveAll;
if (Logger.Prompt("Do you want to keep old MaxStack value? (Y/n): "))
options.MetadataOptions.Flags |= MetadataFlags.KeepOldMaxStack;
Module.NativeWrite(DestPath, options);
}
Logger.Info("Saved to: " + DestName);
Expand Down
6 changes: 3 additions & 3 deletions NetReactorSlayer.Core/Utils/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ namespace NETReactorSlayer.Core.Utils
{
public static class Logger
{
public static void Debug(string message)
public static bool Prompt(string message)
{
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine(" [DEBUG] " + message);
Console.ForegroundColor = ConsoleColor.White;
Console.Write(" [PROMPT] " + message);
return Console.ReadLine().ToLower() == "y";
}

public static void Info(string message)
Expand Down
4 changes: 3 additions & 1 deletion NetReactorSlayer.Core/Utils/Variables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public class Variables
"--no-deob", " Don't deobfuscate methods.",
"--no-arithmetic", " Don't resolve arithmetic equations.",
"--no-proxy-call", " Don't clean proxied calls.",
"--no-dump", " Don't dump embedded assemblies",
"--no-dump", " Don't dump embedded assemblies.",
"--no-decrypt-token", "Don't decrypt tokens.",
"--no-remove", " Don't remove obfuscator methods, resources, etc..."};
public static Dictionary<string, bool> options = new Dictionary<string, bool>()
{
Expand All @@ -45,6 +46,7 @@ public class Variables
["arithmetic"] = true,
["proxycall"] = true,
["dump"] = true,
["decrypttoken"] = true,
["remove"] = true
};
}
Expand Down
4 changes: 2 additions & 2 deletions NetReactorSlayer/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyVersion("2.1.0.0")]
[assembly: AssemblyFileVersion("2.1.0.0")]

0 comments on commit 8bb4f3e

Please sign in to comment.