public VMSlot InferStackValue() { var emulator = new InstructionEmulator(); var pushValue = DataSources.First(); // TODO: might need to verify multiple data sources. emulator.EmulateDependentInstructions(pushValue); emulator.EmulateInstruction(pushValue); return(emulator.Stack.Pop()); }
private void EmulateMethod(DelegateInitInfo info, InstructionEmulator emulator) { var blocks = new Blocks(info.InitMethod); var allBlocks = blocks.MethodBlocks.GetAllBlocks(); emulator.Initialize(blocks, true); emulator.SetArg(0, new ObjectValue(info.Field)); emulator.SetArg(1, new Int32Value(info.Key)); EmulatoeBlock(emulator, allBlocks[0]); }
private void EmulateBrantchBlock(InstructionEmulator emulator, Block block) { if (block == null) { return; } var instr = block.Instructions; var isSwitch = block.LastInstr.OpCode == OpCodes.Switch; for (int i = 0; i < instr.Count - (isSwitch ? 1 : 0); i++) { if (instr[i].OpCode == OpCodes.Call && instr[i].Operand is MethodDef nativeMethod && IsNativeMethod(nativeMethod)) { EmulateNativeMethod(emulator, nativeMethod); }
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 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); }
public static void CleanVarMelt(MethodDef meth) { var blocks = new Blocks(meth); CfDeob.Initialize(blocks); Inemu = new InstructionEmulator(meth); // CfDeob.Add(new LocalsSolver()); CfDeob.Add(new VariableMelting()); // CfDeob.Add(new VariableMelting()); CfDeob.Deobfuscate(); blocks.RepartitionBlocks(); // de4dot.blocks.NetguardCflow tfhdgrs = new de4dot.blocks.NetguardCflow(); // de4dot.blocks.NetguardCflow.test2 = blocks; // tfhdgrs.Deobfuscate(test); IList <Instruction> instructions; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out instructions, out exceptionHandlers); DotNetUtils.RestoreBody(meth, instructions, exceptionHandlers); }
private JumpAnnotation InferJumpTargets(ILInstruction instruction) { try { var metadata = new JumpAnnotation(); var symbolicAddress = instruction.Dependencies[instruction.Dependencies.Count - 1]; foreach (var dataSource in symbolicAddress.DataSources) { var emulator = new InstructionEmulator(); emulator.EmulateDependentInstructions(dataSource); emulator.EmulateInstruction(dataSource); // After partial emulation, IP is on stack. uint nextIp = (uint)emulator.Stack.Pop().U8; Logger.Debug2(Tag, $"Inferred edge IL_{instruction.Offset:X4} -> IL_{nextIp:X4}"); if (nextIp > (ulong)KoiStream.Contents.GetPhysicalSize()) { Logger.Warning(Tag, $"Jump instruction at IL_{instruction.Offset:X4} " + $"transfers control to an instruction outside of the KoiVM stream (IL_{nextIp:X4}."); } metadata.InferredJumpTargets.Add(nextIp); } instruction.Annotation = metadata; return(metadata); } catch (NotSupportedException e) { Logger.Warning(Tag, $"Could not infer jump target for {instruction.Offset:X4}. {e.Message}"); } return(null); }
public void DecryptMethods() { for (int i = 0; i < delegateInfos.Count; i++) { var info = delegateInfos[i]; var emuator = new InstructionEmulator(); EmulateMethod(info, emuator); var local = info.InitMethod.Body.Variables.FirstOrDefault(t => t.Type.FullName == "System.Reflection.MethodBase"); if (local == null) { continue; } var value = emuator.GetLocal(local); if (!(value is ObjectValue objValue) || !(objValue.obj is IMethod method)) { continue; } info.Resolved = true; info.Decrypted = method; info.OpCode = ResolveOpCode(info.InitMethod, info.Field, info.Key); Decrypted++; } }
public ReflectionToDNLibMethodCreator(MethodDef method) { this.method = method; this.emulator = new InstructionEmulator(method); }
public static Value[] getInitializedArray(int arraySize, MethodDefinition 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); }
public BabelMethodCallInliner() { emulator = new InstructionEmulator(); branchEmulator = new BranchEmulator(emulator, this); }
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); }
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]; if (!ldloc.IsLdloc() || instrs[index + 4].OpCode.Code != Code.Stfld) { 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); } var dcGen = dynocode.getDynocodeGenerator(ctor.DeclaringType); if (dcGen == null) { return(false); } int loopLocalValue = initValue2.value; foreach (var val in dcGen.getValues(initValue.value)) { loopLocalValue ^= val; } emu.setLocal(loopLocal, new Int32Value(loopLocalValue)); emu.emulate(instr); index = newIndex - 1; return(true); }
public ReflectionToCecilMethodCreator(MethodDefinition method) { this.method = method; this.emulator = new InstructionEmulator(method); }
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); }