Add some renamer classes

This commit is contained in:
de4dot 2011-11-15 14:26:51 +01:00
parent e5da0a1255
commit fa2f0808b1
16 changed files with 1906 additions and 4 deletions

View File

@ -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) {

View File

@ -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" />

View File

@ -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

View 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();
}
}
}

View 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;
}
}
}
}

View 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();
}
}
}

View 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) {
}
}
}

View 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);
}
}

View 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);
}
}
}

View 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) {
}
}
}

View 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);
}
}
}

View 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()));
}
}
}

View 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;
}
}
}
}

View 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;
}
}
}

View 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() {
}
}
}

View 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));
}
}
}