Add inline bool method hack for DNR
This commit is contained in:
parent
80acf1d59f
commit
7fe71a963a
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user