Add inline bool method hack for DNR

This commit is contained in:
de4dot 2011-10-19 01:53:42 +02:00
parent 80acf1d59f
commit 7fe71a963a
3 changed files with 41 additions and 10 deletions

View File

@ -37,7 +37,10 @@ namespace de4dot.blocks.cflow {
if (instructions.Count == 0)
return false;
for (int i = 0; i < instructions.Count - 1; i++) {
instructionEmulator.emulate(instructions[i].Instruction);
var instr = instructions[i].Instruction;
if (patchBoolCallMethod(instr, i))
instr = instructions[i].Instruction;
instructionEmulator.emulate(instr);
}
switch (block.LastInstr.OpCode.Code) {
@ -72,6 +75,34 @@ namespace de4dot.blocks.cflow {
}
}
// This is a hack for .NET Reactor
bool patchBoolCallMethod(Instruction instr, int instrIndex) {
if (instr.OpCode.Code != Code.Call)
return false;
var method = instr.Operand as MethodDefinition;
if (method == null)
return false;
if (method.Parameters.Count > 0)
return false;
if (!MemberReferenceHelper.verifyType(method.MethodReturnType.ReturnType, "mscorlib", "System.Boolean"))
return false;
var body = method.Body;
if (body == null)
return false;
var instrs = body.Instructions;
if (instrs.Count > 10)
return false;
var ldci4 = instrs[0];
if (ldci4.OpCode.Code == Code.Br || ldci4.OpCode.Code == Code.Br_S)
ldci4 = (Instruction)ldci4.Operand;
if (ldci4 == null || !DotNetUtils.isLdcI4(ldci4) || ldci4.Next == null || ldci4.Next.OpCode.Code != Code.Ret)
return false;
int val = DotNetUtils.getLdcI4Value(ldci4);
block.Instructions[instrIndex] = new Instr(Instruction.Create(OpCodes.Ldc_I4, val));
return true;
}
bool emulateBranch(int stackArgs, Bool3 cond) {
if (cond == Bool3.Unknown)
return false;

View File

@ -22,7 +22,7 @@ using Mono.Cecil.Cil;
namespace de4dot.blocks.cflow {
public class BlocksCflowDeobfuscator {
BlockCflowDeobfuscator blockControlFlowDeobfuscator = new BlockCflowDeobfuscator();
BlockCflowDeobfuscator blockCflowDeobfuscator = new BlockCflowDeobfuscator();
Blocks blocks;
int numRemovedDeadBlocks;
@ -41,8 +41,8 @@ namespace de4dot.blocks.cflow {
bool changed;
do {
changed = false;
changed |= removeDeadBlocks();
changed |= mergeBlocks();
removeDeadBlocks();
mergeBlocks();
allBlocks.Clear();
allBlocks.AddRange(blocks.MethodBlocks.getAllBlocks());
@ -51,8 +51,8 @@ namespace de4dot.blocks.cflow {
var lastInstr = block.LastInstr;
if (!DotNetUtils.isConditionalBranch(lastInstr.OpCode.Code) && lastInstr.OpCode.Code != Code.Switch)
continue;
blockControlFlowDeobfuscator.init(block, blocks.Method.Parameters, blocks.Locals);
changed |= blockControlFlowDeobfuscator.deobfuscate();
blockCflowDeobfuscator.init(block, blocks.Method.Parameters, blocks.Locals);
changed |= blockCflowDeobfuscator.deobfuscate();
}
switchCflowDeobfuscator.init(blocks, allBlocks);

View File

@ -442,7 +442,7 @@ namespace de4dot {
Log.v("Deobfuscating methods");
var methodPrinter = new MethodPrinter();
var cflowObfuscator = new BlocksCflowDeobfuscator();
var cflowDeobfuscator = new BlocksCflowDeobfuscator();
foreach (var method in allMethods) {
Log.v("Deobfuscating {0} ({1:X8})", method, method.MetadataToken.ToUInt32());
Log.indent();
@ -452,9 +452,9 @@ namespace de4dot {
deob.deobfuscateMethodBegin(blocks);
if (options.ControlFlowDeobfuscation) {
cflowObfuscator.init(blocks);
cflowObfuscator.deobfuscate();
int numDeadBlocks = cflowObfuscator.NumberOfRemovedDeadBlocks;
cflowDeobfuscator.init(blocks);
cflowDeobfuscator.deobfuscate();
int numDeadBlocks = cflowDeobfuscator.NumberOfRemovedDeadBlocks;
if (numDeadBlocks > 0)
Log.v("Removed {0} dead block(s)", numDeadBlocks);
}