public MethodDefinition deobfuscate(MethodDefinition method) { MethodDefinition deobfuscatedMethod; if (deobfuscated.TryGetValue(method, out deobfuscatedMethod)) { return(deobfuscatedMethod); } if (method.Body == null || method.Body.Instructions.Count == 0) { deobfuscated[method] = method; return(method); } deobfuscatedMethod = DotNetUtils.clone(method); deobfuscated[method] = deobfuscatedMethod; var blocks = new Blocks(deobfuscatedMethod); deobfuscate(blocks); IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; blocks.getCode(out allInstructions, out allExceptionHandlers); DotNetUtils.restoreBody(deobfuscatedMethod, allInstructions, allExceptionHandlers); return(deobfuscatedMethod); }
public InstructionPatcher(int patchIndex, int afterIndex, Instruction lastInstr) { this.patchIndex = patchIndex; this.afterIndex = afterIndex; this.lastInstr = lastInstr; this.clonedInstr = new Instr(DotNetUtils.clone(lastInstr)); }
protected bool inlineLoadMethod(int patchIndex, MethodDefinition methodToInline, Instruction loadInstr, int instrIndex) { if (!isReturn(methodToInline, instrIndex)) { return(false); } int methodArgsCount = DotNetUtils.getArgsCount(methodToInline); for (int i = 0; i < methodArgsCount; i++) { block.insert(patchIndex++, Instruction.Create(OpCodes.Pop)); } block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(loadInstr)); return(true); }
protected bool inlineLoadMethod(int patchIndex, MethodDefinition methodToInline, Instruction loadInstr, int instrIndex) { var instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex); if (instr == null || instr.OpCode.Code != Code.Ret) { return(false); } int methodArgsCount = DotNetUtils.getArgsCount(methodToInline); for (int i = 0; i < methodArgsCount; i++) { block.insert(patchIndex++, Instruction.Create(OpCodes.Pop)); } block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(loadInstr)); return(true); }
protected bool inlineOtherMethod(int patchIndex, MethodDefinition methodToInline, Instruction instr, int instrIndex, int popLastArgs = 0) { int loadIndex = 0; int methodArgsCount = DotNetUtils.getArgsCount(methodToInline); bool foundLdarga = false; while (instr != null && loadIndex < methodArgsCount) { bool isLdarg = true; 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: break; case Code.Ldarga: case Code.Ldarga_S: foundLdarga = true; break; default: isLdarg = false; break; } if (!isLdarg) { break; } if (DotNetUtils.getArgIndex(instr) != loadIndex) { return(false); } loadIndex++; instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex); } if (instr == null || loadIndex != methodArgsCount - popLastArgs) { return(false); } if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) { if (foundLdarga) { return(false); } var callInstr = instr; var calledMethod = callInstr.Operand as MethodReference; if (calledMethod == null) { return(false); } if (!isCompatibleType(-1, calledMethod.MethodReturnType.ReturnType, methodToInline.MethodReturnType.ReturnType)) { return(false); } if (!checkSameMethods(calledMethod, methodToInline, popLastArgs)) { return(false); } instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex); if (instr == null || instr.OpCode.Code != Code.Ret) { return(false); } block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(callInstr)); return(true); } else if (instr.OpCode.Code == Code.Newobj) { if (foundLdarga) { return(false); } var newobjInstr = instr; var ctor = newobjInstr.Operand as MethodReference; if (ctor == null) { return(false); } if (!isCompatibleType(-1, ctor.DeclaringType, methodToInline.MethodReturnType.ReturnType)) { return(false); } var methodArgs = DotNetUtils.getArgs(methodToInline); var calledMethodArgs = DotNetUtils.getArgs(ctor); if (methodArgs.Count + 1 - popLastArgs != calledMethodArgs.Count) { return(false); } for (int i = 1; i < calledMethodArgs.Count; i++) { if (!isCompatibleType(i, calledMethodArgs[i], methodArgs[i - 1])) { return(false); } } instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex); if (instr == null || instr.OpCode.Code != Code.Ret) { return(false); } block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(newobjInstr)); return(true); } else if (instr.OpCode.Code == Code.Ldfld || instr.OpCode.Code == Code.Ldflda || instr.OpCode.Code == Code.Ldftn || instr.OpCode.Code == Code.Ldvirtftn) { var ldInstr = instr; instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex); if (instr == null || instr.OpCode.Code != Code.Ret) { return(false); } if (methodArgsCount != 1) { return(false); } block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(ldInstr)); return(true); } return(false); }