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) if (instructions.Count == 0)
return false; return false;
for (int i = 0; i < instructions.Count - 1; i++) { 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) { 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) { bool emulateBranch(int stackArgs, Bool3 cond) {
if (cond == Bool3.Unknown) if (cond == Bool3.Unknown)
return false; return false;

View File

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

View File

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