Fix restoring resource names

This commit is contained in:
de4dot 2013-11-25 05:45:34 +01:00
parent ec7bed040b
commit bfcffdd51f
2 changed files with 59 additions and 11 deletions

View File

@ -159,7 +159,6 @@ namespace de4dot.code.deobfuscators.Spices_Net {
if (options.RestoreResourceNames) { if (options.RestoreResourceNames) {
resourceNamesRestorer = new ResourceNamesRestorer(module); resourceNamesRestorer = new ResourceNamesRestorer(module);
resourceNamesRestorer.Find(); resourceNamesRestorer.Find();
resourceNamesRestorer.RenameResources();
} }
stringDecrypter.Initialize(); stringDecrypter.Initialize();
@ -184,6 +183,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
RemoveInlinedMethods(); RemoveInlinedMethods();
if (options.RestoreResourceNames) { if (options.RestoreResourceNames) {
resourceNamesRestorer.RenameResources();
AddTypeToBeRemoved(resourceNamesRestorer.ResourceManagerType, "Obfuscator ResourceManager type"); AddTypeToBeRemoved(resourceNamesRestorer.ResourceManagerType, "Obfuscator ResourceManager type");
AddTypeToBeRemoved(resourceNamesRestorer.ComponentResourceManagerType, "Obfuscator ComponentResourceManager type"); AddTypeToBeRemoved(resourceNamesRestorer.ComponentResourceManagerType, "Obfuscator ComponentResourceManager type");
} }

View File

@ -29,6 +29,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
TypeDef componentResourceManagerType; TypeDef componentResourceManagerType;
MethodDefAndDeclaringTypeDict<IMethod> resourceManagerCtors = new MethodDefAndDeclaringTypeDict<IMethod>(); MethodDefAndDeclaringTypeDict<IMethod> resourceManagerCtors = new MethodDefAndDeclaringTypeDict<IMethod>();
MethodDefAndDeclaringTypeDict<IMethod> componentManagerCtors = new MethodDefAndDeclaringTypeDict<IMethod>(); MethodDefAndDeclaringTypeDict<IMethod> componentManagerCtors = new MethodDefAndDeclaringTypeDict<IMethod>();
Dictionary<TypeDef, bool> callsResourceManager = new Dictionary<TypeDef, bool>();
public TypeDef ResourceManagerType { public TypeDef ResourceManagerType {
get { return resourceManagerType; } get { return resourceManagerType; }
@ -101,23 +102,68 @@ namespace de4dot.code.deobfuscators.Spices_Net {
numToResource[extNum] = resource; numToResource[extNum] = resource;
} }
foreach (var type in module.GetTypes()) { if (module.Assembly != null)
Rename(numToResource, "", type.FullName); Rename(numToResource, "", module.Assembly.Name + ".g");
Rename(numToResource, "", type.FullName + ".g");
Rename(numToResource, type.Namespace.String, type.Name.String); foreach (var type in callsResourceManager.Keys)
Rename(numToResource, type.Namespace.String, type.Name.String + ".g"); Rename(numToResource, type);
if (numToResource.Count != 0) {
foreach (var type in module.GetTypes()) {
if (numToResource.Count == 0)
break;
if (!IsWinFormType(type))
continue;
Rename(numToResource, type);
}
} }
if (module.Assembly != null) if (numToResource.Count != 0) {
Rename(numToResource, "", module.Assembly.Name.String + ".g"); foreach (var type in module.GetTypes()) {
if (numToResource.Count == 0)
break;
Rename(numToResource, type);
}
}
if (numToResource.Count != 0)
Logger.e("Couldn't restore all renamed resource names");
} }
static void Rename(Dictionary<uint, Resource> numToResource, string ns, string name) { static bool IsWinFormType(TypeDef type) {
for (int i = 0; i < 100; i++) {
var baseType = type.BaseType;
if (baseType == null)
break;
if (baseType.FullName == "System.Object" ||
baseType.FullName == "System.ValueType")
return false;
// Speed up common cases
if (baseType.FullName == "System.Windows.Forms.Control" ||
baseType.FullName == "System.Windows.Forms.Form" ||
baseType.FullName == "System.Windows.Forms.UserControl")
return true;
var resolvedBaseType = baseType.ResolveTypeDef();
if (resolvedBaseType == null)
break;
type = resolvedBaseType;
}
return false;
}
static bool Rename(Dictionary<uint, Resource> numToResource, TypeDef type) {
return Rename(numToResource, "", type.FullName) ||
Rename(numToResource, "", type.FullName + ".g") ||
Rename(numToResource, type.Namespace, type.Name) ||
Rename(numToResource, type.Namespace, type.Name + ".g");
}
static bool Rename(Dictionary<uint, Resource> numToResource, string ns, string name) {
var resourceName = name + ".resources"; var resourceName = name + ".resources";
uint hash = GetResourceHash(resourceName); uint hash = GetResourceHash(resourceName);
Resource resource; Resource resource;
if (!numToResource.TryGetValue(hash, out resource)) if (!numToResource.TryGetValue(hash, out resource))
return; return false;
int index = resource.Name.String.LastIndexOf('.'); int index = resource.Name.String.LastIndexOf('.');
string resourceNamespace, newName; string resourceNamespace, newName;
@ -130,13 +176,14 @@ namespace de4dot.code.deobfuscators.Spices_Net {
newName = resourceNamespace + "." + resourceName; newName = resourceNamespace + "." + resourceName;
} }
if (resourceNamespace != ns) if (resourceNamespace != ns)
return; return false;
Logger.v("Restoring resource name: '{0}' => '{1}'", Logger.v("Restoring resource name: '{0}' => '{1}'",
Utils.RemoveNewlines(resource.Name), Utils.RemoveNewlines(resource.Name),
Utils.RemoveNewlines(newName)); Utils.RemoveNewlines(newName));
resource.Name = newName; resource.Name = newName;
numToResource.Remove(hash); numToResource.Remove(hash);
return true;
} }
static uint GetResourceHash(string name) { static uint GetResourceHash(string name) {
@ -169,6 +216,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
if (newCtor == null) if (newCtor == null)
continue; continue;
instr.Operand = newCtor; instr.Operand = newCtor;
callsResourceManager[blocks.Method.DeclaringType] = true;
} }
} }
} }