From 682b0df04abc644f120ff0e2b484dd489aa26b70 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 12 Nov 2013 17:11:54 +0100 Subject: [PATCH] Set locals = 0 when emulating from first instruction --- de4dot.blocks/cflow/BlockCflowDeobfuscator.cs | 2 +- de4dot.blocks/cflow/ConstantsFolder.cs | 2 +- de4dot.blocks/cflow/InstructionEmulator.cs | 37 ++++++++++++++++--- .../cflow/SwitchCflowDeobfuscator.cs | 12 +++--- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/de4dot.blocks/cflow/BlockCflowDeobfuscator.cs b/de4dot.blocks/cflow/BlockCflowDeobfuscator.cs index 24975de0..3bc44f1f 100644 --- a/de4dot.blocks/cflow/BlockCflowDeobfuscator.cs +++ b/de4dot.blocks/cflow/BlockCflowDeobfuscator.cs @@ -35,7 +35,7 @@ namespace de4dot.blocks.cflow { this.block = block; if (!block.LastInstr.IsConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch) return false; - instructionEmulator.Initialize(blocks); + instructionEmulator.Initialize(blocks, allBlocks[0] == block); var instructions = block.Instructions; if (instructions.Count == 0) diff --git a/de4dot.blocks/cflow/ConstantsFolder.cs b/de4dot.blocks/cflow/ConstantsFolder.cs index 43c291de..a0c7b5a7 100644 --- a/de4dot.blocks/cflow/ConstantsFolder.cs +++ b/de4dot.blocks/cflow/ConstantsFolder.cs @@ -37,7 +37,7 @@ namespace de4dot.blocks.cflow { protected override bool Deobfuscate(Block block) { bool modified = false; - instructionEmulator.Initialize(blocks); + instructionEmulator.Initialize(blocks, allBlocks[0] == block); var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; diff --git a/de4dot.blocks/cflow/InstructionEmulator.cs b/de4dot.blocks/cflow/InstructionEmulator.cs index 3345cf64..9dd11a1a 100644 --- a/de4dot.blocks/cflow/InstructionEmulator.cs +++ b/de4dot.blocks/cflow/InstructionEmulator.cs @@ -34,19 +34,24 @@ namespace de4dot.blocks.cflow { MethodDef prev_method; List cached_args = new List(); List cached_locals = new List(); + List cached_zeroed_locals = new List(); public InstructionEmulator() { } public InstructionEmulator(MethodDef method) { - Initialize(method); + Initialize(method, false); } - public void Initialize(Blocks blocks) { - Initialize(blocks.Method); + public void Initialize(Blocks blocks, bool emulateFromFirstInstruction) { + Initialize(blocks.Method, emulateFromFirstInstruction); } public void Initialize(MethodDef method) { + Initialize(method, false); + } + + public void Initialize(MethodDef method, bool emulateFromFirstInstruction) { this.parameterDefs = method.Parameters; this.localDefs = method.Body.Variables; valueStack.Initialize(); @@ -60,14 +65,17 @@ namespace de4dot.blocks.cflow { cached_args.Add(GetUnknownValue(parameterDefs[i].Type)); cached_locals.Clear(); - for (int i = 0; i < localDefs.Count; i++) + cached_zeroed_locals.Clear(); + for (int i = 0; i < localDefs.Count; i++) { cached_locals.Add(GetUnknownValue(localDefs[i].Type)); + cached_zeroed_locals.Add(GetDefaultValue(localDefs[i].Type)); + } } args.Clear(); args.AddRange(cached_args); locals.Clear(); - locals.AddRange(cached_locals); + locals.AddRange(method.Body.InitLocals && emulateFromFirstInstruction ? cached_zeroed_locals : cached_locals); } public void SetProtected(Value value) { @@ -95,6 +103,25 @@ namespace de4dot.blocks.cflow { return new UnknownValue(); } + static Value GetDefaultValue(TypeSig type) { + if (type == null) + return new UnknownValue(); + switch (type.ElementType) { + case ElementType.Boolean: + case ElementType.I1: + case ElementType.U1: + case ElementType.I2: + case ElementType.U2: + case ElementType.I4: + case ElementType.U4: + return Int32Value.zero; + case ElementType.I8: + case ElementType.U8: + return Int64Value.zero; + } + return new UnknownValue(); + } + Value TruncateValue(Value value, TypeSig type) { if (type == null) return value; diff --git a/de4dot.blocks/cflow/SwitchCflowDeobfuscator.cs b/de4dot.blocks/cflow/SwitchCflowDeobfuscator.cs index 329843f3..abec82b8 100644 --- a/de4dot.blocks/cflow/SwitchCflowDeobfuscator.cs +++ b/de4dot.blocks/cflow/SwitchCflowDeobfuscator.cs @@ -158,7 +158,7 @@ namespace de4dot.blocks.cflow { foreach (var source in new List(block.Sources)) { if (!isBranchBlock(source)) continue; - instructionEmulator.Initialize(blocks); + instructionEmulator.Initialize(blocks, allBlocks[0] == source); instructionEmulator.Emulate(source.Instructions); var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop()); @@ -183,7 +183,7 @@ namespace de4dot.blocks.cflow { bool modified = false; foreach (var source in new List(block.Sources)) { if (isBranchBlock(source)) { - instructionEmulator.Initialize(blocks); + instructionEmulator.Initialize(blocks, allBlocks[0] == source); instructionEmulator.Emulate(source.Instructions); var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.GetLocal(switchVariable)); @@ -193,7 +193,7 @@ namespace de4dot.blocks.cflow { modified = true; } else if (IsBccBlock(source)) { - instructionEmulator.Initialize(blocks); + instructionEmulator.Initialize(blocks, allBlocks[0] == source); instructionEmulator.Emulate(source.Instructions); var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.GetLocal(switchVariable)); @@ -223,7 +223,7 @@ namespace de4dot.blocks.cflow { foreach (var source in new List(block.Sources)) { if (!isBranchBlock(source)) continue; - instructionEmulator.Initialize(blocks); + instructionEmulator.Initialize(blocks, allBlocks[0] == source); instructionEmulator.Emulate(source.Instructions); var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop()); @@ -407,7 +407,7 @@ namespace de4dot.blocks.cflow { } bool EmulateGetTarget(Block switchBlock, out Block target) { - instructionEmulator.Initialize(blocks); + instructionEmulator.Initialize(blocks, allBlocks[0] == switchBlock); try { instructionEmulator.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1); } @@ -421,7 +421,7 @@ namespace de4dot.blocks.cflow { } bool WillHaveKnownTarget(Block switchBlock, Block source) { - instructionEmulator.Initialize(blocks); + instructionEmulator.Initialize(blocks, allBlocks[0] == source); try { instructionEmulator.Emulate(source.Instructions); instructionEmulator.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);