Set locals = 0 when emulating from first instruction
This commit is contained in:
parent
4fcb332ddf
commit
682b0df04a
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -34,19 +34,24 @@ namespace de4dot.blocks.cflow {
|
|||
MethodDef prev_method;
|
||||
List<Value> cached_args = new List<Value>();
|
||||
List<Value> cached_locals = new List<Value>();
|
||||
List<Value> cached_zeroed_locals = new List<Value>();
|
||||
|
||||
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;
|
||||
|
|
|
@ -158,7 +158,7 @@ namespace de4dot.blocks.cflow {
|
|||
foreach (var source in new List<Block>(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>(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>(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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user