Add some renamer classes
This commit is contained in:
parent
e5da0a1255
commit
fa2f0808b1
|
@ -22,7 +22,7 @@ using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.old_renamer;
|
using de4dot.renamer;
|
||||||
using de4dot.deobfuscators;
|
using de4dot.deobfuscators;
|
||||||
using de4dot.AssemblyClient;
|
using de4dot.AssemblyClient;
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ namespace de4dot {
|
||||||
file.deobfuscateEnd();
|
file.deobfuscateEnd();
|
||||||
|
|
||||||
if (options.RenameSymbols)
|
if (options.RenameSymbols)
|
||||||
new DefinitionsRenamer(new List<IObfuscatedFile> { file }).renameAll();
|
new Renamer(new List<IObfuscatedFile> { file }).rename();
|
||||||
|
|
||||||
file.save();
|
file.save();
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ namespace de4dot {
|
||||||
void renameAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
void renameAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
||||||
if (!options.RenameSymbols)
|
if (!options.RenameSymbols)
|
||||||
return;
|
return;
|
||||||
new DefinitionsRenamer(allFiles).renameAll();
|
new Renamer(allFiles).rename();
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
void saveAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
||||||
|
|
|
@ -153,6 +153,19 @@
|
||||||
<Compile Include="old_renamer\TypeNames.cs" />
|
<Compile Include="old_renamer\TypeNames.cs" />
|
||||||
<Compile Include="old_renamer\TypeNameState.cs" />
|
<Compile Include="old_renamer\TypeNameState.cs" />
|
||||||
<Compile Include="old_renamer\VariableNameState.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" />
|
||||||
|
<Compile Include="renamer\asmmodules\IResolver.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\MemberRefFinder.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\MethodDef.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\Module.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\Modules.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\PropertyDef.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\Ref.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\RefDict.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\TypeDef.cs" />
|
||||||
|
<Compile Include="renamer\Renamer.cs" />
|
||||||
<Compile Include="StringDecrypter.cs" />
|
<Compile Include="StringDecrypter.cs" />
|
||||||
<Compile Include="UserException.cs" />
|
<Compile Include="UserException.cs" />
|
||||||
<Compile Include="Utils.cs" />
|
<Compile Include="Utils.cs" />
|
||||||
|
|
|
@ -23,7 +23,7 @@ using Mono.Cecil;
|
||||||
using Mono.Cecil.Cil;
|
using Mono.Cecil.Cil;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot {
|
namespace de4dot.old_renamer {
|
||||||
// If it's a non-generic memberref, you could use GetMemberReference() to get a cached
|
// 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
|
// 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
|
// type and all its fields, recursively, to find all of those refererences... That's
|
||||||
|
|
45
de4dot.code/renamer/Renamer.cs
Normal file
45
de4dot.code/renamer/Renamer.cs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules;
|
||||||
|
|
||||||
|
namespace de4dot.renamer {
|
||||||
|
class Renamer {
|
||||||
|
bool renameSymbols = true;
|
||||||
|
bool renameFields = true;
|
||||||
|
bool renameProperties = true;
|
||||||
|
bool renameEvents = true;
|
||||||
|
bool renameMethods = true;
|
||||||
|
Modules modules = new Modules();
|
||||||
|
|
||||||
|
public Renamer(IEnumerable<IObfuscatedFile> files) {
|
||||||
|
foreach (var file in files)
|
||||||
|
modules.add(new Module(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rename() {
|
||||||
|
if (modules.Empty)
|
||||||
|
return;
|
||||||
|
Log.n("Renaming all obfuscated symbols");
|
||||||
|
|
||||||
|
modules.initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
de4dot.code/renamer/asmmodules/EventDef.cs
Normal file
46
de4dot.code/renamer/asmmodules/EventDef.cs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
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;
|
||||||
|
|
||||||
|
namespace de4dot.renamer.asmmodules {
|
||||||
|
class EventDef : Ref {
|
||||||
|
public EventDefinition EventDefinition {
|
||||||
|
get { return (EventDefinition)memberReference; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventDef(EventDefinition eventDefinition, TypeDef owner, int index)
|
||||||
|
: base(eventDefinition, owner, index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<MethodDefinition> methodDefinitions() {
|
||||||
|
if (EventDefinition.AddMethod != null)
|
||||||
|
yield return EventDefinition.AddMethod;
|
||||||
|
if (EventDefinition.RemoveMethod != null)
|
||||||
|
yield return EventDefinition.RemoveMethod;
|
||||||
|
if (EventDefinition.InvokeMethod != null)
|
||||||
|
yield return EventDefinition.InvokeMethod;
|
||||||
|
if (EventDefinition.OtherMethods != null) {
|
||||||
|
foreach (var m in EventDefinition.OtherMethods)
|
||||||
|
yield return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
de4dot.code/renamer/asmmodules/ExternalAssemblies.cs
Normal file
104
de4dot.code/renamer/asmmodules/ExternalAssemblies.cs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 de4dot@gmail.com
|
||||||
|
|
||||||
|
This file is part of de4dot.
|
||||||
|
|
||||||
|
de4dot is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
de4dot is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Mono.Cecil;
|
||||||
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
namespace de4dot.renamer.asmmodules {
|
||||||
|
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.Scope);
|
||||||
|
ExternalAssembly asm;
|
||||||
|
if (assemblies.TryGetValue(asmFullName, out asm))
|
||||||
|
return asm;
|
||||||
|
|
||||||
|
AssemblyDefinition asmDef = null;
|
||||||
|
try {
|
||||||
|
asmDef = GlobalAssemblyResolver.Instance.Resolve(asmFullName);
|
||||||
|
}
|
||||||
|
catch (ResolutionException) {
|
||||||
|
}
|
||||||
|
catch (AssemblyResolutionException) {
|
||||||
|
}
|
||||||
|
if (asmDef == null) {
|
||||||
|
// If we can't load it now, we can't load it later. Make sure above code returns null.
|
||||||
|
assemblies[asmFullName] = null;
|
||||||
|
Log.w("Could not load assembly {0}", asmFullName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
de4dot.code/renamer/asmmodules/FieldDef.cs
Normal file
32
de4dot.code/renamer/asmmodules/FieldDef.cs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules {
|
||||||
|
class FieldDef : Ref {
|
||||||
|
public FieldDefinition FieldDefinition {
|
||||||
|
get { return (FieldDefinition)memberReference; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef(FieldDefinition fieldDefinition, TypeDef owner, int index)
|
||||||
|
: base(fieldDefinition, owner, index) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
de4dot.code/renamer/asmmodules/IResolver.cs
Normal file
28
de4dot.code/renamer/asmmodules/IResolver.cs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules {
|
||||||
|
interface IResolver {
|
||||||
|
TypeDef resolve(TypeReference typeReference);
|
||||||
|
MethodDef resolve(MethodReference methodReference);
|
||||||
|
FieldDef resolve(FieldReference fieldReference);
|
||||||
|
}
|
||||||
|
}
|
703
de4dot.code/renamer/asmmodules/MemberRefFinder.cs
Normal file
703
de4dot.code/renamer/asmmodules/MemberRefFinder.cs
Normal file
|
@ -0,0 +1,703 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
de4dot.code/renamer/asmmodules/MethodDef.cs
Normal file
32
de4dot.code/renamer/asmmodules/MethodDef.cs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules {
|
||||||
|
class MethodDef : Ref {
|
||||||
|
public MethodDefinition MethodDefinition {
|
||||||
|
get { return (MethodDefinition)memberReference; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodDef(MethodDefinition methodDefinition, TypeDef owner, int index)
|
||||||
|
: base(methodDefinition, owner, index) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
137
de4dot.code/renamer/asmmodules/Module.cs
Normal file
137
de4dot.code/renamer/asmmodules/Module.cs
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules {
|
||||||
|
class Module : IResolver {
|
||||||
|
IObfuscatedFile obfuscatedFile;
|
||||||
|
TypeDefDict types = new TypeDefDict();
|
||||||
|
MemberRefFinder memberRefFinder;
|
||||||
|
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>>();
|
||||||
|
|
||||||
|
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 Module(IObfuscatedFile obfuscatedFile) {
|
||||||
|
this.obfuscatedFile = obfuscatedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<TypeDef> getAllTypes() {
|
||||||
|
return types.getAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void findAllMemberReferences(ref int typeIndex) {
|
||||||
|
memberRefFinder = new MemberRefFinder();
|
||||||
|
memberRefFinder.findAll(ModuleDefinition, ModuleDefinition.Types);
|
||||||
|
|
||||||
|
var allTypesList = new List<TypeDef>();
|
||||||
|
foreach (var type in memberRefFinder.typeDefinitions.Keys) {
|
||||||
|
var typeDef = new TypeDef(type, this, typeIndex++);
|
||||||
|
types.add(typeDef);
|
||||||
|
allTypesList.Add(typeDef);
|
||||||
|
typeDef.addMembers();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.types.find(getNonGenericTypeReference(typeReference));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodDef resolve(MethodReference methodReference) {
|
||||||
|
var typeDef = this.types.find(getNonGenericTypeReference(methodReference.DeclaringType));
|
||||||
|
if (typeDef == null)
|
||||||
|
return null;
|
||||||
|
return typeDef.find(methodReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef resolve(FieldReference fieldReference) {
|
||||||
|
var typeDef = this.types.find(getNonGenericTypeReference(fieldReference.DeclaringType));
|
||||||
|
if (typeDef == null)
|
||||||
|
return null;
|
||||||
|
return typeDef.find(fieldReference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
349
de4dot.code/renamer/asmmodules/Modules.cs
Normal file
349
de4dot.code/renamer/asmmodules/Modules.cs
Normal file
|
@ -0,0 +1,349 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules {
|
||||||
|
class Modules : IResolver {
|
||||||
|
bool initializeCalled = false;
|
||||||
|
List<Module> modules = new List<Module>();
|
||||||
|
Dictionary<ModuleDefinition, Module> modulesDict = new Dictionary<ModuleDefinition, Module>();
|
||||||
|
AssemblyHash assemblyHash = new AssemblyHash();
|
||||||
|
|
||||||
|
List<TypeDef> allTypes = new List<TypeDef>(); //TODO: Do we need this?
|
||||||
|
List<TypeDef> baseTypes = new List<TypeDef>(); //TODO: Do we need this?
|
||||||
|
List<TypeDef> nonNestedTypes; //TODO: Do we need this?
|
||||||
|
|
||||||
|
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.\n" +
|
||||||
|
"Is one 32-bit and the other 64-bit?\n" +
|
||||||
|
" Module1: \"{0}\"" +
|
||||||
|
" Module2: \"{1}\"",
|
||||||
|
module.ModuleDefinition.FullyQualifiedName,
|
||||||
|
mainModule.ModuleDefinition.FullyQualifiedName));
|
||||||
|
}
|
||||||
|
mainModule = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
modulesDict.add(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Module lookup(string moduleName) {
|
||||||
|
return modulesDict.lookup(moduleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Module> Modules {
|
||||||
|
get { return modulesDict.Modules; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModulesDict {
|
||||||
|
IDictionary<string, Module> modulesDict = new Dictionary<string, Module>(StringComparer.Ordinal);
|
||||||
|
|
||||||
|
public void add(Module module) {
|
||||||
|
var moduleName = module.ModuleDefinition.Name;
|
||||||
|
if (lookup(moduleName) != null)
|
||||||
|
throw new ApplicationException(string.Format("Module \"{0}\" was found twice", moduleName));
|
||||||
|
modulesDict[moduleName] = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Module lookup(string moduleName) {
|
||||||
|
Module module;
|
||||||
|
if (modulesDict.TryGetValue(moduleName, out module))
|
||||||
|
return module;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Module> Modules {
|
||||||
|
get { return modulesDict.Values; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Empty {
|
||||||
|
get { return modules.Count == 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Module module) {
|
||||||
|
if (initializeCalled)
|
||||||
|
throw new ApplicationException("initialize() has been called");
|
||||||
|
Module otherModule;
|
||||||
|
if (modulesDict.TryGetValue(module.ModuleDefinition, out otherModule))
|
||||||
|
return;
|
||||||
|
modulesDict[module.ModuleDefinition] = module;
|
||||||
|
modules.Add(module);
|
||||||
|
assemblyHash.add(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize() {
|
||||||
|
initializeCalled = true;
|
||||||
|
findAllMemberReferences();
|
||||||
|
resolveAllRefs();
|
||||||
|
initAllTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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) {
|
||||||
|
if (typeDef.baseType == null || !typeDef.baseType.typeDef.HasModule)
|
||||||
|
baseTypes.Add(typeDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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, null, 0);
|
||||||
|
typeDef.addMembers();
|
||||||
|
foreach (var iface in typeDef.TypeDefinition.Interfaces) {
|
||||||
|
var ifaceDef = resolveOther(iface);
|
||||||
|
if (ifaceDef == null)
|
||||||
|
continue;
|
||||||
|
typeDef.addInterface(ifaceDef, iface);
|
||||||
|
}
|
||||||
|
var baseDef = resolveOther(typeDef.TypeDefinition.BaseType);
|
||||||
|
if (baseDef != null)
|
||||||
|
typeDef.addBaseType(baseDef, typeDef.TypeDefinition.BaseType);
|
||||||
|
return otherTypesDict[key] = typeDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns null if it's a non-loaded module/assembly
|
||||||
|
IEnumerable<Module> findModules(TypeReference type) {
|
||||||
|
var scope = type.Scope;
|
||||||
|
|
||||||
|
if (scope is AssemblyNameReference)
|
||||||
|
return findModules((AssemblyNameReference)scope);
|
||||||
|
|
||||||
|
if (scope is ModuleDefinition) {
|
||||||
|
var modules = findModules((ModuleDefinition)scope);
|
||||||
|
if (modules != null)
|
||||||
|
return modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scope is ModuleReference) {
|
||||||
|
var moduleReference = (ModuleReference)scope;
|
||||||
|
if (moduleReference.Name == type.Module.Name) {
|
||||||
|
var modules = findModules(type.Module);
|
||||||
|
if (modules != null)
|
||||||
|
return modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
var asm = type.Module.Assembly;
|
||||||
|
if (asm == null)
|
||||||
|
return null;
|
||||||
|
var moduleHash = assemblyHash.lookup(asm.ToString());
|
||||||
|
if (moduleHash == null)
|
||||||
|
return null;
|
||||||
|
var module = moduleHash.lookup(moduleReference.Name);
|
||||||
|
if (module == null)
|
||||||
|
return null;
|
||||||
|
return new List<Module> { module };
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ApplicationException(string.Format("scope is an unsupported type: {0}", scope.GetType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<Module> findModules(AssemblyNameReference assemblyRef) {
|
||||||
|
var moduleHash = assemblyHash.lookup(assemblyRef.ToString());
|
||||||
|
if (moduleHash != null)
|
||||||
|
return moduleHash.Modules;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<Module> findModules(ModuleDefinition moduleDefinition) {
|
||||||
|
Module module;
|
||||||
|
if (modulesDict.TryGetValue(moduleDefinition, out module))
|
||||||
|
return new List<Module> { module };
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAutoCreatedType(TypeReference typeReference) {
|
||||||
|
return typeReference is ArrayType || typeReference is PointerType || typeReference is FunctionPointerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeDef resolve(TypeReference typeReference) {
|
||||||
|
var modules = findModules(typeReference);
|
||||||
|
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());
|
||||||
|
//TODO: Return null when you've tested all code
|
||||||
|
throw new ApplicationException(string.Format("Could not resolve TypeReference {0} ({1:X8})", typeReference, typeReference.MetadataToken.ToInt32()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodDef resolve(MethodReference methodReference) {
|
||||||
|
if (methodReference.DeclaringType == null)
|
||||||
|
return null;
|
||||||
|
var modules = findModules(methodReference.DeclaringType);
|
||||||
|
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());
|
||||||
|
//TODO: Return null when you've tested all code
|
||||||
|
throw new ApplicationException(string.Format("Could not resolve MethodReference {0} ({1:X8})", methodReference, methodReference.MetadataToken.ToInt32()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef resolve(FieldReference fieldReference) {
|
||||||
|
if (fieldReference.DeclaringType == null)
|
||||||
|
return null;
|
||||||
|
var modules = findModules(fieldReference.DeclaringType);
|
||||||
|
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());
|
||||||
|
//TODO: Return null when you've tested all code
|
||||||
|
throw new ApplicationException(string.Format("Could not resolve FieldReference {0} ({1:X8})", fieldReference, fieldReference.MetadataToken.ToInt32()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
de4dot.code/renamer/asmmodules/PropertyDef.cs
Normal file
44
de4dot.code/renamer/asmmodules/PropertyDef.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
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;
|
||||||
|
|
||||||
|
namespace de4dot.renamer.asmmodules {
|
||||||
|
class PropertyDef : Ref {
|
||||||
|
public PropertyDefinition PropertyDefinition {
|
||||||
|
get { return (PropertyDefinition)memberReference; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyDef(PropertyDefinition propertyDefinition, TypeDef owner, int index)
|
||||||
|
: base(propertyDefinition, owner, index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<MethodDefinition> methodDefinitions() {
|
||||||
|
if (PropertyDefinition.GetMethod != null)
|
||||||
|
yield return PropertyDefinition.GetMethod;
|
||||||
|
if (PropertyDefinition.SetMethod != null)
|
||||||
|
yield return PropertyDefinition.SetMethod;
|
||||||
|
if (PropertyDefinition.OtherMethods != null) {
|
||||||
|
foreach (var m in PropertyDefinition.OtherMethods)
|
||||||
|
yield return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
de4dot.code/renamer/asmmodules/Ref.cs
Normal file
38
de4dot.code/renamer/asmmodules/Ref.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules {
|
||||||
|
abstract class Ref {
|
||||||
|
protected readonly MemberReference memberReference;
|
||||||
|
public int Index { get; set; }
|
||||||
|
public TypeDef Owner { get; set; }
|
||||||
|
|
||||||
|
protected Ref(MemberReference memberReference, TypeDef owner, int index) {
|
||||||
|
this.memberReference = memberReference;
|
||||||
|
Owner = owner;
|
||||||
|
Index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return memberReference != null ? memberReference.ToString() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
214
de4dot.code/renamer/asmmodules/RefDict.cs
Normal file
214
de4dot.code/renamer/asmmodules/RefDict.cs
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 de4dot@gmail.com
|
||||||
|
|
||||||
|
This file is part of de4dot.
|
||||||
|
|
||||||
|
de4dot is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
de4dot is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Mono.Cecil;
|
||||||
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
namespace de4dot.renamer.asmmodules {
|
||||||
|
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() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
de4dot.code/renamer/asmmodules/TypeDef.cs
Normal file
117
de4dot.code/renamer/asmmodules/TypeDef.cs
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
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.renamer.asmmodules {
|
||||||
|
class TypeInfo {
|
||||||
|
public TypeReference typeReference;
|
||||||
|
public TypeDef typeDef;
|
||||||
|
public TypeInfo(TypeReference typeReference, TypeDef typeDef) {
|
||||||
|
this.typeReference = typeReference;
|
||||||
|
this.typeDef = typeDef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeDef : Ref {
|
||||||
|
EventDefDict events = new EventDefDict();
|
||||||
|
FieldDefDict fields = new FieldDefDict();
|
||||||
|
MethodDefDict methods = new MethodDefDict();
|
||||||
|
PropertyDefDict properties = new PropertyDefDict();
|
||||||
|
TypeDefDict types = new TypeDefDict();
|
||||||
|
internal TypeInfo baseType = null;
|
||||||
|
internal IList<TypeInfo> interfaces = new List<TypeInfo>(); // directly implemented interfaces
|
||||||
|
internal IList<TypeDef> derivedTypes = new List<TypeDef>();
|
||||||
|
Module module;
|
||||||
|
|
||||||
|
public bool HasModule {
|
||||||
|
get { return module != null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<TypeDef> NestedTypes {
|
||||||
|
get { return types.getSorted(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeDef NestingType { get; set; }
|
||||||
|
|
||||||
|
public TypeDefinition TypeDefinition {
|
||||||
|
get { return (TypeDefinition)memberReference; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeDef(TypeDefinition typeDefinition, Module module, int index)
|
||||||
|
: base(typeDefinition, null, index) {
|
||||||
|
this.module = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInterface(TypeDef ifaceDef, TypeReference iface) {
|
||||||
|
if (ifaceDef == null || iface == null)
|
||||||
|
return;
|
||||||
|
interfaces.Add(new TypeInfo(iface, ifaceDef));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBaseType(TypeDef baseDef, TypeReference baseRef) {
|
||||||
|
if (baseDef == null || baseRef == null)
|
||||||
|
return;
|
||||||
|
baseType = new TypeInfo(baseRef, baseDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(EventDef e) {
|
||||||
|
events.add(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(FieldDef f) {
|
||||||
|
fields.add(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(MethodDef m) {
|
||||||
|
methods.add(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(PropertyDef p) {
|
||||||
|
properties.add(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(TypeDef t) {
|
||||||
|
types.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodDef find(MethodReference mr) {
|
||||||
|
return methods.find(mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef find(FieldReference fr) {
|
||||||
|
return fields.find(fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMembers() {
|
||||||
|
var type = TypeDefinition;
|
||||||
|
|
||||||
|
for (int i = 0; i < type.Events.Count; i++)
|
||||||
|
add(new EventDef(type.Events[i], this, i));
|
||||||
|
for (int i = 0; i < type.Fields.Count; i++)
|
||||||
|
add(new FieldDef(type.Fields[i], this, i));
|
||||||
|
for (int i = 0; i < type.Methods.Count; i++)
|
||||||
|
add(new MethodDef(type.Methods[i], this, i));
|
||||||
|
for (int i = 0; i < type.Properties.Count; i++)
|
||||||
|
add(new PropertyDef(type.Properties[i], this, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user