private int?CalculateSwitchCaseIndex(Block block, SwitchData switchData, int key) { if (switchData is NativeSwitchData) { _instructionEmulator.Push(new Int32Value(key)); _instructionEmulator.Emulate(block.Instructions, block.SwitchData.IsKeyHardCoded ? 2 : 1, block.Instructions.Count - 1); var popValue = _instructionEmulator.Peek(); _instructionEmulator.Pop(); return(((Int32Value)popValue).Value); } if (switchData is NormalSwitchData) { var normalSwitchData = (NormalSwitchData)switchData; return(key % normalSwitchData.DivisionKey); } return(null); }
public int emulate(int val, out int locValue) { locValue = 0; //we take the value of the arg as a parameter to pass along to the switch block var ins = new InstructionEmulator(blocks.Method); ins.Initialize(blocks.Method); if (native) { var test = x86emulate(switchBlock.FirstInstr.Operand as MethodDef, new[] { val }); ins.Push(new Int32Value(test)); //emulates the block however we dont emulate all the block ins.Emulate(switchBlock.Instructions, 1, switchBlock.Instructions.Count - 1); //we now get the local value this will contain the num value used to work out the next arg in the next case if (!isolder) { locValue = (ins.GetLocal(localSwitch) as Int32Value).Value; } } else { ins.Push(new Int32Value(val)); //emulates the block however we dont emulate all the block ins.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1); //we now get the local value this will contain the num value used to work out the next arg in the next case if (!isolder) { locValue = (ins.GetLocal(localSwitch) as Int32Value).Value; } } //we use de4dots instructionEmulator to emulate the block //we push the arg value to the stack //we peek at the stack value and this is the next case so we return this to continue var caseValue = ins.Peek() as Int32Value; return(caseValue.Value); }
private int EmulateManagedMethod(MethodDef method, int startIndex, int endIndex, params Tuple <Parameter, int>[] parameters) { _instructionEmulator.Initialize(method, false); foreach (var parameter in parameters) { _instructionEmulator.SetArg(parameter.Item1, new Int32Value(parameter.Item2)); } for (var i = startIndex; i < endIndex; i++) { _instructionEmulator.Emulate(method.Body.Instructions[i]); } return(((Int32Value)_instructionEmulator.Pop()).Value); }
uint CalculateMagic(uint input) { instrEmulator.Initialize(method, method.Parameters, locals, method.Body.InitLocals, false); instrEmulator.SetLocal(emuLocal, new Int32Value((int)input)); foreach (var instr in instructions) { instrEmulator.Emulate(instr); } var tos = instrEmulator.Pop() as Int32Value; if (tos == null || !tos.AllBitsValid()) { throw new ApplicationException("Couldn't calculate magic value"); } return((uint)tos.Value); }
int GetOffset(int offset) { if (OffsetCalcInstructions == null || OffsetCalcInstructions.Count == 0) { return(offset); } if (dummyMethod == null) { dummyMethod = new MethodDefUser(); dummyMethod.Body = new CilBody(); } emulator.Initialize(dummyMethod); emulator.Push(new Int32Value(offset)); foreach (var instr in OffsetCalcInstructions) { emulator.Emulate(instr); } return(((Int32Value)emulator.Pop()).Value); }
public static int GetResult(int num, MethodDef targetMd) { InstructionEmulator em = new InstructionEmulator(); MethodDefUser dummy_method = new MethodDefUser(); dummy_method.Body = new dnlib.DotNet.Emit.CilBody(); em.Initialize(dummy_method); List <Instruction> emuTargets = new List <Instruction>(); foreach (Instruction inst in targetMd.Body.Instructions) { if (inst.OpCode == OpCodes.Stfld || inst.OpCode == OpCodes.Ldarg_0 || inst.OpCode == OpCodes.Call || inst.OpCode == OpCodes.Ret) { continue; } if (inst.OpCode == OpCodes.Ldarg_1) { emuTargets.Add(Instruction.Create(OpCodes.Ldc_I4, num)); } else if (inst.OpCode == OpCodes.Ldarg) { if (((Parameter)inst.Operand).Type.FullName == typeof(System.Int32).FullName && ((Parameter)inst.Operand).Index == 0x1) { emuTargets.Add(Instruction.Create(OpCodes.Ldc_I4, num)); } } else { emuTargets.Add(inst); } } foreach (Instruction inst in emuTargets) { em.Emulate(inst); } var x = (Int32Value)em.Pop(); return(x.Value.GetHashCode()); }
public bool Create() { int arrayIndex; Value array; object value; while (true) { var instr = method.Body.Instructions[index]; switch (instr.OpCode.Code) { case Code.Ret: return(true); case Code.Newarr: var arrayType = (ITypeDefOrRef)instr.Operand; int arrayCount = ((Int32Value)emulator.Pop()).Value; if (arrayType.FullName == "System.Char") { emulator.Push(new UserValue(new char[arrayCount])); } else { emulator.Push(new UnknownValue()); } break; case Code.Call: case Code.Callvirt: if (!DoCall(instr)) { return(false); } break; case Code.Ldelem_U1: arrayIndex = ((Int32Value)emulator.Pop()).Value; array = (Value)emulator.Pop(); if (array is UserValue) { emulator.Push(new Int32Value(((byte[])((UserValue)array).obj)[arrayIndex])); } else { emulator.Push(Int32Value.CreateUnknownUInt8()); } break; case Code.Stelem_I1: value = emulator.Pop(); arrayIndex = ((Int32Value)emulator.Pop()).Value; array = (Value)emulator.Pop(); if (array is UserValue) { ((byte[])((UserValue)array).obj)[arrayIndex] = (byte)((Int32Value)value).Value; } break; case Code.Stelem_I2: value = emulator.Pop(); arrayIndex = ((Int32Value)emulator.Pop()).Value; array = (Value)emulator.Pop(); if (array is UserValue) { ((char[])((UserValue)array).obj)[arrayIndex] = (char)((Int32Value)value).Value; } break; case Code.Ldelem_Ref: arrayIndex = ((Int32Value)emulator.Pop()).Value; array = (Value)emulator.Pop(); var userValue = array as UserValue; if (userValue != null && userValue.obj is string[]) { emulator.Push(new StringValue(((string[])userValue.obj)[arrayIndex])); } else { emulator.Push(new UnknownValue()); } break; case Code.Ldsfld: emulator.Push(new UserValue((IField)instr.Operand)); break; default: emulator.Emulate(instr); break; } index++; } }
bool Cleaner() { bool modified = false; List <Block> allblocks = new List <Block>(); foreach (var block in allBlocks) { if (block.FallThrough == switchBlock) { allblocks.Add(block); } } List <Block> targetBlocks = new List <Block>(); targetBlocks = switchBlock.Targets; foreach (Block block in allblocks) { if (block.LastInstr.IsLdcI4()) { int val1 = block.LastInstr.GetLdcI4Value(); ins.Push(new Int32Value(val1)); int nextCase = emulateCase(out int localValue); if (Program.veryVerbose) { Console.ForegroundColor = ConsoleColor.Cyan; Console.Write(nextCase + ","); Console.ForegroundColor = ConsoleColor.Green; } block.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]); replace(targetBlocks[nextCase], localValue); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); modified = true; } else if (isXor(block)) { ins.Emulate(block.Instructions, block.Instructions.Count - 5, block.Instructions.Count); Int32Value val1 = (Int32Value)ins.Pop(); ins.Push(val1); int nextCase = emulateCase(out int localValue); if (Program.veryVerbose) { Console.ForegroundColor = ConsoleColor.Cyan; Console.Write(nextCase + ","); Console.ForegroundColor = ConsoleColor.Green; } block.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]); replace(targetBlocks[nextCase], localValue); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); modified = true; } else if (block.Sources.Count == 2 && block.Instructions.Count == 1) { var sources = new List <Block>(block.Sources); foreach (Block source in sources) { if (source.FirstInstr.IsLdcI4()) { int val1 = source.FirstInstr.GetLdcI4Value(); ins.Push(new Int32Value(val1)); int nextCase = emulateCase(out int localValue); if (Program.veryVerbose) { Console.ForegroundColor = ConsoleColor.Cyan; if (source == sources[0]) { Console.Write("True: " + nextCase + ","); } else { Console.Write("False: " + nextCase + ","); } Console.ForegroundColor = ConsoleColor.Green; } source.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]); replace(targetBlocks[nextCase], localValue); source.Instructions[1] = (new Instr(new Instruction(OpCodes.Pop))); modified = true; } } } else if (block.LastInstr.OpCode == OpCodes.Xor) { if (block.Instructions[block.Instructions.Count - 2].OpCode == OpCodes.Mul) { var instr = block.Instructions; int l = instr.Count; if (!(instr[l - 4].IsLdcI4())) { continue; } var sources = new List <Block>(block.Sources); foreach (Block source in sources) { if (source.FirstInstr.IsLdcI4()) { int val1 = source.FirstInstr.GetLdcI4Value(); try { instr[l - 5] = new Instr(new Instruction(OpCodes.Ldc_I4, val1)); } catch { instr.Insert(l - 4, new Instr(new Instruction(OpCodes.Ldc_I4, val1))); l++; } ins.Emulate(instr, l - 5, l); int nextCase = emulateCase(out int localValue); if (Program.veryVerbose) { Console.ForegroundColor = ConsoleColor.Cyan; if (source == sources[0]) { Console.Write("True: " + nextCase + ","); } else { Console.Write("False: " + nextCase + ","); } Console.ForegroundColor = ConsoleColor.Green; } source.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]); replace(targetBlocks[nextCase], localValue); try { source.Instructions[1] = (new Instr(new Instruction(OpCodes.Pop))); } catch { source.Instructions.Add((new Instr(new Instruction(OpCodes.Pop)))); } modified = true; } } } } } return(modified); }
bool EmulateDynocode(InstructionEmulator emu, ref int index) { var instrs = stringMethod.Body.Instructions; var instr = instrs[index]; var ctor = instr.Operand as MethodDef; if (ctor == null || ctor.MethodSig.GetParamCount() != 1 || ctor.MethodSig.Params[0].ElementType != ElementType.I4) { return(false); } if (index + 4 >= instrs.Count) { return(false); } var ldloc = instrs[index + 3]; var stfld = instrs[index + 4]; if (!ldloc.IsLdloc() || stfld.OpCode.Code != Code.Stfld) { return(false); } var enumerableField = stfld.Operand as FieldDef; if (enumerableField == null) { return(false); } var initValue = emu.GetLocal(ldloc.GetLocal(stringMethod.Body.Variables)) as Int32Value; if (initValue == null || !initValue.AllBitsValid()) { return(false); } int leaveIndex = FindLeave(instrs, index); if (leaveIndex < 0) { return(false); } var afterLoop = instrs[leaveIndex].Operand as Instruction; if (afterLoop == null) { return(false); } int newIndex = instrs.IndexOf(afterLoop); var loopLocal = GetDCLoopLocal(index, newIndex); if (loopLocal == null) { return(false); } var initValue2 = emu.GetLocal(loopLocal) as Int32Value; if (initValue2 == null || !initValue2.AllBitsValid()) { return(false); } int loopStart = GetIndexOfCall(instrs, index, leaveIndex, "System.Int32", "()"); int loopEnd = GetIndexOfCall(instrs, loopStart, leaveIndex, "System.Boolean", "()"); if (loopStart < 0 || loopEnd < 0) { return(false); } loopStart++; loopEnd--; dynocode.Initialize(module); var ctorArg = emu.Pop() as Int32Value; if (ctorArg == null || !ctorArg.AllBitsValid()) { return(false); } dynocode.CreateEnumerable(ctor, new object[] { ctorArg.Value }); dynocode.WriteEnumerableField(enumerableField.MDToken.ToUInt32(), initValue.Value); dynocode.CreateEnumerator(); foreach (var val in dynocode) { emu.Push(new Int32Value(val)); for (int i = loopStart; i < loopEnd; i++) { emu.Emulate(instrs[i]); } } index = newIndex - 1; return(true); }
bool FindInts(int index) { if (index < 0) { return(false); } i2 = 0; var instrs = stringMethod.Body.Instructions; var emu = new InstructionEmulator(stringMethod); foreach (var kv in stringMethodConsts.Locals32) { emu.SetLocal(kv.Key, new Int32Value(kv.Value)); } var fields = new Dictionary <FieldDef, int?>(); for (int i = index; i < instrs.Count - 2; i++) { var instr = instrs[i]; FieldDef field; switch (instr.OpCode.Code) { case Code.Ldsfld: field = instr.Operand as FieldDef; if (field == null || field.DeclaringType != stringMethod.DeclaringType || field.FieldType.GetElementType() != ElementType.I4) { goto default; } fields[field] = null; emu.Push(new Int32Value(i1)); break; case Code.Stsfld: field = instr.Operand as FieldDef; if (field == null || field.DeclaringType != stringMethod.DeclaringType || field.FieldType.GetElementType() != ElementType.I4) { goto default; } if (fields.ContainsKey(field) && fields[field] == null) { goto default; } var val = emu.Pop() as Int32Value; if (val == null || !val.AllBitsValid()) { fields[field] = null; } else { fields[field] = val.Value; } break; case Code.Call: var method = instr.Operand as MethodDef; if (!decrypterType.Detected || method != decrypterType.Int64Method) { goto done; } emu.Push(new Int64Value((long)decrypterType.GetMagic())); break; case Code.Newobj: if (!EmulateDynocode(emu, ref i)) { goto default; } break; default: if (instr.OpCode.FlowControl != FlowControl.Next) { goto done; } emu.Emulate(instr); break; } } done :; foreach (var val in fields.Values) { if (val == null) { continue; } magic1 = i2 = val.Value; return(true); } return(false); }
public static Value[] GetInitializedArray(int arraySize, MethodDef method, ref int newarrIndex, Code stelemOpCode) { var resultValueArray = new Value[arraySize]; var emulator = new InstructionEmulator(method); var theArray = new UnknownValue(); emulator.Push(theArray); var instructions = method.Body.Instructions; int i; for (i = newarrIndex + 1; i < instructions.Count; i++) { var instr = instructions[i]; if (instr.OpCode.FlowControl != FlowControl.Next) { break; } if (instr.OpCode.Code == Code.Newarr) { break; } switch (instr.OpCode.Code) { case Code.Newarr: case Code.Newobj: goto done; case Code.Stloc: case Code.Stloc_S: case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: case Code.Starg: case Code.Starg_S: case Code.Stsfld: case Code.Stfld: if (emulator.Peek() == theArray && i != newarrIndex + 1 && i != newarrIndex + 2) { goto done; } break; } if (instr.OpCode.Code == stelemOpCode) { var value = emulator.Pop(); var index = emulator.Pop() as Int32Value; var array = emulator.Pop(); if (ReferenceEquals(array, theArray) && index != null && index.AllBitsValid()) { if (0 <= index.Value && index.Value < resultValueArray.Length) { resultValueArray[index.Value] = value; } } } else { emulator.Emulate(instr); } } done: if (i != newarrIndex + 1) { i--; } newarrIndex = i; return(resultValueArray); }
bool GetNewValue(MethodDef method, int arg, out int newValue) { newValue = 0; emulator.Initialize(method); emulator.SetArg(method.Parameters[0], new Int32Value(arg)); Instruction instr; emulateIndex = 0; instructions = method.Body.Instructions; int counter = 0; while (true) { if (counter++ >= 50) { return(false); } if (emulateIndex < 0 || emulateIndex >= instructions.Count) { return(false); } instr = instructions[emulateIndex]; switch (instr.OpCode.Code) { case Code.Ldarg: case Code.Ldarg_S: case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Stloc: case Code.Stloc_S: case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: case Code.Ldloc: case Code.Ldloc_S: case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: case Code.Ldc_I4: case Code.Ldc_I4_0: case Code.Ldc_I4_1: case Code.Ldc_I4_2: case Code.Ldc_I4_3: case Code.Ldc_I4_4: case Code.Ldc_I4_5: case Code.Ldc_I4_6: case Code.Ldc_I4_7: case Code.Ldc_I4_8: case Code.Ldc_I4_M1: case Code.Ldc_I4_S: case Code.Add: case Code.Sub: case Code.Xor: case Code.Or: case Code.Nop: case Code.Dup: case Code.Mul: case Code.Rem: case Code.Div: emulator.Emulate(instr); emulateIndex++; break; case Code.Br: case Code.Br_S: case Code.Beq: case Code.Beq_S: case Code.Bge: case Code.Bge_S: case Code.Bge_Un: case Code.Bge_Un_S: case Code.Bgt: case Code.Bgt_S: case Code.Bgt_Un: case Code.Bgt_Un_S: case Code.Ble: case Code.Ble_S: case Code.Ble_Un: case Code.Ble_Un_S: case Code.Blt: case Code.Blt_S: case Code.Blt_Un: case Code.Blt_Un_S: case Code.Bne_Un: case Code.Bne_Un_S: case Code.Brfalse: case Code.Brfalse_S: case Code.Brtrue: case Code.Brtrue_S: case Code.Switch: if (!branchEmulator.Emulate(instr)) { return(false); } break; case Code.Ret: var retValue = emulator.Pop(); if (!retValue.IsInt32()) { return(false); } var retValue2 = (Int32Value)retValue; if (!retValue2.AllBitsValid()) { return(false); } newValue = retValue2.Value; return(true); default: if (instr.OpCode.OpCodeType != OpCodeType.Prefix) { return(false); } emulateIndex++; break; } } }
bool EmulateInstructions(ref int index, bool allowUnknownArgs) { Instruction instr; var instrs = methodToInline.Body.Instructions; int counter = 0; var foundOpCodes = new Dictionary <Code, bool>(); bool checkInstrs = false; while (true) { if (counter++ >= 50) { return(false); } if (index < 0 || index >= instrs.Count) { return(false); } instr = instrs[index]; foundOpCodes[instr.OpCode.Code] = true; switch (instr.OpCode.Code) { case Code.Stloc: case Code.Stloc_S: case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: case Code.Ldloc: case Code.Ldloc_S: case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: case Code.Ldc_I4: case Code.Ldc_I4_0: case Code.Ldc_I4_1: case Code.Ldc_I4_2: case Code.Ldc_I4_3: case Code.Ldc_I4_4: case Code.Ldc_I4_5: case Code.Ldc_I4_6: case Code.Ldc_I4_7: case Code.Ldc_I4_8: case Code.Ldc_I4_M1: case Code.Ldc_I4_S: case Code.Add: case Code.Sub: case Code.Xor: case Code.Or: case Code.Nop: case Code.Dup: case Code.Mul: case Code.Rem: case Code.Div: instructionEmulator.Emulate(instr); index++; break; case Code.Ldarg: case Code.Ldarg_S: case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: var arg = instr.GetParameter(parameters); if (arg != arg1 && arg != arg2) { if (!allowUnknownArgs) { goto done; } checkInstrs = true; } instructionEmulator.Emulate(instr); index++; break; case Code.Call: case Code.Callvirt: case Code.Newobj: goto done; case Code.Switch: var value = instructionEmulator.Pop() as Int32Value; if (value == null || !value.AllBitsValid()) { return(false); } var targets = (Instruction[])instr.Operand; if (value.Value >= 0 && value.Value < targets.Length) { index = instrs.IndexOf(targets[value.Value]); } else { index++; } break; case Code.Br: case Code.Br_S: index = instrs.IndexOf((Instruction)instr.Operand); break; case Code.Brtrue: case Code.Brtrue_S: index = EmulateBrtrue(index); break; case Code.Brfalse: case Code.Brfalse_S: index = EmulateBrfalse(index); break; case Code.Isinst: case Code.Castclass: if (returnValue != null && instructionEmulator.Peek() == returnValue) { // Do nothing } else { instructionEmulator.Emulate(instr); } index++; break; default: if (instr.OpCode.OpCodeType != OpCodeType.Prefix) { goto done; } index++; break; } } done: if (checkInstrs) { if (!foundOpCodes.ContainsKey(Code.Ldc_I4_1)) { return(false); } if (!foundOpCodes.ContainsKey(Code.Ldc_I4_2)) { return(false); } if (!foundOpCodes.ContainsKey(Code.Add)) { return(false); } if (!foundOpCodes.ContainsKey(Code.Dup)) { return(false); } if (!foundOpCodes.ContainsKey(Code.Mul)) { return(false); } if (!foundOpCodes.ContainsKey(Code.Rem)) { return(false); } if (!foundOpCodes.ContainsKey(Code.Brtrue) && !foundOpCodes.ContainsKey(Code.Brtrue_S) && !foundOpCodes.ContainsKey(Code.Brfalse) && !foundOpCodes.ContainsKey(Code.Brfalse_S)) { return(false); } } return(true); }
bool GetNewValue(MethodDef method, int arg, out int newValue) { newValue = 0; emulator.Initialize(method); emulator.SetArg(method.Parameters[0], new Int32Value(arg)); emulateIndex = 0; instructions = method.Body.Instructions; int counter = 0; while (true) { if (counter++ >= 50) { return(false); } if (emulateIndex < 0 || emulateIndex >= instructions.Count) { return(false); } var instr = instructions[emulateIndex]; switch (instr.OpCode.Code) { case Code.Br: case Code.Br_S: case Code.Beq: case Code.Beq_S: case Code.Bge: case Code.Bge_S: case Code.Bge_Un: case Code.Bge_Un_S: case Code.Bgt: case Code.Bgt_S: case Code.Bgt_Un: case Code.Bgt_Un_S: case Code.Ble: case Code.Ble_S: case Code.Ble_Un: case Code.Ble_Un_S: case Code.Blt: case Code.Blt_S: case Code.Blt_Un: case Code.Blt_Un_S: case Code.Bne_Un: case Code.Bne_Un_S: case Code.Brfalse: case Code.Brfalse_S: case Code.Brtrue: case Code.Brtrue_S: case Code.Switch: if (!branchEmulator.Emulate(instr)) { return(false); } break; case Code.Ret: var retValue = emulator.Pop(); if (!retValue.IsInt32()) { return(false); } var retValue2 = (Int32Value)retValue; if (!retValue2.AllBitsValid()) { return(false); } newValue = retValue2.Value; return(true); default: emulator.Emulate(instr); emulateIndex++; break; } } }
private bool doit(Block swBlock) { var modified = false; if (swBlock.Targets == null) { return(modified); } var allSwBlocks = allBlocks.Where(block => block.FallThrough == swBlock).ToList(); foreach (var block in allSwBlocks) { var instr = block.Instructions; var count = block.Instructions.Count; int localVal; if (block.LastInstr.IsLdcI4() && count == 3) { ins.Emulate(instr, count - 3, count); var nextCase = caseEmulate(out localVal); block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); replace(swBlock.Targets[nextCase], localVal); modified = true; } else if (use1(block)) { ins.Emulate(instr, count - 9, count); var nextCase = caseEmulate(out localVal); block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); replace(swBlock.Targets[nextCase], localVal); modified = true; } else if (use2(block)) { ins.Emulate(instr, count - 5, count); var nextCase = caseEmulate(out localVal); block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); replace(swBlock.Targets[nextCase], localVal); modified = true; } else if (iseasyBlock(block)) { ins.Emulate(instr, count - 3, count); var nextCase = caseEmulate(out localVal); block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); replace(swBlock.Targets[nextCase], localVal); modified = true; } else if (isMathCase(block) || isMathCase3(block)) { if (!instr[count - 7].IsLdcI4()) { continue; } ins.Emulate(instr, count - 7, count); var nextCase = caseEmulate(out localVal); block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); replace(swBlock.Targets[nextCase], localVal); modified = true; } else if (isMathCase2(block)) { if (!instr[count - 9].IsLdcI4()) { continue; } ins.Emulate(instr, count - 9, count); var nextCase = caseEmulate(out localVal); block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); replace(swBlock.Targets[nextCase], localVal); modified = true; } else if (isMathCase4(block)) { if (!instr[count - 9].IsLdcI4()) { continue; } ins.Emulate(instr, count - 9, count); var nextCase = caseEmulate(out localVal); block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); replace(swBlock.Targets[nextCase], localVal); modified = true; } else if (anotherunSure(block)) { var sources = new List <Block>(block.Sources); foreach (var sour in sources) { if (!sour.FirstInstr.IsLdcI4()) { continue; } // ins.Push(new Int32Value(sour.FirstInstr.GetLdcI4Value())); block.Instructions[count - 3] = new Instr(Instruction.CreateLdcI4(sour.FirstInstr.GetLdcI4Value())); ins.Emulate(instr, count - 3, count); var nextCase = caseEmulate(out localVal); sour.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); sour.Remove(0, sour.Instructions.Count); replace(swBlock.Targets[nextCase], localVal); modified = true; } } else if (unsureCase(block)) { var sources = new List <Block>(block.Sources); foreach (var sour in sources) { if (!sour.FirstInstr.IsLdcI4()) { continue; } if (sour.Instructions.Count != 2) { continue; } // ins.Push(new Int32Value(sour.FirstInstr.GetLdcI4Value())); block.Instructions[count - 7] = new Instr(Instruction.CreateLdcI4(sour.FirstInstr.GetLdcI4Value())); ins.Emulate(instr, count - 7, count); var nextCase = caseEmulate(out localVal); sour.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]); sour.Remove(0, sour.Instructions.Count); replace(swBlock.Targets[nextCase], localVal); modified = true; } } else if (count == 1) { } } return(modified); }
protected override bool Deobfuscate(Block block) { ins = ControlFlowRemover.Inemu; var modified = false; // var blocks2 = blocks.MethodBlocks.GetAllBlocks(); if (block.LastInstr.OpCode != OpCodes.Switch) { return(false); } if (blocks.Method.MDToken.ToInt32() == 0x060000CC) { } if (block.Instructions.Count <= 4) { return(false); } if (block.Instructions[block.Instructions.Count - 4].IsStloc()) { if (blocks.Method.MDToken.ToInt32() == 0x060000CC) { } // return false; var baseBlocksParent = block.Parent; var abc = baseBlocksParent.GetAllBlocks()[0].Instructions; foreach (var blockInstruction in abc) { if (blockInstruction.IsStloc()) { if (blockInstruction.Instruction.GetLocal(blocks.Method.Body.Variables).Type == blocks.Method.Module.CorLibTypes.UInt32) { loc = blockInstruction.Instruction.GetLocal(blocks.Locals); ins.Emulate(abc); break; } } } // return false; swlocal = Instr.GetLocalVar(blocks.Locals, block.Instructions[block.Instructions.Count - 4]); swBlock = block; modified = doit(block); } else if (!block.Instructions[block.Instructions.Count - 4].IsStloc() && block.Instructions[block.Instructions.Count - 2].OpCode != OpCodes.Nop) { // return false; if (blocks.Method.MDToken.ToInt32() == 0x060000CC) { } var baseBlocksParent = block.Parent; var abc = baseBlocksParent.GetAllBlocks()[0].Instructions; foreach (var blockInstruction in abc) { if (blockInstruction.IsStloc()) { loc = blockInstruction.Instruction.GetLocal(blocks.Locals); ins.Emulate(abc); break; } } // return false; swlocal = null; swBlock = block; modified = doit(block); } return(modified); }