diff --git a/AssemblyData/Properties/AssemblyInfo.cs b/AssemblyData/Properties/AssemblyInfo.cs
index 1d2efaab..b5148af1 100644
--- a/AssemblyData/Properties/AssemblyInfo.cs
+++ b/AssemblyData/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/AssemblyServer-x64/Properties/AssemblyInfo.cs b/AssemblyServer-x64/Properties/AssemblyInfo.cs
index ff65f20e..04c3bebe 100644
--- a/AssemblyServer-x64/Properties/AssemblyInfo.cs
+++ b/AssemblyServer-x64/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/AssemblyServer/Properties/AssemblyInfo.cs b/AssemblyServer/Properties/AssemblyInfo.cs
index e72cf362..ef695877 100644
--- a/AssemblyServer/Properties/AssemblyInfo.cs
+++ b/AssemblyServer/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/Test.Rename.Dll/Properties/AssemblyInfo.cs b/Test.Rename.Dll/Properties/AssemblyInfo.cs
index 03724ec6..c439bb43 100644
--- a/Test.Rename.Dll/Properties/AssemblyInfo.cs
+++ b/Test.Rename.Dll/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/Test.Rename/Properties/AssemblyInfo.cs b/Test.Rename/Properties/AssemblyInfo.cs
index eaee41da..693628fb 100644
--- a/Test.Rename/Properties/AssemblyInfo.cs
+++ b/Test.Rename/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/blocks/Properties/AssemblyInfo.cs b/blocks/Properties/AssemblyInfo.cs
index fe5beb22..edccefa7 100644
--- a/blocks/Properties/AssemblyInfo.cs
+++ b/blocks/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/de4dot-x64/Properties/AssemblyInfo.cs b/de4dot-x64/Properties/AssemblyInfo.cs
index 847651c5..1d9ae89e 100644
--- a/de4dot-x64/Properties/AssemblyInfo.cs
+++ b/de4dot-x64/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/de4dot.code/Properties/AssemblyInfo.cs b/de4dot.code/Properties/AssemblyInfo.cs
index 33a331b1..ee72e069 100644
--- a/de4dot.code/Properties/AssemblyInfo.cs
+++ b/de4dot.code/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/de4dot.code/Utils.cs b/de4dot.code/Utils.cs
index 7f5a51f1..6ece6e7b 100644
--- a/de4dot.code/Utils.cs
+++ b/de4dot.code/Utils.cs
@@ -232,5 +232,22 @@ namespace de4dot.code {
return fileData;
}
}
+
+ public static uint readEncodedUInt32(BinaryReader reader) {
+ uint val = 0;
+ int bits = 0;
+ for (int i = 0; i < 5; i++) {
+ byte b = reader.ReadByte();
+ val |= (uint)(b & 0x7F) << bits;
+ if ((b & 0x80) == 0)
+ return val;
+ bits += 7;
+ }
+ throw new ApplicationException("Invalid encoded int32");
+ }
+
+ public static int readEncodedInt32(BinaryReader reader) {
+ return (int)readEncodedUInt32(reader);
+ }
}
}
diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj
index b22d333b..cb408f96 100644
--- a/de4dot.code/de4dot.code.csproj
+++ b/de4dot.code/de4dot.code.csproj
@@ -67,7 +67,7 @@
-
+
@@ -89,6 +89,7 @@
+
@@ -209,6 +210,8 @@
+
+
diff --git a/de4dot.code/deobfuscators/CliSecure/vm/CsvmToCilMethodConverter.cs b/de4dot.code/deobfuscators/CliSecure/vm/CsvmToCilMethodConverter.cs
index 386dcc54..d0179294 100644
--- a/de4dot.code/deobfuscators/CliSecure/vm/CsvmToCilMethodConverter.cs
+++ b/de4dot.code/deobfuscators/CliSecure/vm/CsvmToCilMethodConverter.cs
@@ -212,7 +212,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
int offset = 0;
while (reader.BaseStream.Position < reader.BaseStream.Length) {
int vmOpCode = reader.ReadUInt16();
- var instr = opCodeDetector.Handlers[vmOpCode].read(reader);
+ var instr = opCodeDetector.Handlers[vmOpCode].Read(reader);
instr.Offset = offset;
offset += getInstructionSize(instr);
instrs.Add(instr);
diff --git a/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandler.cs b/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandler.cs
index 3ce34f01..d3aceec1 100644
--- a/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandler.cs
+++ b/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandler.cs
@@ -20,17 +20,17 @@
using System;
using System.Collections.Generic;
using System.IO;
+using de4dot.blocks;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
-using de4dot.blocks;
namespace de4dot.code.deobfuscators.CliSecure.vm {
- abstract class OpCodeHandler {
- protected abstract OpCodeHandlerSigInfo OpCodeHandlerSigInfo { get; }
- protected abstract bool detectInternal(UnknownHandlerInfo info);
- public abstract Instruction read(BinaryReader reader);
- public abstract string Name { get; }
+ partial class OpCodeHandler {
+ public string Name { get; set; }
+ public OpCodeHandlerSigInfo OpCodeHandlerSigInfo { get; set; }
+ public Predicate Check { get; set; }
+ public Func Read { get; set; }
public bool detect(UnknownHandlerInfo info) {
var sigInfo = OpCodeHandlerSigInfo;
@@ -52,7 +52,9 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
if (sigInfo.ExecuteMethodLocals != null && !new LocalTypes(info.ExecuteMethod).all(sigInfo.ExecuteMethodLocals))
return false;
- return detectInternal(info);
+ if (Check != null)
+ return Check(info);
+ return true;
}
static bool compare(int? val1, int val2) {
@@ -66,30 +68,8 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
}
}
- class ArithmeticOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 14,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "arithmetic"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static partial class OpCodeHandlers {
+ static Instruction arithmetic_read(BinaryReader reader) {
switch (reader.ReadByte()) {
case 0: return Instruction.Create(OpCodes.Add);
case 1: return Instruction.Create(OpCodes.Add_Ovf);
@@ -107,71 +87,19 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
default: throw new ApplicationException("Invalid opcode");
}
}
- }
- class ArrayOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.UInt32",
- },
- ExecuteMethodLocals = new string[] {
- "System.Object",
- "System.Int32",
- "System.Type",
- "System.IntPtr",
- },
- ExecuteMethodThrows = 0,
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "newarr"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
+ static bool newarr_check(UnknownHandlerInfo info) {
return DotNetUtils.callsMethod(info.ExecuteMethod, "System.Type System.Reflection.Module::ResolveType(System.Int32)");
}
- public override Instruction read(BinaryReader reader) {
+ static Instruction newarr_read(BinaryReader reader) {
return new Instruction {
OpCode = OpCodes.Newarr,
Operand = new TokenOperand(reader.ReadInt32()),
};
}
- }
- class BoxOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- FieldsInfo.EnumType,
- "System.UInt32",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 2,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "box/unbox"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction box_read(BinaryReader reader) {
var instr = new Instruction();
switch (reader.ReadByte()) {
case 0: instr.OpCode = OpCodes.Box; break;
@@ -181,36 +109,8 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
instr.Operand = new TokenOperand(reader.ReadInt32());
return instr;
}
- }
- class CallOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.Collections.Generic.Dictionary`2",
- "System.Collections.Generic.Dictionary`2",
- "System.Reflection.MethodBase",
- "System.UInt32",
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 2,
- NumInstanceMethods = 4,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "call"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction call_read(BinaryReader reader) {
var instr = new Instruction();
switch (reader.ReadByte()) {
case 0: instr.OpCode = OpCodes.Newobj; break;
@@ -221,33 +121,8 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
instr.Operand = new TokenOperand(reader.ReadInt32());
return instr;
}
- }
- class CastOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.UInt32",
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 2,
- };
-
- public override string Name {
- get { return "cast"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction cast_read(BinaryReader reader) {
var instr = new Instruction();
switch (reader.ReadByte()) {
case 0: instr.OpCode = OpCodes.Castclass; break;
@@ -257,33 +132,8 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
instr.Operand = new TokenOperand(reader.ReadInt32());
return instr;
}
- }
- class CompareOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.Int32",
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 1,
- NumInstanceMethods = 7,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "compare"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction compare_read(BinaryReader reader) {
int type = reader.ReadByte();
Instruction instr = new Instruction();
switch (type) {
@@ -312,83 +162,57 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
return instr;
}
- }
- class ConvertOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- FieldsInfo.EnumType,
- "System.Boolean",
- "System.Boolean",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 13,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "convert"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- class InstructionInfo {
+ class InstructionInfo1 {
public byte Type { get; set; }
public bool Second { get; set; }
public bool Third { get; set; }
public OpCode OpCode { get; set; }
}
- static List instructionInfos = new List {
- new InstructionInfo { Type = 0, Second = false, Third = false, OpCode = OpCodes.Conv_I1 },
- new InstructionInfo { Type = 1, Second = false, Third = false, OpCode = OpCodes.Conv_I2 },
- new InstructionInfo { Type = 2, Second = false, Third = false, OpCode = OpCodes.Conv_I4 },
- new InstructionInfo { Type = 3, Second = false, Third = false, OpCode = OpCodes.Conv_I8 },
- new InstructionInfo { Type = 4, Second = false, Third = false, OpCode = OpCodes.Conv_R4 },
- new InstructionInfo { Type = 5, Second = false, Third = false, OpCode = OpCodes.Conv_R8 },
- new InstructionInfo { Type = 6, Second = false, Third = false, OpCode = OpCodes.Conv_U1 },
- new InstructionInfo { Type = 7, Second = false, Third = false, OpCode = OpCodes.Conv_U2 },
- new InstructionInfo { Type = 8, Second = false, Third = false, OpCode = OpCodes.Conv_U4 },
- new InstructionInfo { Type = 9, Second = false, Third = false, OpCode = OpCodes.Conv_U8 },
- new InstructionInfo { Type = 10, Second = false, Third = false, OpCode = OpCodes.Conv_I },
- new InstructionInfo { Type = 11, Second = false, Third = false, OpCode = OpCodes.Conv_U },
+ static List instructionInfos1 = new List {
+ new InstructionInfo1 { Type = 0, Second = false, Third = false, OpCode = OpCodes.Conv_I1 },
+ new InstructionInfo1 { Type = 1, Second = false, Third = false, OpCode = OpCodes.Conv_I2 },
+ new InstructionInfo1 { Type = 2, Second = false, Third = false, OpCode = OpCodes.Conv_I4 },
+ new InstructionInfo1 { Type = 3, Second = false, Third = false, OpCode = OpCodes.Conv_I8 },
+ new InstructionInfo1 { Type = 4, Second = false, Third = false, OpCode = OpCodes.Conv_R4 },
+ new InstructionInfo1 { Type = 5, Second = false, Third = false, OpCode = OpCodes.Conv_R8 },
+ new InstructionInfo1 { Type = 6, Second = false, Third = false, OpCode = OpCodes.Conv_U1 },
+ new InstructionInfo1 { Type = 7, Second = false, Third = false, OpCode = OpCodes.Conv_U2 },
+ new InstructionInfo1 { Type = 8, Second = false, Third = false, OpCode = OpCodes.Conv_U4 },
+ new InstructionInfo1 { Type = 9, Second = false, Third = false, OpCode = OpCodes.Conv_U8 },
+ new InstructionInfo1 { Type = 10, Second = false, Third = false, OpCode = OpCodes.Conv_I },
+ new InstructionInfo1 { Type = 11, Second = false, Third = false, OpCode = OpCodes.Conv_U },
- new InstructionInfo { Type = 0, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I1 },
- new InstructionInfo { Type = 1, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I2 },
- new InstructionInfo { Type = 2, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I4 },
- new InstructionInfo { Type = 3, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I8 },
- new InstructionInfo { Type = 6, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U1 },
- new InstructionInfo { Type = 7, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U2 },
- new InstructionInfo { Type = 8, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U4 },
- new InstructionInfo { Type = 9, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U8 },
- new InstructionInfo { Type = 10, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I },
- new InstructionInfo { Type = 11, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U },
+ new InstructionInfo1 { Type = 0, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I1 },
+ new InstructionInfo1 { Type = 1, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I2 },
+ new InstructionInfo1 { Type = 2, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I4 },
+ new InstructionInfo1 { Type = 3, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I8 },
+ new InstructionInfo1 { Type = 6, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U1 },
+ new InstructionInfo1 { Type = 7, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U2 },
+ new InstructionInfo1 { Type = 8, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U4 },
+ new InstructionInfo1 { Type = 9, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U8 },
+ new InstructionInfo1 { Type = 10, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_I },
+ new InstructionInfo1 { Type = 11, Second = true, Third = false, OpCode = OpCodes.Conv_Ovf_U },
- new InstructionInfo { Type = 0, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I1_Un },
- new InstructionInfo { Type = 1, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I2_Un },
- new InstructionInfo { Type = 2, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I4_Un },
- new InstructionInfo { Type = 3, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I8_Un },
- new InstructionInfo { Type = 6, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U1_Un },
- new InstructionInfo { Type = 7, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U2_Un },
- new InstructionInfo { Type = 8, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U4_Un },
- new InstructionInfo { Type = 9, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U8_Un },
- new InstructionInfo { Type = 10, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I_Un },
- new InstructionInfo { Type = 11, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U_Un },
- new InstructionInfo { Type = 12, Second = true, Third = true, OpCode = OpCodes.Conv_R_Un },
+ new InstructionInfo1 { Type = 0, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I1_Un },
+ new InstructionInfo1 { Type = 1, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I2_Un },
+ new InstructionInfo1 { Type = 2, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I4_Un },
+ new InstructionInfo1 { Type = 3, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I8_Un },
+ new InstructionInfo1 { Type = 6, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U1_Un },
+ new InstructionInfo1 { Type = 7, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U2_Un },
+ new InstructionInfo1 { Type = 8, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U4_Un },
+ new InstructionInfo1 { Type = 9, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U8_Un },
+ new InstructionInfo1 { Type = 10, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_I_Un },
+ new InstructionInfo1 { Type = 11, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U_Un },
+ new InstructionInfo1 { Type = 12, Second = true, Third = true, OpCode = OpCodes.Conv_R_Un },
};
- public override Instruction read(BinaryReader reader) {
+ static Instruction convert_read(BinaryReader reader) {
byte type = reader.ReadByte();
bool second = reader.ReadBoolean();
bool third = reader.ReadBoolean();
Instruction instr = null;
- foreach (var info in instructionInfos) {
+ foreach (var info in instructionInfos1) {
if (type != info.Type || info.Second != second || info.Third != third)
continue;
@@ -400,102 +224,51 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
return instr;
}
- }
- class DupPopOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "dup/pop"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction dup_read(BinaryReader reader) {
switch (reader.ReadByte()) {
case 0: return Instruction.Create(OpCodes.Dup);
case 1: return Instruction.Create(OpCodes.Pop);
default: throw new ApplicationException("Invalid opcode");
}
}
- }
- class ElemOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.Boolean",
- "System.Boolean",
- FieldsInfo.EnumType,
- "System.UInt32",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "ldelem/stelem"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- class InstructionInfo {
+ class InstructionInfo2 {
public bool First { get; set; }
public bool Second { get; set; }
public int Value { get; set; }
public OpCode OpCode { get; set; }
}
- static List instructionInfos = new List {
- new InstructionInfo { First = false, Second = true, Value = 24, OpCode = OpCodes.Stelem_I },
- new InstructionInfo { First = false, Second = true, Value = 4, OpCode = OpCodes.Stelem_I1 },
- new InstructionInfo { First = false, Second = true, Value = 6, OpCode = OpCodes.Stelem_I2 },
- new InstructionInfo { First = false, Second = true, Value = 8, OpCode = OpCodes.Stelem_I4 },
- new InstructionInfo { First = false, Second = true, Value = 10, OpCode = OpCodes.Stelem_I8 },
- new InstructionInfo { First = false, Second = true, Value = 12, OpCode = OpCodes.Stelem_R4 },
- new InstructionInfo { First = false, Second = true, Value = 13, OpCode = OpCodes.Stelem_R8 },
- new InstructionInfo { First = false, Second = true, Value = 28, OpCode = OpCodes.Stelem_Ref },
- new InstructionInfo { First = false, Second = false, Value = 0, OpCode = OpCodes.Stelem_Any },
+ static List instructionInfos2 = new List {
+ new InstructionInfo2 { First = false, Second = true, Value = 24, OpCode = OpCodes.Stelem_I },
+ new InstructionInfo2 { First = false, Second = true, Value = 4, OpCode = OpCodes.Stelem_I1 },
+ new InstructionInfo2 { First = false, Second = true, Value = 6, OpCode = OpCodes.Stelem_I2 },
+ new InstructionInfo2 { First = false, Second = true, Value = 8, OpCode = OpCodes.Stelem_I4 },
+ new InstructionInfo2 { First = false, Second = true, Value = 10, OpCode = OpCodes.Stelem_I8 },
+ new InstructionInfo2 { First = false, Second = true, Value = 12, OpCode = OpCodes.Stelem_R4 },
+ new InstructionInfo2 { First = false, Second = true, Value = 13, OpCode = OpCodes.Stelem_R8 },
+ new InstructionInfo2 { First = false, Second = true, Value = 28, OpCode = OpCodes.Stelem_Ref },
+ new InstructionInfo2 { First = false, Second = false, Value = 0, OpCode = OpCodes.Stelem_Any },
- new InstructionInfo { First = true, Second = true, Value = 24, OpCode = OpCodes.Ldelem_I },
- new InstructionInfo { First = true, Second = true, Value = 4, OpCode = OpCodes.Ldelem_I1 },
- new InstructionInfo { First = true, Second = true, Value = 6, OpCode = OpCodes.Ldelem_I2 },
- new InstructionInfo { First = true, Second = true, Value = 8, OpCode = OpCodes.Ldelem_I4 },
- new InstructionInfo { First = true, Second = true, Value = 10, OpCode = OpCodes.Ldelem_I8 },
- new InstructionInfo { First = true, Second = true, Value = 5, OpCode = OpCodes.Ldelem_U1 },
- new InstructionInfo { First = true, Second = true, Value = 7, OpCode = OpCodes.Ldelem_U2 },
- new InstructionInfo { First = true, Second = true, Value = 9, OpCode = OpCodes.Ldelem_U4 },
- new InstructionInfo { First = true, Second = true, Value = 12, OpCode = OpCodes.Ldelem_R4 },
- new InstructionInfo { First = true, Second = true, Value = 13, OpCode = OpCodes.Ldelem_R8 },
- new InstructionInfo { First = true, Second = true, Value = 28, OpCode = OpCodes.Ldelem_Ref },
- new InstructionInfo { First = true, Second = false, Value = 0, OpCode = OpCodes.Ldelem_Any },
+ new InstructionInfo2 { First = true, Second = true, Value = 24, OpCode = OpCodes.Ldelem_I },
+ new InstructionInfo2 { First = true, Second = true, Value = 4, OpCode = OpCodes.Ldelem_I1 },
+ new InstructionInfo2 { First = true, Second = true, Value = 6, OpCode = OpCodes.Ldelem_I2 },
+ new InstructionInfo2 { First = true, Second = true, Value = 8, OpCode = OpCodes.Ldelem_I4 },
+ new InstructionInfo2 { First = true, Second = true, Value = 10, OpCode = OpCodes.Ldelem_I8 },
+ new InstructionInfo2 { First = true, Second = true, Value = 5, OpCode = OpCodes.Ldelem_U1 },
+ new InstructionInfo2 { First = true, Second = true, Value = 7, OpCode = OpCodes.Ldelem_U2 },
+ new InstructionInfo2 { First = true, Second = true, Value = 9, OpCode = OpCodes.Ldelem_U4 },
+ new InstructionInfo2 { First = true, Second = true, Value = 12, OpCode = OpCodes.Ldelem_R4 },
+ new InstructionInfo2 { First = true, Second = true, Value = 13, OpCode = OpCodes.Ldelem_R8 },
+ new InstructionInfo2 { First = true, Second = true, Value = 28, OpCode = OpCodes.Ldelem_Ref },
+ new InstructionInfo2 { First = true, Second = false, Value = 0, OpCode = OpCodes.Ldelem_Any },
};
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldelem_read(BinaryReader reader) {
Instruction instr = null;
bool first = reader.ReadBoolean();
bool second = reader.ReadBoolean();
int value = reader.ReadInt32();
- foreach (var info in instructionInfos) {
+ foreach (var info in instructionInfos2) {
if (info.First != first || info.Second != second)
continue;
if (second && value != info.Value)
@@ -512,60 +285,16 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
return instr;
}
- }
- class EndfinallyOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[0],
- ExecuteMethodThrows = 2,
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "endfinally"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
+ static bool endfinally_check(UnknownHandlerInfo info) {
return DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MethodInfo System.Type::GetMethod(System.String,System.Reflection.BindingFlags)");
}
- public override Instruction read(BinaryReader reader) {
+ static Instruction endfinally_read(BinaryReader reader) {
return Instruction.Create(OpCodes.Endfinally);
}
- }
- class FieldOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.UInt32",
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "load/store field"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldfld_read(BinaryReader reader) {
var instr = new Instruction();
switch (reader.ReadByte()) {
case 0: instr.Operand = new LoadFieldOperand(reader.ReadInt32()); break;
@@ -575,68 +304,15 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
}
return instr;
}
- }
- class InitobjOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.UInt32",
- },
- ExecuteMethodLocals = new string[] {
- "System.Type",
- },
- ExecuteMethodThrows = 1,
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "initobj"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction initobj_read(BinaryReader reader) {
return new Instruction {
OpCode = OpCodes.Initobj,
Operand = new TokenOperand(reader.ReadInt32()),
};
}
- }
- class LdLocalArgOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.Boolean",
- "System.UInt16",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "load local/arg"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldloc_read(BinaryReader reader) {
bool isLdarg = reader.ReadBoolean();
ushort index = reader.ReadUInt16();
@@ -652,33 +328,8 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
return instr;
}
- }
- class LdLocalArgAddrOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.Boolean",
- "System.UInt32",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "load local/arg address"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldloca_read(BinaryReader reader) {
Instruction instr = new Instruction();
if (reader.ReadBoolean()) {
instr.OpCode = OpCodes.Ldarga;
@@ -691,223 +342,55 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
return instr;
}
- }
- class LdelemaOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[0],
- ExecuteMethodLocals = new string[] {
- "System.Int32",
- "System.Array",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "ldelema"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldelema_read(BinaryReader reader) {
return new Instruction {
OpCode = OpCodes.Ldelema,
Operand = null,
};
}
- }
- class LdlenOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[0],
- ExecuteMethodLocals = new string[] {
- "System.Array",
- "System.Object",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "ldlen"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldlen_read(BinaryReader reader) {
return Instruction.Create(OpCodes.Ldlen);
}
- }
- class LdobjOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[0],
- ExecuteMethodThrows = 1,
- ExecuteMethodPops = 1,
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "ldobj"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldobj_read(BinaryReader reader) {
return new Instruction {
OpCode = OpCodes.Ldobj,
Operand = null,
};
}
- }
- class LdstrOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.String",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "ldstr"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldstr_read(BinaryReader reader) {
return Instruction.Create(OpCodes.Ldstr, reader.ReadString());
}
- }
- class LdtokenOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.UInt32",
- },
- ExecuteMethodLocals = new string[] {
- "System.Object",
- "System.Reflection.MemberInfo",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "ldtoken"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
+ static bool ldtoken_check(UnknownHandlerInfo info) {
return DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MemberInfo System.Reflection.Module::ResolveMember(System.Int32)");
}
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldtoken_read(BinaryReader reader) {
return new Instruction {
OpCode = OpCodes.Ldtoken,
Operand = new TokenOperand(reader.ReadInt32()),
};
}
- }
- class LeaveOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.Int32",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "leave"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
+ static bool leave_check(UnknownHandlerInfo info) {
return !DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)") &&
!DotNetUtils.callsMethod(info.ExecuteMethod, "System.Type System.Reflection.Module::ResolveType(System.Int32)") &&
!DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MemberInfo System.Reflection.Module::ResolveMember(System.Int32)");
}
- public override Instruction read(BinaryReader reader) {
+ static Instruction leave_read(BinaryReader reader) {
int displacement = reader.ReadInt32();
return new Instruction {
OpCode = OpCodes.Leave,
Operand = new TargetDisplOperand(displacement),
};
}
- }
- class LoadConstantOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.Object",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "load constant"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldc_read(BinaryReader reader) {
switch ((ElementType)reader.ReadByte()) {
case ElementType.I4: return DotNetUtils.createLdci4(reader.ReadInt32());
case ElementType.I8: return Instruction.Create(OpCodes.Ldc_I8, reader.ReadInt64());
@@ -917,34 +400,8 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
default: throw new ApplicationException("Invalid opcode");
}
}
- }
- class LoadFuncOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- FieldsInfo.EnumType,
- "System.UInt32",
- "System.UInt32",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "load func"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction ldftn_read(BinaryReader reader) {
byte code = reader.ReadByte();
int token = reader.ReadInt32();
@@ -965,32 +422,8 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
return instr;
}
- }
- class LogicalOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 6,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "logical"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction logical_read(BinaryReader reader) {
switch (reader.ReadByte()) {
case 0: return Instruction.Create(OpCodes.And);
case 1: return Instruction.Create(OpCodes.Or);
@@ -1001,27 +434,8 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
default: throw new ApplicationException("Invalid opcode");
}
}
- }
- class NopOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[0],
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
-
- public override string Name {
- get { return "nop"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
+ static bool nop_check(UnknownHandlerInfo info) {
return isEmptyMethod(info.ReadMethod) && isEmptyMethod(info.ExecuteMethod);
}
@@ -1035,93 +449,28 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
return false;
}
- public override Instruction read(BinaryReader reader) {
+ static Instruction nop_read(BinaryReader reader) {
return Instruction.Create(OpCodes.Nop);
}
- }
- class RetOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.UInt32",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "ret"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
+ static bool ret_check(UnknownHandlerInfo info) {
return DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
}
- public override Instruction read(BinaryReader reader) {
+ static Instruction ret_read(BinaryReader reader) {
reader.ReadInt32(); // token of current method
return Instruction.Create(OpCodes.Ret);
}
- }
- class RethrowOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[0],
- ExecuteMethodThrows = 1,
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "rethrow"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
+ static bool rethrow_check(UnknownHandlerInfo info) {
return info.ExecuteMethod.Body.Variables.Count == 0;
}
- public override Instruction read(BinaryReader reader) {
+ static Instruction rethrow_read(BinaryReader reader) {
return Instruction.Create(OpCodes.Rethrow);
}
- }
- class StLocalArgOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.Boolean",
- "System.UInt16",
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "store local/arg"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction stloc_read(BinaryReader reader) {
bool isStarg = reader.ReadBoolean();
ushort index = reader.ReadUInt16();
@@ -1138,64 +487,15 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
return instr;
}
- }
- class StobjOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[0],
- ExecuteMethodThrows = 1,
- ExecuteMethodPops = 2,
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "stobj"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction stobj_read(BinaryReader reader) {
return new Instruction {
OpCode = OpCodes.Stobj,
Operand = null,
};
}
- }
- class SwitchOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- "System.UInt32",
- "System.Int32[]",
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "switch"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction switch_read(BinaryReader reader) {
int numTargets = reader.ReadInt32();
int[] targetDispls = new int[numTargets];
for (int i = 0; i < targetDispls.Length; i++)
@@ -1205,62 +505,16 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
Operand = new SwitchTargetDisplOperand(targetDispls),
};
}
- }
- class ThrowOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[0],
- ExecuteMethodLocals = new string[] {
- "System.Object",
- },
- ExecuteMethodThrows = 2,
- NumStaticMethods = 0,
- NumInstanceMethods = 0,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "throw"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
+ static bool throw_check(UnknownHandlerInfo info) {
return !DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MethodInfo System.Type::GetMethod(System.String,System.Reflection.BindingFlags)");
}
- public override Instruction read(BinaryReader reader) {
+ static Instruction throw_read(BinaryReader reader) {
return Instruction.Create(OpCodes.Throw);
}
- }
- class UnaryOpCodeHandler : OpCodeHandler {
- static readonly OpCodeHandlerSigInfo sigInfo = new OpCodeHandlerSigInfo {
- RequiredFieldTypes = new object[] {
- FieldsInfo.EnumType,
- },
- NumStaticMethods = 0,
- NumInstanceMethods = 2,
- NumVirtualMethods = 2,
- NumCtors = 1,
- };
-
- public override string Name {
- get { return "neg/not"; }
- }
-
- protected override OpCodeHandlerSigInfo OpCodeHandlerSigInfo {
- get { return sigInfo; }
- }
-
- protected override bool detectInternal(UnknownHandlerInfo info) {
- return true;
- }
-
- public override Instruction read(BinaryReader reader) {
+ static Instruction neg_read(BinaryReader reader) {
switch (reader.ReadByte()) {
case 0: return Instruction.Create(OpCodes.Neg);
case 1: return Instruction.Create(OpCodes.Not);
diff --git a/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandlers.cs b/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandlers.cs
new file mode 100644
index 00000000..dbea01d8
--- /dev/null
+++ b/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandlers.cs
@@ -0,0 +1,1198 @@
+/*
+ Copyright (C) 2011-2012 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+namespace de4dot.code.deobfuscators.CliSecure.vm {
+ static partial class OpCodeHandlers {
+ public static readonly OpCodeHandler[][] opcodeHandlers = new OpCodeHandler[][] {
+ new OpCodeHandler[] {
+ new OpCodeHandler {
+ Name = "arithmetic",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 14,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = arithmetic_read,
+ },
+
+ new OpCodeHandler {
+ Name = "newarr",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Int32",
+ "System.Type",
+ "System.IntPtr",
+ },
+ ExecuteMethodThrows = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = newarr_check,
+ Read = newarr_read,
+ },
+
+ new OpCodeHandler {
+ Name = "box/unbox",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ "System.UInt32",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 2,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = box_read,
+ },
+
+ new OpCodeHandler {
+ Name = "call",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Collections.Generic.Dictionary`2",
+ "System.Collections.Generic.Dictionary`2",
+ "System.Reflection.MethodBase",
+ "System.UInt32",
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 2,
+ NumInstanceMethods = 4,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = call_read,
+ },
+
+ new OpCodeHandler {
+ Name = "cast",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 2,
+ },
+ Check = null,
+ Read = cast_read,
+ },
+
+ new OpCodeHandler {
+ Name = "compare",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Int32",
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 1,
+ NumInstanceMethods = 7,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = compare_read,
+ },
+
+ new OpCodeHandler {
+ Name = "convert",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ "System.Boolean",
+ "System.Boolean",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 13,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = convert_read,
+ },
+
+ new OpCodeHandler {
+ Name = "dup/pop",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = dup_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldelem/stelem",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Boolean",
+ "System.Boolean",
+ FieldsInfo.EnumType,
+ "System.UInt32",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldelem_read,
+ },
+
+ new OpCodeHandler {
+ Name = "endfinally",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodThrows = 2,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = endfinally_check,
+ Read = endfinally_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load/store field",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldfld_read,
+ },
+
+ new OpCodeHandler {
+ Name = "initobj",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Type",
+ },
+ ExecuteMethodThrows = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = initobj_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load local/arg",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Boolean",
+ "System.UInt16",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldloc_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load local/arg address",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Boolean",
+ "System.UInt32",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldloca_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldelema",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodLocals = new string[] {
+ "System.Int32",
+ "System.Array",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldelema_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldlen",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodLocals = new string[] {
+ "System.Array",
+ "System.Object",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldlen_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldobj",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldobj_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldstr",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.String",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldstr_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldtoken",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Reflection.MemberInfo",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = ldtoken_check,
+ Read = ldtoken_read,
+ },
+
+ new OpCodeHandler {
+ Name = "leave",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Int32",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = leave_check,
+ Read = leave_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load constant",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Object",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldc_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load func",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ "System.UInt32",
+ "System.UInt32",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldftn_read,
+ },
+
+ new OpCodeHandler {
+ Name = "logical",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 6,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = logical_read,
+ },
+
+ new OpCodeHandler {
+ Name = "nop",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = nop_check,
+ Read = nop_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ret",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = ret_check,
+ Read = ret_read,
+ },
+
+ new OpCodeHandler {
+ Name = "rethrow",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodThrows = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = rethrow_check,
+ Read = rethrow_read,
+ },
+
+ new OpCodeHandler {
+ Name = "store local/arg",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Boolean",
+ "System.UInt16",
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = stloc_read,
+ },
+
+ new OpCodeHandler {
+ Name = "stobj",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 2,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = stobj_read,
+ },
+
+ new OpCodeHandler {
+ Name = "switch",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ "System.Int32[]",
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = switch_read,
+ },
+
+ new OpCodeHandler {
+ Name = "throw",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ },
+ ExecuteMethodThrows = 2,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = throw_check,
+ Read = throw_read,
+ },
+
+ new OpCodeHandler {
+ Name = "neg/not",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ },
+ NumStaticMethods = 0,
+ NumInstanceMethods = 2,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = neg_read,
+ },
+ },
+
+ new OpCodeHandler[] {
+ new OpCodeHandler {
+ Name = "arithmetic",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ "System.Boolean",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 2,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 14,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = arithmetic_read,
+ },
+
+ new OpCodeHandler {
+ Name = "box/unbox",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ "System.UInt32",
+ FieldsInfo.EnumType,
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Type",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 2,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 2,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = box_read,
+ },
+
+ new OpCodeHandler {
+ Name = "call",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Collections.Generic.Dictionary`2",
+ "System.Collections.Generic.Dictionary`2",
+ "System.Reflection.MethodBase",
+ "System.UInt32",
+ FieldsInfo.EnumType,
+ FieldsInfo.EnumType,
+ "System.Boolean",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Boolean",
+ "System.Object",
+ "System.Reflection.ParameterInfo[]",
+ "System.Int32",
+ "System.Object[]",
+ "System.Reflection.ConstructorInfo",
+ "System.Reflection.MethodInfo",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 2,
+ NumStaticMethods = 2,
+ NumInstanceMethods = 4,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = call_read,
+ },
+
+ new OpCodeHandler {
+ Name = "cast",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ FieldsInfo.EnumType,
+ "System.Reflection.MethodBase",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Type",
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 2,
+ },
+ Check = null,
+ Read = cast_read,
+ },
+
+ new OpCodeHandler {
+ Name = "compare",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Int32",
+ FieldsInfo.EnumType,
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Int32",
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 2,
+ NumStaticMethods = 1,
+ NumInstanceMethods = 7,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = compare_read,
+ },
+
+ new OpCodeHandler {
+ Name = "convert",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ "System.Boolean",
+ "System.Boolean",
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 13,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = convert_read,
+ },
+
+ new OpCodeHandler {
+ Name = "dup/pop",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = dup_read,
+ },
+
+ new OpCodeHandler {
+ Name = "endfinally",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Int32",
+ },
+ ExecuteMethodThrows = 2,
+ ExecuteMethodPops = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = endfinally_check,
+ Read = endfinally_read,
+ },
+
+ new OpCodeHandler {
+ Name = "initobj",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ "System.Boolean",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Type",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = initobj_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldelem/stelem",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Boolean",
+ "System.Boolean",
+ FieldsInfo.EnumType,
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Int32",
+ "System.Array",
+ "System.Object",
+ "System.Type",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 5,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldelem_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldelema",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodLocals = new string[] {
+ "System.Int32",
+ "System.Array",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 2,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldelema_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldlen",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodLocals = new string[] {
+ "System.Array",
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldlen_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldobj",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodLocals = new string[] {
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldobj_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldstr",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.String",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldstr_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ldtoken",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Reflection.MemberInfo",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = ldtoken_check,
+ Read = ldtoken_read,
+ },
+
+ new OpCodeHandler {
+ Name = "leave",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Int32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Int32",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = leave_check,
+ Read = leave_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load constant",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Object",
+ "System.Boolean",
+ "System.UInt16",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldc_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load func",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ "System.UInt32",
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Reflection.MethodBase",
+ "System.IntPtr",
+ "System.Type",
+ "System.Delegate",
+ "System.RuntimeMethodHandle",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldftn_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load local/arg",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Boolean",
+ "System.UInt16",
+ "System.Boolean",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldloc_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load local/arg address",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Boolean",
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Array",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldloca_read,
+ },
+
+ new OpCodeHandler {
+ Name = "load/store field",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ FieldsInfo.EnumType,
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Reflection.FieldInfo",
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 4,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = ldfld_read,
+ },
+
+ new OpCodeHandler {
+ Name = "logical",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ FieldsInfo.EnumType,
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 2,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 6,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = logical_read,
+ },
+
+ new OpCodeHandler {
+ Name = "neg/not",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ FieldsInfo.EnumType,
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 2,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = neg_read,
+ },
+
+ new OpCodeHandler {
+ Name = "newarr",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Int32",
+ "System.Type",
+ "System.Boolean",
+ "System.IntPtr",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = newarr_check,
+ Read = newarr_read,
+ },
+
+ new OpCodeHandler {
+ Name = "nop",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = nop_check,
+ Read = nop_read,
+ },
+
+ new OpCodeHandler {
+ Name = "ret",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Reflection.MethodInfo",
+ "System.Type",
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = ret_check,
+ Read = ret_read,
+ },
+
+ new OpCodeHandler {
+ Name = "rethrow",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 0,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = rethrow_check,
+ Read = rethrow_read,
+ },
+
+ new OpCodeHandler {
+ Name = "stobj",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodLocals = new string[] {
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 1,
+ ExecuteMethodPops = 2,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = stobj_read,
+ },
+
+ new OpCodeHandler {
+ Name = "store local/arg",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.Boolean",
+ "System.UInt16",
+ FieldsInfo.EnumType,
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = stloc_read,
+ },
+
+ new OpCodeHandler {
+ Name = "switch",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[] {
+ "System.UInt32",
+ "System.Int32[]",
+ },
+ ExecuteMethodLocals = new string[] {
+ "System.Int32",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 0,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = null,
+ Read = switch_read,
+ },
+
+ new OpCodeHandler {
+ Name = "throw",
+ OpCodeHandlerSigInfo = new OpCodeHandlerSigInfo {
+ RequiredFieldTypes = new object[0],
+ ExecuteMethodLocals = new string[] {
+ "System.Object",
+ "System.Boolean",
+ },
+ ExecuteMethodThrows = 2,
+ ExecuteMethodPops = 1,
+ NumStaticMethods = 0,
+ NumInstanceMethods = 0,
+ NumVirtualMethods = 2,
+ NumCtors = 1,
+ },
+ Check = throw_check,
+ Read = throw_read,
+ },
+ },
+ };
+ }
+}
diff --git a/de4dot.code/deobfuscators/CliSecure/vm/UnknownHandlerInfo.cs b/de4dot.code/deobfuscators/CliSecure/vm/UnknownHandlerInfo.cs
index fa89cc93..9ce21539 100644
--- a/de4dot.code/deobfuscators/CliSecure/vm/UnknownHandlerInfo.cs
+++ b/de4dot.code/deobfuscators/CliSecure/vm/UnknownHandlerInfo.cs
@@ -74,7 +74,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
executeMethodPops = countPops(executeMethod);
}
- static IEnumerable getFields(TypeDefinition type) {
+ static internal IEnumerable getFields(TypeDefinition type) {
var typeFields = new FieldDefinitionAndDeclaringTypeDict();
foreach (var field in type.Fields)
typeFields.add(field, field);
diff --git a/de4dot.code/deobfuscators/CliSecure/vm/VmOpCodeHandlerDetector.cs b/de4dot.code/deobfuscators/CliSecure/vm/VmOpCodeHandlerDetector.cs
index 782dd42f..639314e9 100644
--- a/de4dot.code/deobfuscators/CliSecure/vm/VmOpCodeHandlerDetector.cs
+++ b/de4dot.code/deobfuscators/CliSecure/vm/VmOpCodeHandlerDetector.cs
@@ -45,39 +45,6 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
class VmOpCodeHandlerDetector {
ModuleDefinition module;
- static readonly OpCodeHandler[] opCodeHandlerDetectors = new OpCodeHandler[] {
- new ArithmeticOpCodeHandler(),
- new ArrayOpCodeHandler(),
- new BoxOpCodeHandler(),
- new CallOpCodeHandler(),
- new CastOpCodeHandler(),
- new CompareOpCodeHandler(),
- new ConvertOpCodeHandler(),
- new DupPopOpCodeHandler(),
- new ElemOpCodeHandler(),
- new EndfinallyOpCodeHandler(),
- new FieldOpCodeHandler(),
- new InitobjOpCodeHandler(),
- new LdLocalArgOpCodeHandler(),
- new LdLocalArgAddrOpCodeHandler(),
- new LdelemaOpCodeHandler(),
- new LdlenOpCodeHandler(),
- new LdobjOpCodeHandler(),
- new LdstrOpCodeHandler(),
- new LdtokenOpCodeHandler(),
- new LeaveOpCodeHandler(),
- new LoadConstantOpCodeHandler(),
- new LoadFuncOpCodeHandler(),
- new LogicalOpCodeHandler(),
- new NopOpCodeHandler(),
- new RetOpCodeHandler(),
- new RethrowOpCodeHandler(),
- new StLocalArgOpCodeHandler(),
- new StobjOpCodeHandler(),
- new SwitchOpCodeHandler(),
- new ThrowOpCodeHandler(),
- new UnaryOpCodeHandler(),
- };
List opCodeHandlers;
public List Handlers {
@@ -95,12 +62,15 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
if (vmHandlerTypes == null)
throw new ApplicationException("Could not find CSVM opcode handler types");
+ detectHandlers(vmHandlerTypes, createCsvmInfo());
+ }
+
+ internal CsvmInfo createCsvmInfo() {
var csvmInfo = new CsvmInfo();
csvmInfo.StackValue = findStackValueType();
csvmInfo.Stack = findStackType(csvmInfo.StackValue);
initStackTypeMethods(csvmInfo);
-
- detectHandlers(vmHandlerTypes, csvmInfo);
+ return csvmInfo;
}
TypeDefinition findStackValueType() {
@@ -239,19 +209,26 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
void detectHandlers(List handlerTypes, CsvmInfo csvmInfo) {
opCodeHandlers = new List();
var detected = new List();
- foreach (var handlerType in handlerTypes) {
- var info = new UnknownHandlerInfo(handlerType, csvmInfo);
- detected.Clear();
- foreach (var opCodeHandler in opCodeHandlerDetectors) {
- if (opCodeHandler.detect(info))
- detected.Add(opCodeHandler);
+
+ foreach (var handlersList in OpCodeHandlers.opcodeHandlers) {
+ opCodeHandlers.Clear();
+
+ foreach (var handlerType in handlerTypes) {
+ var info = new UnknownHandlerInfo(handlerType, csvmInfo);
+ detected.Clear();
+ foreach (var opCodeHandler in handlersList) {
+ if (opCodeHandler.detect(info))
+ detected.Add(opCodeHandler);
+ }
+ if (detected.Count != 1)
+ goto next;
+ opCodeHandlers.Add(detected[0]);
}
- if (detected.Count != 1)
- throw new ApplicationException("Could not detect VM opcode handler");
- opCodeHandlers.Add(detected[0]);
+ if (new List(Utils.unique(opCodeHandlers)).Count == opCodeHandlers.Count)
+ return;
+next: ;
}
- if (new List(Utils.unique(opCodeHandlers)).Count != opCodeHandlers.Count)
- throw new ApplicationException("Could not detect all VM opcode handlers");
+ throw new ApplicationException("Could not detect all VM opcode handlers");
}
}
}
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs b/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs
index c3f77c34..5c57f303 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs
@@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (DotNetUtils.getPInvokeMethod(type, "kernel32", "GetProcAddress") == null)
continue;
deobfuscate(method);
- if (!containsString(method, "debugger is active"))
+ if (!containsString(method, "debugger is activ"))
continue;
antiDebuggerType = type;
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs
index 7035939b..7c5153bc 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs
@@ -129,7 +129,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
MethodDefinition getProxyCreateMethod(TypeDefinition type) {
if (DotNetUtils.findFieldType(type, "System.ModuleHandle", true) == null)
return null;
- if (type.Fields.Count < 1 || type.Fields.Count > 4)
+ if (type.Fields.Count < 1 || type.Fields.Count > 5)
return null;
MethodDefinition createMethod = null;
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs
index 2736d3b5..fd41b58c 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs
@@ -298,6 +298,8 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
foreach (var method in type.Methods) {
if (DotNetUtils.isMethod(method, "System.Byte[]", "(System.IO.Stream)"))
return method;
+ if (DotNetUtils.isMethod(method, "System.Byte[]", "(System.Int32,System.IO.Stream)"))
+ return method;
}
return null;
}
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs b/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs
index b9cfa651..545a146e 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs
@@ -84,7 +84,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()"))
return false;
- if (type.Methods.Count < 3 || type.Methods.Count > 6)
+ if (type.Methods.Count < 3 || type.Methods.Count > 7)
return false;
if (DotNetUtils.getPInvokeMethod(type, "mscoree", "StrongNameSignatureVerificationEx") != null) {
}
diff --git a/de4dot.code/deobfuscators/DeobUtils.cs b/de4dot.code/deobfuscators/DeobUtils.cs
index 65fd9f52..8ac0d8fb 100644
--- a/de4dot.code/deobfuscators/DeobUtils.cs
+++ b/de4dot.code/deobfuscators/DeobUtils.cs
@@ -124,6 +124,17 @@ namespace de4dot.code.deobfuscators {
} while ((sum -= DELTA) != 0);
}
+ // Code converted from C implementation @ http://en.wikipedia.org/wiki/XTEA (decipher() func)
+ public static void xteaDecrypt(ref uint v0, ref uint v1, uint[] key, int rounds) {
+ const uint delta = 0x9E3779B9;
+ uint sum = (uint)(delta * rounds);
+ for (int i = 0; i < rounds; i++) {
+ v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
+ sum -= delta;
+ v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
+ }
+ }
+
public static string getExtension(ModuleKind kind) {
switch (kind) {
case ModuleKind.Dll:
diff --git a/de4dot.code/deobfuscators/Babel_NET/MethodBodyReaderBase.cs b/de4dot.code/deobfuscators/MethodBodyReaderBase.cs
similarity index 98%
rename from de4dot.code/deobfuscators/Babel_NET/MethodBodyReaderBase.cs
rename to de4dot.code/deobfuscators/MethodBodyReaderBase.cs
index 18ca8c7a..962e4abf 100644
--- a/de4dot.code/deobfuscators/Babel_NET/MethodBodyReaderBase.cs
+++ b/de4dot.code/deobfuscators/MethodBodyReaderBase.cs
@@ -24,13 +24,13 @@ using Mono.Cecil;
using Mono.Cecil.Cil;
using de4dot.blocks;
-namespace de4dot.code.deobfuscators.Babel_NET {
+namespace de4dot.code.deobfuscators {
abstract class MethodBodyReaderBase {
protected BinaryReader reader;
public List Locals { get; set; }
public Instruction[] Instructions { get; set; }
public ExceptionHandler[] ExceptionHandlers { get; set; }
- protected ParameterDefinition[] parameters;
+ protected IList parameters;
int currentOffset;
public MethodBodyReaderBase(BinaryReader reader) {
diff --git a/de4dot.code/deobfuscators/Rummage/Deobfuscator.cs b/de4dot.code/deobfuscators/Rummage/Deobfuscator.cs
new file mode 100644
index 00000000..f99473bb
--- /dev/null
+++ b/de4dot.code/deobfuscators/Rummage/Deobfuscator.cs
@@ -0,0 +1,110 @@
+/*
+ Copyright (C) 2011-2012 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System.Collections.Generic;
+using Mono.Cecil;
+using de4dot.blocks;
+
+namespace de4dot.code.deobfuscators.Rummage {
+ public class DeobfuscatorInfo : DeobfuscatorInfoBase {
+ public const string THE_NAME = "Rummage";
+ public const string THE_TYPE = "rm";
+ const string DEFAULT_REGEX = @"!.";
+ public DeobfuscatorInfo()
+ : base(DEFAULT_REGEX) {
+ }
+
+ public override string Name {
+ get { return THE_NAME; }
+ }
+
+ public override string Type {
+ get { return THE_TYPE; }
+ }
+
+ public override IDeobfuscator createDeobfuscator() {
+ return new Deobfuscator(new Deobfuscator.Options {
+ ValidNameRegex = validNameRegex.get(),
+ });
+ }
+ }
+
+ class Deobfuscator : DeobfuscatorBase {
+ StringDecrypter stringDecrypter;
+
+ internal class Options : OptionsBase {
+ }
+
+ public override string Type {
+ get { return DeobfuscatorInfo.THE_TYPE; }
+ }
+
+ public override string TypeLong {
+ get { return DeobfuscatorInfo.THE_NAME; }
+ }
+
+ public override string Name {
+ get { return TypeLong; }
+ }
+
+ public Deobfuscator(Options options)
+ : base(options) {
+ }
+
+ protected override int detectInternal() {
+ int val = 0;
+
+ int sum = toInt32(stringDecrypter.Detected);
+ if (sum > 0)
+ val += 100 + 10 * (sum - 1);
+
+ return val;
+ }
+
+ protected override void scanForObfuscator() {
+ stringDecrypter = new StringDecrypter(module);
+ stringDecrypter.find();
+ }
+
+ public override void deobfuscateBegin() {
+ base.deobfuscateBegin();
+
+ stringDecrypter.initialize();
+ }
+
+
+ public override void deobfuscateMethodEnd(Blocks blocks) {
+ if (CanRemoveStringDecrypterType)
+ stringDecrypter.deobfuscate(blocks);
+ base.deobfuscateMethodEnd(blocks);
+ }
+
+ public override void deobfuscateEnd() {
+ if (CanRemoveStringDecrypterType) {
+ addTypeToBeRemoved(stringDecrypter.Type, "String decrypter type");
+ addTypesToBeRemoved(stringDecrypter.OtherTypes, "Decrypted string type");
+ }
+ base.deobfuscateEnd();
+ }
+
+ public override IEnumerable getStringDecrypterMethods() {
+ return new List();
+ }
+ }
+}
diff --git a/de4dot.code/deobfuscators/Rummage/StringDecrypter.cs b/de4dot.code/deobfuscators/Rummage/StringDecrypter.cs
new file mode 100644
index 00000000..fc390be8
--- /dev/null
+++ b/de4dot.code/deobfuscators/Rummage/StringDecrypter.cs
@@ -0,0 +1,256 @@
+/*
+ Copyright (C) 2011-2012 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using de4dot.blocks;
+
+namespace de4dot.code.deobfuscators.Rummage {
+ class StringDecrypter {
+ ModuleDefinition module;
+ MethodDefinition stringDecrypterMethod;
+ FieldDefinitionAndDeclaringTypeDict stringInfos = new FieldDefinitionAndDeclaringTypeDict();
+ int fileDispl;
+ uint[] key;
+ BinaryReader reader;
+
+ class StringInfo {
+ public readonly FieldDefinition field;
+ public readonly int stringId;
+ public string decrypted;
+
+ public StringInfo(FieldDefinition field, int stringId) {
+ this.field = field;
+ this.stringId = stringId;
+ }
+
+ public override string ToString() {
+ if (decrypted != null)
+ return string.Format("{0:X8} - {1}", stringId, Utils.toCsharpString(decrypted));
+ return string.Format("{0:X8}", stringId);
+ }
+ }
+
+ public TypeDefinition Type {
+ get { return stringDecrypterMethod != null ? stringDecrypterMethod.DeclaringType : null; }
+ }
+
+ public IEnumerable OtherTypes {
+ get {
+ var list = new List(stringInfos.Count);
+ foreach (var info in stringInfos.getValues())
+ list.Add(info.field.DeclaringType);
+ return list;
+ }
+ }
+
+ public bool Detected {
+ get { return stringDecrypterMethod != null; }
+ }
+
+ public StringDecrypter(ModuleDefinition module) {
+ this.module = module;
+ }
+
+ public void find() {
+ foreach (var type in module.Types) {
+ var method = checkType(type);
+ if (method == null)
+ continue;
+ if (!getDispl(method, ref fileDispl))
+ continue;
+
+ stringDecrypterMethod = method;
+ break;
+ }
+ }
+
+ static readonly string[] requiredFields = new string[] {
+ "System.UInt32[]",
+ };
+ static readonly string[] requiredLocals = new string[] {
+ "System.Byte[]",
+ "System.Int32",
+ "System.IO.FileStream",
+ };
+ static MethodDefinition checkType(TypeDefinition type) {
+ if (!new FieldTypes(type).exactly(requiredFields))
+ return null;
+ var cctor = DotNetUtils.getMethod(type, ".cctor");
+ if (cctor == null)
+ return null;
+ if (!new LocalTypes(cctor).all(requiredLocals))
+ return null;
+
+ return checkMethods(type);
+ }
+
+ static MethodDefinition checkMethods(TypeDefinition type) {
+ MethodDefinition cctor = null, decrypterMethod = null;
+ foreach (var method in type.Methods) {
+ if (!method.IsStatic || method.Body == null)
+ return null;
+ if (method.Name == ".cctor")
+ cctor = method;
+ else if (DotNetUtils.isMethod(method, "System.String", "(System.Int32)"))
+ decrypterMethod = method;
+ else
+ return null;
+ }
+ if (cctor == null || decrypterMethod == null)
+ return null;
+
+ return decrypterMethod;
+ }
+
+ static bool getDispl(MethodDefinition method, ref int displ) {
+ var instrs = method.Body.Instructions;
+ for (int i = 0; i < instrs.Count - 2; i++) {
+ var mul = instrs[i];
+ if (mul.OpCode.Code != Code.Mul)
+ continue;
+
+ var ldci4 = instrs[i + 1];
+ if (!DotNetUtils.isLdcI4(ldci4))
+ continue;
+
+ var sub = instrs[i + 2];
+ if (sub.OpCode.Code != Code.Sub)
+ continue;
+
+ displ = DotNetUtils.getLdcI4Value(ldci4);
+ return true;
+ }
+
+ return false;
+ }
+
+ public void initialize() {
+ reader = new BinaryReader(new FileStream(module.FullyQualifiedName, FileMode.Open, FileAccess.Read, FileShare.Read));
+ initKey();
+
+ foreach (var type in module.Types)
+ initType(type);
+ }
+
+ void initKey() {
+ reader.BaseStream.Position = reader.BaseStream.Length - 48;
+ key = new uint[4];
+ for (int i = 0; i < key.Length; i++)
+ key[i] = reader.ReadUInt32();
+ }
+
+ void initType(TypeDefinition type) {
+ var cctor = DotNetUtils.getMethod(type, ".cctor");
+ if (cctor == null)
+ return;
+ var info = getStringInfo(cctor);
+ if (info == null)
+ return;
+
+ stringInfos.add(info.field, info);
+ }
+
+ StringInfo getStringInfo(MethodDefinition method) {
+ if (method == null || method.Body == null)
+ return null;
+ var instrs = method.Body.Instructions;
+ for (int i = 0; i < instrs.Count - 2; i++) {
+ var ldci4 = instrs[i];
+ if (!DotNetUtils.isLdcI4(ldci4))
+ continue;
+ int stringId = DotNetUtils.getLdcI4Value(ldci4);
+
+ var call = instrs[i + 1];
+ if (call.OpCode.Code != Code.Call)
+ continue;
+ var calledMethod = call.Operand as MethodReference;
+ if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(stringDecrypterMethod, calledMethod))
+ continue;
+
+ var stsfld = instrs[i + 2];
+ if (stsfld.OpCode.Code != Code.Stsfld)
+ continue;
+ var field = stsfld.Operand as FieldDefinition;
+ if (field == null)
+ continue;
+
+ return new StringInfo(field, stringId);
+ }
+
+ return null;
+ }
+
+ public void deobfuscate(Blocks blocks) {
+ foreach (var block in blocks.MethodBlocks.getAllBlocks()) {
+ var instrs = block.Instructions;
+ for (int i = 0; i < instrs.Count; i++) {
+ var instr = instrs[i];
+
+ if (instr.OpCode.Code != Code.Ldsfld)
+ continue;
+
+ var field = instr.Operand as FieldReference;
+ if (field == null)
+ continue;
+ var info = stringInfos.find(field);
+ if (info == null)
+ continue;
+ var decrypted = decrypt(info);
+
+ instrs[i] = new Instr(Instruction.Create(OpCodes.Ldstr, decrypted));
+ Log.v("Decrypted string: {0}", Utils.toCsharpString(decrypted));
+ }
+ }
+ }
+
+ string decrypt(StringInfo info) {
+ if (info.decrypted == null)
+ info.decrypted = decrypt(info.stringId);
+
+ return info.decrypted;
+ }
+
+ string decrypt(int stringId) {
+ reader.BaseStream.Position = reader.BaseStream.Length + (stringId * 4 - fileDispl);
+
+ uint v0 = reader.ReadUInt32();
+ uint v1 = reader.ReadUInt32();
+ DeobUtils.xteaDecrypt(ref v0, ref v1, key, 32);
+ int utf8Length = (int)v0;
+ var decrypted = new uint[(utf8Length + 11) / 8 * 2 - 1];
+ decrypted[0] = v1;
+ for (int i = 1; i + 1 < decrypted.Length; i += 2) {
+ v0 = reader.ReadUInt32();
+ v1 = reader.ReadUInt32();
+ DeobUtils.xteaDecrypt(ref v0, ref v1, key, 32);
+ decrypted[i] = v0;
+ decrypted[i + 1] = v1;
+ }
+
+ var utf8 = new byte[utf8Length];
+ Buffer.BlockCopy(decrypted, 0, utf8, 0, utf8.Length);
+ return Encoding.UTF8.GetString(utf8);
+ }
+ }
+}
diff --git a/de4dot.code/resources/ResourceReader.cs b/de4dot.code/resources/ResourceReader.cs
index 26b979ab..e56c0746 100644
--- a/de4dot.code/resources/ResourceReader.cs
+++ b/de4dot.code/resources/ResourceReader.cs
@@ -154,14 +154,12 @@ namespace de4dot.code.resources {
}
static uint readUInt32(BinaryReader reader) {
- uint val = 0;
- for (int i = 0; i < 5; i++) {
- byte b = reader.ReadByte();
- val |= b;
- if ((b & 0x80) == 0)
- return val;
+ try {
+ return Utils.readEncodedUInt32(reader);
+ }
+ catch {
+ throw new ResourceReaderException("Invalid encoded int32");
}
- throw new ResourceReaderException("Invalid encoded int32");
}
bool checkReaders() {
diff --git a/de4dot.cui/Program.cs b/de4dot.cui/Program.cs
index 806cd773..e673043b 100644
--- a/de4dot.cui/Program.cs
+++ b/de4dot.cui/Program.cs
@@ -51,6 +51,7 @@ namespace de4dot.cui {
new de4dot.code.deobfuscators.Goliath_NET.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.MaxtoCode.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.MPRESS.DeobfuscatorInfo(),
+ new de4dot.code.deobfuscators.Rummage.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.Skater_NET.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.SmartAssembly.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.Spices_Net.DeobfuscatorInfo(),
diff --git a/de4dot.cui/Properties/AssemblyInfo.cs b/de4dot.cui/Properties/AssemblyInfo.cs
index f5506648..969276d3 100644
--- a/de4dot.cui/Properties/AssemblyInfo.cs
+++ b/de4dot.cui/Properties/AssemblyInfo.cs
@@ -30,7 +30,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
[assembly: InternalsVisibleTo("de4dot, PublicKey=00240000048000009400000006020000002400005253413100040000010001007b5ffd8f48f1397cd4e21c9e30a5cb36b2c013d6f20688c90e3f0c2d24e6d67cbeea7a6ec3faf9ba081f3d6b6fbe389677adbb8337d3a16187cd13b16a34008a22b89089da41c4a08fd35615c77de0827adcca6d49b08c0ed3e0404a1c44b7d083be614acb1779e4fb275e14427f3687f375d03f3b465c8a6cdeebd1f8c7f4ea")]
[assembly: InternalsVisibleTo("de4dot-x64, PublicKey=00240000048000009400000006020000002400005253413100040000010001007b5ffd8f48f1397cd4e21c9e30a5cb36b2c013d6f20688c90e3f0c2d24e6d67cbeea7a6ec3faf9ba081f3d6b6fbe389677adbb8337d3a16187cd13b16a34008a22b89089da41c4a08fd35615c77de0827adcca6d49b08c0ed3e0404a1c44b7d083be614acb1779e4fb275e14427f3687f375d03f3b465c8a6cdeebd1f8c7f4ea")]
diff --git a/de4dot.mdecrypt/DynamicMethodsDecrypter.cs b/de4dot.mdecrypt/DynamicMethodsDecrypter.cs
index cf898c6c..21051842 100644
--- a/de4dot.mdecrypt/DynamicMethodsDecrypter.cs
+++ b/de4dot.mdecrypt/DynamicMethodsDecrypter.cs
@@ -244,7 +244,8 @@ namespace de4dot.mdecrypt {
uint size = pSection->VirtualSize;
uint rva = pSection->VirtualAddress;
- return new IntPtr((byte*)hDll + rva + size);
+ int displ = -4;
+ return new IntPtr((byte*)hDll + rva + size + displ);
}
throw new ApplicationException("Could not find .text section");
diff --git a/de4dot.mdecrypt/Properties/AssemblyInfo.cs b/de4dot.mdecrypt/Properties/AssemblyInfo.cs
index ace0ff4e..104fc3ef 100644
--- a/de4dot.mdecrypt/Properties/AssemblyInfo.cs
+++ b/de4dot.mdecrypt/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]
diff --git a/de4dot/Properties/AssemblyInfo.cs b/de4dot/Properties/AssemblyInfo.cs
index 5f0873fa..91fcd4d3 100644
--- a/de4dot/Properties/AssemblyInfo.cs
+++ b/de4dot/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.8.4.3405")]
-[assembly: AssemblyFileVersion("1.8.4.3405")]
+[assembly: AssemblyVersion("1.8.5.3405")]
+[assembly: AssemblyFileVersion("1.8.5.3405")]