void FindOverrideMethods() { foreach (var method in type.Methods) { if (!method.IsVirtual) { continue; } if (DotNetUtils.IsMethod(method, "System.Void", "(System.IO.BinaryReader)")) { if (readMethod != null) { throw new ApplicationException("Found another read method"); } readMethod = method; } else if (!DotNetUtils.HasReturnValue(method) && method.MethodSig.GetParamCount() == 1) { if (executeMethod != null) { throw new ApplicationException("Found another execute method"); } executeMethod = method; } } if (readMethod == null) { throw new ApplicationException("Could not find read method"); } if (executeMethod == null) { throw new ApplicationException("Could not find execute method"); } }
public void Find() { foreach (var type in module.Types) { if (!type.HasMethods) { continue; } if (type.Methods.Count > 3) { continue; } MethodDef errorMethod = null; foreach (var method in type.Methods) { if (method.Name == ".ctor") { continue; // .ctor is allowed } if (method.Name == ".cctor") { continue; // .cctor is allowed } var sig = method.MethodSig; if (sig != null && method.IsStatic && method.HasBody && sig.Params.Count == 2 && !method.HasGenericParameters && !DotNetUtils.HasReturnValue(method) && sig.Params[0].GetFullName() == "System.Exception" && sig.Params[1].GetFullName() == "System.Object[]") { errorMethod = method; } else { break; } } if (errorMethod != null) { stackFrameHelperType = type; exceptionLoggerRemover.Add(errorMethod); return; } } }
static void GetReadAndExecMethods(TypeDef handler, out MethodDef readMethod, out MethodDef execMethod) { readMethod = execMethod = null; foreach (var method in handler.Methods) { if (!method.IsVirtual) { continue; } if (DotNetUtils.IsMethod(method, "System.Void", "(System.IO.BinaryReader)")) { if (readMethod != null) { throw new ApplicationException("Found another read method"); } readMethod = method; } else if (!DotNetUtils.HasReturnValue(method) && method.MethodSig.GetParamCount() == 1) { if (execMethod != null) { throw new ApplicationException("Found another execute method"); } execMethod = method; } } if (readMethod == null) { throw new ApplicationException("Could not find read method"); } if (execMethod == null) { throw new ApplicationException("Could not find execute method"); } }
BlockInstr FindProxyCall(DelegateInfo di, Block block, int index, Dictionary <Block, bool> visited, int stack) { if (visited.ContainsKey(block)) { return(null); } if (index <= 0) { visited[block] = true; } var instrs = block.Instructions; for (int i = index + 1; i < instrs.Count; i++) { if (stack <= 0) { return(null); } var instr = instrs[i]; instr.Instruction.UpdateStack(ref stack, false); if (stack < 0) { return(null); } if (instr.OpCode != OpCodes.Call && instr.OpCode != OpCodes.Callvirt) { if (stack <= 0) { return(null); } continue; } var calledMethod = instr.Operand as IMethod; if (calledMethod == null) { return(null); } if (stack != (DotNetUtils.HasReturnValue(calledMethod) ? 1 : 0)) { continue; } if (calledMethod.Name != "Invoke") { return(null); } return(new BlockInstr { Block = block, Index = i, }); } if (stack <= 0) { return(null); } foreach (var target in block.GetTargets()) { var info = FindProxyCall(di, target, -1, visited, stack); if (info != null) { return(info); } } return(null); }
public bool Deobfuscate(List <Block> allBlocks) { if (!Initialize(allBlocks)) { return(false); } bool modified = false; var indexesToRemove = new List <int>(); foreach (var block in allBlocks) { indexesToRemove.Clear(); var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var instr = instrs[i]; if (instr.OpCode.Code == Code.Ldloca || instr.OpCode.Code == Code.Ldloca_S) { var local = instr.Operand as Local; if (local == null) { continue; } localInfos[local].invalid(); } else if (instr.IsLdloc()) { var local = instr.Instruction.GetLocal(blocks.Locals); if (local == null) { continue; } var localInfo = localInfos[local]; var cast = instrs[i + 1]; if (localInfo.CastType == null) { continue; } if (!IsCast(cast)) { throw new ApplicationException("Not a cast instr"); } indexesToRemove.Add(i + 1); } } if (indexesToRemove.Count > 0) { block.Remove(indexesToRemove); modified = true; } } foreach (var info in localInfos.Values) { if (info.CastType == null) { continue; } info.local.Type = info.CastType.ToTypeSig(); } if (modified) { foreach (var block in allBlocks) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var instr = instrs[i]; int castIndex = i + 1; if (instr.OpCode.Code == Code.Dup) { if (i == 0) { continue; } castIndex = i; instr = instrs[i - 1]; } if (instr.IsLdarg()) { AddCast(block, castIndex, i + 1, instr.Instruction.GetArgumentType(blocks.Method.MethodSig, blocks.Method.DeclaringType)); } else if (instr.OpCode.Code == Code.Ldfld || instr.OpCode.Code == Code.Ldsfld) { var field = instr.Operand as IField; if (field == null) { continue; } AddCast(block, castIndex, i + 1, field.FieldSig.GetFieldType()); } else if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) { var calledMethod = instr.Operand as IMethod; if (calledMethod == null || !DotNetUtils.HasReturnValue(calledMethod)) { continue; } AddCast(block, castIndex, i + 1, calledMethod.MethodSig.GetRetType()); } } } } return(modified); }