Add another proxy call fixer class

This commit is contained in:
de4dot 2012-05-29 19:13:43 +02:00
parent 2a7a134300
commit 512c650e11

View File

@ -192,7 +192,7 @@ namespace de4dot.code.deobfuscators {
fieldToDelegateInfo.add(di.field, di);
}
DelegateInfo getDelegateInfo(FieldReference field) {
protected DelegateInfo getDelegateInfo(FieldReference field) {
if (field == null)
return null;
return fieldToDelegateInfo.find(field);
@ -257,8 +257,7 @@ namespace de4dot.code.deobfuscators {
if (di == null)
continue;
var visited = new Dictionary<Block, bool>();
var callInfo = findProxyCall(di, block, i, visited, 1);
var callInfo = findProxyCall(di, block, i);
if (callInfo != null) {
add(removeInfos, block, i, null);
add(removeInfos, callInfo.Block, callInfo.Index, di);
@ -277,6 +276,10 @@ namespace de4dot.code.deobfuscators {
return fixProxyCalls(removeInfos);
}
protected virtual BlockInstr findProxyCall(DelegateInfo di, Block block, int index) {
return findProxyCall(di, block, index, new Dictionary<Block, bool>(), 1);
}
BlockInstr findProxyCall(DelegateInfo di, Block block, int index, Dictionary<Block, bool> visited, int stack) {
if (visited.ContainsKey(block))
return null;
@ -453,4 +456,38 @@ namespace de4dot.code.deobfuscators {
return fixProxyCalls(removeInfos);
}
}
// Fixes proxy calls that call a static method with the instance of
// of a delegate as the last arg, which then calls the Invoke method.
// ...push args...
// ldsfld delegate instance
// call static method
abstract class ProxyCallFixer3 : ProxyCallFixer1 {
protected ProxyCallFixer3(ModuleDefinition module)
: base(module) {
}
protected ProxyCallFixer3(ModuleDefinition module, ProxyCallFixer3 oldOne)
: base(module, oldOne) {
}
protected override BlockInstr findProxyCall(DelegateInfo di, Block block, int index) {
index++;
if (index >= block.Instructions.Count)
return null;
var calledMethod = getCalledMethod(block.Instructions[index]);
if (calledMethod == null)
return null;
return new BlockInstr {
Block = block,
Index = index,
};
}
static MethodReference getCalledMethod(Instr instr) {
if (instr.OpCode.Code != Code.Call)
return null;
return instr.Operand as MethodReference;
}
}
}