diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index bc39df46..c8ed7178 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -89,6 +89,7 @@ + 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.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");