public static void Execute() { foreach (TypeDef type in Context.module.GetTypes()) { foreach (MethodDef method in type.Methods) { bool flag = method.HasBody && ContainsControlFlow(method); if (flag) { for (int i = 0; i < 1; i++) { CfDeob = new BlocksCflowDeobfuscator(); Blocks blocks = new Blocks(method); List <Block> test = blocks.MethodBlocks.GetAllBlocks(); blocks.RemoveDeadBlocks(); blocks.RepartitionBlocks(); blocks.UpdateBlocks(); blocks.Method.Body.SimplifyBranches(); blocks.Method.Body.OptimizeBranches(); CfDeob.Initialize(blocks); CfDeob.Add(new ControlFlow_BlockDeobfuscator()); CfDeob.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> instructions; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out instructions, out exceptionHandlers); DotNetUtils.RestoreBody(method, instructions, exceptionHandlers); } } } } }
// All Cflow Remover Credits Go to : https://github.com/SychicBoy/.NetReactorCfCleaner public static void Execute(Context Ctx) { var CfDeob = new BlocksCflowDeobfuscator(); ExecuteArithmetic(Ctx); foreach (var TypeDef in Ctx.DnModule.Types.ToArray()) { foreach (var MethodDef in TypeDef.Methods.Where(x => x.HasBody && ContainsSwitch(x)).ToArray()) { try { Blocks blocks = new Blocks(MethodDef); List <Block> test = blocks.MethodBlocks.GetAllBlocks(); blocks.RemoveDeadBlocks(); blocks.RepartitionBlocks(); blocks.UpdateBlocks(); blocks.Method.Body.SimplifyBranches(); blocks.Method.Body.OptimizeBranches(); CfDeob.Initialize(blocks); CfDeob.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> instructions; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out instructions, out exceptionHandlers); DotNetUtils.RestoreBody(MethodDef, instructions, exceptionHandlers); } catch { } } } }
public static void DeobfuscateCflow(MethodDef meth) { for (int i = 0; i < 1; i++) { CfDeob = new BlocksCflowDeobfuscator(); Blocks blocks = new Blocks(meth); List <Block> test = blocks.MethodBlocks.GetAllBlocks(); blocks.RemoveDeadBlocks(); blocks.RepartitionBlocks(); blocks.UpdateBlocks(); blocks.Method.Body.SimplifyBranches(); blocks.Method.Body.OptimizeBranches(); CfDeob.Initialize(blocks); //CfDeob.Deobfuscate(); CfDeob.Add(new Cflow()); // CfDeob.Add(new Cflow()); CfDeob.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> instructions; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out instructions, out exceptionHandlers); DotNetUtils.RestoreBody(meth, instructions, exceptionHandlers); } }
void Deobfuscate(MethodDef method, string msg, Action <Blocks> handler) { if (savedMethodBodies != null) { savedMethodBodies.Save(method); } Logger.v("{0}: {1} ({2:X8})", msg, Utils.RemoveNewlines(method), method.MDToken.ToUInt32()); Logger.Instance.Indent(); if (HasNonEmptyBody(method)) { try { var blocks = new Blocks(method); handler(blocks); IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(method, allInstructions, allExceptionHandlers); } catch { Logger.v("Could not deobfuscate {0:X8}", method.MDToken.ToInt32()); } } Logger.Instance.DeIndent(); }
public MethodDef Deobfuscate(MethodDef method) { MethodDef 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); }
void Deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter, bool isVerbose, bool isVV) { if (!HasNonEmptyBody(method)) { return; } var blocks = new Blocks(method); int numRemovedLocals = 0; int oldNumInstructions = method.Body.Instructions.Count; deob.DeobfuscateMethodBegin(blocks); if (options.ControlFlowDeobfuscation) { cflowDeobfuscator.Initialize(blocks); cflowDeobfuscator.Deobfuscate(); } if (deob.DeobfuscateOther(blocks) && options.ControlFlowDeobfuscation) { cflowDeobfuscator.Deobfuscate(); } if (options.ControlFlowDeobfuscation) { if (CanOptimizeLocals()) { numRemovedLocals = blocks.OptimizeLocals(); } blocks.RepartitionBlocks(); } DeobfuscateStrings(blocks); deob.DeobfuscateMethodEnd(blocks); IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(method, allInstructions, allExceptionHandlers); if (isVerbose && numRemovedLocals > 0) { Logger.v("Removed {0} unused local(s)", numRemovedLocals); } int numRemovedInstructions = oldNumInstructions - method.Body.Instructions.Count; if (isVerbose && numRemovedInstructions > 0) { Logger.v("Removed {0} dead instruction(s)", numRemovedInstructions); } if (isVV) { Logger.Log(LoggerEvent.VeryVerbose, "Deobfuscated code:"); Logger.Instance.Indent(); methodPrinter.Print(LoggerEvent.VeryVerbose, allInstructions, allExceptionHandlers); Logger.Instance.DeIndent(); } }
private static void DeadCodeHandler(MethodDef method, CancellationToken token) { List <Block> allBlocks = new List <Block>(); IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; ILAstDeadCode deadCodeRemover = new ILAstDeadCode(); List <Instruction> deadInstructions = new List <Instruction>(); deadCodeRemover.RemoveDeadCode(method, deadInstructions); if (!DeFlowSettings.Settings.Remove) { foreach (var instr in deadInstructions) { uint rva = (uint)method.RVA; uint baseRva = rva == 0 ? 0 : rva + method.Body.HeaderSize; long baseOffs = baseRva == 0 ? 0 : method.Module.ToFileOffset(baseRva) ?? 0; ulong fileOffset = (ulong)baseOffs + instr.Offset; DeadInstructions.DeadInstrsList.Add(new DeadInstr((ulong)baseOffs, instr.Offset, method.Module.Location)); } } else { var tempMethod = DotNetUtils.Clone(method); var blocks = new Blocks(tempMethod); blocks.MethodBlocks.GetAllBlocks(allBlocks); foreach (var block in allBlocks) { foreach (var instr in deadInstructions) { var indx = block.Instructions.FindIndex(x => x.Instruction.Offset == instr.Offset && x.Instruction.OpCode == instr.OpCode && x.Instruction.Operand == instr.Operand); if (indx != -1) { block.Instructions.RemoveAt(indx); block.Instructions.Insert(indx, new Instr(OpCodes.Nop.ToInstruction())); } } } if (DeFlowSettings.Settings.Nops) { foreach (Block block in allBlocks) { if (block.Instructions.Count() > 1) { block.Instructions.RemoveAll(x => x.Instruction.OpCode == OpCodes.Nop); } } } blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(tempMethod, (IEnumerable <Instruction>)allInstructions, (IEnumerable <ExceptionHandler>)allExceptionHandlers); RestoreMethod(method, tempMethod); } }
void RestoreMethod(Blocks blocks) { IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(blocks.Method, allInstructions, allExceptionHandlers); }
void StringDecrypterBugWorkaround() { // There's a bug in Eazfuscator.NET when the VM and string encryption features are // enabled. The string decrypter's initialization code checks to make sure it's not // called by eg. a dynamic method. When it's called from the VM code, it is // called by MethodBase.Invoke() and the string decrypter antis set in causing it // to fail. // One way to work around this is to make sure the string decrypter has been called // once. That way, any VM code calling it won't trigger a failure. // We can put this code in <Module>::.cctor() since it gets executed before any // other code. // Note that we can't call the string decrypter from <Module>::.cctor() since // its DeclaringType property will return null (since it's the global type). We // must call another created class which calls the string decrypter. // You must use --dont-rename --keep-types --preserve-tokens and decrypt strings if (!Operations.KeepObfuscatorTypes || Operations.DecryptStrings == OpDecryptString.None || (Operations.RenamerFlags & (RenamerFlags.RenameNamespaces | RenamerFlags.RenameTypes)) != 0) { return; } if (stringDecrypter.ValidStringDecrypterValue == null) { return; } var newType = Module.UpdateRowId(new TypeDefUser(Guid.NewGuid().ToString("B"), Module.CorLibTypes.Object.TypeDefOrRef)); Module.Types.Add(newType); var newMethod = Module.UpdateRowId(new MethodDefUser("x", MethodSig.CreateStatic(Module.CorLibTypes.Void), 0, MethodAttributes.Static | MethodAttributes.HideBySig)); newType.Methods.Add(newMethod); newMethod.Body = new CilBody(); newMethod.Body.MaxStack = 1; newMethod.Body.Instructions.Add(Instruction.CreateLdcI4(stringDecrypter.ValidStringDecrypterValue.Value)); newMethod.Body.Instructions.Add(OpCodes.Call.ToInstruction(stringDecrypter.Method)); newMethod.Body.Instructions.Add(OpCodes.Pop.ToInstruction()); newMethod.Body.Instructions.Add(OpCodes.Ret.ToInstruction()); var cctor = Module.GlobalType.FindOrCreateStaticConstructor(); var blocks = new Blocks(cctor); var block = blocks.MethodBlocks.GetAllBlocks()[0]; block.Insert(0, OpCodes.Call.ToInstruction(newMethod)); IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(cctor, allInstructions, allExceptionHandlers); }
private static void ControlFlowClean() { try { foreach (ModuleDef module in Globals.ASM.Modules) //Go through all the modules in the assembly { foreach (TypeDef type in module.GetTypes()) //Go through all the type and nested types in the module { foreach (MethodDef method in type.Methods) //Go through all the methods in the type { if (method.HasBody && ContainsControlFlow(method)) //Check to see if the method has a body and it contains a (Switch) opcode which is used in the Agile controlflow { for (int i = 0; i < 1; i++) { CfDeob = new BlocksCflowDeobfuscator(); Blocks blocks = new Blocks(method); List <Block> test = blocks.MethodBlocks.GetAllBlocks(); blocks.RemoveDeadBlocks(); blocks.RepartitionBlocks(); blocks.UpdateBlocks(); blocks.Method.Body.SimplifyBranches(); blocks.Method.Body.OptimizeBranches(); CfDeob.Initialize(blocks); //CfDeob.Deobfuscate(); CfDeob.Add(new ControlFlow()); // CfDeob.Add(new Cflow()); CfDeob.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> instructions; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out instructions, out exceptionHandlers); DotNetUtils.RestoreBody(method, instructions, exceptionHandlers); } controlflowCleaned++; } } } } } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[-] Looks like something bad happened in the controlflow phase, please contact me to fix this issue."); } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(string.Format("[+] Controlflow cleaned in {0} methods", controlflowCleaned)); }
void Deobfuscate(MethodDef method, Action <Blocks> handler) { if (HasNonEmptyBody(method)) { var blocks = new Blocks(method); handler(blocks); IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(method, allInstructions, allExceptionHandlers); } }
//Removing Control Flow public static void Cleaner(MethodDef method) { BlocksCflowDeobfuscator blocksCflowDeobfuscator = new BlocksCflowDeobfuscator(); Blocks blocks = new Blocks(method); blocksCflowDeobfuscator.Initialize(blocks); blocksCflowDeobfuscator.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> list; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out list, out exceptionHandlers); DotNetUtils.RestoreBody(method, list, exceptionHandlers); }
public static void DeobfuscateCflow2(MethodDef meth) { for (int i = 0; i < 1; i++) { Blocks blocks = new Blocks(meth); De4Dot.CfDeob.Initialize(blocks); De4Dot.CfDeob.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> instructions; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out instructions, out exceptionHandlers); DotNetUtils.RestoreBody(meth, instructions, exceptionHandlers); } }
public static void DeobfuscateCflow(MethodDef meth) { var blocks = new Blocks(meth); var test = blocks.MethodBlocks.GetAllBlocks(); CfDeob.Initialize(blocks); // CfDeob.Add(new VariableMelting()); CfDeob.Deobfuscate(); blocks.RepartitionBlocks(); // blocks.RepartitionBlocks(); IList <Instruction> instructions; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out instructions, out exceptionHandlers); DotNetUtils.RestoreBody(meth, instructions, exceptionHandlers); }
public static (int, int) RemoveCF(ModuleDef moduleDef) { int success = 0; int failed = 0; foreach (TypeDef type in moduleDef.GetTypes()) { foreach (MethodDef method in type.Methods) { if (method.HasBody && HasCF(method)) { try { var cflowDeobfuscator = new BlocksCflowDeobfuscator(); Blocks blocks = new Blocks(method); List <Block> test = blocks.MethodBlocks.GetAllBlocks(); blocks.RemoveDeadBlocks(); blocks.RepartitionBlocks(); blocks.UpdateBlocks(); blocks.Method.Body.OptimizeBranches(); blocks.UpdateBlocks(); blocks.Method.Body.SimplifyBranches(); blocks.UpdateBlocks(); cflowDeobfuscator.Initialize(blocks); cflowDeobfuscator.Add(new ControlFlow_BlockDeobfuscator()); cflowDeobfuscator.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> instructions; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out instructions, out exceptionHandlers); DotNetUtils.RestoreBody(method, instructions, exceptionHandlers); success++; } catch (Exception e) { Console.WriteLine($"Failed to deobfuscate {method.DeclaringType.Name}:{method.Name} with exception: {e.Message}"); failed++; } } } } return(success, failed); }
public static void BlockDeobfuscator(MethodDef methodDef) { var cfDeob = new BlocksCflowDeobfuscator(); var blocks = new Blocks(methodDef); blocks.RemoveDeadBlocks(); blocks.RepartitionBlocks(); blocks.UpdateBlocks(); blocks.Method.Body.SimplifyBranches(); blocks.Method.Body.OptimizeBranches(); cfDeob.Initialize(blocks); cfDeob.Deobfuscate(); blocks.RepartitionBlocks(); blocks.RemoveDeadBlocks(); blocks.OptimizeLocals(); blocks.Method.Body.SimplifyBranches(); blocks.Method.Body.OptimizeBranches(); blocks.GetCode(out var instructions, out var exceptionHandlers); DotNetUtils.RestoreBody(methodDef, instructions, exceptionHandlers); }
public void Convert(MethodDef cilMethod, CsvmMethodData csvmMethod) { cilToVmIndex.Clear(); vmIndexToCil.Clear(); var newInstructions = ReadInstructions(cilMethod, csvmMethod); var newLocals = ReadLocals(cilMethod, csvmMethod); var newExceptions = ReadExceptions(cilMethod, csvmMethod); FixInstructionOperands(newInstructions); FixLocals(newInstructions, cilMethod.Body.Variables); FixArgs(newInstructions, cilMethod); DotNetUtils.RestoreBody(cilMethod, newInstructions, newExceptions); if (!operandRestorer.Restore(cilMethod)) { Logger.w("Failed to restore one or more instruction operands in CSVM method {0:X8}", cilMethod.MDToken.ToInt32()); } RestoreConstrainedPrefix(cilMethod); }
public static void CFLow() { foreach (TypeDef type in module.Types) { foreach (MethodDef method in type.Methods) { if (method.HasBody == false) { continue; } BlocksCflowDeobfuscator blocksCflowDeobfuscator = new BlocksCflowDeobfuscator(); Blocks blocks = new Blocks(method); blocksCflowDeobfuscator.Initialize(blocks); blocksCflowDeobfuscator.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> list; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out list, out exceptionHandlers); DotNetUtils.RestoreBody(method, list, exceptionHandlers); } } }
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); }
public static void Deobfuscate(MethodDef method, CancellationToken token) { bool result; CflowDeobfuscator cflowDeobfuscator = new CflowDeobfuscator(); IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; MethodDef tempMethod = DotNetUtils.Clone(method); Blocks blocks = new Blocks(tempMethod); cflowDeobfuscator.Initialize(blocks, token); result = cflowDeobfuscator.Deobfuscate(); blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(tempMethod, (IEnumerable <Instruction>)allInstructions, (IEnumerable <ExceptionHandler>)allExceptionHandlers); RestoreMethod(method, tempMethod); if (result) { DeadCodeHandler(method, token); } }
public static void DeobfuscateAssisted(MethodDef method, CancellationToken token, Context ctx, BoolExpr expr, Block block) { CflowDeobfuscator cflowDeobfuscator = new CflowDeobfuscator(); IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; MethodDef tempMethod = DotNetUtils.Clone(method); Blocks blocks = new Blocks(tempMethod); cflowDeobfuscator.Initialize(blocks, token); List <Block> allBlocks = new List <Block>(); blocks.MethodBlocks.GetAllBlocks(allBlocks); var newBlock = allBlocks.Find(x => x.FirstInstr.Instruction.Offset == block.FirstInstr.Instruction.Offset); cflowDeobfuscator.SolveBlockAssisted(ctx, expr, newBlock); blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(tempMethod, (IEnumerable <Instruction>)allInstructions, (IEnumerable <ExceptionHandler>)allExceptionHandlers); RestoreMethod(method, tempMethod); DeadCodeHandler(method, token); }
public IEnumerable <FieldDef> CleanUp() { var removedFields = new List <FieldDef>(); var moduleCctor = DotNetUtils.GetModuleTypeCctor(module); if (moduleCctor == null) { return(removedFields); } var moduleCctorBlocks = new Blocks(moduleCctor); var keep = FindFieldsToKeep(); foreach (var fieldInfo in fieldToInfo.GetValues()) { if (keep.ContainsKey(fieldInfo)) { continue; } if (RemoveInitCode(moduleCctorBlocks, fieldInfo)) { removedFields.Add(fieldInfo.field); removedFields.Add(fieldInfo.arrayInitField); } fieldInfo.arrayInitField.InitialValue = new byte[1]; fieldInfo.arrayInitField.FieldSig.Type = module.CorLibTypes.Byte; fieldInfo.arrayInitField.RVA = 0; } IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; moduleCctorBlocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(moduleCctorBlocks.Method, allInstructions, allExceptionHandlers); return(removedFields); }
public void Restore() { DotNetUtils.RestoreBody(method, instructions, exceptionHandlers); }
void RestoreMethod(Blocks blocks) { blocks.GetCode(out var allInstructions, out var allExceptionHandlers); DotNetUtils.RestoreBody(blocks.Method, allInstructions, allExceptionHandlers); }
public void Execute() { if (token.IsCancellationRequested) { // it means its called from Redo command token = default(CancellationToken); } try { methods.Add(methodNode.MethodDef); origMethodBodys.Add(methodNode.MethodDef.MethodBody); isBodyModified.Add(methodAnnotations.IsBodyModified(methodNode.MethodDef)); methodAnnotations.SetBodyModified(methodNode.MethodDef, true); var method = methodNode.MethodDef; if (method.Body.Instructions.Any(x => x.OpCode.Code == Code.Call && x.Operand is MethodDef)) { //At first lets restore all methods called from this method for (int i = 0; i < method.Body.Instructions.Count(); i++) { if (method.Body.Instructions[i].OpCode.Code == Code.Call && method.Body.Instructions[i].Operand is MethodDef && (method.Body.Instructions[i].Operand as MethodDef).Body != null) { methods.Add(method.Body.Instructions[i].Operand as MethodDef); origMethodBodys.Add((method.Body.Instructions[i].Operand as MethodDef).MethodBody); isBodyModified.Add(methodAnnotations.IsBodyModified(method.Body.Instructions[i].Operand as MethodDef)); methodAnnotations.SetBodyModified(method.Body.Instructions[i].Operand as MethodDef, true); MethodDeobfuscator.Deobfuscate(method.Body.Instructions[i].Operand as MethodDef, token); } } var tempMethod = DotNetUtils.Clone(method); var blocks = new Blocks(tempMethod); List <Block> allBlocks = new List <Block>(); blocks.MethodBlocks.GetAllBlocks(allBlocks); foreach (var block in allBlocks) { for (int i = 0; i < block.Instructions.Count; i++) { var instruction = block.Instructions[i]; if (instruction.OpCode.Code == Code.Call && instruction.Operand is MethodDef && (instruction.Operand as MethodDef).Body != null) { // Remove empty method if ((instruction.Operand as MethodDef).Body.Instructions.All(x => x.OpCode.Code == Code.Nop || x.OpCode.Code == Code.Ret)) { block.Instructions.RemoveAt(i); //TODO: remove all inner empty methods, but better to have addititonal command for it tho } // Inline proxy method if ((instruction.Operand as MethodDef).Body.Instructions.All(x => IsOkOpcode(x.OpCode.Code))) { var inlined = GetInstruction((instruction.Operand as MethodDef).Body.Instructions); if (inlined != null) { block.Instructions.RemoveAt(i); block.Instructions.Insert(i, new Instr(new Instruction(inlined.OpCode, inlined.Operand))); } } } } } IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; blocks.GetCode(out allInstructions, out allExceptionHandlers); DotNetUtils.RestoreBody(tempMethod, (IEnumerable <Instruction>)allInstructions, (IEnumerable <ExceptionHandler>)allExceptionHandlers); MethodDeobfuscator.RestoreMethod(method, tempMethod); } } catch (OperationCanceledException) { } }
private void unpack(ModuleDef module) { this.methods = new List <MethodDef>(); if (module.HasTypes) { foreach (TypeDef type in module.Types) { this.AddMethods(type); } } BlocksCflowDeobfuscator blocksCflowDeobfuscator = new BlocksCflowDeobfuscator(); for (int i = 0; i < this.methods.Count; i++) { Blocks blocks = new Blocks(this.methods[i]); blocksCflowDeobfuscator.Initialize(blocks); blocksCflowDeobfuscator.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> list; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out list, out exceptionHandlers); DotNetUtils.RestoreBody(this.methods[i], list, exceptionHandlers); } for (int i = 0; i < this.methods.Count; i++) { for (int j = 0; j < this.methods[i].Body.Instructions.Count; j++) { if (this.methods[i].Body.Instructions[j].IsLdcI4() && j + 1 < this.methods[i].Body.Instructions.Count && this.methods[i].Body.Instructions[j + 1].OpCode == OpCodes.Pop) { this.methods[i].Body.Instructions[j].OpCode = OpCodes.Nop; this.methods[i].Body.Instructions[j + 1].OpCode = OpCodes.Nop; for (int k = 0; k < this.methods[i].Body.Instructions.Count; k++) { if (this.methods[i].Body.Instructions[k].OpCode == OpCodes.Br || this.methods[i].Body.Instructions[k].OpCode == OpCodes.Br_S) { if (this.methods[i].Body.Instructions[k].Operand is Instruction) { Instruction instruction = this.methods[i].Body.Instructions[k].Operand as Instruction; if (instruction == this.methods[i].Body.Instructions[j + 1]) { if (k - 1 >= 0 && this.methods[i].Body.Instructions[k - 1].IsLdcI4()) { this.methods[i].Body.Instructions[k - 1].OpCode = OpCodes.Nop; } } } } } } if (this.methods[i].Body.Instructions[j].OpCode == OpCodes.Dup && j + 1 < this.methods[i].Body.Instructions.Count && this.methods[i].Body.Instructions[j + 1].OpCode == OpCodes.Pop) { this.methods[i].Body.Instructions[j].OpCode = OpCodes.Nop; this.methods[i].Body.Instructions[j + 1].OpCode = OpCodes.Nop; for (int k = 0; k < this.methods[i].Body.Instructions.Count; k++) { if (this.methods[i].Body.Instructions[k].OpCode == OpCodes.Br || this.methods[i].Body.Instructions[k].OpCode == OpCodes.Br_S) { if (this.methods[i].Body.Instructions[k].Operand is Instruction) { Instruction instruction = this.methods[i].Body.Instructions[k].Operand as Instruction; if (instruction == this.methods[i].Body.Instructions[j + 1]) { if (k - 1 >= 0 && this.methods[i].Body.Instructions[k - 1].OpCode == OpCodes.Dup) { this.methods[i].Body.Instructions[k - 1].OpCode = OpCodes.Nop; } } } } } } } } for (int i = 0; i < this.methods.Count; i++) { Blocks blocks = new Blocks(this.methods[i]); blocksCflowDeobfuscator.Initialize(blocks); blocksCflowDeobfuscator.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> list; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out list, out exceptionHandlers); DotNetUtils.RestoreBody(this.methods[i], list, exceptionHandlers); } for (int i = 0; i < this.methods.Count; i++) { Dictionary <Instruction, Instruction> dictionary = new Dictionary <Instruction, Instruction>(); for (int j = 0; j < this.methods[i].Body.Instructions.Count; j++) { if (this.methods[i].Body.Instructions[j].IsConditionalBranch()) { Instruction instruction2 = this.methods[i].Body.Instructions[j]; for (int k = 0; k < this.methods[i].Body.Instructions.Count; k++) { if (this.methods[i].Body.Instructions[k].IsBr()) { Instruction instruction3 = this.methods[i].Body.Instructions[k]; Instruction instruction4 = this.methods[i].Body.Instructions[k].Operand as Instruction; if (instruction4 == instruction2) { if (!dictionary.ContainsKey(instruction4)) { this.methods[i].Body.Instructions[k].OpCode = instruction2.GetOpCode(); this.methods[i].Body.Instructions[k].Operand = instruction2.GetOperand(); this.methods[i].Body.Instructions.Insert(k + 1, OpCodes.Br.ToInstruction(this.methods[i].Body.Instructions[j + 1])); k++; dictionary.Add(instruction4, this.methods[i].Body.Instructions[k]); } } } } } } this.methods[i].Body.SimplifyBranches(); this.methods[i].Body.OptimizeBranches(); } for (int i = 0; i < this.methods.Count; i++) { Blocks blocks = new Blocks(this.methods[i]); blocksCflowDeobfuscator.Initialize(blocks); blocksCflowDeobfuscator.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> list; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out list, out exceptionHandlers); DotNetUtils.RestoreBody(this.methods[i], list, exceptionHandlers); } int num = 0; for (int i = 0; i < this.methods.Count; i++) { this.toberemoved = new List <int>(); this.integer_values_1 = new List <int>(); this.tobenooped_start = new List <int>(); this.tobenooped_len = new List <int>(); this.for_rem = new List <int>(); this.switchinstructions = new List <Instruction>(); this.wheretojump = new List <Instruction>(); for (int j = 0; j < this.methods[i].Body.Instructions.Count; j++) { if (j + 2 < this.methods[i].Body.Instructions.Count && this.methods[i].Body.Instructions[j].IsStloc() && (this.methods[i].Body.Instructions[j + 1].IsLdloc() || this.methods[i].Body.Instructions[j + 1].IsLdcI4()) && (this.methods[i].Body.Instructions[j + 2].IsLdcI4() || this.methods[i].Body.Instructions[j + 2].IsLdloc() || this.methods[i].Body.Instructions[j + 2].OpCode == OpCodes.Neg || this.methods[i].Body.Instructions[j + 2].OpCode == OpCodes.Not)) { int stlocInsIndex = GetStlocInsIndex(this.methods[i].Body.Instructions, j); if (stlocInsIndex != -1) { Instruction instruction5 = this.methods[i].Body.Instructions[stlocInsIndex - 1]; if ((stlocInsIndex - 1 >= 0 && this.methods[i].Body.Instructions[stlocInsIndex - 1].IsBr()) || this.methods[i].Body.Instructions[stlocInsIndex - 1].IsLdloc() || this.methods[i].Body.Instructions[stlocInsIndex - 1].IsLdcI4() || this.methods[i].Body.Instructions[stlocInsIndex - 1].OpCode == OpCodes.Xor) { int stlocInsIndex2 = GetStlocInsIndex(this.methods[i].Body.Instructions, stlocInsIndex + 1); if (stlocInsIndex2 != -1) { int switchInsIndex = GetSwitchInsIndex(this.methods[i].Body.Instructions, stlocInsIndex2 + 1); if (switchInsIndex != -1) { this.local_variable1 = this.methods[i].Body.Instructions[stlocInsIndex].GetLocal(this.methods[i].Body.Variables); this.local_variable2 = this.methods[i].Body.Instructions[stlocInsIndex2].GetLocal(this.methods[i].Body.Variables); if (this.local_variable1.Type != null && (this.local_variable1.Type.FullName == "System.Int32" || this.local_variable1.Type.FullName == "System.UInt32") && this.local_variable2.Type != null && (this.local_variable2.Type.FullName == "System.Int32" || this.local_variable2.Type.FullName == "System.UInt32")) { int num2 = switchInsIndex - j; this.wheretojump.Add(this.methods[i].Body.Instructions[j]); this.switchinstructions.Add(this.methods[i].Body.Instructions[switchInsIndex]); this.tobenooped_start.Add(j); this.tobenooped_len.Add(num2); j += num2; } } } } } } } if (this.switchinstructions.Count > 0) { this.placeintindexes = new List <int>(); this.intvalues = new List <int>(); this.conditionalinstructions = new List <Instruction>(); this.brinstructions = new List <Instruction>(); this.realbrinstructions = new List <Instruction>(); this.instructions = this.methods[i].Body.Instructions; this.method = this.methods[i]; this.InstructionParse2(0, 0, 0); num += this.placeintindexes.Count; for (int k = 0; k < this.placeintindexes.Count; k++) { this.methods[i].Body.Instructions[this.placeintindexes[k]].OpCode = OpCodes.Ldc_I4; this.methods[i].Body.Instructions[this.placeintindexes[k]].Operand = this.intvalues[k]; } for (int k = 0; k < this.tobenooped_start.Count; k++) { for (int l = 0; l < this.tobenooped_len[k]; l++) { this.methods[i].Body.Instructions[this.tobenooped_start[k] + l].OpCode = OpCodes.Nop; } } } this.toberemoved = new List <int>(); this.integer_values_1 = new List <int>(); this.for_rem = new List <int>(); this.switchinstructions = new List <Instruction>(); for (int j = 0; j < this.methods[i].Body.Instructions.Count; j++) { if (j + 6 < this.methods[i].Body.Instructions.Count && this.methods[i].Body.Instructions[j].IsLdcI4()) { if (this.methods[i].Body.Instructions[j + 1].OpCode == OpCodes.Xor) { if (this.methods[i].Body.Instructions[j + 2].IsLdcI4()) { if (this.methods[i].Body.Instructions[j + 3].OpCode == OpCodes.Rem_Un) { if (this.methods[i].Body.Instructions[j + 4].OpCode == OpCodes.Switch) { this.toberemoved.Add(j); this.integer_values_1.Add(this.methods[i].Body.Instructions[j].GetLdcI4Value()); this.for_rem.Add(this.methods[i].Body.Instructions[j + 2].GetLdcI4Value()); this.switchinstructions.Add(this.methods[i].Body.Instructions[j + 4]); } } } } } } if (this.switchinstructions.Count > 0) { this.toberemovedindex = new List <int>(); this.toberemovedvalues = new List <int>(); this.conditionalinstructions = new List <Instruction>(); this.brinstructions = new List <Instruction>(); this.realbrinstructions = new List <Instruction>(); this.instructions = this.methods[i].Body.Instructions; this.method = this.methods[i]; this.InstructionParseNoLocal(0); num += this.toberemovedindex.Count; if (this.toberemovedindex.Count > 0) { for (int m = 0; m < this.toberemoved.Count; m++) { for (int j = 0; j < 4; j++) { this.methods[i].Body.Instructions[j + this.toberemoved[m]].OpCode = OpCodes.Nop; this.methods[i].Body.Instructions[j + this.toberemoved[m]].Operand = null; } } for (int j = 0; j < this.toberemovedindex.Count; j++) { this.methods[i].Body.Instructions[this.toberemovedindex[j]].OpCode = OpCodes.Ldc_I4; this.methods[i].Body.Instructions[this.toberemovedindex[j]].Operand = this.toberemovedvalues[j]; if (!this.methods[i].Body.Instructions[this.toberemovedindex[j] + 1].IsBr()) { for (int k = 0; k < 4; k++) { this.methods[i].Body.Instructions[this.toberemovedindex[j] + k + 1].OpCode = OpCodes.Nop; this.methods[i].Body.Instructions[this.toberemovedindex[j] + k + 1].Operand = null; } } } } } Blocks blocks = new Blocks(this.methods[i]); blocksCflowDeobfuscator.Initialize(blocks); blocksCflowDeobfuscator.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> list; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out list, out exceptionHandlers); DotNetUtils.RestoreBody(this.methods[i], list, exceptionHandlers); this.methods[i].Body.SimplifyBranches(); this.methods[i].Body.OptimizeBranches(); } for (int i = 0; i < this.methods.Count; i++) { Blocks blocks = new Blocks(this.methods[i]); blocksCflowDeobfuscator.Initialize(blocks); blocksCflowDeobfuscator.Deobfuscate(); blocks.RepartitionBlocks(); IList <Instruction> list; IList <ExceptionHandler> exceptionHandlers; blocks.GetCode(out list, out exceptionHandlers); DotNetUtils.RestoreBody(this.methods[i], list, exceptionHandlers); } }