From c35e14ac0043ea1e793b2e1a24913a118e4b0c01 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 29 Jan 2014 03:35:35 +0100 Subject: [PATCH] Don't remove methods that exist in VTable fixups --- de4dot.code/deobfuscators/DeobfuscatorBase.cs | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/de4dot.code/deobfuscators/DeobfuscatorBase.cs b/de4dot.code/deobfuscators/DeobfuscatorBase.cs index 121c8479..cd9c5a29 100644 --- a/de4dot.code/deobfuscators/DeobfuscatorBase.cs +++ b/de4dot.code/deobfuscators/DeobfuscatorBase.cs @@ -54,6 +54,7 @@ namespace de4dot.code.deobfuscators { protected InitializedDataCreator initializedDataCreator; bool keepTypes; MetaDataFlags? mdFlags; + Dictionary objectsThatMustBeKept = new Dictionary(); protected byte[] ModuleBytes { get { return moduleBytes; } @@ -187,6 +188,8 @@ namespace de4dot.code.deobfuscators { module.EnableTypeDefFindCache = false; if (CanRemoveTypes) { + InitializeObjectsToKeepFromVTableFixups(); + RemoveTypesWithInvalidBaseTypes(); DeleteEmptyCctors(); @@ -204,6 +207,26 @@ namespace de4dot.code.deobfuscators { module.EnableTypeDefFindCache = cacheState; } + void InitializeObjectsToKeepFromVTableFixups() { + var fixups = module.VTableFixups; + if (fixups == null || fixups.VTables.Count == 0) + return; + + foreach (var vtable in fixups) { + if (vtable == null) + continue; + foreach (var method in vtable) { + if (method == null) + continue; + objectsThatMustBeKept[method] = true; + } + } + } + + bool MustKeepObject(object o) { + return o != null && objectsThatMustBeKept.ContainsKey(o); + } + static bool IsTypeWithInvalidBaseType(TypeDef moduleType, TypeDef type) { return type.BaseType == null && !type.IsInterface && type != moduleType; } @@ -233,7 +256,7 @@ namespace de4dot.code.deobfuscators { void RemoveTypesWithInvalidBaseTypes() { var moduleType = DotNetUtils.GetModuleType(module); foreach (var type in module.GetTypes()) { - if (!IsTypeWithInvalidBaseType(moduleType, type)) + if (!IsTypeWithInvalidBaseType(moduleType, type) || MustKeepObject(type)) continue; AddTypeToBeRemoved(type, "Invalid type with no base type (anti-reflection)"); } @@ -412,7 +435,7 @@ namespace de4dot.code.deobfuscators { var emptyCctorsToRemove = new List(); foreach (var type in module.GetTypes()) { var cctor = type.FindStaticConstructor(); - if (cctor != null && DotNetUtils.IsEmpty(cctor)) + if (cctor != null && DotNetUtils.IsEmpty(cctor) && !MustKeepObject(cctor)) emptyCctorsToRemove.Add(cctor); } @@ -442,7 +465,7 @@ namespace de4dot.code.deobfuscators { Logger.Instance.Indent(); foreach (var info in methodsToRemove) { var method = info.obj; - if (method == null) + if (method == null || MustKeepObject(method)) continue; var type = method.DeclaringType; if (type == null) @@ -465,7 +488,7 @@ namespace de4dot.code.deobfuscators { Logger.Instance.Indent(); foreach (var info in fieldsToRemove) { var field = info.obj; - if (field == null) + if (field == null || MustKeepObject(field)) continue; var type = field.DeclaringType; if (type == null) @@ -490,7 +513,7 @@ namespace de4dot.code.deobfuscators { var moduleType = DotNetUtils.GetModuleType(module); foreach (var info in typesToRemove) { var typeDef = info.obj; - if (typeDef == null || typeDef == moduleType) + if (typeDef == null || typeDef == moduleType || MustKeepObject(typeDef)) continue; bool removed; if (typeDef.DeclaringType != null) @@ -566,7 +589,7 @@ namespace de4dot.code.deobfuscators { Logger.Instance.Indent(); foreach (var info in resourcesToRemove) { var resource = info.obj; - if (resource == null) + if (resource == null || MustKeepObject(resource)) continue; if (module.Resources.Remove(resource)) Logger.v("Removed resource {0} (reason: {1})", Utils.ToCsharpString(resource.Name), info.reason);