Update code that removes methods and types

This commit is contained in:
de4dot 2011-12-28 13:30:44 +01:00
parent ffbceae488
commit 8de51ca227
2 changed files with 27 additions and 17 deletions

View File

@ -379,7 +379,12 @@ namespace de4dot.code.deobfuscators {
var typeDef = info.obj; var typeDef = info.obj;
if (typeDef == null) if (typeDef == null)
continue; continue;
if (types.Remove(typeDef)) bool removed;
if (typeDef.IsNested)
removed = typeDef.DeclaringType.NestedTypes.Remove(typeDef);
else
removed = types.Remove(typeDef);
if (removed)
Log.v("Removed type {0} ({1:X8}) (reason: {2})", typeDef, typeDef.MetadataToken.ToUInt32(), info.reason); Log.v("Removed type {0} ({1:X8}) (reason: {2})", typeDef, typeDef.MetadataToken.ToUInt32(), info.reason);
} }
Log.deIndent(); Log.deIndent();
@ -592,31 +597,32 @@ namespace de4dot.code.deobfuscators {
public void findAndRemoveInlinedMethods() { public void findAndRemoveInlinedMethods() {
var inlinedMethods = InlinedMethodsFinder.find(module); var inlinedMethods = InlinedMethodsFinder.find(module);
addMethodsToBeRemoved(new UnusedMethodsFinder(module, inlinedMethods).find(), "Inlined method"); addMethodsToBeRemoved(new UnusedMethodsFinder(module, inlinedMethods, getRemovedMethods()).find(), "Inlined method");
}
MethodCollection getRemovedMethods() {
var removedMethods = new MethodCollection();
removedMethods.add(getMethodsToRemove());
removedMethods.addAndNested(getTypesToRemove());
return removedMethods;
} }
protected bool isTypeCalled(TypeDefinition decrypterType) { protected bool isTypeCalled(TypeDefinition decrypterType) {
if (decrypterType == null) if (decrypterType == null)
return false; return false;
var decrypterMethods = new Dictionary<MethodReferenceAndDeclaringTypeKey, bool>(); var decrypterMethods = new MethodCollection();
foreach (var type in TypeDefinition.GetTypes(new List<TypeDefinition> { decrypterType })) decrypterMethods.addAndNested(decrypterType);
addMethods(type, decrypterMethods);
var removedMethods = new Dictionary<MethodReferenceAndDeclaringTypeKey, bool>(); var removedMethods = getRemovedMethods();
foreach (var method in getMethodsToRemove())
removedMethods[new MethodReferenceAndDeclaringTypeKey(method)] = true;
foreach (var type in TypeDefinition.GetTypes(getTypesToRemove()))
addMethods(type, removedMethods);
foreach (var type in module.GetTypes()) { foreach (var type in module.GetTypes()) {
foreach (var method in type.Methods) { foreach (var method in type.Methods) {
if (method.Body == null) if (method.Body == null)
continue; continue;
var key = new MethodReferenceAndDeclaringTypeKey(method); if (decrypterMethods.exists(method))
if (decrypterMethods.ContainsKey(key))
break; // decrypter type / nested type method break; // decrypter type / nested type method
if (removedMethods.ContainsKey(key)) if (removedMethods.exists(method))
continue; continue;
foreach (var instr in method.Body.Instructions) { foreach (var instr in method.Body.Instructions) {
@ -627,8 +633,7 @@ namespace de4dot.code.deobfuscators {
var calledMethod = instr.Operand as MethodReference; var calledMethod = instr.Operand as MethodReference;
if (calledMethod == null) if (calledMethod == null)
break; break;
key = new MethodReferenceAndDeclaringTypeKey(calledMethod); if (decrypterMethods.exists(calledMethod))
if (decrypterMethods.ContainsKey(key))
return true; return true;
break; break;

View File

@ -25,13 +25,15 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators { namespace de4dot.code.deobfuscators {
class UnusedMethodsFinder { class UnusedMethodsFinder {
ModuleDefinition module; ModuleDefinition module;
MethodCollection removedMethods;
Dictionary<MethodDefinition, bool> possiblyUnusedMethods = new Dictionary<MethodDefinition, bool>(); Dictionary<MethodDefinition, bool> possiblyUnusedMethods = new Dictionary<MethodDefinition, bool>();
Stack<MethodDefinition> notUnusedStack = new Stack<MethodDefinition>(); Stack<MethodDefinition> notUnusedStack = new Stack<MethodDefinition>();
public UnusedMethodsFinder(ModuleDefinition module, IEnumerable<MethodDefinition> possiblyUnusedMethods) { public UnusedMethodsFinder(ModuleDefinition module, IEnumerable<MethodDefinition> possiblyUnusedMethods, MethodCollection removedMethods) {
this.module = module; this.module = module;
this.removedMethods = removedMethods;
foreach (var method in possiblyUnusedMethods) { foreach (var method in possiblyUnusedMethods) {
if (method != module.EntryPoint) if (method != module.EntryPoint && !removedMethods.exists(method))
this.possiblyUnusedMethods[method] = true; this.possiblyUnusedMethods[method] = true;
} }
} }
@ -60,6 +62,8 @@ namespace de4dot.code.deobfuscators {
return; return;
if (possiblyUnusedMethods.ContainsKey(method)) if (possiblyUnusedMethods.ContainsKey(method))
return; return;
if (removedMethods.exists(method))
return;
foreach (var instr in method.Body.Instructions) { foreach (var instr in method.Body.Instructions) {
switch (instr.OpCode.Code) { switch (instr.OpCode.Code) {
@ -69,6 +73,7 @@ namespace de4dot.code.deobfuscators {
case Code.Newobj: case Code.Newobj:
case Code.Ldtoken: case Code.Ldtoken:
case Code.Ldftn: case Code.Ldftn:
case Code.Ldvirtftn:
break; break;
default: default:
continue; continue;