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;
|
this.block = block;
|
||||||
if (!block.LastInstr.IsConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch)
|
if (!block.LastInstr.IsConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch)
|
||||||
return false;
|
return false;
|
||||||
instructionEmulator.Initialize(blocks);
|
instructionEmulator.Initialize(blocks, allBlocks[0] == block);
|
||||||
|
|
||||||
var instructions = block.Instructions;
|
var instructions = block.Instructions;
|
||||||
if (instructions.Count == 0)
|
if (instructions.Count == 0)
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace de4dot.blocks.cflow {
|
||||||
protected override bool Deobfuscate(Block block) {
|
protected override bool Deobfuscate(Block block) {
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
instructionEmulator.Initialize(blocks);
|
instructionEmulator.Initialize(blocks, allBlocks[0] == block);
|
||||||
var instrs = block.Instructions;
|
var instrs = block.Instructions;
|
||||||
for (int i = 0; i < instrs.Count; i++) {
|
for (int i = 0; i < instrs.Count; i++) {
|
||||||
var instr = instrs[i];
|
var instr = instrs[i];
|
||||||
|
|
|
@ -34,19 +34,24 @@ namespace de4dot.blocks.cflow {
|
||||||
MethodDef prev_method;
|
MethodDef prev_method;
|
||||||
List<Value> cached_args = new List<Value>();
|
List<Value> cached_args = new List<Value>();
|
||||||
List<Value> cached_locals = new List<Value>();
|
List<Value> cached_locals = new List<Value>();
|
||||||
|
List<Value> cached_zeroed_locals = new List<Value>();
|
||||||
|
|
||||||
public InstructionEmulator() {
|
public InstructionEmulator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstructionEmulator(MethodDef method) {
|
public InstructionEmulator(MethodDef method) {
|
||||||
Initialize(method);
|
Initialize(method, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(Blocks blocks) {
|
public void Initialize(Blocks blocks, bool emulateFromFirstInstruction) {
|
||||||
Initialize(blocks.Method);
|
Initialize(blocks.Method, emulateFromFirstInstruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(MethodDef method) {
|
public void Initialize(MethodDef method) {
|
||||||
|
Initialize(method, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(MethodDef method, bool emulateFromFirstInstruction) {
|
||||||
this.parameterDefs = method.Parameters;
|
this.parameterDefs = method.Parameters;
|
||||||
this.localDefs = method.Body.Variables;
|
this.localDefs = method.Body.Variables;
|
||||||
valueStack.Initialize();
|
valueStack.Initialize();
|
||||||
|
@ -60,14 +65,17 @@ namespace de4dot.blocks.cflow {
|
||||||
cached_args.Add(GetUnknownValue(parameterDefs[i].Type));
|
cached_args.Add(GetUnknownValue(parameterDefs[i].Type));
|
||||||
|
|
||||||
cached_locals.Clear();
|
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_locals.Add(GetUnknownValue(localDefs[i].Type));
|
||||||
|
cached_zeroed_locals.Add(GetDefaultValue(localDefs[i].Type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Clear();
|
args.Clear();
|
||||||
args.AddRange(cached_args);
|
args.AddRange(cached_args);
|
||||||
locals.Clear();
|
locals.Clear();
|
||||||
locals.AddRange(cached_locals);
|
locals.AddRange(method.Body.InitLocals && emulateFromFirstInstruction ? cached_zeroed_locals : cached_locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetProtected(Value value) {
|
public void SetProtected(Value value) {
|
||||||
|
@ -95,6 +103,25 @@ namespace de4dot.blocks.cflow {
|
||||||
return new UnknownValue();
|
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) {
|
Value TruncateValue(Value value, TypeSig type) {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return value;
|
return value;
|
||||||
|
|
|
@ -158,7 +158,7 @@ namespace de4dot.blocks.cflow {
|
||||||
foreach (var source in new List<Block>(block.Sources)) {
|
foreach (var source in new List<Block>(block.Sources)) {
|
||||||
if (!isBranchBlock(source))
|
if (!isBranchBlock(source))
|
||||||
continue;
|
continue;
|
||||||
instructionEmulator.Initialize(blocks);
|
instructionEmulator.Initialize(blocks, allBlocks[0] == source);
|
||||||
instructionEmulator.Emulate(source.Instructions);
|
instructionEmulator.Emulate(source.Instructions);
|
||||||
|
|
||||||
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop());
|
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop());
|
||||||
|
@ -183,7 +183,7 @@ namespace de4dot.blocks.cflow {
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
foreach (var source in new List<Block>(block.Sources)) {
|
foreach (var source in new List<Block>(block.Sources)) {
|
||||||
if (isBranchBlock(source)) {
|
if (isBranchBlock(source)) {
|
||||||
instructionEmulator.Initialize(blocks);
|
instructionEmulator.Initialize(blocks, allBlocks[0] == source);
|
||||||
instructionEmulator.Emulate(source.Instructions);
|
instructionEmulator.Emulate(source.Instructions);
|
||||||
|
|
||||||
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.GetLocal(switchVariable));
|
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.GetLocal(switchVariable));
|
||||||
|
@ -193,7 +193,7 @@ namespace de4dot.blocks.cflow {
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
else if (IsBccBlock(source)) {
|
else if (IsBccBlock(source)) {
|
||||||
instructionEmulator.Initialize(blocks);
|
instructionEmulator.Initialize(blocks, allBlocks[0] == source);
|
||||||
instructionEmulator.Emulate(source.Instructions);
|
instructionEmulator.Emulate(source.Instructions);
|
||||||
|
|
||||||
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.GetLocal(switchVariable));
|
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)) {
|
foreach (var source in new List<Block>(block.Sources)) {
|
||||||
if (!isBranchBlock(source))
|
if (!isBranchBlock(source))
|
||||||
continue;
|
continue;
|
||||||
instructionEmulator.Initialize(blocks);
|
instructionEmulator.Initialize(blocks, allBlocks[0] == source);
|
||||||
instructionEmulator.Emulate(source.Instructions);
|
instructionEmulator.Emulate(source.Instructions);
|
||||||
|
|
||||||
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop());
|
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop());
|
||||||
|
@ -407,7 +407,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulateGetTarget(Block switchBlock, out Block target) {
|
bool EmulateGetTarget(Block switchBlock, out Block target) {
|
||||||
instructionEmulator.Initialize(blocks);
|
instructionEmulator.Initialize(blocks, allBlocks[0] == switchBlock);
|
||||||
try {
|
try {
|
||||||
instructionEmulator.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
|
instructionEmulator.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WillHaveKnownTarget(Block switchBlock, Block source) {
|
bool WillHaveKnownTarget(Block switchBlock, Block source) {
|
||||||
instructionEmulator.Initialize(blocks);
|
instructionEmulator.Initialize(blocks, allBlocks[0] == source);
|
||||||
try {
|
try {
|
||||||
instructionEmulator.Emulate(source.Instructions);
|
instructionEmulator.Emulate(source.Instructions);
|
||||||
instructionEmulator.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
|
instructionEmulator.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user