Update symbol renamer to load referenced assemblies.
This way it's possible to use a rename-all regex (.*) without renaming symbols that shouldn't be renamed (eg. methods that are defined in an interface in a non-deobfuscated module, eg. Dispose()). A warning is displayed if an assembly can't be loaded.
This commit is contained in:
parent
2a967dc699
commit
f351a09564
|
@ -21,13 +21,7 @@
|
||||||
/*
|
/*
|
||||||
How to test it:
|
How to test it:
|
||||||
- Compile this assembly and the other test assembly
|
- Compile this assembly and the other test assembly
|
||||||
- Force rename of everything (set name regex to eg. asdfasdfasdf)
|
- Force rename of everything (set name regex to eg. .*)
|
||||||
Make sure the code doesn't rename any types inheriting from
|
|
||||||
Delegate or MulticastDelegate. renameMembers() should
|
|
||||||
return before renaming the members
|
|
||||||
if (TypeDefinition.BaseType != null && TypeDefinition.BaseType.Name.Contains("Delegate"))
|
|
||||||
return;
|
|
||||||
...real code...
|
|
||||||
- Run peverify /IL /MD on both files
|
- Run peverify /IL /MD on both files
|
||||||
- Decompile them and create a solution for both projects. I recommend using ILSpy.
|
- Decompile them and create a solution for both projects. I recommend using ILSpy.
|
||||||
- Compile with VS. If it fails to build, make sure the decompiler isn't buggy.
|
- Compile with VS. If it fails to build, make sure the decompiler isn't buggy.
|
||||||
|
|
|
@ -330,12 +330,29 @@ namespace de4dot.blocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string getCanonicalizedScopeName(IMetadataScope scope) {
|
public static string getCanonicalizedScopeName(IMetadataScope scope) {
|
||||||
var name = scope.Name.ToLowerInvariant();
|
AssemblyNameReference asmRef = null;
|
||||||
if (scope is ModuleDefinition) {
|
|
||||||
if (name.EndsWith(".exe", StringComparison.Ordinal) || name.EndsWith(".dll", StringComparison.Ordinal))
|
switch (scope.MetadataScopeType) {
|
||||||
name = name.Remove(name.Length - 4);
|
case MetadataScopeType.AssemblyNameReference:
|
||||||
|
asmRef = (AssemblyNameReference)scope;
|
||||||
|
break;
|
||||||
|
case MetadataScopeType.ModuleDefinition:
|
||||||
|
var module = (ModuleDefinition)scope;
|
||||||
|
if (module.Assembly != null)
|
||||||
|
asmRef = module.Assembly.Name;
|
||||||
|
break;
|
||||||
|
case MetadataScopeType.ModuleReference:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ApplicationException(string.Format("Invalid scope type: {0}", scope.GetType()));
|
||||||
}
|
}
|
||||||
return name;
|
|
||||||
|
if (asmRef != null) {
|
||||||
|
if (asmRef.FullName.StartsWith("mscorlib,", StringComparison.Ordinal))
|
||||||
|
return "mscorlib";
|
||||||
|
return string.Format("{0}", asmRef.FullName.ToLowerInvariant());
|
||||||
|
}
|
||||||
|
return string.Format("{0}", scope.ToString().ToLowerInvariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool compareScope(IMetadataScope a, IMetadataScope b) {
|
public static bool compareScope(IMetadataScope a, IMetadataScope b) {
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="renamer\DefinitionsRenamer.cs" />
|
<Compile Include="renamer\DefinitionsRenamer.cs" />
|
||||||
|
<Compile Include="renamer\ExternalAssemblies.cs" />
|
||||||
<Compile Include="renamer\MemberRefFinder.cs" />
|
<Compile Include="renamer\MemberRefFinder.cs" />
|
||||||
<Compile Include="renamer\MemberRefs.cs" />
|
<Compile Include="renamer\MemberRefs.cs" />
|
||||||
<Compile Include="renamer\MemberRenameState.cs" />
|
<Compile Include="renamer\MemberRenameState.cs" />
|
||||||
|
|
|
@ -23,7 +23,7 @@ using Mono.Cecil;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.renamer {
|
namespace de4dot.renamer {
|
||||||
// Renames all typedefs, methoddefs, eventdefs, fielddefs, and propdefs
|
// Renames typedefs, methoddefs, eventdefs, fielddefs, propdefs, and genparams
|
||||||
class DefinitionsRenamer : IResolver, IDefFinder {
|
class DefinitionsRenamer : IResolver, IDefFinder {
|
||||||
// All types that don't derive from an existing type definition (most likely mscorlib
|
// All types that don't derive from an existing type definition (most likely mscorlib
|
||||||
// isn't loaded, so this won't have just one element).
|
// isn't loaded, so this won't have just one element).
|
||||||
|
@ -31,7 +31,6 @@ namespace de4dot.renamer {
|
||||||
IList<TypeDef> nonNestedTypes;
|
IList<TypeDef> nonNestedTypes;
|
||||||
IList<Module> modules = new List<Module>();
|
IList<Module> modules = new List<Module>();
|
||||||
List<TypeDef> allTypes = new List<TypeDef>();
|
List<TypeDef> allTypes = new List<TypeDef>();
|
||||||
IDictionary<MethodDefinition, MethodDef> methodToMethodDef = new Dictionary<MethodDefinition, MethodDef>();
|
|
||||||
TypeNameState typeNameState;
|
TypeNameState typeNameState;
|
||||||
ModulesDict modulesDict = new ModulesDict();
|
ModulesDict modulesDict = new ModulesDict();
|
||||||
AssemblyHash assemblyHash = new AssemblyHash();
|
AssemblyHash assemblyHash = new AssemblyHash();
|
||||||
|
@ -114,7 +113,7 @@ namespace de4dot.renamer {
|
||||||
public void renameAll() {
|
public void renameAll() {
|
||||||
if (modules.Count == 0)
|
if (modules.Count == 0)
|
||||||
return;
|
return;
|
||||||
Log.n("Renaming all obfuscated names");
|
Log.n("Renaming all obfuscated symbols");
|
||||||
findAllMemberReferences();
|
findAllMemberReferences();
|
||||||
resolveAllRefs();
|
resolveAllRefs();
|
||||||
initAllTypes();
|
initAllTypes();
|
||||||
|
@ -132,7 +131,7 @@ namespace de4dot.renamer {
|
||||||
foreach (var module in modules)
|
foreach (var module in modules)
|
||||||
allTypes.AddRange(module.getAllTypes());
|
allTypes.AddRange(module.getAllTypes());
|
||||||
|
|
||||||
var typeToTypeDef = new Dictionary<TypeDefinition, TypeDef>();
|
var typeToTypeDef = new Dictionary<TypeDefinition, TypeDef>(allTypes.Count);
|
||||||
foreach (var typeDef in allTypes)
|
foreach (var typeDef in allTypes)
|
||||||
typeToTypeDef[typeDef.TypeDefinition] = typeDef;
|
typeToTypeDef[typeDef.TypeDefinition] = typeDef;
|
||||||
|
|
||||||
|
@ -147,22 +146,21 @@ namespace de4dot.renamer {
|
||||||
var baseType = typeDef.TypeDefinition.BaseType;
|
var baseType = typeDef.TypeDefinition.BaseType;
|
||||||
if (baseType == null)
|
if (baseType == null)
|
||||||
continue;
|
continue;
|
||||||
var baseTypeDefinition = resolve(baseType);
|
var baseTypeDef = resolve(baseType) ?? resolveOther(baseType);
|
||||||
if (baseTypeDefinition == null)
|
if (baseTypeDef != null) {
|
||||||
continue;
|
typeDef.addBaseType(baseTypeDef, baseType);
|
||||||
var baseTypeDef = typeToTypeDef[baseTypeDefinition];
|
|
||||||
typeDef.baseType = new TypeInfo(baseType, baseTypeDef);
|
|
||||||
baseTypeDef.derivedTypes.Add(typeDef);
|
baseTypeDef.derivedTypes.Add(typeDef);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize interfaces
|
// Initialize interfaces
|
||||||
foreach (var typeDef in allTypes) {
|
foreach (var typeDef in allTypes) {
|
||||||
if (typeDef.TypeDefinition.Interfaces == null)
|
if (typeDef.TypeDefinition.Interfaces == null)
|
||||||
continue;
|
continue;
|
||||||
foreach (var iface in typeDef.TypeDefinition.Interfaces) {
|
foreach (var iface in typeDef.TypeDefinition.Interfaces) {
|
||||||
var ifaceTypeDefinition = resolve(iface);
|
var ifaceTypeDef = resolve(iface) ?? resolveOther(iface);
|
||||||
if (ifaceTypeDefinition != null)
|
if (ifaceTypeDef != null)
|
||||||
typeDef.interfaces.Add(new TypeInfo(iface, typeToTypeDef[ifaceTypeDefinition]));
|
typeDef.addInterface(ifaceTypeDef, iface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,15 +174,11 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
nonNestedTypes = new List<TypeDef>(allTypesDict.Keys);
|
nonNestedTypes = new List<TypeDef>(allTypesDict.Keys);
|
||||||
|
|
||||||
// So we can quickly look up MethodDefs
|
foreach (var typeDef in allTypes)
|
||||||
foreach (var typeDef in allTypes) {
|
|
||||||
foreach (var methodDef in typeDef.Methods)
|
|
||||||
methodToMethodDef[methodDef.MethodDefinition] = methodDef;
|
|
||||||
typeDef.defFinder = this;
|
typeDef.defFinder = this;
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var typeDef in allTypes) {
|
foreach (var typeDef in allTypes) {
|
||||||
if (typeDef.baseType == null)
|
if (typeDef.baseType == null || !typeDef.baseType.typeDef.IsRenamable)
|
||||||
baseTypes.Add(typeDef);
|
baseTypes.Add(typeDef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,12 +322,48 @@ namespace de4dot.renamer {
|
||||||
renameEntryPoints();
|
renameEntryPoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary<TypeReferenceKey, TypeDef> otherTypesDict = new Dictionary<TypeReferenceKey, TypeDef>();
|
||||||
|
ExternalAssemblies externalAssemblies = new ExternalAssemblies();
|
||||||
|
TypeDef resolveOther(TypeReference type) {
|
||||||
|
if (type == null)
|
||||||
|
return null;
|
||||||
|
type = type.GetElementType();
|
||||||
|
|
||||||
|
TypeDef typeDef;
|
||||||
|
var key = new TypeReferenceKey(type);
|
||||||
|
if (otherTypesDict.TryGetValue(key, out typeDef))
|
||||||
|
return typeDef;
|
||||||
|
otherTypesDict[key] = null; // In case of a circular reference
|
||||||
|
|
||||||
|
TypeDefinition typeDefinition = externalAssemblies.resolve(type);
|
||||||
|
if (typeDefinition == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
typeDef = new TypeDef(typeDefinition);
|
||||||
|
typeDef.MemberRenameState = new MemberRenameState();
|
||||||
|
typeDef.addMembers();
|
||||||
|
foreach (var iface in typeDef.TypeDefinition.Interfaces) {
|
||||||
|
var ifaceDef = resolveOther(iface);
|
||||||
|
if (ifaceDef == null)
|
||||||
|
continue;
|
||||||
|
typeDef.MemberRenameState.mergeRenamed(ifaceDef.MemberRenameState);
|
||||||
|
typeDef.addInterface(ifaceDef, iface);
|
||||||
|
}
|
||||||
|
var baseDef = resolveOther(typeDef.TypeDefinition.BaseType);
|
||||||
|
if (baseDef != null) {
|
||||||
|
typeDef.MemberRenameState.mergeRenamed(baseDef.MemberRenameState);
|
||||||
|
typeDef.addBaseType(baseDef, typeDef.TypeDefinition.BaseType);
|
||||||
|
}
|
||||||
|
typeDef.initializeVirtualMembers();
|
||||||
|
return otherTypesDict[key] = typeDef;
|
||||||
|
}
|
||||||
|
|
||||||
void renameEntryPoints() {
|
void renameEntryPoints() {
|
||||||
foreach (var module in modules) {
|
foreach (var module in modules) {
|
||||||
var entryPoint = module.ModuleDefinition.EntryPoint;
|
var entryPoint = module.ModuleDefinition.EntryPoint;
|
||||||
if (entryPoint == null)
|
if (entryPoint == null)
|
||||||
continue;
|
continue;
|
||||||
var methodDef = findMethod(entryPoint);
|
var methodDef = resolve(entryPoint);
|
||||||
if (methodDef == null)
|
if (methodDef == null)
|
||||||
throw new ApplicationException(string.Format("Could not find entry point. Module: {0}, Method: {1}", module.ModuleDefinition.FullyQualifiedName, entryPoint));
|
throw new ApplicationException(string.Format("Could not find entry point. Module: {0}, Method: {1}", module.ModuleDefinition.FullyQualifiedName, entryPoint));
|
||||||
if (!methodDef.MethodDefinition.IsStatic)
|
if (!methodDef.MethodDefinition.IsStatic)
|
||||||
|
@ -402,7 +432,7 @@ namespace de4dot.renamer {
|
||||||
|
|
||||||
IEnumerable<InterfaceScopeInfo> getInterfaceScopeInfo(IEnumerable<TypeDef> baseTypes) {
|
IEnumerable<InterfaceScopeInfo> getInterfaceScopeInfo(IEnumerable<TypeDef> baseTypes) {
|
||||||
foreach (var typeDef in baseTypes) {
|
foreach (var typeDef in baseTypes) {
|
||||||
yield return new InterfaceScopeInfo(typeDef, new List<TypeDef>(typeDef.getAllInterfaces()));
|
yield return new InterfaceScopeInfo(typeDef, new List<TypeDef>(typeDef.getAllRenamableInterfaces()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,7 +491,7 @@ namespace de4dot.renamer {
|
||||||
return typeReference is ArrayType || typeReference is PointerType;
|
return typeReference is ArrayType || typeReference is PointerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition resolve(TypeReference typeReference) {
|
public TypeDef resolve(TypeReference typeReference) {
|
||||||
var modules = findModules(typeReference.Scope);
|
var modules = findModules(typeReference.Scope);
|
||||||
if (modules == null)
|
if (modules == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -475,7 +505,7 @@ namespace de4dot.renamer {
|
||||||
throw new ApplicationException(string.Format("Could not resolve TypeReference {0} ({1:X8})", typeReference, typeReference.MetadataToken.ToInt32()));
|
throw new ApplicationException(string.Format("Could not resolve TypeReference {0} ({1:X8})", typeReference, typeReference.MetadataToken.ToInt32()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition resolve(MethodReference methodReference) {
|
public MethodDef resolve(MethodReference methodReference) {
|
||||||
if (methodReference.DeclaringType == null)
|
if (methodReference.DeclaringType == null)
|
||||||
return null;
|
return null;
|
||||||
var modules = findModules(methodReference.DeclaringType.Scope);
|
var modules = findModules(methodReference.DeclaringType.Scope);
|
||||||
|
@ -491,7 +521,7 @@ namespace de4dot.renamer {
|
||||||
throw new ApplicationException(string.Format("Could not resolve MethodReference {0} ({1:X8})", methodReference, methodReference.MetadataToken.ToInt32()));
|
throw new ApplicationException(string.Format("Could not resolve MethodReference {0} ({1:X8})", methodReference, methodReference.MetadataToken.ToInt32()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldDefinition resolve(FieldReference fieldReference) {
|
public FieldDef resolve(FieldReference fieldReference) {
|
||||||
if (fieldReference.DeclaringType == null)
|
if (fieldReference.DeclaringType == null)
|
||||||
return null;
|
return null;
|
||||||
var modules = findModules(fieldReference.DeclaringType.Scope);
|
var modules = findModules(fieldReference.DeclaringType.Scope);
|
||||||
|
@ -508,21 +538,18 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDef findMethod(MethodReference methodReference) {
|
public MethodDef findMethod(MethodReference methodReference) {
|
||||||
var method = resolve(methodReference);
|
return resolve(methodReference);
|
||||||
if (method == null)
|
|
||||||
return null;
|
|
||||||
return methodToMethodDef[method];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyDef findProp(MethodReference methodReference) {
|
public PropertyDef findProp(MethodReference methodReference) {
|
||||||
var methodDef = findMethod(methodReference);
|
var methodDef = resolve(methodReference);
|
||||||
if (methodDef == null)
|
if (methodDef == null)
|
||||||
return null;
|
return null;
|
||||||
return methodDef.Property;
|
return methodDef.Property;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventDef findEvent(MethodReference methodReference) {
|
public EventDef findEvent(MethodReference methodReference) {
|
||||||
var methodDef = findMethod(methodReference);
|
var methodDef = resolve(methodReference);
|
||||||
if (methodDef == null)
|
if (methodDef == null)
|
||||||
return null;
|
return null;
|
||||||
return methodDef.Event;
|
return methodDef.Event;
|
||||||
|
|
79
de4dot.code/renamer/ExternalAssemblies.cs
Normal file
79
de4dot.code/renamer/ExternalAssemblies.cs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 de4dot@gmail.com
|
||||||
|
|
||||||
|
This file is part of de4dot.
|
||||||
|
|
||||||
|
de4dot is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
de4dot is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Mono.Cecil;
|
||||||
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
namespace de4dot.renamer {
|
||||||
|
class ExternalAssembly {
|
||||||
|
AssemblyDefinition asmDef;
|
||||||
|
|
||||||
|
public ExternalAssembly(AssemblyDefinition asmDef) {
|
||||||
|
this.asmDef = asmDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeDefinition resolve(TypeReference type) {
|
||||||
|
foreach (var module in asmDef.Modules) {
|
||||||
|
var typeDef = DotNetUtils.getType(module, type);
|
||||||
|
if (typeDef != null)
|
||||||
|
return typeDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loads assemblies that aren't renamed
|
||||||
|
class ExternalAssemblies {
|
||||||
|
Dictionary<string, ExternalAssembly> assemblies = new Dictionary<string, ExternalAssembly>();
|
||||||
|
|
||||||
|
ExternalAssembly load(TypeReference type) {
|
||||||
|
var asmFullName = DotNetUtils.getFullAssemblyName(type.Scope);
|
||||||
|
ExternalAssembly asm;
|
||||||
|
if (assemblies.TryGetValue(asmFullName, out asm))
|
||||||
|
return asm;
|
||||||
|
|
||||||
|
AssemblyDefinition asmDef = null;
|
||||||
|
try {
|
||||||
|
asmDef = GlobalAssemblyResolver.Instance.Resolve(asmFullName);
|
||||||
|
}
|
||||||
|
catch (ResolutionException) {
|
||||||
|
}
|
||||||
|
catch (AssemblyResolutionException) {
|
||||||
|
}
|
||||||
|
if (asmDef == null) {
|
||||||
|
// If we can't load it now, we can't load it later. Make sure above code returns null.
|
||||||
|
assemblies[asmFullName] = null;
|
||||||
|
Log.w("Could not load assembly {0}", asmFullName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Log.v("Loaded assembly {0}", asmFullName);
|
||||||
|
|
||||||
|
return assemblies[asmFullName] = asm = new ExternalAssembly(asmDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeDefinition resolve(TypeReference type) {
|
||||||
|
var asm = load(type);
|
||||||
|
if (asm == null)
|
||||||
|
return null;
|
||||||
|
return asm.resolve(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,6 +69,10 @@ namespace de4dot.renamer {
|
||||||
list.Add(new GenericParamDef(param, i++));
|
list.Add(new GenericParamDef(param, i++));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return MemberReference != null ? MemberReference.ToString() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FieldDef : Ref {
|
class FieldDef : Ref {
|
||||||
|
@ -312,6 +316,16 @@ namespace de4dot.renamer {
|
||||||
get { return genericParams; }
|
get { return genericParams; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsRenamable {
|
||||||
|
get { return module != null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDelegate { get; set; }
|
||||||
|
|
||||||
|
public TypeDef(TypeDefinition typeDefinition)
|
||||||
|
: this(typeDefinition, null) {
|
||||||
|
}
|
||||||
|
|
||||||
public TypeDef(TypeDefinition typeDefinition, Module module, int index = 0)
|
public TypeDef(TypeDefinition typeDefinition, Module module, int index = 0)
|
||||||
: base(typeDefinition, null, index) {
|
: base(typeDefinition, null, index) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
|
@ -330,8 +344,18 @@ namespace de4dot.renamer {
|
||||||
get { return methods.getAll(); }
|
get { return methods.getAll(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when all members (events, fields, props, methods) have been added
|
public void addMembers() {
|
||||||
public void membersAdded() {
|
var type = TypeDefinition;
|
||||||
|
|
||||||
|
for (int i = 0; i < type.Events.Count; i++)
|
||||||
|
add(new EventDef(type.Events[i], this, i));
|
||||||
|
for (int i = 0; i < type.Fields.Count; i++)
|
||||||
|
add(new FieldDef(type.Fields[i], this, i));
|
||||||
|
for (int i = 0; i < type.Methods.Count; i++)
|
||||||
|
add(new MethodDef(type.Methods[i], this, i));
|
||||||
|
for (int i = 0; i < type.Properties.Count; i++)
|
||||||
|
add(new PropertyDef(type.Properties[i], this, i));
|
||||||
|
|
||||||
foreach (var propDef in properties.getAll()) {
|
foreach (var propDef in properties.getAll()) {
|
||||||
foreach (var method in propDef.methodDefinitions()) {
|
foreach (var method in propDef.methodDefinitions()) {
|
||||||
var methodDef = find(method);
|
var methodDef = find(method);
|
||||||
|
@ -351,6 +375,19 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addInterface(TypeDef ifaceDef, TypeReference iface) {
|
||||||
|
if (ifaceDef == null || iface == null)
|
||||||
|
return;
|
||||||
|
interfaces.Add(new TypeInfo(iface, ifaceDef));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBaseType(TypeDef baseDef, TypeReference baseRef) {
|
||||||
|
if (baseDef == null || baseRef == null)
|
||||||
|
return;
|
||||||
|
baseType = new TypeInfo(baseRef, baseDef);
|
||||||
|
IsDelegate = baseRef.FullName == "System.Delegate" || baseRef.FullName == "System.MulticastDelegate";
|
||||||
|
}
|
||||||
|
|
||||||
// Called when all types have been renamed
|
// Called when all types have been renamed
|
||||||
public void onTypesRenamed() {
|
public void onTypesRenamed() {
|
||||||
events.onTypesRenamed();
|
events.onTypesRenamed();
|
||||||
|
@ -372,6 +409,13 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<TypeDef> getAllRenamableInterfaces() {
|
||||||
|
foreach (var iface in getAllInterfaces()) {
|
||||||
|
if (iface.IsRenamable)
|
||||||
|
yield return iface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void add(EventDef e) {
|
public void add(EventDef e) {
|
||||||
events.add(e);
|
events.add(e);
|
||||||
}
|
}
|
||||||
|
@ -562,6 +606,22 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initializeVirtualMembers() {
|
||||||
|
expandGenerics();
|
||||||
|
foreach (var propDef in properties.getSorted()) {
|
||||||
|
if (propDef.isVirtual())
|
||||||
|
MemberRenameState.add(propDef);
|
||||||
|
}
|
||||||
|
foreach (var eventDef in events.getSorted()) {
|
||||||
|
if (eventDef.isVirtual())
|
||||||
|
MemberRenameState.add(eventDef);
|
||||||
|
}
|
||||||
|
foreach (var methodDef in methods.getSorted()) {
|
||||||
|
if (methodDef.isVirtual())
|
||||||
|
MemberRenameState.add(methodDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void prepareRenameMembers() {
|
public void prepareRenameMembers() {
|
||||||
if (prepareRenameMembersCalled)
|
if (prepareRenameMembersCalled)
|
||||||
return;
|
return;
|
||||||
|
@ -572,20 +632,34 @@ namespace de4dot.renamer {
|
||||||
if (baseType != null)
|
if (baseType != null)
|
||||||
baseType.typeDef.prepareRenameMembers();
|
baseType.typeDef.prepareRenameMembers();
|
||||||
|
|
||||||
if (baseType != null)
|
if (MemberRenameState == null)
|
||||||
MemberRenameState = baseType.typeDef.MemberRenameState.clone();
|
MemberRenameState = baseType.typeDef.MemberRenameState.clone();
|
||||||
MemberRenameState.variableNameState.IsValidName = module.IsValidName;
|
|
||||||
|
// For each base type and interface it implements, add all its virtual methods, props,
|
||||||
|
// and events if the type is a non-renamable type (eg. it's from mscorlib or some other
|
||||||
|
// non-deobfuscated assembly).
|
||||||
|
if (IsRenamable) {
|
||||||
|
foreach (var ifaceInfo in interfaces) {
|
||||||
|
if (!ifaceInfo.typeDef.IsRenamable)
|
||||||
|
MemberRenameState.mergeRenamed(ifaceInfo.typeDef.MemberRenameState);
|
||||||
|
}
|
||||||
|
if (baseType != null && !baseType.typeDef.IsRenamable)
|
||||||
|
MemberRenameState.mergeRenamed(baseType.typeDef.MemberRenameState);
|
||||||
|
}
|
||||||
|
|
||||||
if (InterfaceScopeState != null)
|
if (InterfaceScopeState != null)
|
||||||
MemberRenameState.mergeRenamed(InterfaceScopeState);
|
MemberRenameState.mergeRenamed(InterfaceScopeState);
|
||||||
|
|
||||||
expandGenerics();
|
expandGenerics();
|
||||||
|
|
||||||
|
if (IsRenamable) {
|
||||||
|
MemberRenameState.variableNameState.IsValidName = module.IsValidName;
|
||||||
prepareRenameFields(); // must be first
|
prepareRenameFields(); // must be first
|
||||||
prepareRenameProperties();
|
prepareRenameProperties();
|
||||||
prepareRenameEvents();
|
prepareRenameEvents();
|
||||||
prepareRenameMethods(); // must be last
|
prepareRenameMethods(); // must be last
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Replaces the generic params with the generic args, if any
|
// Replaces the generic params with the generic args, if any
|
||||||
void expandGenerics() {
|
void expandGenerics() {
|
||||||
|
@ -851,13 +925,31 @@ namespace de4dot.renamer {
|
||||||
if (methodDef.Renamed)
|
if (methodDef.Renamed)
|
||||||
return;
|
return;
|
||||||
methodDef.Renamed = true;
|
methodDef.Renamed = true;
|
||||||
|
|
||||||
|
bool canRenameName = true;
|
||||||
|
if (IsDelegate && methodDef.isVirtual()) {
|
||||||
|
switch (methodDef.MethodDefinition.Name) {
|
||||||
|
case "GetMethodImpl":
|
||||||
|
case "CombineImpl":
|
||||||
|
case "DynamicInvokeImpl":
|
||||||
|
case "GetInvocationList":
|
||||||
|
case "RemoveImpl":
|
||||||
|
case "Invoke":
|
||||||
|
case "BeginInvoke":
|
||||||
|
case "EndInvoke":
|
||||||
|
canRenameName = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var variableNameState = MemberRenameState.variableNameState;
|
var variableNameState = MemberRenameState.variableNameState;
|
||||||
bool isVirtual = methodDef.isVirtual();
|
bool isVirtual = methodDef.isVirtual();
|
||||||
|
|
||||||
|
if (canRenameName) {
|
||||||
var nameCreator = getMethodNameCreator(methodDef, suggestedName);
|
var nameCreator = getMethodNameCreator(methodDef, suggestedName);
|
||||||
|
|
||||||
if (!methodDef.MethodDefinition.IsRuntimeSpecialName && !variableNameState.IsValidName(methodDef.OldName))
|
if (!methodDef.MethodDefinition.IsRuntimeSpecialName && !variableNameState.IsValidName(methodDef.OldName))
|
||||||
methodDef.NewName = nameCreator.newName();
|
methodDef.NewName = nameCreator.newName();
|
||||||
|
}
|
||||||
|
|
||||||
if (methodDef.ParamDefs.Count > 0) {
|
if (methodDef.ParamDefs.Count > 0) {
|
||||||
var newVariableNameState = variableNameState.clone();
|
var newVariableNameState = variableNameState.clone();
|
||||||
|
|
|
@ -27,6 +27,10 @@ namespace de4dot.renamer {
|
||||||
public Dictionary<EventReferenceKey, EventRef> events = new Dictionary<EventReferenceKey, EventRef>();
|
public Dictionary<EventReferenceKey, EventRef> events = new Dictionary<EventReferenceKey, EventRef>();
|
||||||
public Dictionary<MethodReferenceKey, MethodRef> methods = new Dictionary<MethodReferenceKey, MethodRef>();
|
public Dictionary<MethodReferenceKey, MethodRef> methods = new Dictionary<MethodReferenceKey, MethodRef>();
|
||||||
|
|
||||||
|
public MemberRenameState()
|
||||||
|
: this(null) {
|
||||||
|
}
|
||||||
|
|
||||||
public MemberRenameState(VariableNameState variableNameState) {
|
public MemberRenameState(VariableNameState variableNameState) {
|
||||||
this.variableNameState = variableNameState;
|
this.variableNameState = variableNameState;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +82,7 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemberRenameState clone() {
|
public MemberRenameState clone() {
|
||||||
var rv = new MemberRenameState(variableNameState.clone());
|
var rv = new MemberRenameState(variableNameState == null ? null : variableNameState.clone());
|
||||||
rv.properties = new Dictionary<PropertyReferenceKey, PropertyRef>(properties);
|
rv.properties = new Dictionary<PropertyReferenceKey, PropertyRef>(properties);
|
||||||
rv.events = new Dictionary<EventReferenceKey, EventRef>(events);
|
rv.events = new Dictionary<EventReferenceKey, EventRef>(events);
|
||||||
rv.methods = new Dictionary<MethodReferenceKey, MethodRef>(methods);
|
rv.methods = new Dictionary<MethodReferenceKey, MethodRef>(methods);
|
||||||
|
@ -86,7 +90,7 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemberRenameState cloneVariables() {
|
public MemberRenameState cloneVariables() {
|
||||||
var rv = new MemberRenameState(variableNameState.clone());
|
var rv = new MemberRenameState(variableNameState == null ? null : variableNameState.clone());
|
||||||
rv.properties = properties;
|
rv.properties = properties;
|
||||||
rv.events = events;
|
rv.events = events;
|
||||||
rv.methods = methods;
|
rv.methods = methods;
|
||||||
|
|
|
@ -17,16 +17,15 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.renamer {
|
namespace de4dot.renamer {
|
||||||
interface IResolver {
|
interface IResolver {
|
||||||
TypeDefinition resolve(TypeReference typeReference);
|
TypeDef resolve(TypeReference typeReference);
|
||||||
MethodDefinition resolve(MethodReference methodReference);
|
MethodDef resolve(MethodReference methodReference);
|
||||||
FieldDefinition resolve(FieldReference fieldReference);
|
FieldDef resolve(FieldReference fieldReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IDefFinder {
|
interface IDefFinder {
|
||||||
|
@ -212,9 +211,9 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventDef find(EventReference eventReference) {
|
public EventDef find(EventReference eventReference) {
|
||||||
EventDef propDef;
|
EventDef eventDef;
|
||||||
tokenToEventDef.TryGetValue(new ScopeAndTokenKey(eventReference), out propDef);
|
tokenToEventDef.TryGetValue(new ScopeAndTokenKey(eventReference), out eventDef);
|
||||||
return propDef;
|
return eventDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(EventDef eventDef) {
|
public void add(EventDef eventDef) {
|
||||||
|
|
|
@ -199,36 +199,16 @@ namespace de4dot.renamer {
|
||||||
allTypes.add(typeDef);
|
allTypes.add(typeDef);
|
||||||
allTypesList.Add(typeDef);
|
allTypesList.Add(typeDef);
|
||||||
|
|
||||||
if (type.Events != null) {
|
typeDef.addMembers();
|
||||||
for (int i = 0; i < type.Events.Count; i++) {
|
|
||||||
var ev = type.Events[i];
|
|
||||||
typeDef.add(new EventDef(ev, typeDef, i));
|
|
||||||
memberRefFinder.removeEventDefinition(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (type.Fields != null) {
|
|
||||||
for (int i = 0; i < type.Fields.Count; i++) {
|
|
||||||
var field = type.Fields[i];
|
|
||||||
typeDef.add(new FieldDef(field, typeDef, i));
|
|
||||||
memberRefFinder.removeFieldDefinition(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (type.Methods != null) {
|
|
||||||
for (int i = 0; i < type.Methods.Count; i++) {
|
|
||||||
var method = type.Methods[i];
|
|
||||||
typeDef.add(new MethodDef(method, typeDef, i));
|
|
||||||
memberRefFinder.removeMethodDefinition(method);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (type.Properties != null) {
|
|
||||||
for (int i = 0; i < type.Properties.Count; i++) {
|
|
||||||
var property = type.Properties[i];
|
|
||||||
typeDef.add(new PropertyDef(property, typeDef, i));
|
|
||||||
memberRefFinder.removePropertyDefinition(property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typeDef.membersAdded();
|
foreach (var ev in type.Events)
|
||||||
|
memberRefFinder.removeEventDefinition(ev);
|
||||||
|
foreach (var field in type.Fields)
|
||||||
|
memberRefFinder.removeFieldDefinition(field);
|
||||||
|
foreach (var method in type.Methods)
|
||||||
|
memberRefFinder.removeMethodDefinition(method);
|
||||||
|
foreach (var property in type.Properties)
|
||||||
|
memberRefFinder.removePropertyDefinition(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all nested types to the correct TypeDef's types list
|
// Add all nested types to the correct TypeDef's types list
|
||||||
|
@ -265,21 +245,21 @@ namespace de4dot.renamer {
|
||||||
|
|
||||||
public void resolveAllRefs(IResolver resolver) {
|
public void resolveAllRefs(IResolver resolver) {
|
||||||
foreach (var typeRef in memberRefFinder.typeReferences.Keys) {
|
foreach (var typeRef in memberRefFinder.typeReferences.Keys) {
|
||||||
var typeDefinition = resolver.resolve(typeRef);
|
var typeDef = resolver.resolve(typeRef);
|
||||||
if (typeDefinition != null)
|
if (typeDef != null)
|
||||||
typeRefsToRename.Add(new RefToDef<TypeReference, TypeDefinition>(typeRef, typeDefinition));
|
typeRefsToRename.Add(new RefToDef<TypeReference, TypeDefinition>(typeRef, typeDef.TypeDefinition));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var methodRef in memberRefFinder.methodReferences.Keys) {
|
foreach (var methodRef in memberRefFinder.methodReferences.Keys) {
|
||||||
var methodDefinition = resolver.resolve(methodRef);
|
var methodDef = resolver.resolve(methodRef);
|
||||||
if (methodDefinition != null)
|
if (methodDef != null)
|
||||||
methodRefsToRename.Add(new RefToDef<MethodReference, MethodDefinition>(methodRef, methodDefinition));
|
methodRefsToRename.Add(new RefToDef<MethodReference, MethodDefinition>(methodRef, methodDef.MethodDefinition));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var fieldRef in memberRefFinder.fieldReferences.Keys) {
|
foreach (var fieldRef in memberRefFinder.fieldReferences.Keys) {
|
||||||
var fieldDefinition = resolver.resolve(fieldRef);
|
var fieldDef = resolver.resolve(fieldRef);
|
||||||
if (fieldDefinition != null)
|
if (fieldDef != null)
|
||||||
fieldRefsToRename.Add(new RefToDef<FieldReference, FieldDefinition>(fieldRef, fieldDefinition));
|
fieldRefsToRename.Add(new RefToDef<FieldReference, FieldDefinition>(fieldRef, fieldDef.FieldDefinition));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,31 +299,22 @@ namespace de4dot.renamer {
|
||||||
return type.ElementType;
|
return type.ElementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition resolve(TypeReference typeReference) {
|
public TypeDef resolve(TypeReference typeReference) {
|
||||||
var typeDef = this.allTypes.find(getNonGenericTypeReference(typeReference));
|
return this.allTypes.find(getNonGenericTypeReference(typeReference));
|
||||||
if (typeDef == null)
|
|
||||||
return null;
|
|
||||||
return typeDef.TypeDefinition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition resolve(MethodReference methodReference) {
|
public MethodDef resolve(MethodReference methodReference) {
|
||||||
var typeDef = this.allTypes.find(getNonGenericTypeReference(methodReference.DeclaringType));
|
var typeDef = this.allTypes.find(getNonGenericTypeReference(methodReference.DeclaringType));
|
||||||
if (typeDef == null)
|
if (typeDef == null)
|
||||||
return null;
|
return null;
|
||||||
var methodDef = typeDef.find(methodReference);
|
return typeDef.find(methodReference);
|
||||||
if (methodDef == null)
|
|
||||||
return null;
|
|
||||||
return methodDef.MethodDefinition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldDefinition resolve(FieldReference fieldReference) {
|
public FieldDef resolve(FieldReference fieldReference) {
|
||||||
var typeDef = this.allTypes.find(getNonGenericTypeReference(fieldReference.DeclaringType));
|
var typeDef = this.allTypes.find(getNonGenericTypeReference(fieldReference.DeclaringType));
|
||||||
if (typeDef == null)
|
if (typeDef == null)
|
||||||
return null;
|
return null;
|
||||||
var fieldDef = typeDef.find(fieldReference);
|
return typeDef.find(fieldReference);
|
||||||
if (fieldDef == null)
|
|
||||||
return null;
|
|
||||||
return fieldDef.FieldDefinition;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user