From cdd92d1415b4d6c9ea163747be2d9476a59912e6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 21 Oct 2011 20:14:25 +0200 Subject: [PATCH] Add fix for old DF --- blocks/cflow/BlocksCflowDeobfuscator.cs | 53 +++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/blocks/cflow/BlocksCflowDeobfuscator.cs b/blocks/cflow/BlocksCflowDeobfuscator.cs index b5bf20cf..d05936c1 100644 --- a/blocks/cflow/BlocksCflowDeobfuscator.cs +++ b/blocks/cflow/BlocksCflowDeobfuscator.cs @@ -42,13 +42,18 @@ namespace de4dot.blocks.cflow { public void deobfuscate() { bool changed; + int iterations = -1; do { + iterations++; changed = false; removeDeadBlocks(); mergeBlocks(); blocks.MethodBlocks.getAllBlocks(allBlocks); + if (iterations == 0) + changed |= fixDotfuscatorLoop(); + foreach (var block in allBlocks) { var lastInstr = block.LastInstr; if (!DotNetUtils.isConditionalBranch(lastInstr.OpCode.Code) && lastInstr.OpCode.Code != Code.Switch) @@ -73,6 +78,54 @@ namespace de4dot.blocks.cflow { } while (changed); } + // Hack for old Dotfuscator + bool fixDotfuscatorLoop() { + /* + blk1: + ... + ldc.i4.x + blk2: + dup + dup + ldc.i4.y + some_op + bcc blk2 + blk3: + pop + ... + */ + bool changed = false; + foreach (var block in allBlocks) { + if (block.Instructions.Count != 5) + continue; + var instructions = block.Instructions; + if (instructions[0].OpCode.Code != Code.Dup) + continue; + if (instructions[1].OpCode.Code != Code.Dup) + continue; + if (!instructions[2].isLdcI4()) + continue; + if (instructions[3].OpCode.Code != Code.Sub && instructions[3].OpCode.Code != Code.Add) + continue; + if (instructions[4].OpCode.Code != Code.Blt && instructions[4].OpCode.Code != Code.Blt_S && + instructions[4].OpCode.Code != Code.Bgt && instructions[4].OpCode.Code != Code.Bgt_S) + continue; + if (block.Sources.Count != 2) + continue; + var prev = block.Sources[0]; + if (prev == block) + prev = block.Sources[1]; + if (prev == null || !prev.LastInstr.isLdcI4()) + continue; + var next = block.FallThrough; + if (next.FirstInstr.OpCode.Code != Code.Pop) + continue; + block.replaceLastInstrsWithBranch(5, next); + changed = true; + } + return changed; + } + bool removeDeadBlocks() { int count = new DeadBlocksRemover(blocks.MethodBlocks).remove(); numRemovedDeadBlocks += count;