Don't remove methods that exist in VTable fixups
This commit is contained in:
parent
bfcffdd51f
commit
c35e14ac00
|
@ -54,6 +54,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
protected InitializedDataCreator initializedDataCreator;
|
protected InitializedDataCreator initializedDataCreator;
|
||||||
bool keepTypes;
|
bool keepTypes;
|
||||||
MetaDataFlags? mdFlags;
|
MetaDataFlags? mdFlags;
|
||||||
|
Dictionary<object, bool> objectsThatMustBeKept = new Dictionary<object, bool>();
|
||||||
|
|
||||||
protected byte[] ModuleBytes {
|
protected byte[] ModuleBytes {
|
||||||
get { return moduleBytes; }
|
get { return moduleBytes; }
|
||||||
|
@ -187,6 +188,8 @@ namespace de4dot.code.deobfuscators {
|
||||||
module.EnableTypeDefFindCache = false;
|
module.EnableTypeDefFindCache = false;
|
||||||
|
|
||||||
if (CanRemoveTypes) {
|
if (CanRemoveTypes) {
|
||||||
|
InitializeObjectsToKeepFromVTableFixups();
|
||||||
|
|
||||||
RemoveTypesWithInvalidBaseTypes();
|
RemoveTypesWithInvalidBaseTypes();
|
||||||
|
|
||||||
DeleteEmptyCctors();
|
DeleteEmptyCctors();
|
||||||
|
@ -204,6 +207,26 @@ namespace de4dot.code.deobfuscators {
|
||||||
module.EnableTypeDefFindCache = cacheState;
|
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) {
|
static bool IsTypeWithInvalidBaseType(TypeDef moduleType, TypeDef type) {
|
||||||
return type.BaseType == null && !type.IsInterface && type != moduleType;
|
return type.BaseType == null && !type.IsInterface && type != moduleType;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +256,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
void RemoveTypesWithInvalidBaseTypes() {
|
void RemoveTypesWithInvalidBaseTypes() {
|
||||||
var moduleType = DotNetUtils.GetModuleType(module);
|
var moduleType = DotNetUtils.GetModuleType(module);
|
||||||
foreach (var type in module.GetTypes()) {
|
foreach (var type in module.GetTypes()) {
|
||||||
if (!IsTypeWithInvalidBaseType(moduleType, type))
|
if (!IsTypeWithInvalidBaseType(moduleType, type) || MustKeepObject(type))
|
||||||
continue;
|
continue;
|
||||||
AddTypeToBeRemoved(type, "Invalid type with no base type (anti-reflection)");
|
AddTypeToBeRemoved(type, "Invalid type with no base type (anti-reflection)");
|
||||||
}
|
}
|
||||||
|
@ -412,7 +435,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var emptyCctorsToRemove = new List<MethodDef>();
|
var emptyCctorsToRemove = new List<MethodDef>();
|
||||||
foreach (var type in module.GetTypes()) {
|
foreach (var type in module.GetTypes()) {
|
||||||
var cctor = type.FindStaticConstructor();
|
var cctor = type.FindStaticConstructor();
|
||||||
if (cctor != null && DotNetUtils.IsEmpty(cctor))
|
if (cctor != null && DotNetUtils.IsEmpty(cctor) && !MustKeepObject(cctor))
|
||||||
emptyCctorsToRemove.Add(cctor);
|
emptyCctorsToRemove.Add(cctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +465,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
Logger.Instance.Indent();
|
Logger.Instance.Indent();
|
||||||
foreach (var info in methodsToRemove) {
|
foreach (var info in methodsToRemove) {
|
||||||
var method = info.obj;
|
var method = info.obj;
|
||||||
if (method == null)
|
if (method == null || MustKeepObject(method))
|
||||||
continue;
|
continue;
|
||||||
var type = method.DeclaringType;
|
var type = method.DeclaringType;
|
||||||
if (type == null)
|
if (type == null)
|
||||||
|
@ -465,7 +488,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
Logger.Instance.Indent();
|
Logger.Instance.Indent();
|
||||||
foreach (var info in fieldsToRemove) {
|
foreach (var info in fieldsToRemove) {
|
||||||
var field = info.obj;
|
var field = info.obj;
|
||||||
if (field == null)
|
if (field == null || MustKeepObject(field))
|
||||||
continue;
|
continue;
|
||||||
var type = field.DeclaringType;
|
var type = field.DeclaringType;
|
||||||
if (type == null)
|
if (type == null)
|
||||||
|
@ -490,7 +513,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var moduleType = DotNetUtils.GetModuleType(module);
|
var moduleType = DotNetUtils.GetModuleType(module);
|
||||||
foreach (var info in typesToRemove) {
|
foreach (var info in typesToRemove) {
|
||||||
var typeDef = info.obj;
|
var typeDef = info.obj;
|
||||||
if (typeDef == null || typeDef == moduleType)
|
if (typeDef == null || typeDef == moduleType || MustKeepObject(typeDef))
|
||||||
continue;
|
continue;
|
||||||
bool removed;
|
bool removed;
|
||||||
if (typeDef.DeclaringType != null)
|
if (typeDef.DeclaringType != null)
|
||||||
|
@ -566,7 +589,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
Logger.Instance.Indent();
|
Logger.Instance.Indent();
|
||||||
foreach (var info in resourcesToRemove) {
|
foreach (var info in resourcesToRemove) {
|
||||||
var resource = info.obj;
|
var resource = info.obj;
|
||||||
if (resource == null)
|
if (resource == null || MustKeepObject(resource))
|
||||||
continue;
|
continue;
|
||||||
if (module.Resources.Remove(resource))
|
if (module.Resources.Remove(resource))
|
||||||
Logger.v("Removed resource {0} (reason: {1})", Utils.ToCsharpString(resource.Name), info.reason);
|
Logger.v("Removed resource {0} (reason: {1})", Utils.ToCsharpString(resource.Name), info.reason);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user