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 Mono.Cecil;
|
||||
using de4dot.blocks;
|
||||
using de4dot.old_renamer;
|
||||
using de4dot.renamer;
|
||||
using de4dot.deobfuscators;
|
||||
using de4dot.AssemblyClient;
|
||||
|
||||
|
@ -91,7 +91,7 @@ namespace de4dot {
|
|||
file.deobfuscateEnd();
|
||||
|
||||
if (options.RenameSymbols)
|
||||
new DefinitionsRenamer(new List<IObfuscatedFile> { file }).renameAll();
|
||||
new Renamer(new List<IObfuscatedFile> { file }).rename();
|
||||
|
||||
file.save();
|
||||
|
||||
|
@ -339,7 +339,7 @@ namespace de4dot {
|
|||
void renameAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
||||
if (!options.RenameSymbols)
|
||||
return;
|
||||
new DefinitionsRenamer(allFiles).renameAll();
|
||||
new Renamer(allFiles).rename();
|
||||
}
|
||||
|
||||
void saveAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
||||
|
|
|
@ -153,6 +153,19 @@
|
|||
<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" />
|
||||
<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="UserException.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
|
|
|
@ -23,7 +23,7 @@ using Mono.Cecil;
|
|||
using Mono.Cecil.Cil;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot {
|
||||
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
|
||||
|
|
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