bool deobfuscateMethods() { bool changed = false; foreach (var method in allMethods) { methodReturnInfo = new TypeInfo <ParameterDefinition>(method.MethodReturnType.Parameter2); deobfuscateMethod(method); if (methodReturnInfo.updateNewType(module)) { getUpdatedMethod(method).newReturnType = methodReturnInfo.newType; method.MethodReturnType.ReturnType = methodReturnInfo.newType; changed = true; } foreach (var info in argInfos.Values) { if (info.updateNewType(module)) { getUpdatedMethod(method).newArgTypes[DotNetUtils.getArgIndex(info.arg)] = info.newType; info.arg.ParameterType = info.newType; changed = true; } } } return(changed); }
static bool findMagic(MethodDefinition method, out int magic) { var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldarg = instrs[i]; if (DotNetUtils.getArgIndex(ldarg) < 0) { continue; } var ldci4 = instrs[i + 1]; if (!DotNetUtils.isLdcI4(ldci4)) { continue; } if (instrs[i + 2].OpCode.Code != Code.Xor) { continue; } magic = DotNetUtils.getLdcI4Value(ldci4); return(true); } magic = 0; return(false); }
bool checkRestoreBody2(MethodDefinition instanceMethod, out MethodDefinition calledMethod) { calledMethod = null; var instrs = instanceMethod.Body.Instructions; int index; for (index = 0; index < instrs.Count; index++) { if (DotNetUtils.getArgIndex(instrs[index]) != index) { break; } } var call = instrs[index++]; if (call.OpCode.Code != Code.Call) { return(false); } calledMethod = call.Operand as MethodDefinition; if (calledMethod == null) { return(false); } if (instrs[index++].OpCode.Code != Code.Ret) { return(false); } return(true); }
static int getMagicArgIndex41Retail(MethodDefinition method) { var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 3; i++) { var add = instrs[i]; if (add.OpCode.Code != Code.Add) { continue; } var ldarg = instrs[i + 1]; if (!DotNetUtils.isLdarg(ldarg)) { continue; } var sub = instrs[i + 2]; if (sub.OpCode.Code != Code.Sub) { continue; } var ldci4 = instrs[i + 3]; if (!DotNetUtils.isLdcI4(ldci4) || DotNetUtils.getLdcI4Value(ldci4) != 0xFF) { continue; } return(DotNetUtils.getArgIndex(ldarg)); } return(-1); }
static int getMagicIndex41Trial(MethodDefinition method) { var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 4; i++) { int index = i; if (instrs[index++].OpCode.Code != Code.Div) { continue; } var ldarg = instrs[index++]; if (!DotNetUtils.isLdarg(ldarg)) { continue; } if (instrs[index++].OpCode.Code != Code.Add) { continue; } var ldci4 = instrs[index++]; if (!DotNetUtils.isLdcI4(ldci4)) { continue; } if (DotNetUtils.getLdcI4Value(ldci4) != 0xFF) { continue; } return(DotNetUtils.getArgIndex(ldarg)); } return(-1); }
static bool isCallMethod(MethodDefinition method) { int loadIndex = 0; int methodArgsCount = DotNetUtils.getArgsCount(method); var instrs = method.Body.Instructions; int i = 0; for (; i < instrs.Count && i < methodArgsCount; i++) { var instr = instrs[i]; 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.Ldarga: case Code.Ldarga_S: if (DotNetUtils.getArgIndex(instr) != loadIndex) { return(false); } loadIndex++; continue; } break; } if (loadIndex != methodArgsCount) { return(false); } if (i + 1 >= instrs.Count) { return(false); } switch (instrs[i].OpCode.Code) { case Code.Call: case Code.Callvirt: case Code.Newobj: case Code.Ldfld: case Code.Ldflda: case Code.Ldftn: case Code.Ldvirtftn: break; default: return(false); } if (instrs[i + 1].OpCode.Code != Code.Ret) { return(false); } return(true); }
string findWindowsFormsClassName(TypeDef type) { foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDefinition.Body == null) { continue; } if (methodDef.MethodDefinition.IsStatic || methodDef.MethodDefinition.IsVirtual) { continue; } var instructions = methodDef.MethodDefinition.Body.Instructions; for (int i = 2; i < instructions.Count; i++) { var call = instructions[i]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) { continue; } if (!isWindowsFormsSetNameMethod(call.Operand as MethodReference)) { continue; } var ldstr = instructions[i - 1]; if (ldstr.OpCode.Code != Code.Ldstr) { continue; } var className = ldstr.Operand as string; if (className == null) { continue; } if (DotNetUtils.getArgIndex(instructions[i - 2]) != 0) { continue; } findInitializeComponentMethod(type, methodDef); return(className); } } return(null); }
static FieldReference getFieldReference(MethodDefinition method) { if (method == null || method.Body == null) { return(null); } var instructions = method.Body.Instructions; int index = 0; var ldarg0 = DotNetUtils.getInstruction(instructions, ref index); if (ldarg0 == null || DotNetUtils.getArgIndex(ldarg0) != 0) { return(null); } var ldfld = DotNetUtils.getInstruction(instructions, ref index); if (ldfld == null || ldfld.OpCode.Code != Code.Ldfld) { return(null); } var ret = DotNetUtils.getInstruction(instructions, ref index); if (ret == null) { return(null); } if (DotNetUtils.isStloc(ret)) { var local = DotNetUtils.getLocalVar(method.Body.Variables, ret); ret = DotNetUtils.getInstruction(instructions, ref index); if (ret == null || !DotNetUtils.isLdloc(ret)) { return(null); } if (DotNetUtils.getLocalVar(method.Body.Variables, ret) != local) { return(null); } ret = DotNetUtils.getInstruction(instructions, ref index); } if (ret == null || ret.OpCode.Code != Code.Ret) { return(null); } return(ldfld.Operand as FieldReference); }
string getOperandString(Instruction instr) { if (instr.Operand is Instruction) { return(getLabel((Instruction)instr.Operand)); } else if (instr.Operand is Instruction[]) { var sb = new StringBuilder(); var targets = (Instruction[])instr.Operand; for (int i = 0; i < targets.Length; i++) { if (i > 0) { sb.Append(','); } sb.Append(getLabel(targets[i])); } return(sb.ToString()); } else if (instr.Operand is string) { return(Utils.toCsharpString((string)instr.Operand)); } else if (instr.Operand is ParameterDefinition) { var arg = (ParameterDefinition)instr.Operand; var s = instr.GetOperandString(); if (s != "") { return(s); } return(string.Format("<arg_{0}>", DotNetUtils.getArgIndex(arg))); } else { return(instr.GetOperandString()); } }
static int findMagic3(MethodDefinition method) { var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldarg = instrs[i]; if (!DotNetUtils.isLdarg(ldarg) || DotNetUtils.getArgIndex(ldarg) != 2) { continue; } var ldci4 = instrs[i + 1]; if (!DotNetUtils.isLdcI4(ldci4)) { continue; } if (instrs[i + 2].OpCode.Code != Code.Xor) { continue; } return(DotNetUtils.getLdcI4Value(ldci4)); } throw new ApplicationException("Could not find magic3"); }
static int getMagicArgIndex41Trial(MethodDefinition method) { var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldarg = instrs[i]; if (!DotNetUtils.isLdarg(ldarg)) { continue; } if (!DotNetUtils.isLdcI4(instrs[i + 1])) { continue; } if (instrs[i + 2].OpCode.Code != Code.Shr) { continue; } return(DotNetUtils.getArgIndex(ldarg)); } return(-1); }
void initFieldEventHandlers(FieldDefinitionAndDeclaringTypeDict <FieldDef> ourFields, MethodDefinitionAndDeclaringTypeDict <MethodDef> ourMethods) { var checker = NameChecker; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDefinition.Body == null) { continue; } if (methodDef.MethodDefinition.IsStatic) { continue; } var instructions = methodDef.MethodDefinition.Body.Instructions; for (int i = 0; i < instructions.Count - 6; i++) { // We're looking for this code pattern: // ldarg.0 // ldfld field // ldarg.0 // ldftn method / ldarg.0 + ldvirtftn // newobj event_handler_ctor // callvirt add_SomeEvent if (DotNetUtils.getArgIndex(instructions[i]) != 0) { continue; } int index = i + 1; var ldfld = instructions[index++]; if (ldfld.OpCode.Code != Code.Ldfld) { continue; } var fieldRef = ldfld.Operand as FieldReference; if (fieldRef == null) { continue; } var fieldDef = ourFields.find(fieldRef); if (fieldDef == null) { continue; } if (DotNetUtils.getArgIndex(instructions[index++]) != 0) { continue; } MethodReference methodRef; var instr = instructions[index + 1]; if (instr.OpCode.Code == Code.Ldvirtftn) { if (!isThisOrDup(instructions[index++])) { continue; } var ldvirtftn = instructions[index++]; methodRef = ldvirtftn.Operand as MethodReference; } else { var ldftn = instructions[index++]; if (ldftn.OpCode.Code != Code.Ldftn) { continue; } methodRef = ldftn.Operand as MethodReference; } if (methodRef == null) { continue; } var handlerMethod = ourMethods.find(methodRef); if (handlerMethod == null) { continue; } var newobj = instructions[index++]; if (newobj.OpCode.Code != Code.Newobj) { continue; } if (!isEventHandlerCtor(newobj.Operand as MethodReference)) { continue; } var call = instructions[index++]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) { continue; } var addHandler = call.Operand as MethodReference; if (addHandler == null) { continue; } if (!Utils.StartsWith(addHandler.Name, "add_", StringComparison.Ordinal)) { continue; } var eventName = addHandler.Name.Substring(4); if (!checker.isValidEventName(eventName)) { continue; } memberInfos.method(handlerMethod).suggestedName = string.Format("{0}_{1}", memberInfos.field(fieldDef).newName, eventName); } } }
static bool isThisOrDup(Instruction instr) { return(DotNetUtils.getArgIndex(instr) == 0 || instr.OpCode.Code == Code.Dup); }
void initTypeEventHandlers(FieldDefinitionAndDeclaringTypeDict <FieldDef> ourFields, MethodDefinitionAndDeclaringTypeDict <MethodDef> ourMethods) { var checker = NameChecker; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDefinition.Body == null) { continue; } if (methodDef.MethodDefinition.IsStatic) { continue; } var method = methodDef.MethodDefinition; var instructions = method.Body.Instructions; for (int i = 0; i < instructions.Count - 5; i++) { // ldarg.0 // ldarg.0 / dup // ldarg.0 / dup // ldvirtftn handler // newobj event handler ctor // call add_Xyz if (DotNetUtils.getArgIndex(instructions[i]) != 0) { continue; } int index = i + 1; if (!isThisOrDup(instructions[index++])) { continue; } MethodReference handler; if (instructions[index].OpCode.Code == Code.Ldftn) { handler = instructions[index++].Operand as MethodReference; } else { if (!isThisOrDup(instructions[index++])) { continue; } var instr = instructions[index++]; if (instr.OpCode.Code != Code.Ldvirtftn) { continue; } handler = instr.Operand as MethodReference; } if (handler == null) { continue; } var handlerDef = ourMethods.find(handler); if (handlerDef == null) { continue; } var newobj = instructions[index++]; if (newobj.OpCode.Code != Code.Newobj) { continue; } if (!isEventHandlerCtor(newobj.Operand as MethodReference)) { continue; } var call = instructions[index++]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) { continue; } var addMethod = call.Operand as MethodReference; if (addMethod == null) { continue; } if (!Utils.StartsWith(addMethod.Name, "add_", StringComparison.Ordinal)) { continue; } var eventName = addMethod.Name.Substring(4); if (!checker.isValidEventName(eventName)) { continue; } memberInfos.method(handlerDef).suggestedName = string.Format("{0}_{1}", newName, eventName); } } }
protected InstructionPatcher tryInlineOtherMethod(int patchIndex, MethodDefinition methodToInline, Instruction instr, int instrIndex, int popLastArgs) { 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(null); } loadIndex++; instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex); } if (instr == null || loadIndex != methodArgsCount - popLastArgs) { return(null); } if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) { if (foundLdarga) { return(null); } var callInstr = instr; var calledMethod = callInstr.Operand as MethodReference; if (calledMethod == null) { return(null); } if (!isCompatibleType(-1, calledMethod.MethodReturnType.ReturnType, methodToInline.MethodReturnType.ReturnType)) { return(null); } if (!checkSameMethods(calledMethod, methodToInline, popLastArgs)) { return(null); } return(new InstructionPatcher(patchIndex, instrIndex, callInstr)); } else if (instr.OpCode.Code == Code.Newobj) { if (foundLdarga) { return(null); } var newobjInstr = instr; var ctor = newobjInstr.Operand as MethodReference; if (ctor == null) { return(null); } if (!isCompatibleType(-1, ctor.DeclaringType, methodToInline.MethodReturnType.ReturnType)) { return(null); } var methodArgs = DotNetUtils.getArgs(methodToInline); var calledMethodArgs = DotNetUtils.getArgs(ctor); if (methodArgs.Count + 1 - popLastArgs != calledMethodArgs.Count) { return(null); } for (int i = 1; i < calledMethodArgs.Count; i++) { if (!isCompatibleType(i, calledMethodArgs[i], methodArgs[i - 1])) { return(null); } } return(new InstructionPatcher(patchIndex, instrIndex, newobjInstr)); } 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; if (methodArgsCount != 1) { return(null); } return(new InstructionPatcher(patchIndex, instrIndex, ldInstr)); } return(null); }
bool checkProxyMethod(MethodDefinition method, out DelegateInfo info) { info = null; if (!method.IsStatic || method.Body == null) { return(false); } var instrs = method.Body.Instructions; if (instrs.Count < 7) { return(false); } int index = 0; if (instrs[index].OpCode.Code != Code.Ldsfld) { return(false); } var field = instrs[index++].Operand as FieldDefinition; if (field == null || !field.IsStatic) { return(false); } if (!MemberReferenceHelper.compareTypes(method.DeclaringType, field.DeclaringType)) { return(false); } if (!DotNetUtils.isBrtrue(instrs[index++])) { return(false); } if (instrs[index++].OpCode.Code != Code.Ldnull) { return(false); } if (instrs[index].OpCode.Code != Code.Ldftn) { return(false); } var calledMethod = instrs[index++].Operand as MethodReference; if (calledMethod == null) { return(false); } if (instrs[index++].OpCode.Code != Code.Newobj) { return(false); } if (instrs[index].OpCode.Code != Code.Stsfld) { return(false); } if (!MemberReferenceHelper.compareFieldReference(field, instrs[index++].Operand as FieldReference)) { return(false); } if (instrs[index].OpCode.Code != Code.Ldsfld) { return(false); } if (!MemberReferenceHelper.compareFieldReference(field, instrs[index++].Operand as FieldReference)) { return(false); } for (int i = 0; i < method.Parameters.Count; i++) { if (index >= instrs.Count) { return(false); } if (DotNetUtils.getArgIndex(instrs[index++]) != i) { return(false); } } if (index + 2 > instrs.Count) { return(false); } var call = instrs[index++]; if (call.OpCode.Code != Code.Callvirt) { return(false); } if (instrs[index++].OpCode.Code != Code.Ret) { return(false); } info = new DelegateInfo(field, calledMethod, OpCodes.Call); return(true); }