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")]