Remove old renamer code
This commit is contained in:
parent
b2b563ef22
commit
d7c55cfbc3
|
@ -140,19 +140,6 @@
|
|||
<Compile Include="PE\DotNetStream.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="old_renamer\CurrentNames.cs" />
|
||||
<Compile Include="old_renamer\DefinitionsRenamer.cs" />
|
||||
<Compile Include="old_renamer\ExternalAssemblies.cs" />
|
||||
<Compile Include="old_renamer\MemberRefFinder.cs" />
|
||||
<Compile Include="old_renamer\MemberRefs.cs" />
|
||||
<Compile Include="old_renamer\MemberRenameState.cs" />
|
||||
<Compile Include="old_renamer\Misc.cs" />
|
||||
<Compile Include="old_renamer\Module.cs" />
|
||||
<Compile Include="old_renamer\NameCreators.cs" />
|
||||
<Compile Include="old_renamer\RefExpander.cs" />
|
||||
<Compile Include="old_renamer\TypeNames.cs" />
|
||||
<Compile Include="old_renamer\TypeNameState.cs" />
|
||||
<Compile Include="old_renamer\VariableNameState.cs" />
|
||||
<Compile Include="renamer\asmmodules\EventDef.cs" />
|
||||
<Compile Include="renamer\asmmodules\ExternalAssemblies.cs" />
|
||||
<Compile Include="renamer\asmmodules\FieldDef.cs" />
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
class CurrentNames {
|
||||
Dictionary<string, bool> allNames = new Dictionary<string, bool>(StringComparer.Ordinal);
|
||||
|
||||
public void add(string name) {
|
||||
allNames[name] = true;
|
||||
}
|
||||
|
||||
bool exists(string name) {
|
||||
return allNames.ContainsKey(name);
|
||||
}
|
||||
|
||||
public string newName(string oldName, INameCreator nameCreator) {
|
||||
return newName(oldName, () => nameCreator.newName());
|
||||
}
|
||||
|
||||
public string newName(string oldName, Func<string> createNewName) {
|
||||
string prevName = null;
|
||||
while (true) {
|
||||
var name = createNewName();
|
||||
if (name == prevName)
|
||||
throw new ApplicationException(string.Format("Could not rename symbol to {0}", Utils.toCsharpString(name)));
|
||||
|
||||
if (!exists(name) || name == oldName) {
|
||||
allNames[name] = true;
|
||||
return name;
|
||||
}
|
||||
|
||||
prevName = name;
|
||||
}
|
||||
}
|
||||
|
||||
public CurrentNames clone() {
|
||||
var cn = new CurrentNames();
|
||||
foreach (var key in allNames.Keys)
|
||||
cn.allNames[key] = true;
|
||||
return cn;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,569 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
// Renames typedefs, methoddefs, eventdefs, fielddefs, propdefs, and genparams
|
||||
class DefinitionsRenamer : IResolver, IDefFinder {
|
||||
// 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).
|
||||
IList<TypeDef> baseTypes = new List<TypeDef>();
|
||||
IList<TypeDef> nonNestedTypes;
|
||||
IList<Module> modules = new List<Module>();
|
||||
List<TypeDef> allTypes = new List<TypeDef>();
|
||||
TypeNameState typeNameState;
|
||||
ModulesDict modulesDict = new ModulesDict();
|
||||
AssemblyHash assemblyHash = new AssemblyHash();
|
||||
|
||||
class AssemblyHash {
|
||||
IDictionary<string, ModuleHash> assemblyHash = new Dictionary<string, ModuleHash>(StringComparer.Ordinal);
|
||||
|
||||
public void add(Module module) {
|
||||
ModuleHash moduleHash;
|
||||
var key = getModuleKey(module);
|
||||
if (!assemblyHash.TryGetValue(key, out moduleHash))
|
||||
assemblyHash[key] = moduleHash = new ModuleHash();
|
||||
moduleHash.add(module);
|
||||
}
|
||||
|
||||
string getModuleKey(Module module) {
|
||||
if (module.ModuleDefinition.Assembly != null)
|
||||
return module.ModuleDefinition.Assembly.ToString();
|
||||
return Utils.getBaseName(module.ModuleDefinition.FullyQualifiedName);
|
||||
}
|
||||
|
||||
public ModuleHash lookup(string assemblyName) {
|
||||
ModuleHash moduleHash;
|
||||
if (assemblyHash.TryGetValue(assemblyName, out moduleHash))
|
||||
return moduleHash;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class ModuleHash {
|
||||
ModulesDict modulesDict = new ModulesDict();
|
||||
Module mainModule = null;
|
||||
|
||||
public void add(Module module) {
|
||||
var asm = module.ModuleDefinition.Assembly;
|
||||
if (asm != null && ReferenceEquals(asm.MainModule, module.ModuleDefinition)) {
|
||||
if (mainModule != null)
|
||||
throw new UserException(string.Format("Two modules in the same assembly are main modules. If 32-bit vs 64-bit, don't use both assemblies at the same time! \"{0}\" and \"{1}\"", module.ModuleDefinition.FullyQualifiedName, mainModule.ModuleDefinition.FullyQualifiedName));
|
||||
mainModule = module;
|
||||
}
|
||||
|
||||
modulesDict.add(module);
|
||||
}
|
||||
|
||||
public IEnumerable<Module> Modules {
|
||||
get { return modulesDict.Modules; }
|
||||
}
|
||||
}
|
||||
|
||||
class ModulesDict {
|
||||
IDictionary<string, Module> modulesDict = new Dictionary<string, Module>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public void add(Module module) {
|
||||
if (lookup(module.Pathname) != null)
|
||||
throw new ApplicationException(string.Format("Module \"{0}\" was found twice", module.Pathname));
|
||||
modulesDict[module.Pathname] = module;
|
||||
}
|
||||
|
||||
public Module lookup(string pathname) {
|
||||
Module module;
|
||||
if (modulesDict.TryGetValue(pathname, out module))
|
||||
return module;
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<Module> Modules {
|
||||
get { return modulesDict.Values; }
|
||||
}
|
||||
}
|
||||
|
||||
public DefinitionsRenamer(IEnumerable<IObfuscatedFile> files) {
|
||||
foreach (var file in files) {
|
||||
var module = new Module(file);
|
||||
modulesDict.add(module);
|
||||
modules.Add(module);
|
||||
assemblyHash.add(module);
|
||||
}
|
||||
}
|
||||
|
||||
public void renameAll() {
|
||||
if (modules.Count == 0)
|
||||
return;
|
||||
Log.n("Renaming all obfuscated symbols");
|
||||
findAllMemberReferences();
|
||||
resolveAllRefs();
|
||||
initAllTypes();
|
||||
renameTypeDefinitions();
|
||||
renameTypeReferences();
|
||||
foreach (var module in modules)
|
||||
module.onTypesRenamed();
|
||||
prepareRenameMemberDefinitions();
|
||||
renameMemberDefinitions();
|
||||
renameMemberReferences();
|
||||
renameResources();
|
||||
externalAssemblies.unloadAll();
|
||||
DotNetUtils.typeCaches.invalidateAll();
|
||||
}
|
||||
|
||||
void initAllTypes() {
|
||||
foreach (var module in modules)
|
||||
allTypes.AddRange(module.getAllTypes());
|
||||
|
||||
var typeToTypeDef = new Dictionary<TypeDefinition, TypeDef>(allTypes.Count);
|
||||
foreach (var typeDef in allTypes)
|
||||
typeToTypeDef[typeDef.TypeDefinition] = typeDef;
|
||||
|
||||
// Initialize Owner
|
||||
foreach (var typeDef in allTypes) {
|
||||
if (typeDef.TypeDefinition.DeclaringType != null)
|
||||
typeDef.Owner = typeToTypeDef[typeDef.TypeDefinition.DeclaringType];
|
||||
}
|
||||
|
||||
// Initialize baseType and derivedTypes
|
||||
foreach (var typeDef in allTypes) {
|
||||
var baseType = typeDef.TypeDefinition.BaseType;
|
||||
if (baseType == null)
|
||||
continue;
|
||||
var baseTypeDef = resolve(baseType) ?? resolveOther(baseType);
|
||||
if (baseTypeDef != null) {
|
||||
typeDef.addBaseType(baseTypeDef, baseType);
|
||||
baseTypeDef.derivedTypes.Add(typeDef);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize interfaces
|
||||
foreach (var typeDef in allTypes) {
|
||||
if (typeDef.TypeDefinition.Interfaces == null)
|
||||
continue;
|
||||
foreach (var iface in typeDef.TypeDefinition.Interfaces) {
|
||||
var ifaceTypeDef = resolve(iface) ?? resolveOther(iface);
|
||||
if (ifaceTypeDef != null)
|
||||
typeDef.addInterface(ifaceTypeDef, iface);
|
||||
}
|
||||
}
|
||||
|
||||
// Find all non-nested types
|
||||
var allTypesDict = new Dictionary<TypeDef, bool>();
|
||||
foreach (var t in allTypes)
|
||||
allTypesDict[t] = true;
|
||||
foreach (var t in allTypes) {
|
||||
foreach (var t2 in t.NestedTypes)
|
||||
allTypesDict.Remove(t2);
|
||||
}
|
||||
nonNestedTypes = new List<TypeDef>(allTypesDict.Keys);
|
||||
|
||||
foreach (var typeDef in allTypes)
|
||||
typeDef.defFinder = this;
|
||||
|
||||
foreach (var typeDef in allTypes) {
|
||||
if (typeDef.baseType == null || !typeDef.baseType.typeDef.IsRenamable)
|
||||
baseTypes.Add(typeDef);
|
||||
}
|
||||
}
|
||||
|
||||
void findAllMemberReferences() {
|
||||
Log.v("Finding all MemberReferences");
|
||||
int index = 0;
|
||||
foreach (var module in modules) {
|
||||
if (modules.Count > 1)
|
||||
Log.v("Finding all MemberReferences ({0})", module.Filename);
|
||||
Log.indent();
|
||||
module.findAllMemberReferences(ref index);
|
||||
Log.deIndent();
|
||||
}
|
||||
}
|
||||
|
||||
void resolveAllRefs() {
|
||||
Log.v("Resolving references");
|
||||
foreach (var module in modules) {
|
||||
if (modules.Count > 1)
|
||||
Log.v("Resolving references ({0})", module.Filename);
|
||||
Log.indent();
|
||||
module.resolveAllRefs(this);
|
||||
Log.deIndent();
|
||||
}
|
||||
}
|
||||
|
||||
void renameTypeDefinitions() {
|
||||
Log.v("Renaming obfuscated type definitions");
|
||||
|
||||
foreach (var module in modules)
|
||||
module.onBeforeRenamingTypeDefinitions();
|
||||
|
||||
typeNameState = new TypeNameState();
|
||||
foreach (var typeDef in allTypes)
|
||||
typeNameState.currentNames.add(typeDef.OldName);
|
||||
prepareRenameTypeDefinitions(baseTypes);
|
||||
typeNameState = null;
|
||||
|
||||
fixClsTypeNames();
|
||||
renameTypeDefinitions(nonNestedTypes);
|
||||
}
|
||||
|
||||
void prepareRenameTypeDefinitions(IEnumerable<TypeDef> typeDefs) {
|
||||
foreach (var typeDef in typeDefs) {
|
||||
typeNameState.IsValidName = typeDef.module.IsValidName;
|
||||
typeDef.prepareRename(typeNameState);
|
||||
prepareRenameTypeDefinitions(typeDef.derivedTypes);
|
||||
}
|
||||
}
|
||||
|
||||
void renameTypeDefinitions(IEnumerable<TypeDef> typeDefs) {
|
||||
Log.indent();
|
||||
foreach (var typeDef in typeDefs) {
|
||||
typeDef.rename();
|
||||
renameTypeDefinitions(typeDef.NestedTypes);
|
||||
}
|
||||
Log.deIndent();
|
||||
}
|
||||
|
||||
// Make sure the renamed types are using valid CLS names. That means renaming all
|
||||
// generic types from eg. Class1 to Class1`2. If we don't do this, some decompilers
|
||||
// (eg. ILSpy v1.0) won't produce correct output.
|
||||
void fixClsTypeNames() {
|
||||
foreach (var type in nonNestedTypes)
|
||||
fixClsTypeNames(null, type);
|
||||
}
|
||||
|
||||
void fixClsTypeNames(TypeDef nesting, TypeDef nested) {
|
||||
int nestingCount = nesting == null ? 0 : nesting.GenericParams.Count;
|
||||
int arity = nested.GenericParams.Count - nestingCount;
|
||||
if (nested.gotNewName() && arity > 0)
|
||||
nested.NewName += "`" + arity;
|
||||
foreach (var nestedType in nested.NestedTypes)
|
||||
fixClsTypeNames(nested, nestedType);
|
||||
}
|
||||
|
||||
void renameTypeReferences() {
|
||||
Log.v("Renaming references to type definitions");
|
||||
foreach (var module in modules) {
|
||||
if (modules.Count > 1)
|
||||
Log.v("Renaming references to type definitions ({0})", module.Filename);
|
||||
Log.indent();
|
||||
module.renameTypeReferences();
|
||||
Log.deIndent();
|
||||
}
|
||||
}
|
||||
|
||||
class InterfaceScope {
|
||||
Dictionary<TypeDef, bool> interfaces = new Dictionary<TypeDef, bool>();
|
||||
Dictionary<TypeDef, bool> classes = new Dictionary<TypeDef, bool>();
|
||||
|
||||
public IEnumerable<TypeDef> Interfaces {
|
||||
get { return interfaces.Keys; }
|
||||
}
|
||||
|
||||
public IEnumerable<TypeDef> Classes {
|
||||
get { return classes.Keys; }
|
||||
}
|
||||
|
||||
public void addInterfaces(IEnumerable<TypeDef> list) {
|
||||
foreach (var iface in list)
|
||||
interfaces[iface] = true;
|
||||
}
|
||||
|
||||
public void addClass(TypeDef cls) {
|
||||
classes[cls] = true;
|
||||
}
|
||||
|
||||
public void merge(InterfaceScope other) {
|
||||
if (ReferenceEquals(this, other))
|
||||
return;
|
||||
addInterfaces(other.interfaces.Keys);
|
||||
foreach (var cls in other.classes.Keys)
|
||||
addClass(cls);
|
||||
}
|
||||
}
|
||||
|
||||
void prepareRenameMemberDefinitions() {
|
||||
Log.v("Renaming member definitions #1");
|
||||
|
||||
var interfaceScopes = createInterfaceScopes();
|
||||
foreach (var interfaceScope in interfaceScopes) {
|
||||
var state = new MemberRenameState(new InterfaceVariableNameState());
|
||||
foreach (var iface in interfaceScope.Interfaces)
|
||||
iface.MemberRenameState = state.cloneVariables();
|
||||
foreach (var cls in interfaceScope.Classes) {
|
||||
if (cls.isInterface())
|
||||
continue;
|
||||
cls.InterfaceScopeState = state;
|
||||
}
|
||||
}
|
||||
foreach (var interfaceScope in interfaceScopes) {
|
||||
foreach (var iface in interfaceScope.Interfaces)
|
||||
iface.prepareRenameMembers();
|
||||
}
|
||||
|
||||
var variableNameState = new VariableNameState();
|
||||
foreach (var typeDef in baseTypes) {
|
||||
var state = new MemberRenameState(variableNameState.clone());
|
||||
typeDef.MemberRenameState = state;
|
||||
}
|
||||
|
||||
foreach (var typeDef in allTypes)
|
||||
typeDef.prepareRenameMembers();
|
||||
|
||||
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() {
|
||||
foreach (var module in modules) {
|
||||
var entryPoint = module.ModuleDefinition.EntryPoint;
|
||||
if (entryPoint == null)
|
||||
continue;
|
||||
var methodDef = resolve(entryPoint);
|
||||
if (methodDef == null)
|
||||
throw new ApplicationException(string.Format("Could not find entry point. Module: {0}, Method: {1}", module.ModuleDefinition.FullyQualifiedName, entryPoint));
|
||||
if (!methodDef.MethodDefinition.IsStatic)
|
||||
continue;
|
||||
methodDef.NewName = "Main";
|
||||
if (methodDef.ParamDefs.Count == 1) {
|
||||
var paramDef = methodDef.ParamDefs[0];
|
||||
var type = paramDef.ParameterDefinition.ParameterType;
|
||||
if (MemberReferenceHelper.verifyType(type, "mscorlib", "System.String", "[]"))
|
||||
paramDef.NewName = "args";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class InterfaceScopeInfo {
|
||||
public TypeDef theClass;
|
||||
public List<TypeDef> interfaces;
|
||||
public InterfaceScopeInfo(TypeDef theClass, List<TypeDef> interfaces) {
|
||||
this.theClass = theClass;
|
||||
this.interfaces = interfaces;
|
||||
}
|
||||
}
|
||||
|
||||
IList<InterfaceScope> createInterfaceScopes() {
|
||||
var interfaceScopes = new Dictionary<TypeDef, InterfaceScope>();
|
||||
foreach (var scopeInfo in getInterfaceScopeInfo(baseTypes)) {
|
||||
InterfaceScope interfaceScope = null;
|
||||
foreach (var iface in scopeInfo.interfaces) {
|
||||
if (interfaceScopes.TryGetValue(iface, out interfaceScope))
|
||||
break;
|
||||
}
|
||||
List<InterfaceScope> mergeScopes = null;
|
||||
if (interfaceScope == null)
|
||||
interfaceScope = new InterfaceScope();
|
||||
else {
|
||||
// Find all interfaces in scopeInfo.interfaces that are in another
|
||||
// InterfaceScope, and merge them with interfaceScope.
|
||||
foreach (var iface in scopeInfo.interfaces) {
|
||||
InterfaceScope scope;
|
||||
if (!interfaceScopes.TryGetValue(iface, out scope))
|
||||
continue; // not in any scope yet
|
||||
if (ReferenceEquals(scope, interfaceScope))
|
||||
continue; // same scope
|
||||
|
||||
if (mergeScopes == null)
|
||||
mergeScopes = new List<InterfaceScope>();
|
||||
mergeScopes.Add(scope);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var iface in scopeInfo.interfaces)
|
||||
interfaceScopes[iface] = interfaceScope;
|
||||
if (mergeScopes != null) {
|
||||
foreach (var scope in mergeScopes) {
|
||||
interfaceScope.merge(scope);
|
||||
foreach (var iface in scope.Interfaces)
|
||||
interfaceScopes[iface] = interfaceScope;
|
||||
}
|
||||
}
|
||||
interfaceScope.addInterfaces(scopeInfo.interfaces);
|
||||
interfaceScope.addClass(scopeInfo.theClass);
|
||||
}
|
||||
|
||||
return new List<InterfaceScope>(Utils.unique(interfaceScopes.Values));
|
||||
}
|
||||
|
||||
IEnumerable<InterfaceScopeInfo> getInterfaceScopeInfo(IEnumerable<TypeDef> baseTypes) {
|
||||
foreach (var typeDef in baseTypes) {
|
||||
yield return new InterfaceScopeInfo(typeDef, new List<TypeDef>(typeDef.getAllRenamableInterfaces()));
|
||||
}
|
||||
}
|
||||
|
||||
void renameMemberDefinitions() {
|
||||
Log.v("Renaming member definitions #2");
|
||||
|
||||
Log.indent();
|
||||
foreach (var typeDef in allTypes)
|
||||
typeDef.renameMembers();
|
||||
Log.deIndent();
|
||||
}
|
||||
|
||||
void renameMemberReferences() {
|
||||
Log.v("Renaming references to other definitions");
|
||||
foreach (var module in modules) {
|
||||
if (modules.Count > 1)
|
||||
Log.v("Renaming references to other definitions ({0})", module.Filename);
|
||||
Log.indent();
|
||||
module.renameMemberReferences();
|
||||
Log.deIndent();
|
||||
}
|
||||
}
|
||||
|
||||
void renameResources() {
|
||||
Log.v("Renaming resources");
|
||||
foreach (var module in modules) {
|
||||
if (modules.Count > 1)
|
||||
Log.v("Renaming resources ({0})", module.Filename);
|
||||
Log.indent();
|
||||
module.renameResources();
|
||||
Log.deIndent();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns null if it's a non-loaded module/assembly
|
||||
IEnumerable<Module> findModules(IMetadataScope scope) {
|
||||
if (scope is AssemblyNameReference) {
|
||||
var assemblyRef = (AssemblyNameReference)scope;
|
||||
var moduleHash = assemblyHash.lookup(assemblyRef.ToString());
|
||||
if (moduleHash != null)
|
||||
return moduleHash.Modules;
|
||||
}
|
||||
else if (scope is ModuleDefinition) {
|
||||
var moduleDefinition = (ModuleDefinition)scope;
|
||||
var module = modulesDict.lookup(moduleDefinition.FullyQualifiedName);
|
||||
if (module != null)
|
||||
return new List<Module> { module };
|
||||
}
|
||||
else
|
||||
throw new ApplicationException(string.Format("IMetadataScope is an unsupported type: {0}", scope.GetType()));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
bool isAutoCreatedType(TypeReference typeReference) {
|
||||
return typeReference is ArrayType || typeReference is PointerType;
|
||||
}
|
||||
|
||||
public TypeDef resolve(TypeReference typeReference) {
|
||||
var modules = findModules(typeReference.Scope);
|
||||
if (modules == null)
|
||||
return null;
|
||||
foreach (var module in modules) {
|
||||
var rv = module.resolve(typeReference);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
}
|
||||
if (isAutoCreatedType(typeReference))
|
||||
return null;
|
||||
Log.e("Could not resolve TypeReference {0} ({1:X8})", typeReference, typeReference.MetadataToken.ToInt32());
|
||||
return null;
|
||||
}
|
||||
|
||||
public MethodDef resolve(MethodReference methodReference) {
|
||||
if (methodReference.DeclaringType == null)
|
||||
return null;
|
||||
var modules = findModules(methodReference.DeclaringType.Scope);
|
||||
if (modules == null)
|
||||
return null;
|
||||
foreach (var module in modules) {
|
||||
var rv = module.resolve(methodReference);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
}
|
||||
if (isAutoCreatedType(methodReference.DeclaringType))
|
||||
return null;
|
||||
Log.e("Could not resolve MethodReference {0} ({1:X8})", methodReference, methodReference.MetadataToken.ToInt32());
|
||||
return null;
|
||||
}
|
||||
|
||||
public FieldDef resolve(FieldReference fieldReference) {
|
||||
if (fieldReference.DeclaringType == null)
|
||||
return null;
|
||||
var modules = findModules(fieldReference.DeclaringType.Scope);
|
||||
if (modules == null)
|
||||
return null;
|
||||
foreach (var module in modules) {
|
||||
var rv = module.resolve(fieldReference);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
}
|
||||
if (isAutoCreatedType(fieldReference.DeclaringType))
|
||||
return null;
|
||||
Log.e("Could not resolve FieldReference {0} ({1:X8})", fieldReference, fieldReference.MetadataToken.ToInt32());
|
||||
return null;
|
||||
}
|
||||
|
||||
public MethodDef findMethod(MethodReference methodReference) {
|
||||
return resolve(methodReference);
|
||||
}
|
||||
|
||||
public PropertyDef findProp(MethodReference methodReference) {
|
||||
var methodDef = resolve(methodReference);
|
||||
if (methodDef == null)
|
||||
return null;
|
||||
return methodDef.Property;
|
||||
}
|
||||
|
||||
public EventDef findEvent(MethodReference methodReference) {
|
||||
var methodDef = resolve(methodReference);
|
||||
if (methodDef == null)
|
||||
return null;
|
||||
return methodDef.Event;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
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.old_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;
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
foreach (var module in asmDef.Modules)
|
||||
DotNetUtils.typeCaches.invalidate(module);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
if (assemblies.ContainsKey(asmDef.Name.FullName)) {
|
||||
assemblies[asmFullName] = assemblies[asmDef.Name.FullName];
|
||||
return assemblies[asmDef.Name.FullName];
|
||||
}
|
||||
|
||||
if (asmFullName == asmDef.Name.FullName)
|
||||
Log.v("Loaded assembly {0}", asmFullName);
|
||||
else
|
||||
Log.v("Loaded assembly {0} (but wanted {1})", asmDef.Name.FullName, asmFullName);
|
||||
|
||||
asm = new ExternalAssembly(asmDef);
|
||||
assemblies[asmFullName] = asm;
|
||||
assemblies[asmDef.Name.FullName] = asm;
|
||||
return asm;
|
||||
}
|
||||
|
||||
public TypeDefinition resolve(TypeReference type) {
|
||||
var asm = load(type);
|
||||
if (asm == null)
|
||||
return null;
|
||||
return asm.resolve(type);
|
||||
}
|
||||
|
||||
public void unloadAll() {
|
||||
foreach (var asm in assemblies.Values) {
|
||||
if (asm == null)
|
||||
continue;
|
||||
asm.unload();
|
||||
}
|
||||
assemblies.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,707 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
// If it's a non-generic memberref, you could use GetMemberReference() to get a cached
|
||||
// instance. For non-generics though, there's no other way than to scan every single
|
||||
// type and all its fields, recursively, to find all of those refererences... That's
|
||||
// what this class does. Close your eyes.
|
||||
class MemberRefFinder {
|
||||
public Dictionary<EventDefinition, bool> eventDefinitions = new Dictionary<EventDefinition, bool>();
|
||||
public Dictionary<FieldReference, bool> fieldReferences = new Dictionary<FieldReference, bool>();
|
||||
public Dictionary<FieldDefinition, bool> fieldDefinitions = new Dictionary<FieldDefinition, bool>();
|
||||
public Dictionary<MethodReference, bool> methodReferences = new Dictionary<MethodReference, bool>();
|
||||
public Dictionary<MethodDefinition, bool> methodDefinitions = new Dictionary<MethodDefinition, bool>();
|
||||
public Dictionary<GenericInstanceMethod, bool> genericInstanceMethods = new Dictionary<GenericInstanceMethod, bool>();
|
||||
public Dictionary<PropertyDefinition, bool> propertyDefinitions = new Dictionary<PropertyDefinition, bool>();
|
||||
public Dictionary<TypeReference, bool> typeReferences = new Dictionary<TypeReference, bool>();
|
||||
public Dictionary<TypeDefinition, bool> typeDefinitions = new Dictionary<TypeDefinition, bool>();
|
||||
public Dictionary<GenericParameter, bool> genericParameters = new Dictionary<GenericParameter, bool>();
|
||||
public Dictionary<ArrayType, bool> arrayTypes = new Dictionary<ArrayType, bool>();
|
||||
public Dictionary<FunctionPointerType, bool> functionPointerTypes = new Dictionary<FunctionPointerType, bool>();
|
||||
public Dictionary<GenericInstanceType, bool> genericInstanceTypes = new Dictionary<GenericInstanceType, bool>();
|
||||
public Dictionary<OptionalModifierType, bool> optionalModifierTypes = new Dictionary<OptionalModifierType, bool>();
|
||||
public Dictionary<RequiredModifierType, bool> requiredModifierTypes = new Dictionary<RequiredModifierType, bool>();
|
||||
public Dictionary<PinnedType, bool> pinnedTypes = new Dictionary<PinnedType, bool>();
|
||||
public Dictionary<PointerType, bool> pointerTypes = new Dictionary<PointerType, bool>();
|
||||
public Dictionary<ByReferenceType, bool> byReferenceTypes = new Dictionary<ByReferenceType, bool>();
|
||||
public Dictionary<SentinelType, bool> sentinelTypes = new Dictionary<SentinelType, bool>();
|
||||
|
||||
Stack<MemberReference> memberRefStack;
|
||||
|
||||
public void removeTypeDefinition(TypeDefinition td) {
|
||||
if (!typeDefinitions.Remove(td))
|
||||
throw new ApplicationException(string.Format("Could not remove TypeDefinition: {0}", td));
|
||||
}
|
||||
|
||||
public void removeEventDefinition(EventDefinition ed) {
|
||||
if (!eventDefinitions.Remove(ed))
|
||||
throw new ApplicationException(string.Format("Could not remove EventDefinition: {0}", ed));
|
||||
}
|
||||
|
||||
public void removeFieldDefinition(FieldDefinition fd) {
|
||||
if (!fieldDefinitions.Remove(fd))
|
||||
throw new ApplicationException(string.Format("Could not remove FieldDefinition: {0}", fd));
|
||||
}
|
||||
|
||||
public void removeMethodDefinition(MethodDefinition md) {
|
||||
if (!methodDefinitions.Remove(md))
|
||||
throw new ApplicationException(string.Format("Could not remove MethodDefinition: {0}", md));
|
||||
}
|
||||
|
||||
public void removePropertyDefinition(PropertyDefinition pd) {
|
||||
if (!propertyDefinitions.Remove(pd))
|
||||
throw new ApplicationException(string.Format("Could not remove PropertyDefinition: {0}", pd));
|
||||
}
|
||||
|
||||
public void findAll(ModuleDefinition module, IEnumerable<TypeDefinition> types) {
|
||||
// This needs to be big. About 2048 entries should be enough for most though...
|
||||
memberRefStack = new Stack<MemberReference>(0x1000);
|
||||
|
||||
foreach (var type in types)
|
||||
pushMember(type);
|
||||
|
||||
addModule(module);
|
||||
processAll();
|
||||
|
||||
memberRefStack = null;
|
||||
}
|
||||
|
||||
Dictionary<string, bool> exceptionMessages = new Dictionary<string, bool>(StringComparer.Ordinal);
|
||||
void access(Action action) {
|
||||
string exMessage = null;
|
||||
try {
|
||||
action();
|
||||
}
|
||||
catch (ResolutionException ex) {
|
||||
exMessage = ex.Message;
|
||||
}
|
||||
catch (AssemblyResolutionException ex) {
|
||||
exMessage = ex.Message;
|
||||
}
|
||||
if (exMessage != null) {
|
||||
if (!exceptionMessages.ContainsKey(exMessage)) {
|
||||
exceptionMessages[exMessage] = true;
|
||||
Log.w("Could not resolve a reference. ERROR: {0}", exMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pushMember(MemberReference memberReference) {
|
||||
if (memberReference == null)
|
||||
return;
|
||||
memberRefStack.Push(memberReference);
|
||||
}
|
||||
|
||||
void addModule(ModuleDefinition module) {
|
||||
pushMember(module.EntryPoint);
|
||||
access(() => addCustomAttributes(module.CustomAttributes));
|
||||
if (module.Assembly != null && module == module.Assembly.MainModule) {
|
||||
var asm = module.Assembly;
|
||||
access(() => addCustomAttributes(asm.CustomAttributes));
|
||||
addSecurityDeclarations(asm.SecurityDeclarations);
|
||||
}
|
||||
}
|
||||
|
||||
void processAll() {
|
||||
while (memberRefStack.Count > 0)
|
||||
process(memberRefStack.Pop());
|
||||
}
|
||||
|
||||
void process(MemberReference memberRef) {
|
||||
if (memberRef == null)
|
||||
return;
|
||||
|
||||
var type = MemberReferenceHelper.getMemberReferenceType(memberRef);
|
||||
switch (type) {
|
||||
case CecilType.ArrayType:
|
||||
doArrayType((ArrayType)memberRef);
|
||||
break;
|
||||
case CecilType.ByReferenceType:
|
||||
doByReferenceType((ByReferenceType)memberRef);
|
||||
break;
|
||||
case CecilType.EventDefinition:
|
||||
doEventDefinition((EventDefinition)memberRef);
|
||||
break;
|
||||
case CecilType.FieldDefinition:
|
||||
doFieldDefinition((FieldDefinition)memberRef);
|
||||
break;
|
||||
case CecilType.FieldReference:
|
||||
doFieldReference((FieldReference)memberRef);
|
||||
break;
|
||||
case CecilType.FunctionPointerType:
|
||||
doFunctionPointerType((FunctionPointerType)memberRef);
|
||||
break;
|
||||
case CecilType.GenericInstanceMethod:
|
||||
doGenericInstanceMethod((GenericInstanceMethod)memberRef);
|
||||
break;
|
||||
case CecilType.GenericInstanceType:
|
||||
doGenericInstanceType((GenericInstanceType)memberRef);
|
||||
break;
|
||||
case CecilType.GenericParameter:
|
||||
doGenericParameter((GenericParameter)memberRef);
|
||||
break;
|
||||
case CecilType.MethodDefinition:
|
||||
doMethodDefinition((MethodDefinition)memberRef);
|
||||
break;
|
||||
case CecilType.MethodReference:
|
||||
doMethodReference((MethodReference)memberRef);
|
||||
break;
|
||||
case CecilType.OptionalModifierType:
|
||||
doOptionalModifierType((OptionalModifierType)memberRef);
|
||||
break;
|
||||
case CecilType.PinnedType:
|
||||
doPinnedType((PinnedType)memberRef);
|
||||
break;
|
||||
case CecilType.PointerType:
|
||||
doPointerType((PointerType)memberRef);
|
||||
break;
|
||||
case CecilType.PropertyDefinition:
|
||||
doPropertyDefinition((PropertyDefinition)memberRef);
|
||||
break;
|
||||
case CecilType.RequiredModifierType:
|
||||
doRequiredModifierType((RequiredModifierType)memberRef);
|
||||
break;
|
||||
case CecilType.SentinelType:
|
||||
doSentinelType((SentinelType)memberRef);
|
||||
break;
|
||||
case CecilType.TypeDefinition:
|
||||
doTypeDefinition((TypeDefinition)memberRef);
|
||||
break;
|
||||
case CecilType.TypeReference:
|
||||
doTypeReference((TypeReference)memberRef);
|
||||
break;
|
||||
default:
|
||||
throw new ApplicationException(string.Format("Unknown cecil type {0}", type));
|
||||
}
|
||||
}
|
||||
|
||||
void addCustomAttributes(IEnumerable<CustomAttribute> attributes) {
|
||||
if (attributes == null)
|
||||
return;
|
||||
foreach (var attr in attributes)
|
||||
addCustomAttribute(attr);
|
||||
}
|
||||
void addCustomAttributeArguments(IEnumerable<CustomAttributeArgument> args) {
|
||||
if (args == null)
|
||||
return;
|
||||
foreach (var arg in args)
|
||||
addCustomAttributeArgument(arg);
|
||||
}
|
||||
void addCustomAttributeNamedArguments(IEnumerable<CustomAttributeNamedArgument> args) {
|
||||
if (args == null)
|
||||
return;
|
||||
foreach (var arg in args)
|
||||
addCustomAttributeNamedArgument(arg);
|
||||
}
|
||||
void addParameterDefinitions(IEnumerable<ParameterDefinition> parameters) {
|
||||
if (parameters == null)
|
||||
return;
|
||||
foreach (var param in parameters)
|
||||
addParameterDefinition(param);
|
||||
}
|
||||
void addSecurityDeclarations(IEnumerable<SecurityDeclaration> decls) {
|
||||
if (decls == null)
|
||||
return;
|
||||
foreach (var decl in decls)
|
||||
addSecurityDeclaration(decl);
|
||||
}
|
||||
void addSecurityAttributes(IEnumerable<SecurityAttribute> attrs) {
|
||||
if (attrs == null)
|
||||
return;
|
||||
foreach (var attr in attrs)
|
||||
addSecurityAttribute(attr);
|
||||
}
|
||||
void addExceptionHandlers(IEnumerable<ExceptionHandler> handlers) {
|
||||
if (handlers == null)
|
||||
return;
|
||||
foreach (var h in handlers)
|
||||
addExceptionHandler(h);
|
||||
}
|
||||
void addVariableDefinitions(IEnumerable<VariableDefinition> vars) {
|
||||
if (vars == null)
|
||||
return;
|
||||
foreach (var v in vars)
|
||||
addVariableDefinition(v);
|
||||
}
|
||||
void addScopes(IEnumerable<Scope> scopes) {
|
||||
if (scopes == null)
|
||||
return;
|
||||
foreach (var s in scopes)
|
||||
addScope(s);
|
||||
}
|
||||
void addInstructions(IEnumerable<Instruction> instrs) {
|
||||
if (instrs == null)
|
||||
return;
|
||||
foreach (var instr in instrs) {
|
||||
switch (instr.OpCode.OperandType) {
|
||||
case OperandType.InlineTok:
|
||||
case OperandType.InlineType:
|
||||
case OperandType.InlineMethod:
|
||||
case OperandType.InlineField:
|
||||
pushMember(instr.Operand as MemberReference);
|
||||
break;
|
||||
case OperandType.InlineSig:
|
||||
addCallSite(instr.Operand as CallSite);
|
||||
break;
|
||||
case OperandType.InlineVar:
|
||||
case OperandType.ShortInlineVar:
|
||||
addVariableDefinition(instr.Operand as VariableDefinition);
|
||||
break;
|
||||
case OperandType.InlineArg:
|
||||
case OperandType.ShortInlineArg:
|
||||
addParameterDefinition(instr.Operand as ParameterDefinition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void addTypeReferences(IEnumerable<TypeReference> types) {
|
||||
if (types == null)
|
||||
return;
|
||||
foreach (var typeRef in types)
|
||||
pushMember(typeRef);
|
||||
}
|
||||
void addTypeDefinitions(IEnumerable<TypeDefinition> types) {
|
||||
if (types == null)
|
||||
return;
|
||||
foreach (var type in types)
|
||||
pushMember(type);
|
||||
}
|
||||
void addMethodReferences(IEnumerable<MethodReference> methodRefs) {
|
||||
if (methodRefs == null)
|
||||
return;
|
||||
foreach (var m in methodRefs)
|
||||
pushMember(m);
|
||||
}
|
||||
void addMethodDefinitions(IEnumerable<MethodDefinition> methods) {
|
||||
if (methods == null)
|
||||
return;
|
||||
foreach (var m in methods)
|
||||
pushMember(m);
|
||||
}
|
||||
void addGenericParameters(IEnumerable<GenericParameter> parameters) {
|
||||
if (parameters == null)
|
||||
return;
|
||||
foreach (var param in parameters)
|
||||
pushMember(param);
|
||||
}
|
||||
void addFieldDefinitions(IEnumerable<FieldDefinition> fields) {
|
||||
if (fields == null)
|
||||
return;
|
||||
foreach (var f in fields)
|
||||
pushMember(f);
|
||||
}
|
||||
void addEventDefinitions(IEnumerable<EventDefinition> events) {
|
||||
if (events == null)
|
||||
return;
|
||||
foreach (var e in events)
|
||||
pushMember(e);
|
||||
}
|
||||
void addPropertyDefinitions(IEnumerable<PropertyDefinition> props) {
|
||||
if (props == null)
|
||||
return;
|
||||
foreach (var p in props)
|
||||
pushMember(p);
|
||||
}
|
||||
void addMemberReference(MemberReference memberReference) {
|
||||
if (memberReference == null)
|
||||
return;
|
||||
pushMember(memberReference.DeclaringType);
|
||||
}
|
||||
void addEventReference(EventReference eventReference) {
|
||||
if (eventReference == null)
|
||||
return;
|
||||
addMemberReference(eventReference);
|
||||
pushMember(eventReference.EventType);
|
||||
}
|
||||
void addEventDefinition(EventDefinition eventDefinition) {
|
||||
if (eventDefinition == null)
|
||||
return;
|
||||
addEventReference(eventDefinition);
|
||||
pushMember(eventDefinition.AddMethod);
|
||||
pushMember(eventDefinition.InvokeMethod);
|
||||
pushMember(eventDefinition.RemoveMethod);
|
||||
addMethodDefinitions(eventDefinition.OtherMethods);
|
||||
access(() => addCustomAttributes(eventDefinition.CustomAttributes));
|
||||
}
|
||||
void addCustomAttribute(CustomAttribute attr) {
|
||||
if (attr == null)
|
||||
return;
|
||||
pushMember(attr.Constructor);
|
||||
|
||||
// Some obfuscators don't rename custom ctor arguments to the new name, causing
|
||||
// Mono.Cecil to use a null reference.
|
||||
try { access(() => addCustomAttributeArguments(attr.ConstructorArguments)); } catch (NullReferenceException) { }
|
||||
try { access(() => addCustomAttributeNamedArguments(attr.Fields)); } catch (NullReferenceException) { }
|
||||
try { access(() => addCustomAttributeNamedArguments(attr.Properties)); } catch (NullReferenceException) { }
|
||||
}
|
||||
void addCustomAttributeArgument(CustomAttributeArgument arg) {
|
||||
pushMember(arg.Type);
|
||||
}
|
||||
void addCustomAttributeNamedArgument(CustomAttributeNamedArgument field) {
|
||||
addCustomAttributeArgument(field.Argument);
|
||||
}
|
||||
void addFieldReference(FieldReference fieldReference) {
|
||||
if (fieldReference == null)
|
||||
return;
|
||||
addMemberReference(fieldReference);
|
||||
pushMember(fieldReference.FieldType);
|
||||
}
|
||||
void addFieldDefinition(FieldDefinition fieldDefinition) {
|
||||
if (fieldDefinition == null)
|
||||
return;
|
||||
addFieldReference(fieldDefinition);
|
||||
access(() => addCustomAttributes(fieldDefinition.CustomAttributes));
|
||||
}
|
||||
void addMethodReference(MethodReference methodReference) {
|
||||
if (methodReference == null)
|
||||
return;
|
||||
addMemberReference(methodReference);
|
||||
addParameterDefinitions(methodReference.Parameters);
|
||||
addMethodReturnType(methodReference.MethodReturnType);
|
||||
addGenericParameters(methodReference.GenericParameters);
|
||||
}
|
||||
void addParameterReference(ParameterReference param) {
|
||||
if (param == null)
|
||||
return;
|
||||
pushMember(param.ParameterType);
|
||||
}
|
||||
void addParameterDefinition(ParameterDefinition param) {
|
||||
if (param == null)
|
||||
return;
|
||||
addParameterReference(param);
|
||||
pushMember(param.Method as MemberReference);
|
||||
access(() => addCustomAttributes(param.CustomAttributes));
|
||||
}
|
||||
void addMethodReturnType(MethodReturnType methodReturnType) {
|
||||
if (methodReturnType == null)
|
||||
return;
|
||||
pushMember(methodReturnType.Method as MemberReference);
|
||||
pushMember(methodReturnType.ReturnType);
|
||||
addParameterDefinition(methodReturnType.Parameter);
|
||||
}
|
||||
void addGenericParameter(GenericParameter param) {
|
||||
if (param == null)
|
||||
return;
|
||||
addTypeReference(param);
|
||||
pushMember(param.Owner as MemberReference);
|
||||
access(() => addCustomAttributes(param.CustomAttributes));
|
||||
addTypeReferences(param.Constraints);
|
||||
}
|
||||
void addTypeReference(TypeReference typeReference) {
|
||||
if (typeReference == null)
|
||||
return;
|
||||
addMemberReference(typeReference);
|
||||
addGenericParameters(typeReference.GenericParameters);
|
||||
}
|
||||
void addMethodDefinition(MethodDefinition methodDefinition) {
|
||||
if (methodDefinition == null)
|
||||
return;
|
||||
addMethodReference(methodDefinition);
|
||||
access(() => addCustomAttributes(methodDefinition.CustomAttributes));
|
||||
addSecurityDeclarations(methodDefinition.SecurityDeclarations);
|
||||
addMethodReferences(methodDefinition.Overrides);
|
||||
addMethodBody(methodDefinition.Body);
|
||||
}
|
||||
void addSecurityDeclaration(SecurityDeclaration decl) {
|
||||
if (decl == null)
|
||||
return;
|
||||
access(() => addSecurityAttributes(decl.SecurityAttributes));
|
||||
}
|
||||
void addSecurityAttribute(SecurityAttribute attr) {
|
||||
if (attr == null)
|
||||
return;
|
||||
pushMember(attr.AttributeType);
|
||||
addCustomAttributeNamedArguments(attr.Fields);
|
||||
addCustomAttributeNamedArguments(attr.Properties);
|
||||
}
|
||||
void addMethodBody(MethodBody body) {
|
||||
if (body == null)
|
||||
return;
|
||||
pushMember(body.Method);
|
||||
addParameterDefinition(body.ThisParameter);
|
||||
addExceptionHandlers(body.ExceptionHandlers);
|
||||
addVariableDefinitions(body.Variables);
|
||||
addScope(body.Scope);
|
||||
addInstructions(body.Instructions);
|
||||
}
|
||||
void addExceptionHandler(ExceptionHandler handler) {
|
||||
if (handler == null)
|
||||
return;
|
||||
pushMember(handler.CatchType);
|
||||
}
|
||||
void addVariableDefinition(VariableDefinition v) {
|
||||
if (v == null)
|
||||
return;
|
||||
addVariableReference(v);
|
||||
}
|
||||
void addVariableReference(VariableReference v) {
|
||||
if (v == null)
|
||||
return;
|
||||
pushMember(v.VariableType);
|
||||
}
|
||||
void addScope(Scope scope) {
|
||||
if (scope == null)
|
||||
return;
|
||||
addVariableDefinitions(scope.Variables);
|
||||
addScopes(scope.Scopes);
|
||||
}
|
||||
void addGenericInstanceMethod(GenericInstanceMethod genericInstanceMethod) {
|
||||
if (genericInstanceMethod == null)
|
||||
return;
|
||||
addMethodSpecification(genericInstanceMethod);
|
||||
addTypeReferences(genericInstanceMethod.GenericArguments);
|
||||
}
|
||||
void addMethodSpecification(MethodSpecification methodSpecification) {
|
||||
if (methodSpecification == null)
|
||||
return;
|
||||
addMethodReference(methodSpecification);
|
||||
pushMember(methodSpecification.ElementMethod);
|
||||
}
|
||||
void addPropertyReference(PropertyReference propertyReference) {
|
||||
if (propertyReference == null)
|
||||
return;
|
||||
addMemberReference(propertyReference);
|
||||
pushMember(propertyReference.PropertyType);
|
||||
}
|
||||
void addPropertyDefinition(PropertyDefinition propertyDefinition) {
|
||||
if (propertyDefinition == null)
|
||||
return;
|
||||
addPropertyReference(propertyDefinition);
|
||||
access(() => addCustomAttributes(propertyDefinition.CustomAttributes));
|
||||
pushMember(propertyDefinition.GetMethod);
|
||||
pushMember(propertyDefinition.SetMethod);
|
||||
addMethodDefinitions(propertyDefinition.OtherMethods);
|
||||
}
|
||||
void addTypeDefinition(TypeDefinition typeDefinition) {
|
||||
if (typeDefinition == null)
|
||||
return;
|
||||
addTypeReference(typeDefinition);
|
||||
pushMember(typeDefinition.BaseType);
|
||||
addTypeReferences(typeDefinition.Interfaces);
|
||||
addTypeDefinitions(typeDefinition.NestedTypes);
|
||||
addMethodDefinitions(typeDefinition.Methods);
|
||||
addFieldDefinitions(typeDefinition.Fields);
|
||||
addEventDefinitions(typeDefinition.Events);
|
||||
addPropertyDefinitions(typeDefinition.Properties);
|
||||
access(() => addCustomAttributes(typeDefinition.CustomAttributes));
|
||||
addSecurityDeclarations(typeDefinition.SecurityDeclarations);
|
||||
}
|
||||
void addTypeSpecification(TypeSpecification ts) {
|
||||
if (ts == null)
|
||||
return;
|
||||
addTypeReference(ts);
|
||||
pushMember(ts.ElementType);
|
||||
}
|
||||
void addArrayType(ArrayType at) {
|
||||
if (at == null)
|
||||
return;
|
||||
addTypeSpecification(at);
|
||||
}
|
||||
void addFunctionPointerType(FunctionPointerType fpt) {
|
||||
if (fpt == null)
|
||||
return;
|
||||
addTypeSpecification(fpt);
|
||||
|
||||
// It's an anon MethodReference created by the class. Not useful to us.
|
||||
//pushMember(fpt.function);
|
||||
}
|
||||
void addGenericInstanceType(GenericInstanceType git) {
|
||||
if (git == null)
|
||||
return;
|
||||
addTypeSpecification(git);
|
||||
addTypeReferences(git.GenericArguments);
|
||||
}
|
||||
void addOptionalModifierType(OptionalModifierType omt) {
|
||||
if (omt == null)
|
||||
return;
|
||||
addTypeSpecification(omt);
|
||||
pushMember(omt.ModifierType);
|
||||
}
|
||||
void addRequiredModifierType(RequiredModifierType rmt) {
|
||||
if (rmt == null)
|
||||
return;
|
||||
addTypeSpecification(rmt);
|
||||
pushMember(rmt.ModifierType);
|
||||
}
|
||||
void addPinnedType(PinnedType pt) {
|
||||
if (pt == null)
|
||||
return;
|
||||
addTypeSpecification(pt);
|
||||
}
|
||||
void addPointerType(PointerType pt) {
|
||||
if (pt == null)
|
||||
return;
|
||||
addTypeSpecification(pt);
|
||||
}
|
||||
void addByReferenceType(ByReferenceType brt) {
|
||||
if (brt == null)
|
||||
return;
|
||||
addTypeSpecification(brt);
|
||||
}
|
||||
void addSentinelType(SentinelType st) {
|
||||
if (st == null)
|
||||
return;
|
||||
addTypeSpecification(st);
|
||||
}
|
||||
void addCallSite(CallSite cs) {
|
||||
pushMember(cs.signature);
|
||||
}
|
||||
|
||||
void doEventDefinition(EventDefinition eventDefinition) {
|
||||
bool present;
|
||||
if (eventDefinitions.TryGetValue(eventDefinition, out present))
|
||||
return;
|
||||
eventDefinitions[eventDefinition] = true;
|
||||
addEventDefinition(eventDefinition);
|
||||
}
|
||||
void doFieldReference(FieldReference fieldReference) {
|
||||
bool present;
|
||||
if (fieldReferences.TryGetValue(fieldReference, out present))
|
||||
return;
|
||||
fieldReferences[fieldReference] = true;
|
||||
addFieldReference(fieldReference);
|
||||
}
|
||||
void doFieldDefinition(FieldDefinition fieldDefinition) {
|
||||
bool present;
|
||||
if (fieldDefinitions.TryGetValue(fieldDefinition, out present))
|
||||
return;
|
||||
fieldDefinitions[fieldDefinition] = true;
|
||||
addFieldDefinition(fieldDefinition);
|
||||
}
|
||||
void doMethodReference(MethodReference methodReference) {
|
||||
bool present;
|
||||
if (methodReferences.TryGetValue(methodReference, out present))
|
||||
return;
|
||||
methodReferences[methodReference] = true;
|
||||
addMethodReference(methodReference);
|
||||
}
|
||||
void doMethodDefinition(MethodDefinition methodDefinition) {
|
||||
bool present;
|
||||
if (methodDefinitions.TryGetValue(methodDefinition, out present))
|
||||
return;
|
||||
methodDefinitions[methodDefinition] = true;
|
||||
addMethodDefinition(methodDefinition);
|
||||
}
|
||||
void doGenericInstanceMethod(GenericInstanceMethod genericInstanceMethod) {
|
||||
bool present;
|
||||
if (genericInstanceMethods.TryGetValue(genericInstanceMethod, out present))
|
||||
return;
|
||||
genericInstanceMethods[genericInstanceMethod] = true;
|
||||
addGenericInstanceMethod(genericInstanceMethod);
|
||||
}
|
||||
void doPropertyDefinition(PropertyDefinition propertyDefinition) {
|
||||
bool present;
|
||||
if (propertyDefinitions.TryGetValue(propertyDefinition, out present))
|
||||
return;
|
||||
propertyDefinitions[propertyDefinition] = true;
|
||||
addPropertyDefinition(propertyDefinition);
|
||||
}
|
||||
void doTypeReference(TypeReference typeReference) {
|
||||
bool present;
|
||||
if (typeReferences.TryGetValue(typeReference, out present))
|
||||
return;
|
||||
typeReferences[typeReference] = true;
|
||||
addTypeReference(typeReference);
|
||||
}
|
||||
void doTypeDefinition(TypeDefinition typeDefinition) {
|
||||
bool present;
|
||||
if (typeDefinitions.TryGetValue(typeDefinition, out present))
|
||||
return;
|
||||
typeDefinitions[typeDefinition] = true;
|
||||
addTypeDefinition(typeDefinition);
|
||||
}
|
||||
void doGenericParameter(GenericParameter genericParameter) {
|
||||
bool present;
|
||||
if (genericParameters.TryGetValue(genericParameter, out present))
|
||||
return;
|
||||
genericParameters[genericParameter] = true;
|
||||
addGenericParameter(genericParameter);
|
||||
}
|
||||
void doArrayType(ArrayType arrayType) {
|
||||
bool present;
|
||||
if (arrayTypes.TryGetValue(arrayType, out present))
|
||||
return;
|
||||
arrayTypes[arrayType] = true;
|
||||
addArrayType(arrayType);
|
||||
}
|
||||
void doFunctionPointerType(FunctionPointerType functionPointerType) {
|
||||
bool present;
|
||||
if (functionPointerTypes.TryGetValue(functionPointerType, out present))
|
||||
return;
|
||||
functionPointerTypes[functionPointerType] = true;
|
||||
addFunctionPointerType(functionPointerType);
|
||||
}
|
||||
void doGenericInstanceType(GenericInstanceType genericInstanceType) {
|
||||
bool present;
|
||||
if (genericInstanceTypes.TryGetValue(genericInstanceType, out present))
|
||||
return;
|
||||
genericInstanceTypes[genericInstanceType] = true;
|
||||
addGenericInstanceType(genericInstanceType);
|
||||
}
|
||||
void doOptionalModifierType(OptionalModifierType optionalModifierType) {
|
||||
bool present;
|
||||
if (optionalModifierTypes.TryGetValue(optionalModifierType, out present))
|
||||
return;
|
||||
optionalModifierTypes[optionalModifierType] = true;
|
||||
addOptionalModifierType(optionalModifierType);
|
||||
}
|
||||
void doRequiredModifierType(RequiredModifierType requiredModifierType) {
|
||||
bool present;
|
||||
if (requiredModifierTypes.TryGetValue(requiredModifierType, out present))
|
||||
return;
|
||||
requiredModifierTypes[requiredModifierType] = true;
|
||||
addRequiredModifierType(requiredModifierType);
|
||||
}
|
||||
void doPinnedType(PinnedType pinnedType) {
|
||||
bool present;
|
||||
if (pinnedTypes.TryGetValue(pinnedType, out present))
|
||||
return;
|
||||
pinnedTypes[pinnedType] = true;
|
||||
addPinnedType(pinnedType);
|
||||
}
|
||||
void doPointerType(PointerType pointerType) {
|
||||
bool present;
|
||||
if (pointerTypes.TryGetValue(pointerType, out present))
|
||||
return;
|
||||
pointerTypes[pointerType] = true;
|
||||
addPointerType(pointerType);
|
||||
}
|
||||
void doByReferenceType(ByReferenceType byReferenceType) {
|
||||
bool present;
|
||||
if (byReferenceTypes.TryGetValue(byReferenceType, out present))
|
||||
return;
|
||||
byReferenceTypes[byReferenceType] = true;
|
||||
addByReferenceType(byReferenceType);
|
||||
}
|
||||
void doSentinelType(SentinelType sentinelType) {
|
||||
bool present;
|
||||
if (sentinelTypes.TryGetValue(sentinelType, out present))
|
||||
return;
|
||||
sentinelTypes[sentinelType] = true;
|
||||
addSentinelType(sentinelType);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
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 de4dot.blocks;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
class MemberRenameState {
|
||||
public VariableNameState variableNameState;
|
||||
public Dictionary<PropertyReferenceKey, PropertyRef> properties = new Dictionary<PropertyReferenceKey, PropertyRef>();
|
||||
public Dictionary<EventReferenceKey, EventRef> events = new Dictionary<EventReferenceKey, EventRef>();
|
||||
public Dictionary<MethodReferenceKey, MethodRef> methods = new Dictionary<MethodReferenceKey, MethodRef>();
|
||||
|
||||
public MemberRenameState()
|
||||
: this(null) {
|
||||
}
|
||||
|
||||
public MemberRenameState(VariableNameState variableNameState) {
|
||||
this.variableNameState = variableNameState;
|
||||
}
|
||||
|
||||
// Used to merge all renamed interface props/events/methods
|
||||
public void mergeRenamed(MemberRenameState other) {
|
||||
foreach (var key in other.properties.Keys)
|
||||
add(properties, key, other.properties[key]);
|
||||
foreach (var key in other.events.Keys)
|
||||
add(events, key, other.events[key]);
|
||||
foreach (var key in other.methods.Keys)
|
||||
add(methods, key, other.methods[key]);
|
||||
}
|
||||
|
||||
public PropertyRef get(PropertyRef p) {
|
||||
return get(properties, new PropertyReferenceKey(p.PropertyReference));
|
||||
}
|
||||
|
||||
public EventRef get(EventRef e) {
|
||||
return get(events, new EventReferenceKey(e.EventReference));
|
||||
}
|
||||
|
||||
public MethodRef get(MethodRef m) {
|
||||
return get(methods, new MethodReferenceKey(m.MethodReference));
|
||||
}
|
||||
|
||||
// Returns null if not found
|
||||
D get<K, D>(Dictionary<K, D> dict, K key) where D : class {
|
||||
D value;
|
||||
if (dict.TryGetValue(key, out value))
|
||||
return value;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void add(PropertyRef p) {
|
||||
add(properties, new PropertyReferenceKey(p.PropertyReference), p);
|
||||
}
|
||||
|
||||
public void add(EventRef e) {
|
||||
add(events, new EventReferenceKey(e.EventReference), e);
|
||||
}
|
||||
|
||||
public void add(MethodRef m) {
|
||||
add(methods, new MethodReferenceKey(m.MethodReference), m);
|
||||
}
|
||||
|
||||
void add<K, D>(Dictionary<K, D> dict, K key, D d) {
|
||||
dict[key] = d;
|
||||
}
|
||||
|
||||
public MemberRenameState clone() {
|
||||
var rv = new MemberRenameState(variableNameState == null ? null : variableNameState.clone());
|
||||
rv.properties = new Dictionary<PropertyReferenceKey, PropertyRef>(properties);
|
||||
rv.events = new Dictionary<EventReferenceKey, EventRef>(events);
|
||||
rv.methods = new Dictionary<MethodReferenceKey, MethodRef>(methods);
|
||||
return rv;
|
||||
}
|
||||
|
||||
public MemberRenameState cloneVariables() {
|
||||
var rv = new MemberRenameState(variableNameState == null ? null : variableNameState.clone());
|
||||
rv.properties = properties;
|
||||
rv.events = events;
|
||||
rv.methods = methods;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
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.old_renamer {
|
||||
interface IResolver {
|
||||
TypeDef resolve(TypeReference typeReference);
|
||||
MethodDef resolve(MethodReference methodReference);
|
||||
FieldDef resolve(FieldReference fieldReference);
|
||||
}
|
||||
|
||||
interface IDefFinder {
|
||||
MethodDef findMethod(MethodReference methodReference);
|
||||
PropertyDef findProp(MethodReference methodReference);
|
||||
EventDef findEvent(MethodReference methodReference);
|
||||
}
|
||||
|
||||
interface RefDict<TRef, TMRef> where TRef : Ref where TMRef : MemberReference {
|
||||
IEnumerable<TRef> getAll();
|
||||
IEnumerable<TRef> getSorted();
|
||||
TRef find(TMRef tmref);
|
||||
void add(TRef tref);
|
||||
void onTypesRenamed();
|
||||
}
|
||||
|
||||
class TypeDefDict : RefDict<TypeDef, TypeReference> {
|
||||
Dictionary<ScopeAndTokenKey, TypeDef> tokenToTypeDef = new Dictionary<ScopeAndTokenKey, TypeDef>();
|
||||
Dictionary<TypeReferenceKey, TypeDef> typeRefToDef = new Dictionary<TypeReferenceKey, TypeDef>();
|
||||
|
||||
public IEnumerable<TypeDef> getAll() {
|
||||
return tokenToTypeDef.Values;
|
||||
}
|
||||
|
||||
public IEnumerable<TypeDef> getSorted() {
|
||||
var list = new List<TypeDef>(getAll());
|
||||
list.Sort((a, b) => {
|
||||
if (a.Index < b.Index) return -1;
|
||||
if (a.Index > b.Index) return 1;
|
||||
return 0;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public TypeDef find(TypeReference typeReference) {
|
||||
TypeDef typeDef;
|
||||
if (tokenToTypeDef.TryGetValue(new ScopeAndTokenKey(typeReference), out typeDef))
|
||||
return typeDef;
|
||||
|
||||
typeRefToDef.TryGetValue(new TypeReferenceKey(typeReference), out typeDef);
|
||||
return typeDef;
|
||||
}
|
||||
|
||||
public void add(TypeDef typeDef) {
|
||||
tokenToTypeDef[new ScopeAndTokenKey(typeDef.TypeDefinition)] = typeDef;
|
||||
typeRefToDef[new TypeReferenceKey(typeDef.TypeDefinition)] = typeDef;
|
||||
}
|
||||
|
||||
public void onTypesRenamed() {
|
||||
var all = new List<TypeDef>(typeRefToDef.Values);
|
||||
typeRefToDef.Clear();
|
||||
foreach (var typeDef in all)
|
||||
typeRefToDef[new TypeReferenceKey(typeDef.TypeDefinition)] = typeDef;
|
||||
}
|
||||
}
|
||||
|
||||
class FieldDefDict : RefDict<FieldDef, FieldReference> {
|
||||
Dictionary<ScopeAndTokenKey, FieldDef> tokenToFieldDef = new Dictionary<ScopeAndTokenKey, FieldDef>();
|
||||
Dictionary<FieldReferenceKey, FieldDef> fieldRefToDef = new Dictionary<FieldReferenceKey, FieldDef>();
|
||||
|
||||
public IEnumerable<FieldDef> getAll() {
|
||||
return tokenToFieldDef.Values;
|
||||
}
|
||||
|
||||
public IEnumerable<FieldDef> getSorted() {
|
||||
var list = new List<FieldDef>(getAll());
|
||||
list.Sort((a, b) => {
|
||||
if (a.Index < b.Index) return -1;
|
||||
if (a.Index > b.Index) return 1;
|
||||
return 0;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public FieldDef find(FieldReference fieldReference) {
|
||||
FieldDef fieldDef;
|
||||
if (tokenToFieldDef.TryGetValue(new ScopeAndTokenKey(fieldReference), out fieldDef))
|
||||
return fieldDef;
|
||||
|
||||
fieldRefToDef.TryGetValue(new FieldReferenceKey(fieldReference), out fieldDef);
|
||||
return fieldDef;
|
||||
}
|
||||
|
||||
public void add(FieldDef fieldDef) {
|
||||
tokenToFieldDef[new ScopeAndTokenKey(fieldDef.FieldDefinition)] = fieldDef;
|
||||
fieldRefToDef[new FieldReferenceKey(fieldDef.FieldDefinition)] = fieldDef;
|
||||
}
|
||||
|
||||
public void onTypesRenamed() {
|
||||
var all = new List<FieldDef>(fieldRefToDef.Values);
|
||||
fieldRefToDef.Clear();
|
||||
foreach (var fieldDef in all)
|
||||
fieldRefToDef[new FieldReferenceKey(fieldDef.FieldDefinition)] = fieldDef;
|
||||
}
|
||||
}
|
||||
|
||||
class MethodDefDict : RefDict<MethodDef, MethodReference> {
|
||||
Dictionary<ScopeAndTokenKey, MethodDef> tokenToMethodDef = new Dictionary<ScopeAndTokenKey, MethodDef>();
|
||||
Dictionary<MethodReferenceKey, MethodDef> methodRefToDef = new Dictionary<MethodReferenceKey, MethodDef>();
|
||||
|
||||
public IEnumerable<MethodDef> getAll() {
|
||||
return tokenToMethodDef.Values;
|
||||
}
|
||||
|
||||
public IEnumerable<MethodDef> getSorted() {
|
||||
var list = new List<MethodDef>(getAll());
|
||||
list.Sort((a, b) => {
|
||||
if (a.Index < b.Index) return -1;
|
||||
if (a.Index > b.Index) return 1;
|
||||
return 0;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public MethodDef find(MethodReference methodReference) {
|
||||
MethodDef methodDef;
|
||||
if (tokenToMethodDef.TryGetValue(new ScopeAndTokenKey(methodReference), out methodDef))
|
||||
return methodDef;
|
||||
|
||||
methodRefToDef.TryGetValue(new MethodReferenceKey(methodReference), out methodDef);
|
||||
return methodDef;
|
||||
}
|
||||
|
||||
public void add(MethodDef methodDef) {
|
||||
tokenToMethodDef[new ScopeAndTokenKey(methodDef.MethodDefinition)] = methodDef;
|
||||
methodRefToDef[new MethodReferenceKey(methodDef.MethodDefinition)] = methodDef;
|
||||
}
|
||||
|
||||
public void onTypesRenamed() {
|
||||
var all = new List<MethodDef>(methodRefToDef.Values);
|
||||
methodRefToDef.Clear();
|
||||
foreach (var methodDef in all)
|
||||
methodRefToDef[new MethodReferenceKey(methodDef.MethodDefinition)] = methodDef;
|
||||
}
|
||||
}
|
||||
|
||||
class PropertyDefDict : RefDict<PropertyDef, PropertyReference> {
|
||||
Dictionary<ScopeAndTokenKey, PropertyDef> tokenToPropDef = new Dictionary<ScopeAndTokenKey, PropertyDef>();
|
||||
|
||||
public IEnumerable<PropertyDef> getAll() {
|
||||
return tokenToPropDef.Values;
|
||||
}
|
||||
|
||||
public IEnumerable<PropertyDef> getSorted() {
|
||||
var list = new List<PropertyDef>(getAll());
|
||||
list.Sort((a, b) => {
|
||||
if (a.Index < b.Index) return -1;
|
||||
if (a.Index > b.Index) return 1;
|
||||
return 0;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public PropertyDef find(PropertyReference propertyReference) {
|
||||
PropertyDef propDef;
|
||||
tokenToPropDef.TryGetValue(new ScopeAndTokenKey(propertyReference), out propDef);
|
||||
return propDef;
|
||||
}
|
||||
|
||||
public void add(PropertyDef propDef) {
|
||||
tokenToPropDef[new ScopeAndTokenKey(propDef.PropertyDefinition)] = propDef;
|
||||
}
|
||||
|
||||
public void onTypesRenamed() {
|
||||
}
|
||||
}
|
||||
|
||||
class EventDefDict : RefDict<EventDef, EventReference> {
|
||||
Dictionary<ScopeAndTokenKey, EventDef> tokenToEventDef = new Dictionary<ScopeAndTokenKey, EventDef>();
|
||||
|
||||
public IEnumerable<EventDef> getAll() {
|
||||
return tokenToEventDef.Values;
|
||||
}
|
||||
|
||||
public IEnumerable<EventDef> getSorted() {
|
||||
var list = new List<EventDef>(getAll());
|
||||
list.Sort((a, b) => {
|
||||
if (a.Index < b.Index) return -1;
|
||||
if (a.Index > b.Index) return 1;
|
||||
return 0;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public EventDef find(EventReference eventReference) {
|
||||
EventDef eventDef;
|
||||
tokenToEventDef.TryGetValue(new ScopeAndTokenKey(eventReference), out eventDef);
|
||||
return eventDef;
|
||||
}
|
||||
|
||||
public void add(EventDef eventDef) {
|
||||
tokenToEventDef[new ScopeAndTokenKey(eventDef.EventDefinition)] = eventDef;
|
||||
}
|
||||
|
||||
public void onTypesRenamed() {
|
||||
}
|
||||
}
|
||||
|
||||
class Renamed {
|
||||
public string OldName { get; set; }
|
||||
public string NewName { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,355 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using de4dot.deobfuscators;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
class Module : IResolver {
|
||||
IObfuscatedFile obfuscatedFile;
|
||||
MemberRefFinder memberRefFinder;
|
||||
TypeDefDict allTypes = new TypeDefDict();
|
||||
IList<RefToDef<TypeReference, TypeDefinition>> typeRefsToRename = new List<RefToDef<TypeReference, TypeDefinition>>();
|
||||
IList<RefToDef<MethodReference, MethodDefinition>> methodRefsToRename = new List<RefToDef<MethodReference, MethodDefinition>>();
|
||||
IList<RefToDef<FieldReference, FieldDefinition>> fieldRefsToRename = new List<RefToDef<FieldReference, FieldDefinition>>();
|
||||
List<MethodDefinition> allMethods;
|
||||
|
||||
public Func<string, bool> IsValidName {
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
class RefToDef<R, D> where R : MemberReference where D : R {
|
||||
public R reference;
|
||||
public D definition;
|
||||
public RefToDef(R reference, D definition) {
|
||||
this.reference = reference;
|
||||
this.definition = definition;
|
||||
}
|
||||
}
|
||||
|
||||
public string Filename {
|
||||
get { return obfuscatedFile.Filename; }
|
||||
}
|
||||
|
||||
public ModuleDefinition ModuleDefinition {
|
||||
get { return obfuscatedFile.ModuleDefinition; }
|
||||
}
|
||||
|
||||
public string Pathname {
|
||||
get { return ModuleDefinition.FullyQualifiedName; }
|
||||
}
|
||||
|
||||
public Module(IObfuscatedFile obfuscatedFile) {
|
||||
this.obfuscatedFile = obfuscatedFile;
|
||||
}
|
||||
|
||||
public IEnumerable<TypeDef> getAllTypes() {
|
||||
return allTypes.getAll();
|
||||
}
|
||||
|
||||
IEnumerable<Renamed> getRenamedTypeNames() {
|
||||
foreach (var typeDef in allTypes.getAll()) {
|
||||
if (typeDef.OldFullName != typeDef.TypeDefinition.FullName) {
|
||||
yield return new Renamed {
|
||||
OldName = typeDef.OldFullName,
|
||||
NewName = typeDef.TypeDefinition.FullName
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeRenamingTypeDefinitions() {
|
||||
if (obfuscatedFile.RemoveNamespaceWithOneType)
|
||||
removeOneClassNamespaces();
|
||||
}
|
||||
|
||||
void removeOneClassNamespaces() {
|
||||
var nsToTypes = new Dictionary<string, List<TypeDef>>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var typeDef in allTypes.getAll()) {
|
||||
List<TypeDef> list;
|
||||
var ns = typeDef.TypeDefinition.Namespace;
|
||||
if (string.IsNullOrEmpty(ns))
|
||||
continue;
|
||||
if (IsValidName(ns))
|
||||
continue;
|
||||
if (!nsToTypes.TryGetValue(ns, out list))
|
||||
nsToTypes[ns] = list = new List<TypeDef>();
|
||||
list.Add(typeDef);
|
||||
}
|
||||
|
||||
var sortedNamespaces = new List<List<TypeDef>>(nsToTypes.Values);
|
||||
sortedNamespaces.Sort((a, b) => {
|
||||
return string.CompareOrdinal(a[0].TypeDefinition.Namespace, b[0].TypeDefinition.Namespace);
|
||||
});
|
||||
foreach (var list in sortedNamespaces) {
|
||||
const int maxClasses = 1;
|
||||
if (list.Count != maxClasses)
|
||||
continue;
|
||||
var ns = list[0].TypeDefinition.Namespace;
|
||||
Log.v("Removing namespace: {0}", ns);
|
||||
foreach (var type in list)
|
||||
type.NewNamespace = "";
|
||||
}
|
||||
}
|
||||
|
||||
static string renameResourceString(string s, string oldTypeName, string newTypeName) {
|
||||
if (!Utils.StartsWith(s, oldTypeName, StringComparison.Ordinal))
|
||||
return s;
|
||||
if (s.Length == oldTypeName.Length)
|
||||
return newTypeName;
|
||||
// s.Length > oldTypeName.Length
|
||||
if (s[oldTypeName.Length] != '.')
|
||||
return s;
|
||||
if (!s.EndsWith(".resources", StringComparison.Ordinal))
|
||||
return s;
|
||||
return newTypeName + s.Substring(oldTypeName.Length);
|
||||
}
|
||||
|
||||
public void renameResources() {
|
||||
var renamedTypes = new List<Renamed>(getRenamedTypeNames());
|
||||
|
||||
// Rename the longest names first. Otherwise eg. b.g.resources could be renamed
|
||||
// Class0.g.resources instead of Class1.resources when b.g was renamed Class1.
|
||||
renamedTypes.Sort((a, b) => {
|
||||
if (a.OldName.Length > b.OldName.Length) return -1;
|
||||
if (a.OldName.Length < b.OldName.Length) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
renameResourceNamesInCode(renamedTypes);
|
||||
renameResources(renamedTypes);
|
||||
}
|
||||
|
||||
void renameResourceNamesInCode(IEnumerable<Renamed> renamedTypes) {
|
||||
// This is needed to speed up this method
|
||||
var oldToNewTypeName = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
foreach (var renamed in renamedTypes)
|
||||
oldToNewTypeName[renamed.OldName] = renamed.NewName;
|
||||
|
||||
List<string> validResourceNames = new List<string>();
|
||||
if (ModuleDefinition.Resources != null) {
|
||||
foreach (var resource in ModuleDefinition.Resources) {
|
||||
var name = resource.Name;
|
||||
if (name.EndsWith(".resources", StringComparison.Ordinal))
|
||||
validResourceNames.Add(name);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var method in allMethods) {
|
||||
if (!method.HasBody)
|
||||
continue;
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
if (instr.OpCode != OpCodes.Ldstr)
|
||||
continue;
|
||||
var s = (string)instr.Operand;
|
||||
if (string.IsNullOrEmpty(s))
|
||||
continue; // Ignore emtpy strings since we'll get lots of false warnings
|
||||
|
||||
string newName = null;
|
||||
string oldName = null;
|
||||
if (oldToNewTypeName.ContainsKey(s)) {
|
||||
oldName = s;
|
||||
newName = oldToNewTypeName[s];
|
||||
}
|
||||
else if (s.EndsWith(".resources", StringComparison.Ordinal)) {
|
||||
// This should rarely, if ever, execute...
|
||||
foreach (var renamed in renamedTypes) { // Slow loop
|
||||
var newName2 = renameResourceString(s, renamed.OldName, renamed.NewName);
|
||||
if (newName2 != s) {
|
||||
newName = newName2;
|
||||
oldName = renamed.OldName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newName == null || string.IsNullOrEmpty(oldName))
|
||||
continue;
|
||||
|
||||
bool isValid = false;
|
||||
foreach (var validName in validResourceNames) {
|
||||
if (Utils.StartsWith(validName, oldName, StringComparison.Ordinal)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid)
|
||||
continue;
|
||||
|
||||
if (s == "" || !obfuscatedFile.RenameResourcesInCode)
|
||||
Log.v("Possible resource name in code: '{0}' => '{1}' in method {2}", s, newName, method);
|
||||
else {
|
||||
instr.Operand = newName;
|
||||
Log.v("Renamed resource string in code: '{0}' => '{1}' ({2})", s, newName, method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renameResources(IEnumerable<Renamed> renamedTypes) {
|
||||
if (ModuleDefinition.Resources == null)
|
||||
return;
|
||||
foreach (var resource in ModuleDefinition.Resources) {
|
||||
var s = resource.Name;
|
||||
foreach (var renamed in renamedTypes) {
|
||||
var newName = renameResourceString(s, renamed.OldName, renamed.NewName);
|
||||
if (newName != s) {
|
||||
resource.Name = newName;
|
||||
Log.v("Renamed resource in resources: {0} => {1}", s, newName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void findAllMemberReferences(ref int typeIndex) {
|
||||
memberRefFinder = new MemberRefFinder();
|
||||
memberRefFinder.findAll(ModuleDefinition, ModuleDefinition.Types);
|
||||
allMethods = new List<MethodDefinition>(memberRefFinder.methodDefinitions.Keys);
|
||||
|
||||
var allTypesList = new List<TypeDef>();
|
||||
foreach (var type in new List<TypeDefinition>(memberRefFinder.typeDefinitions.Keys)) {
|
||||
memberRefFinder.removeTypeDefinition(type);
|
||||
var typeDef = new TypeDef(type, this, typeIndex++);
|
||||
allTypes.add(typeDef);
|
||||
allTypesList.Add(typeDef);
|
||||
|
||||
typeDef.addMembers();
|
||||
|
||||
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
|
||||
var allTypesCopy = new List<TypeDef>(allTypesList);
|
||||
var typeToIndex = new Dictionary<TypeDefinition, int>();
|
||||
for (int i = 0; i < allTypesList.Count; i++)
|
||||
typeToIndex[allTypesList[i].TypeDefinition] = i;
|
||||
foreach (var typeDef in allTypesList) {
|
||||
if (typeDef.TypeDefinition.NestedTypes == null)
|
||||
continue;
|
||||
foreach (var nestedTypeDefinition in typeDef.TypeDefinition.NestedTypes) {
|
||||
int index = typeToIndex[nestedTypeDefinition];
|
||||
var nestedTypeDef = allTypesCopy[index];
|
||||
allTypesCopy[index] = null;
|
||||
if (nestedTypeDef == null) // Impossible
|
||||
throw new ApplicationException("Nested type belongs to two or more types");
|
||||
typeDef.add(nestedTypeDef);
|
||||
nestedTypeDef.NestingType = typeDef;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we got all definitions
|
||||
if (memberRefFinder.typeDefinitions.Count > 0)
|
||||
throw new ApplicationException("There are types left");
|
||||
if (memberRefFinder.eventDefinitions.Count > 0)
|
||||
throw new ApplicationException("There are events left");
|
||||
if (memberRefFinder.fieldDefinitions.Count > 0)
|
||||
throw new ApplicationException("There are fields left");
|
||||
if (memberRefFinder.methodDefinitions.Count > 0)
|
||||
throw new ApplicationException("There are methods left");
|
||||
if (memberRefFinder.propertyDefinitions.Count > 0)
|
||||
throw new ApplicationException("There are properties left");
|
||||
}
|
||||
|
||||
public void resolveAllRefs(IResolver resolver) {
|
||||
foreach (var typeRef in memberRefFinder.typeReferences.Keys) {
|
||||
var typeDef = resolver.resolve(typeRef);
|
||||
if (typeDef != null)
|
||||
typeRefsToRename.Add(new RefToDef<TypeReference, TypeDefinition>(typeRef, typeDef.TypeDefinition));
|
||||
}
|
||||
|
||||
foreach (var methodRef in memberRefFinder.methodReferences.Keys) {
|
||||
var methodDef = resolver.resolve(methodRef);
|
||||
if (methodDef != null)
|
||||
methodRefsToRename.Add(new RefToDef<MethodReference, MethodDefinition>(methodRef, methodDef.MethodDefinition));
|
||||
}
|
||||
|
||||
foreach (var fieldRef in memberRefFinder.fieldReferences.Keys) {
|
||||
var fieldDef = resolver.resolve(fieldRef);
|
||||
if (fieldDef != null)
|
||||
fieldRefsToRename.Add(new RefToDef<FieldReference, FieldDefinition>(fieldRef, fieldDef.FieldDefinition));
|
||||
}
|
||||
}
|
||||
|
||||
public void renameTypeReferences() {
|
||||
foreach (var refToDef in typeRefsToRename) {
|
||||
refToDef.reference.Name = refToDef.definition.Name;
|
||||
refToDef.reference.Namespace = refToDef.definition.Namespace;
|
||||
}
|
||||
}
|
||||
|
||||
public void renameMemberReferences() {
|
||||
foreach (var refToDef in methodRefsToRename)
|
||||
refToDef.reference.Name = refToDef.definition.Name;
|
||||
foreach (var refToDef in fieldRefsToRename)
|
||||
refToDef.reference.Name = refToDef.definition.Name;
|
||||
}
|
||||
|
||||
public void onTypesRenamed() {
|
||||
rebuildAllTypesDict();
|
||||
}
|
||||
|
||||
void rebuildAllTypesDict() {
|
||||
var newAllTypes = new TypeDefDict();
|
||||
foreach (var typeDef in allTypes.getAll()) {
|
||||
typeDef.onTypesRenamed();
|
||||
newAllTypes.add(typeDef);
|
||||
}
|
||||
allTypes = newAllTypes;
|
||||
}
|
||||
|
||||
static TypeReference getNonGenericTypeReference(TypeReference typeReference) {
|
||||
if (typeReference == null)
|
||||
return null;
|
||||
if (!typeReference.IsGenericInstance)
|
||||
return typeReference;
|
||||
var type = (GenericInstanceType)typeReference;
|
||||
return type.ElementType;
|
||||
}
|
||||
|
||||
public TypeDef resolve(TypeReference typeReference) {
|
||||
return this.allTypes.find(getNonGenericTypeReference(typeReference));
|
||||
}
|
||||
|
||||
public MethodDef resolve(MethodReference methodReference) {
|
||||
var typeDef = this.allTypes.find(getNonGenericTypeReference(methodReference.DeclaringType));
|
||||
if (typeDef == null)
|
||||
return null;
|
||||
return typeDef.find(methodReference);
|
||||
}
|
||||
|
||||
public FieldDef resolve(FieldReference fieldReference) {
|
||||
var typeDef = this.allTypes.find(getNonGenericTypeReference(fieldReference.DeclaringType));
|
||||
if (typeDef == null)
|
||||
return null;
|
||||
return typeDef.find(fieldReference);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
interface INameCreator {
|
||||
INameCreator clone();
|
||||
string newName();
|
||||
}
|
||||
|
||||
class OneNameCreator : INameCreator {
|
||||
string name;
|
||||
|
||||
public OneNameCreator(string name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public INameCreator clone() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public string newName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
class GlobalNameCreator : INameCreator {
|
||||
INameCreator other;
|
||||
|
||||
public GlobalNameCreator(INameCreator other) {
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
public INameCreator clone() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public string newName() {
|
||||
return other.newName();
|
||||
}
|
||||
}
|
||||
|
||||
class GenericParamNameCreator : INameCreator {
|
||||
static string[] names = new string[] { "T", "U", "V", "W", "X", "Y", "Z" };
|
||||
int index = 0;
|
||||
|
||||
public string newName() {
|
||||
if (index < names.Length)
|
||||
return names[index++];
|
||||
return string.Format("T{0}", index++);
|
||||
}
|
||||
|
||||
public INameCreator clone() {
|
||||
var rv = new GenericParamNameCreator();
|
||||
rv.index = index;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
class NameCreator : INameCreator {
|
||||
string prefix;
|
||||
int num;
|
||||
|
||||
public NameCreator(string prefix, int num = 0) {
|
||||
this.prefix = prefix;
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
public INameCreator clone() {
|
||||
return new NameCreator(prefix, num);
|
||||
}
|
||||
|
||||
public string newName() {
|
||||
return prefix + num++;
|
||||
}
|
||||
}
|
||||
|
||||
// Like NameCreator but don't add the counter the first time
|
||||
class NameCreator2 : INameCreator {
|
||||
string prefix;
|
||||
int num;
|
||||
const string separator = "_";
|
||||
|
||||
public NameCreator2(string prefix, int num = 0) {
|
||||
this.prefix = prefix;
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
public INameCreator clone() {
|
||||
return new NameCreator2(prefix, num);
|
||||
}
|
||||
|
||||
public string newName() {
|
||||
string rv;
|
||||
if (num == 0)
|
||||
rv = prefix;
|
||||
else
|
||||
rv = prefix + separator + num;
|
||||
num++;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
interface ITypeNameCreator {
|
||||
string newName(TypeDefinition typeDefinition, string newBaseTypeName = null);
|
||||
}
|
||||
|
||||
class NameInfos {
|
||||
IList<NameInfo> nameInfos = new List<NameInfo>();
|
||||
|
||||
class NameInfo {
|
||||
public string name;
|
||||
public INameCreator nameCreator;
|
||||
public NameInfo(string name, INameCreator nameCreator) {
|
||||
this.name = name;
|
||||
this.nameCreator = nameCreator;
|
||||
}
|
||||
}
|
||||
|
||||
public void add(string name, INameCreator nameCreator) {
|
||||
nameInfos.Add(new NameInfo(name, nameCreator));
|
||||
}
|
||||
|
||||
public INameCreator find(string typeName) {
|
||||
foreach (var nameInfo in nameInfos) {
|
||||
if (typeName.Contains(nameInfo.name))
|
||||
return nameInfo.nameCreator;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class TypeNameCreator : ITypeNameCreator {
|
||||
CurrentNames currentNames;
|
||||
INameCreator createUnknownTypeName;
|
||||
INameCreator createEnumName;
|
||||
INameCreator createStructName;
|
||||
INameCreator createDelegateName;
|
||||
INameCreator createClassName;
|
||||
INameCreator createInterfaceName;
|
||||
NameInfos nameInfos = new NameInfos();
|
||||
|
||||
public TypeNameCreator(CurrentNames currentNames) {
|
||||
this.currentNames = currentNames;
|
||||
createUnknownTypeName = createNameCreator("Type");
|
||||
createEnumName = createNameCreator("Enum");
|
||||
createStructName = createNameCreator("Struct");
|
||||
createDelegateName = createNameCreator("Delegate");
|
||||
createClassName = createNameCreator("Class");
|
||||
createInterfaceName = createNameCreator("Interface");
|
||||
|
||||
var names = new string[] {
|
||||
"Exception",
|
||||
"EventArgs",
|
||||
"Attribute",
|
||||
"Form",
|
||||
"Dialog",
|
||||
"Control",
|
||||
};
|
||||
foreach (var name in names)
|
||||
nameInfos.add(name, createNameCreator(name));
|
||||
}
|
||||
|
||||
protected virtual INameCreator createNameCreator(string prefix) {
|
||||
return new NameCreator(prefix);
|
||||
}
|
||||
|
||||
public string newName(TypeDefinition typeDefinition, string newBaseTypeName = null) {
|
||||
var nameCreator = getNameCreator(typeDefinition, newBaseTypeName);
|
||||
return currentNames.newName(typeDefinition.Name, nameCreator);
|
||||
}
|
||||
|
||||
INameCreator getNameCreator(TypeDefinition typeDefinition, string newBaseTypeName) {
|
||||
var nameCreator = createUnknownTypeName;
|
||||
if (typeDefinition.IsEnum)
|
||||
nameCreator = createEnumName;
|
||||
else if (typeDefinition.IsValueType)
|
||||
nameCreator = createStructName;
|
||||
else if (typeDefinition.IsClass) {
|
||||
if (typeDefinition.BaseType != null) {
|
||||
if (MemberReferenceHelper.verifyType(typeDefinition.BaseType, "mscorlib", "System.Delegate"))
|
||||
nameCreator = createDelegateName;
|
||||
else if (MemberReferenceHelper.verifyType(typeDefinition.BaseType, "mscorlib", "System.MulticastDelegate"))
|
||||
nameCreator = createDelegateName;
|
||||
else {
|
||||
nameCreator = nameInfos.find(newBaseTypeName ?? typeDefinition.BaseType.Name);
|
||||
if (nameCreator == null)
|
||||
nameCreator = createClassName;
|
||||
}
|
||||
}
|
||||
else
|
||||
nameCreator = createClassName;
|
||||
}
|
||||
else if (typeDefinition.IsInterface)
|
||||
nameCreator = createInterfaceName;
|
||||
return nameCreator;
|
||||
}
|
||||
}
|
||||
|
||||
class GlobalTypeNameCreator : TypeNameCreator {
|
||||
public GlobalTypeNameCreator(CurrentNames currentNames)
|
||||
: base(currentNames) {
|
||||
}
|
||||
|
||||
protected override INameCreator createNameCreator(string prefix) {
|
||||
return new GlobalNameCreator(base.createNameCreator("G" + prefix));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
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 Mono.Cecil;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
abstract class RefExpander {
|
||||
protected GenericInstanceType git;
|
||||
bool modified = false;
|
||||
|
||||
public RefExpander(GenericInstanceType git) {
|
||||
this.git = git;
|
||||
}
|
||||
|
||||
protected void checkModified(object a, object b) {
|
||||
if (!ReferenceEquals(a, b))
|
||||
modified = true;
|
||||
}
|
||||
|
||||
protected MethodReference expandMethodReference(MethodReference methodReference) {
|
||||
var mr = MethodReferenceInstance.make(methodReference, git);
|
||||
checkModified(methodReference, mr);
|
||||
return mr;
|
||||
}
|
||||
|
||||
protected EventReference expandEventReference(EventReference eventReference) {
|
||||
var er = EventReferenceInstance.make(eventReference, git);
|
||||
checkModified(eventReference, er);
|
||||
return er;
|
||||
}
|
||||
|
||||
protected PropertyReference expandPropertyReference(PropertyReference propertyReference) {
|
||||
var pr = PropertyReferenceInstance.make(propertyReference, git);
|
||||
checkModified(propertyReference, pr);
|
||||
return pr;
|
||||
}
|
||||
|
||||
protected T getResult<T>(T orig, T expanded) {
|
||||
return modified ? expanded : orig;
|
||||
}
|
||||
}
|
||||
|
||||
class GenericMethodRefExpander : RefExpander {
|
||||
MethodRef methodRef;
|
||||
|
||||
public GenericMethodRefExpander(MethodRef methodRef, GenericInstanceType git)
|
||||
: base(git) {
|
||||
this.methodRef = methodRef;
|
||||
}
|
||||
|
||||
public MethodRef expand() {
|
||||
var newMethodRef = new MethodRef(expandMethodReference(methodRef.MethodReference), methodRef.Owner, methodRef.Index);
|
||||
newMethodRef.NewName = methodRef.NewName;
|
||||
return getResult(methodRef, newMethodRef);
|
||||
}
|
||||
}
|
||||
|
||||
class GenericEventRefExpander : RefExpander {
|
||||
EventRef eventRef;
|
||||
|
||||
public GenericEventRefExpander(EventRef eventRef, GenericInstanceType git)
|
||||
: base(git) {
|
||||
this.eventRef = eventRef;
|
||||
}
|
||||
|
||||
public EventRef expand() {
|
||||
var newEventRef = new EventRef(expandEventReference(eventRef.EventReference), eventRef.Owner, eventRef.Index);
|
||||
newEventRef.NewName = eventRef.NewName;
|
||||
return getResult(eventRef, newEventRef);
|
||||
}
|
||||
}
|
||||
|
||||
class GenericPropertyRefExpander : RefExpander {
|
||||
PropertyRef propRef;
|
||||
|
||||
public GenericPropertyRefExpander(PropertyRef propRef, GenericInstanceType git)
|
||||
: base(git) {
|
||||
this.propRef = propRef;
|
||||
}
|
||||
|
||||
public PropertyRef expand() {
|
||||
var newPropRef = new PropertyRef(expandPropertyReference(propRef.PropertyReference), propRef.Owner, propRef.Index);
|
||||
newPropRef.NewName = propRef.NewName;
|
||||
return getResult(propRef, newPropRef);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using de4dot.deobfuscators;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
class TypeNameState {
|
||||
public CurrentNames currentNames;
|
||||
IDictionary<string, string> namespaceToNewName;
|
||||
INameCreator createNamespaceName;
|
||||
public ITypeNameCreator globalTypeNameCreator;
|
||||
public ITypeNameCreator internalTypeNameCreator;
|
||||
Func<string, bool> isValidName;
|
||||
|
||||
public Func<string, bool> IsValidName {
|
||||
get { return isValidName; }
|
||||
set { isValidName = value; }
|
||||
}
|
||||
|
||||
public TypeNameState() {
|
||||
currentNames = new CurrentNames();
|
||||
namespaceToNewName = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
createNamespaceName = new GlobalNameCreator(new NameCreator("ns"));
|
||||
globalTypeNameCreator = new GlobalTypeNameCreator(currentNames);
|
||||
internalTypeNameCreator = new TypeNameCreator(currentNames);
|
||||
}
|
||||
|
||||
public bool isValidNamespace(string ns) {
|
||||
foreach (var part in ns.Split(new char[] { '.' })) {
|
||||
if (!isValidName(part))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public string newNamespace(string ns) {
|
||||
string newName;
|
||||
if (namespaceToNewName.TryGetValue(ns, out newName))
|
||||
return newName;
|
||||
return namespaceToNewName[ns] = createNamespaceName.newName();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
abstract class TypeNames {
|
||||
protected IDictionary<string, INameCreator> typeNames = new Dictionary<string, INameCreator>(StringComparer.Ordinal);
|
||||
protected INameCreator genericParamNameCreator = new NameCreator("gparam_");
|
||||
|
||||
public TypeNames() {
|
||||
insertTypeName("System.Boolean", "bool");
|
||||
insertTypeName("System.Byte", "byte");
|
||||
insertTypeName("System.Char", "char");
|
||||
insertTypeName("System.Double", "double");
|
||||
insertTypeName("System.Int16", "short");
|
||||
insertTypeName("System.Int32", "int");
|
||||
insertTypeName("System.Int64", "long");
|
||||
insertTypeName("System.IntPtr", "intptr");
|
||||
insertTypeName("System.SByte", "sbyte");
|
||||
insertTypeName("System.Single", "float");
|
||||
insertTypeName("System.String", "string");
|
||||
insertTypeName("System.UInt16", "ushort");
|
||||
insertTypeName("System.UInt32", "uint");
|
||||
insertTypeName("System.UInt64", "ulong");
|
||||
insertTypeName("System.UIntPtr", "uintptr");
|
||||
insertTypeName("System.Decimal", "decimal");
|
||||
}
|
||||
|
||||
public string newName(TypeReference typeRef) {
|
||||
var elementType = typeRef.GetElementType();
|
||||
if (elementType is GenericParameter)
|
||||
return genericParamNameCreator.newName();
|
||||
|
||||
var name = elementType.FullName;
|
||||
INameCreator nc;
|
||||
if (typeNames.TryGetValue(name, out nc))
|
||||
return nc.newName();
|
||||
|
||||
var parts = name.Replace('/', '.').Split(new char[] { '.' });
|
||||
var newName = parts[parts.Length - 1];
|
||||
int tickIndex = newName.LastIndexOf('`');
|
||||
if (tickIndex > 0)
|
||||
newName = newName.Substring(0, tickIndex);
|
||||
|
||||
return insertTypeName(name, newName).newName();
|
||||
}
|
||||
|
||||
INameCreator insertTypeName(string fullName, string newName) {
|
||||
newName = fixName(newName);
|
||||
|
||||
var name2 = " " + newName;
|
||||
INameCreator nc;
|
||||
if (!typeNames.TryGetValue(name2, out nc))
|
||||
typeNames[name2] = nc = new NameCreator(newName + "_");
|
||||
|
||||
typeNames[fullName] = nc;
|
||||
return nc;
|
||||
}
|
||||
|
||||
protected abstract string fixName(string name);
|
||||
public abstract TypeNames clone();
|
||||
|
||||
protected IDictionary<string, INameCreator> cloneDict() {
|
||||
var rv = new Dictionary<string, INameCreator>(StringComparer.Ordinal);
|
||||
foreach (var key in typeNames.Keys)
|
||||
rv[key] = typeNames[key].clone();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
class VariableNameCreator : TypeNames {
|
||||
protected override string fixName(string name) {
|
||||
// Make all leading upper case chars lower case
|
||||
var s = "";
|
||||
for (int i = 0; i < name.Length; i++) {
|
||||
char c = char.ToLowerInvariant(name[i]);
|
||||
if (c == name[i])
|
||||
return s + name.Substring(i);
|
||||
s += c;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public override TypeNames clone() {
|
||||
var rv = new VariableNameCreator();
|
||||
rv.typeNames = cloneDict();
|
||||
rv.genericParamNameCreator = genericParamNameCreator.clone();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
class PropertyNameCreator : TypeNames {
|
||||
protected override string fixName(string name) {
|
||||
return name.Substring(0, 1).ToUpperInvariant() + name.Substring(1);
|
||||
}
|
||||
|
||||
public override TypeNames clone() {
|
||||
var rv = new PropertyNameCreator();
|
||||
rv.typeNames = cloneDict();
|
||||
rv.genericParamNameCreator = genericParamNameCreator.clone();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
class GlobalInterfacePropertyNameCreator : TypeNames {
|
||||
protected override string fixName(string name) {
|
||||
return "I_" + name.Substring(0, 1).ToUpperInvariant() + name.Substring(1);
|
||||
}
|
||||
|
||||
public override TypeNames clone() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
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 Mono.Cecil;
|
||||
|
||||
namespace de4dot.old_renamer {
|
||||
// State when renaming type members
|
||||
class VariableNameState {
|
||||
CurrentNames currentVariableNames = new CurrentNames();
|
||||
CurrentNames currentMethodNames = new CurrentNames();
|
||||
protected TypeNames variableNameCreator = new VariableNameCreator(); // For fields and method args
|
||||
protected TypeNames propertyNameCreator = new PropertyNameCreator();
|
||||
protected INameCreator eventNameCreator = new NameCreator("Event_");
|
||||
public INameCreator staticMethodNameCreator = new NameCreator("smethod_");
|
||||
public INameCreator virtualMethodNameCreator = new NameCreator("vmethod_");
|
||||
public INameCreator instanceMethodNameCreator = new NameCreator("method_");
|
||||
protected INameCreator genericPropertyNameCreator = new NameCreator("Prop_");
|
||||
Func<string, bool> isValidName;
|
||||
|
||||
public Func<string, bool> IsValidName {
|
||||
get { return isValidName; }
|
||||
set { isValidName = value; }
|
||||
}
|
||||
|
||||
public virtual VariableNameState clone() {
|
||||
var rv = new VariableNameState();
|
||||
cloneInit(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
public void addFieldName(string fieldName) {
|
||||
currentVariableNames.add(fieldName);
|
||||
}
|
||||
|
||||
public void addMethodName(string methodName) {
|
||||
currentMethodNames.add(methodName);
|
||||
}
|
||||
|
||||
protected void cloneInit(VariableNameState variableNameState) {
|
||||
variableNameState.currentVariableNames = new CurrentNames();
|
||||
variableNameState.currentMethodNames = new CurrentNames();
|
||||
variableNameState.variableNameCreator = variableNameCreator.clone();
|
||||
variableNameState.propertyNameCreator = propertyNameCreator.clone();
|
||||
variableNameState.eventNameCreator = eventNameCreator.clone();
|
||||
variableNameState.staticMethodNameCreator = staticMethodNameCreator.clone();
|
||||
variableNameState.virtualMethodNameCreator = virtualMethodNameCreator.clone();
|
||||
variableNameState.instanceMethodNameCreator = instanceMethodNameCreator.clone();
|
||||
variableNameState.genericPropertyNameCreator = genericPropertyNameCreator.clone();
|
||||
variableNameState.isValidName = isValidName;
|
||||
}
|
||||
|
||||
public string getNewPropertyName(PropertyDefinition propertyDefinition) {
|
||||
var propType = propertyDefinition.PropertyType;
|
||||
if (propType is GenericParameter)
|
||||
return genericPropertyNameCreator.newName();
|
||||
return propertyNameCreator.newName(propType);
|
||||
}
|
||||
|
||||
public string getNewEventName(EventDefinition eventDefinition) {
|
||||
return eventNameCreator.newName();
|
||||
}
|
||||
|
||||
public string getNewFieldName(FieldDefinition field) {
|
||||
return currentVariableNames.newName(field.Name, () => variableNameCreator.newName(field.FieldType));
|
||||
}
|
||||
|
||||
public string getNewFieldName(string oldName, INameCreator nameCreator) {
|
||||
return currentVariableNames.newName(oldName, () => nameCreator.newName());
|
||||
}
|
||||
|
||||
public string getNewParamName(string oldName, ParameterDefinition param) {
|
||||
return currentVariableNames.newName(oldName, () => variableNameCreator.newName(param.ParameterType));
|
||||
}
|
||||
|
||||
public string getNewMethodName(string oldName, INameCreator nameCreator) {
|
||||
return currentMethodNames.newName(oldName, nameCreator);
|
||||
}
|
||||
}
|
||||
|
||||
class InterfaceVariableNameState : VariableNameState {
|
||||
public InterfaceVariableNameState() {
|
||||
propertyNameCreator = new GlobalInterfacePropertyNameCreator();
|
||||
eventNameCreator = new GlobalNameCreator(new NameCreator("I_Event_"));
|
||||
virtualMethodNameCreator = new GlobalNameCreator(new NameCreator("imethod_"));
|
||||
genericPropertyNameCreator = new GlobalNameCreator(new NameCreator("I_Prop_"));
|
||||
}
|
||||
|
||||
public override VariableNameState clone() {
|
||||
var rv = new InterfaceVariableNameState();
|
||||
cloneInit(rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user