Port more code

This commit is contained in:
de4dot 2012-11-02 20:10:34 +01:00
parent 00177034b9
commit 89cd55a071
10 changed files with 277 additions and 294 deletions

View File

@ -49,7 +49,7 @@ namespace AssemblyData.methodsrewriter {
} }
TypeResolver getTypeResolver(ITypeDefOrRef typeRef) { TypeResolver getTypeResolver(ITypeDefOrRef typeRef) {
var key = typeRef.Namespace + "." + typeRef.Name; var key = typeRef.Namespace + "." + typeRef.TypeName;
List<TypeResolver> list; List<TypeResolver> list;
if (!types.TryGetValue(key, out list)) if (!types.TryGetValue(key, out list))
return null; return null;

View File

@ -48,63 +48,52 @@ namespace de4dot.code {
dataDict.Remove(name); dataDict.Remove(name);
} }
#if PORT static ITypeDefOrRef getNonGenericTypeReference(ITypeDefOrRef typeRef) {
static TypeReference getNonGenericTypeReference(TypeReference typeReference) { var ts = typeRef as TypeSpec;
if (typeReference == null) if (ts == null)
return null; return typeRef;
if (!typeReference.IsGenericInstance) var gis = ts.TypeSig.RemovePinnedAndModifiers() as GenericInstSig;
return typeReference; if (gis == null || gis.GenericType == null)
var type = (GenericInstanceType)typeReference; return typeRef;
return type.ElementType; return gis.GenericType.TypeDefOrRef;
} }
public TypeDef resolve(TypeReference type) { public TypeDef resolveType(ITypeDefOrRef type) {
if (type == null) if (type == null)
return null; return null;
var typeDef = getNonGenericTypeReference(type) as TypeDef; type = getNonGenericTypeReference(type);
var typeDef = type as TypeDef;
if (typeDef != null) if (typeDef != null)
return typeDef; return typeDef;
return externalAssemblies.resolve(type); var tr = type as TypeRef;
if (tr != null)
return tr.Resolve();
return null;
} }
public MethodDef resolve(MethodReference method) { public MethodDef resolveMethod(MemberRef method) {
if (method == null) if (method == null)
return null; return null;
var methodDef = method as MethodDef;
if (methodDef != null)
return methodDef;
var type = resolve(method.DeclaringType); var type = resolveType(method.DeclaringType);
if (type == null) if (type == null)
return null; return null;
foreach (var m in type.Methods) { return type.Resolve(method) as MethodDef;
if (MemberReferenceHelper.compareMethodReference(method, m))
return m;
}
return null;
} }
public FieldDef resolve(FieldReference field) { public FieldDef resolveField(MemberRef field) {
if (field == null) if (field == null)
return null; return null;
var fieldDef = field as FieldDef;
if (fieldDef != null)
return fieldDef;
var type = resolve(field.DeclaringType); var type = resolveType(field.DeclaringType);
if (type == null) if (type == null)
return null; return null;
foreach (var f in type.Fields) { return type.Resolve(field) as FieldDef;
if (MemberReferenceHelper.compareFieldReference(field, f))
return f;
}
return null;
} }
#endif
} }
} }

View File

@ -25,10 +25,8 @@ namespace de4dot.code {
void setData(string name, object data); void setData(string name, object data);
object getData(string name); object getData(string name);
void clearData(string name); void clearData(string name);
#if PORT TypeDef resolveType(ITypeDefOrRef type);
TypeDef resolve(TypeRef type); MethodDef resolveMethod(MemberRef method);
MethodDef resolve(IMethod method); FieldDef resolveField(MemberRef field);
FieldDef resolve(IField field);
#endif
} }
} }

View File

@ -273,20 +273,20 @@
<Compile Include="ObfuscatedFile.cs" /> <Compile Include="ObfuscatedFile.cs" />
<Compile Include="Option.cs" /> <Compile Include="Option.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<None Include="renamer\asmmodules\EventDef.cs" /> <Compile Include="renamer\asmmodules\EventDef.cs" />
<None Include="renamer\asmmodules\FieldDef.cs" /> <Compile Include="renamer\asmmodules\FieldDef.cs" />
<None Include="renamer\asmmodules\GenericParamDef.cs" /> <Compile Include="renamer\asmmodules\GenericParamDef.cs" />
<None Include="renamer\asmmodules\IResolver.cs" /> <Compile Include="renamer\asmmodules\IResolver.cs" />
<Compile Include="renamer\asmmodules\MemberRefFinder.cs" /> <Compile Include="renamer\asmmodules\MemberRefFinder.cs" />
<None Include="renamer\asmmodules\MethodDef.cs" /> <Compile Include="renamer\asmmodules\MethodDef.cs" />
<None Include="renamer\asmmodules\MethodNameGroups.cs" /> <Compile Include="renamer\asmmodules\MethodNameGroups.cs" />
<None Include="renamer\asmmodules\Module.cs" /> <Compile Include="renamer\asmmodules\Module.cs" />
<None Include="renamer\asmmodules\Modules.cs" /> <Compile Include="renamer\asmmodules\Modules.cs" />
<None Include="renamer\asmmodules\ParamDef.cs" /> <Compile Include="renamer\asmmodules\ParamDef.cs" />
<None Include="renamer\asmmodules\PropertyDef.cs" /> <Compile Include="renamer\asmmodules\PropertyDef.cs" />
<None Include="renamer\asmmodules\Ref.cs" /> <Compile Include="renamer\asmmodules\Ref.cs" />
<None Include="renamer\asmmodules\RefDict.cs" /> <Compile Include="renamer\asmmodules\RefDict.cs" />
<None Include="renamer\asmmodules\TypeDef.cs" /> <Compile Include="renamer\asmmodules\TypeDef.cs" />
<None Include="renamer\DerivedFrom.cs" /> <None Include="renamer\DerivedFrom.cs" />
<None Include="renamer\ExistingNames.cs" /> <None Include="renamer\ExistingNames.cs" />
<None Include="renamer\INameChecker.cs" /> <None Include="renamer\INameChecker.cs" />

View File

@ -21,7 +21,7 @@ using dot10.DotNet;
namespace de4dot.code.renamer.asmmodules { namespace de4dot.code.renamer.asmmodules {
interface IResolver { interface IResolver {
MTypeDef resolveType(TypeRef typeReference); MTypeDef resolveType(ITypeDefOrRef typeReference);
MMethodDef resolveMethod(MemberRef methodReference); MMethodDef resolveMethod(MemberRef methodReference);
MFieldDef resolveField(MemberRef fieldReference); MFieldDef resolveField(MemberRef fieldReference);
} }

View File

@ -401,38 +401,35 @@ namespace de4dot.code.renamer.asmmodules {
void add(IEnumerable<Instruction> instrs) { void add(IEnumerable<Instruction> instrs) {
if (instrs == null) if (instrs == null)
return; return;
foreach (var instr in instrs) foreach (var instr in instrs) {
add(instr); if (instr == null)
} continue;
switch (instr.OpCode.OperandType) {
case OperandType.InlineTok:
case OperandType.InlineType:
case OperandType.InlineMethod:
case OperandType.InlineField:
push(instr.Operand);
break;
void add(Instruction instr) { case OperandType.InlineSig:
if (instr == null) add(instr.Operand as CallingConventionSig);
return; break;
switch (instr.OpCode.OperandType) {
case OperandType.InlineTok:
case OperandType.InlineType:
case OperandType.InlineMethod:
case OperandType.InlineField:
push(instr.Operand);
break;
case OperandType.InlineSig: case OperandType.InlineVar:
add(instr.Operand as CallingConventionSig); case OperandType.ShortInlineVar:
break; var local = instr.Operand as Local;
if (local != null) {
case OperandType.InlineVar: add(local);
case OperandType.ShortInlineVar: break;
var local = instr.Operand as Local; }
if (local != null) { var arg = instr.Operand as Parameter;
add(local); if (arg != null) {
add(arg);
break;
}
break; break;
} }
var arg = instr.Operand as Parameter;
if (arg != null) {
add(arg);
break;
}
break;
} }
} }

View File

@ -20,6 +20,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.MD;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.renamer.asmmodules { namespace de4dot.code.renamer.asmmodules {
@ -27,9 +28,9 @@ namespace de4dot.code.renamer.asmmodules {
IObfuscatedFile obfuscatedFile; IObfuscatedFile obfuscatedFile;
TypeDefDict types = new TypeDefDict(); TypeDefDict types = new TypeDefDict();
MemberRefFinder memberRefFinder; MemberRefFinder memberRefFinder;
IList<RefToDef<TypeReference, TypeDef>> typeRefsToRename = new List<RefToDef<TypeReference, TypeDef>>(); IList<RefToDef<TypeRef, TypeDef>> typeRefsToRename = new List<RefToDef<TypeRef, TypeDef>>();
IList<RefToDef<MethodReference, MethodDef>> methodRefsToRename = new List<RefToDef<MethodReference, MethodDef>>(); IList<RefToDef<MemberRef, MethodDef>> methodRefsToRename = new List<RefToDef<MemberRef, MethodDef>>();
IList<RefToDef<FieldReference, FieldDef>> fieldRefsToRename = new List<RefToDef<FieldReference, FieldDef>>(); IList<RefToDef<MemberRef, FieldDef>> fieldRefsToRename = new List<RefToDef<MemberRef, FieldDef>>();
List<CustomAttributeReference> customAttributeFieldReferences = new List<CustomAttributeReference>(); List<CustomAttributeReference> customAttributeFieldReferences = new List<CustomAttributeReference>();
List<CustomAttributeReference> customAttributePropertyReferences = new List<CustomAttributeReference>(); List<CustomAttributeReference> customAttributePropertyReferences = new List<CustomAttributeReference>();
List<MethodDef> allMethods; List<MethodDef> allMethods;
@ -37,15 +38,15 @@ namespace de4dot.code.renamer.asmmodules {
public class CustomAttributeReference { public class CustomAttributeReference {
public CustomAttribute cattr; public CustomAttribute cattr;
public int index; public int index;
public MemberReference reference; public IMemberRef reference;
public CustomAttributeReference(CustomAttribute cattr, int index, MemberReference reference) { public CustomAttributeReference(CustomAttribute cattr, int index, IMemberRef reference) {
this.cattr = cattr; this.cattr = cattr;
this.index = index; this.index = index;
this.reference = reference; this.reference = reference;
} }
} }
public class RefToDef<R, D> where R : MemberReference where D : R { public class RefToDef<R, D> where R : ICodedToken where D : ICodedToken {
public R reference; public R reference;
public D definition; public D definition;
public RefToDef(R reference, D definition) { public RefToDef(R reference, D definition) {
@ -54,15 +55,15 @@ namespace de4dot.code.renamer.asmmodules {
} }
} }
public IEnumerable<RefToDef<TypeReference, TypeDef>> TypeRefsToRename { public IEnumerable<RefToDef<TypeRef, TypeDef>> TypeRefsToRename {
get { return typeRefsToRename; } get { return typeRefsToRename; }
} }
public IEnumerable<RefToDef<MethodReference, MethodDef>> MethodRefsToRename { public IEnumerable<RefToDef<MemberRef, MethodDef>> MethodRefsToRename {
get { return methodRefsToRename; } get { return methodRefsToRename; }
} }
public IEnumerable<RefToDef<FieldReference, FieldDef>> FieldRefsToRename { public IEnumerable<RefToDef<MemberRef, FieldDef>> FieldRefsToRename {
get { return fieldRefsToRename; } get { return fieldRefsToRename; }
} }
@ -100,11 +101,11 @@ namespace de4dot.code.renamer.asmmodules {
public void findAllMemberReferences(ref int typeIndex) { public void findAllMemberReferences(ref int typeIndex) {
memberRefFinder = new MemberRefFinder(); memberRefFinder = new MemberRefFinder();
memberRefFinder.findAll(ModuleDefMD, ModuleDefMD.Types); memberRefFinder.findAll(ModuleDefMD);
allMethods = new List<MethodDef>(memberRefFinder.methodDefinitions.Keys); allMethods = new List<MethodDef>(memberRefFinder.methodDefs.Keys);
var allTypesList = new List<MTypeDef>(); var allTypesList = new List<MTypeDef>();
foreach (var type in memberRefFinder.typeDefinitions.Keys) { foreach (var type in memberRefFinder.typeDefs.Keys) {
var typeDef = new MTypeDef(type, this, typeIndex++); var typeDef = new MTypeDef(type, this, typeIndex++);
types.add(typeDef); types.add(typeDef);
allTypesList.Add(typeDef); allTypesList.Add(typeDef);
@ -131,36 +132,37 @@ namespace de4dot.code.renamer.asmmodules {
} }
public void resolveAllRefs(IResolver resolver) { public void resolveAllRefs(IResolver resolver) {
foreach (var typeRef in memberRefFinder.typeReferences.Keys) { foreach (var typeRef in memberRefFinder.typeRefs.Keys) {
var typeDef = resolver.resolveType(typeRef); var typeDef = resolver.resolveType(typeRef);
if (typeDef != null) if (typeDef != null)
typeRefsToRename.Add(new RefToDef<TypeReference, TypeDef>(typeRef, typeDef.TypeDef)); typeRefsToRename.Add(new RefToDef<TypeRef, TypeDef>(typeRef, typeDef.TypeDef));
} }
foreach (var methodRef in memberRefFinder.methodReferences.Keys) { foreach (var memberRef in memberRefFinder.memberRefs.Keys) {
var methodDef = resolver.resolveMethod(methodRef); if (memberRef.IsMethodRef) {
if (methodDef != null) var methodDef = resolver.resolveMethod(memberRef);
methodRefsToRename.Add(new RefToDef<MethodReference, MethodDef>(methodRef, methodDef.MethodDef)); if (methodDef != null)
} methodRefsToRename.Add(new RefToDef<MemberRef, MethodDef>(memberRef, methodDef.MethodDef));
}
foreach (var fieldRef in memberRefFinder.fieldReferences.Keys) { else if (memberRef.IsFieldRef) {
var fieldDef = resolver.resolveField(fieldRef); var fieldDef = resolver.resolveField(memberRef);
if (fieldDef != null) if (fieldDef != null)
fieldRefsToRename.Add(new RefToDef<FieldReference, FieldDef>(fieldRef, fieldDef.FieldDef)); fieldRefsToRename.Add(new RefToDef<MemberRef, FieldDef>(memberRef, fieldDef.FieldDef));
}
} }
foreach (var cattr in memberRefFinder.customAttributes.Keys) { foreach (var cattr in memberRefFinder.customAttributes.Keys) {
try { var typeDef = resolver.resolveType(cattr.AttributeType);
var typeDef = resolver.resolveType(cattr.AttributeType); if (typeDef == null)
if (typeDef == null) continue;
continue;
for (int i = 0; i < cattr.Fields.Count; i++) { for (int i = 0; i < cattr.NamedArguments.Count; i++) {
var field = cattr.Fields[i]; var namedArg = cattr.NamedArguments[i];
var fieldDef = findFieldByName(typeDef, field.Name); if (namedArg.IsField) {
var fieldDef = findField(typeDef, namedArg.Name, namedArg.Type);
if (fieldDef == null) { if (fieldDef == null) {
Log.w("Could not find field {0} in attribute {1} ({2:X8})", Log.w("Could not find field {0} in attribute {1} ({2:X8})",
Utils.toCsharpString(field.Name), Utils.toCsharpString(namedArg.Name),
Utils.toCsharpString(typeDef.TypeDef.Name), Utils.toCsharpString(typeDef.TypeDef.Name),
typeDef.TypeDef.MDToken.ToInt32()); typeDef.TypeDef.MDToken.ToInt32());
continue; continue;
@ -168,13 +170,11 @@ namespace de4dot.code.renamer.asmmodules {
customAttributeFieldReferences.Add(new CustomAttributeReference(cattr, i, fieldDef.FieldDef)); customAttributeFieldReferences.Add(new CustomAttributeReference(cattr, i, fieldDef.FieldDef));
} }
else {
for (int i = 0; i < cattr.Properties.Count; i++) { var propDef = findProperty(typeDef, namedArg.Name, namedArg.Type);
var prop = cattr.Properties[i];
var propDef = findPropertyByName(typeDef, prop.Name);
if (propDef == null) { if (propDef == null) {
Log.w("Could not find property {0} in attribute {1} ({2:X8})", Log.w("Could not find property {0} in attribute {1} ({2:X8})",
Utils.toCsharpString(prop.Name), Utils.toCsharpString(namedArg.Name),
Utils.toCsharpString(typeDef.TypeDef.Name), Utils.toCsharpString(typeDef.TypeDef.Name),
typeDef.TypeDef.MDToken.ToInt32()); typeDef.TypeDef.MDToken.ToInt32());
continue; continue;
@ -183,15 +183,15 @@ namespace de4dot.code.renamer.asmmodules {
customAttributePropertyReferences.Add(new CustomAttributeReference(cattr, i, propDef.PropertyDef)); customAttributePropertyReferences.Add(new CustomAttributeReference(cattr, i, propDef.PropertyDef));
} }
} }
catch {
}
} }
} }
static MFieldDef findFieldByName(MTypeDef typeDef, string name) { static MFieldDef findField(MTypeDef typeDef, UTF8String name, TypeSig fieldType) {
while (typeDef != null) { while (typeDef != null) {
foreach (var fieldDef in typeDef.AllFields) { foreach (var fieldDef in typeDef.AllFields) {
if (fieldDef.FieldDef.Name == name) if (fieldDef.FieldDef.Name != name)
continue;
if (new SigComparer().Equals(fieldDef.FieldDef.FieldSig.Type, fieldType))
return fieldDef; return fieldDef;
} }
@ -202,10 +202,12 @@ namespace de4dot.code.renamer.asmmodules {
return null; return null;
} }
static MPropertyDef findPropertyByName(MTypeDef typeDef, string name) { static MPropertyDef findProperty(MTypeDef typeDef, UTF8String name, TypeSig propType) {
while (typeDef != null) { while (typeDef != null) {
foreach (var propDef in typeDef.AllProperties) { foreach (var propDef in typeDef.AllProperties) {
if (propDef.PropertyDef.Name == name) if (propDef.PropertyDef.Name != name)
continue;
if (new SigComparer().Equals(propDef.PropertyDef.PropertySig.RetType, propType))
return propDef; return propDef;
} }
@ -225,31 +227,32 @@ namespace de4dot.code.renamer.asmmodules {
types = newTypes; types = newTypes;
} }
static TypeReference getNonGenericTypeReference(TypeReference typeReference) { static ITypeDefOrRef getNonGenericTypeReference(ITypeDefOrRef typeRef) {
if (typeReference == null) var ts = typeRef as TypeSpec;
return null; if (ts == null)
if (!typeReference.IsGenericInstance) return typeRef;
return typeReference; var gis = ts.TypeSig.RemovePinnedAndModifiers() as GenericInstSig;
var type = (GenericInstanceType)typeReference; if (gis == null || gis.GenericType == null)
return type.ElementType; return typeRef;
return gis.GenericType.TypeDefOrRef;
} }
public MTypeDef resolveType(TypeReference typeReference) { public MTypeDef resolveType(ITypeDefOrRef typeReference) {
return this.types.find(getNonGenericTypeReference(typeReference)); return this.types.find(getNonGenericTypeReference(typeReference));
} }
public MMethodDef resolveMethod(MethodReference methodReference) { public MMethodDef resolveMethod(MemberRef methodRef) {
var typeDef = this.types.find(getNonGenericTypeReference(methodReference.DeclaringType)); var typeDef = this.types.find(getNonGenericTypeReference(methodRef.DeclaringType));
if (typeDef == null) if (typeDef == null)
return null; return null;
return typeDef.find(methodReference); return typeDef.findMethod(methodRef);
} }
public MFieldDef resolveField(FieldReference fieldReference) { public MFieldDef resolveField(MemberRef fieldRef) {
var typeDef = this.types.find(getNonGenericTypeReference(fieldReference.DeclaringType)); var typeDef = this.types.find(getNonGenericTypeReference(fieldRef.DeclaringType));
if (typeDef == null) if (typeDef == null)
return null; return null;
return typeDef.find(fieldReference); return typeDef.findField(fieldRef);
} }
} }
} }

View File

@ -62,9 +62,9 @@ namespace de4dot.code.renamer.asmmodules {
} }
string getModuleKey(Module module) { string getModuleKey(Module module) {
if (module.ModuleDef.Assembly != null) if (module.ModuleDefMD.Assembly != null)
return module.ModuleDef.Assembly.ToString(); return module.ModuleDefMD.Assembly.ToString();
return Utils.getBaseName(module.ModuleDef.FullyQualifiedName); return Utils.getBaseName(module.ModuleDefMD.Location);
} }
public ModuleHash lookup(string assemblyName) { public ModuleHash lookup(string assemblyName) {
@ -80,16 +80,16 @@ namespace de4dot.code.renamer.asmmodules {
Module mainModule = null; Module mainModule = null;
public void add(Module module) { public void add(Module module) {
var asm = module.ModuleDef.Assembly; var asm = module.ModuleDefMD.Assembly;
if (asm != null && ReferenceEquals(asm.MainModule, module.ModuleDef)) { if (asm != null && ReferenceEquals(asm.ManifestModule, module.ModuleDefMD)) {
if (mainModule != null) { if (mainModule != null) {
throw new UserException(string.Format( throw new UserException(string.Format(
"Two modules in the same assembly are main modules.\n" + "Two modules in the same assembly are main modules.\n" +
"Is one 32-bit and the other 64-bit?\n" + "Is one 32-bit and the other 64-bit?\n" +
" Module1: \"{0}\"" + " Module1: \"{0}\"" +
" Module2: \"{1}\"", " Module2: \"{1}\"",
module.ModuleDef.FullyQualifiedName, module.ModuleDefMD.Location,
mainModule.ModuleDef.FullyQualifiedName)); mainModule.ModuleDefMD.Location));
} }
mainModule = module; mainModule = module;
} }
@ -110,7 +110,7 @@ namespace de4dot.code.renamer.asmmodules {
IDictionary<string, Module> modulesDict = new Dictionary<string, Module>(StringComparer.Ordinal); IDictionary<string, Module> modulesDict = new Dictionary<string, Module>(StringComparer.Ordinal);
public void add(Module module) { public void add(Module module) {
var moduleName = module.ModuleDef.Name; var moduleName = module.ModuleDefMD.Name.String;
if (lookup(moduleName) != null) if (lookup(moduleName) != null)
throw new ApplicationException(string.Format("Module \"{0}\" was found twice", moduleName)); throw new ApplicationException(string.Format("Module \"{0}\" was found twice", moduleName));
modulesDict[moduleName] = module; modulesDict[moduleName] = module;
@ -140,9 +140,9 @@ namespace de4dot.code.renamer.asmmodules {
if (initializeCalled) if (initializeCalled)
throw new ApplicationException("initialize() has been called"); throw new ApplicationException("initialize() has been called");
Module otherModule; Module otherModule;
if (modulesDict.TryGetValue(module.ModuleDef, out otherModule)) if (modulesDict.TryGetValue(module.ModuleDefMD, out otherModule))
return; return;
modulesDict[module.ModuleDef] = module; modulesDict[module.ModuleDefMD] = module;
modules.Add(module); modules.Add(module);
assemblyHash.add(module); assemblyHash.add(module);
} }
@ -205,12 +205,10 @@ namespace de4dot.code.renamer.asmmodules {
// Initialize interfaces // Initialize interfaces
foreach (var typeDef in allTypes) { foreach (var typeDef in allTypes) {
if (typeDef.TypeDef.Interfaces == null) foreach (var iface in typeDef.TypeDef.InterfaceImpls) {
continue; var ifaceTypeDef = resolveType(iface.Interface) ?? resolveOther(iface.Interface);
foreach (var iface in typeDef.TypeDef.Interfaces) {
var ifaceTypeDef = resolveType(iface) ?? resolveOther(iface);
if (ifaceTypeDef != null) if (ifaceTypeDef != null)
typeDef.addInterface(ifaceTypeDef, iface); typeDef.addInterface(ifaceTypeDef, iface.Interface);
} }
} }
@ -231,10 +229,10 @@ namespace de4dot.code.renamer.asmmodules {
} }
class AssemblyKeyDictionary<T> where T : class { class AssemblyKeyDictionary<T> where T : class {
Dictionary<TypeReferenceSameVersionKey, T> dict = new Dictionary<TypeReferenceSameVersionKey, T>(); Dictionary<ITypeDefOrRef, T> dict = new Dictionary<ITypeDefOrRef, T>(new TypeEqualityComparer(SigComparerOptions.CompareAssemblyVersion));
Dictionary<TypeReferenceKey, List<TypeReference>> refs = new Dictionary<TypeReferenceKey, List<TypeReference>>(); Dictionary<ITypeDefOrRef, List<ITypeDefOrRef>> refs = new Dictionary<ITypeDefOrRef, List<ITypeDefOrRef>>(TypeEqualityComparer.Instance);
public T this[TypeReference type] { public T this[ITypeDefOrRef type] {
get { get {
T value; T value;
if (tryGetValue(type, out value)) if (tryGetValue(type, out value))
@ -242,39 +240,35 @@ namespace de4dot.code.renamer.asmmodules {
throw new KeyNotFoundException(); throw new KeyNotFoundException();
} }
set { set {
var key = new TypeReferenceSameVersionKey(type); dict[type] = value;
dict[key] = value;
if (value != null) { if (value != null) {
var key2 = new TypeReferenceKey(type); List<ITypeDefOrRef> list;
List<TypeReference> list; if (!refs.TryGetValue(type, out list))
if (!refs.TryGetValue(key2, out list)) refs[type] = list = new List<ITypeDefOrRef>();
refs[key2] = list = new List<TypeReference>();
list.Add(type); list.Add(type);
} }
} }
} }
public bool tryGetValue(TypeReference type, out T value) { public bool tryGetValue(ITypeDefOrRef type, out T value) {
return dict.TryGetValue(new TypeReferenceSameVersionKey(type), out value); return dict.TryGetValue(type, out value);
} }
public bool tryGetSimilarValue(TypeReference type, out T value) { public bool tryGetSimilarValue(ITypeDefOrRef type, out T value) {
var key2 = new TypeReferenceKey(type); List<ITypeDefOrRef> list;
List<TypeReference> list; if (!refs.TryGetValue(type, out list)) {
if (!refs.TryGetValue(key2, out list)) {
value = default(T); value = default(T);
return false; return false;
} }
// Find a type whose version is >= type's version and closest to it. // Find a type whose version is >= type's version and closest to it.
TypeReference foundType = null; ITypeDefOrRef foundType = null;
var typeAsmName = MemberReferenceHelper.getAssemblyNameReference(type.Scope); var typeAsmName = type.DefinitionAssembly;
AssemblyNameReference foundAsmName = null; IAssembly foundAsmName = null;
foreach (var otherRef in list) { foreach (var otherRef in list) {
var key = new TypeReferenceSameVersionKey(otherRef); if (!dict.TryGetValue(otherRef, out value))
if (!dict.TryGetValue(key, out value))
continue; continue;
if (typeAsmName == null) { if (typeAsmName == null) {
@ -282,11 +276,11 @@ namespace de4dot.code.renamer.asmmodules {
break; break;
} }
var otherAsmName = MemberReferenceHelper.getAssemblyNameReference(otherRef.Scope); var otherAsmName = otherRef.DefinitionAssembly;
if (otherAsmName == null) if (otherAsmName == null)
continue; continue;
// Check pkt or we could return a type in eg. a SL assembly when it's not a SL app. // Check pkt or we could return a type in eg. a SL assembly when it's not a SL app.
if (!same(typeAsmName.PublicKeyToken, otherAsmName.PublicKeyToken)) if (!PublicKeyBase.TokenEquals(typeAsmName.PublicKeyOrToken, otherAsmName.PublicKeyOrToken))
continue; continue;
if (typeAsmName.Version > otherAsmName.Version) if (typeAsmName.Version > otherAsmName.Version)
continue; // old version continue; // old version
@ -304,40 +298,28 @@ namespace de4dot.code.renamer.asmmodules {
} }
if (foundType != null) { if (foundType != null) {
value = dict[new TypeReferenceSameVersionKey(foundType)]; value = dict[foundType];
return true; return true;
} }
value = default(T); value = default(T);
return false; return false;
} }
bool same(byte[] a, byte[] b) {
if (ReferenceEquals(a, b))
return true;
if (a == null || b == null)
return false;
if (a.Length != b.Length)
return false;
for (int i = 0; i < a.Length; i++) {
if (a[i] != b[i])
return false;
}
return true;
}
} }
AssemblyKeyDictionary<MTypeDef> typeToTypeDefDict = new AssemblyKeyDictionary<MTypeDef>(); AssemblyKeyDictionary<MTypeDef> typeToTypeDefDict = new AssemblyKeyDictionary<MTypeDef>();
public MTypeDef resolveOther(TypeReference type) { public MTypeDef resolveOther(ITypeDefOrRef type) {
if (type == null)
return null;
type = type.ScopeType;
if (type == null) if (type == null)
return null; return null;
type = type.GetElementType();
MTypeDef typeDef; MTypeDef typeDef;
if (typeToTypeDefDict.tryGetValue(type, out typeDef)) if (typeToTypeDefDict.tryGetValue(type, out typeDef))
return typeDef; return typeDef;
var typeDefinition = deobfuscatorContext.resolve(type); var typeDefinition = deobfuscatorContext.resolveType(type);
if (typeDefinition == null) { if (typeDefinition == null) {
typeToTypeDefDict.tryGetSimilarValue(type, out typeDef); typeToTypeDefDict.tryGetSimilarValue(type, out typeDef);
typeToTypeDefDict[type] = typeDef; typeToTypeDefDict[type] = typeDef;
@ -354,11 +336,11 @@ namespace de4dot.code.renamer.asmmodules {
typeDef = new MTypeDef(typeDefinition, null, 0); typeDef = new MTypeDef(typeDefinition, null, 0);
typeDef.addMembers(); typeDef.addMembers();
foreach (var iface in typeDef.TypeDef.Interfaces) { foreach (var iface in typeDef.TypeDef.InterfaceImpls) {
var ifaceDef = resolveOther(iface); var ifaceDef = resolveOther(iface.Interface);
if (ifaceDef == null) if (ifaceDef == null)
continue; continue;
typeDef.addInterface(ifaceDef, iface); typeDef.addInterface(ifaceDef, iface.Interface);
} }
var baseDef = resolveOther(typeDef.TypeDef.BaseType); var baseDef = resolveOther(typeDef.TypeDef.BaseType);
if (baseDef != null) if (baseDef != null)
@ -383,40 +365,42 @@ namespace de4dot.code.renamer.asmmodules {
} }
public void cleanUp() { public void cleanUp() {
#if PORT
foreach (var module in DotNetUtils.typeCaches.invalidateAll()) foreach (var module in DotNetUtils.typeCaches.invalidateAll())
AssemblyResolver.Instance.removeModule(module); AssemblyResolver.Instance.removeModule(module);
#endif
} }
// Returns null if it's a non-loaded module/assembly // Returns null if it's a non-loaded module/assembly
IEnumerable<Module> findModules(TypeReference type) { IEnumerable<Module> findModules(ITypeDefOrRef type) {
var scope = type.Scope; var scope = type.Scope;
if (scope == null) if (scope == null)
return null; return null;
if (scope is AssemblyNameReference) if (scope.ScopeType == ScopeType.AssemblyRef)
return findModules((AssemblyNameReference)scope); return findModules((AssemblyRef)scope);
if (scope is ModuleDef) { if (scope.ScopeType == ScopeType.ModuleDef) {
var modules = findModules((ModuleDef)scope); var modules = findModules((ModuleDef)scope);
if (modules != null) if (modules != null)
return modules; return modules;
} }
if (scope is ModuleReference) { if (scope.ScopeType == ScopeType.ModuleRef) {
var moduleReference = (ModuleReference)scope; var moduleRef = (ModuleRef)scope;
if (moduleReference.Name == type.Module.Name) { if (moduleRef.Name == type.OwnerModule.Name) {
var modules = findModules(type.Module); var modules = findModules(type.OwnerModule);
if (modules != null) if (modules != null)
return modules; return modules;
} }
var asm = type.Module.Assembly; var asm = type.OwnerModule.Assembly;
if (asm == null) if (asm == null)
return null; return null;
var moduleHash = assemblyHash.lookup(asm.ToString()); var moduleHash = assemblyHash.lookup(asm.FullName);
if (moduleHash == null) if (moduleHash == null)
return null; return null;
var module = moduleHash.lookup(moduleReference.Name); var module = moduleHash.lookup(moduleRef.Name.String);
if (module == null) if (module == null)
return null; return null;
return new List<Module> { module }; return new List<Module> { module };
@ -425,65 +409,71 @@ namespace de4dot.code.renamer.asmmodules {
throw new ApplicationException(string.Format("scope is an unsupported type: {0}", scope.GetType())); throw new ApplicationException(string.Format("scope is an unsupported type: {0}", scope.GetType()));
} }
IEnumerable<Module> findModules(AssemblyNameReference assemblyRef) { IEnumerable<Module> findModules(AssemblyRef assemblyRef) {
var moduleHash = assemblyHash.lookup(assemblyRef.ToString()); var moduleHash = assemblyHash.lookup(assemblyRef.FullName);
if (moduleHash != null) if (moduleHash != null)
return moduleHash.Modules; return moduleHash.Modules;
return null; return null;
} }
IEnumerable<Module> findModules(ModuleDef moduleDefinition) { IEnumerable<Module> findModules(ModuleDef moduleDef) {
Module module; Module module;
if (modulesDict.TryGetValue(moduleDefinition, out module)) if (modulesDict.TryGetValue(moduleDef, out module))
return new List<Module> { module }; return new List<Module> { module };
return null; return null;
} }
bool isAutoCreatedType(TypeReference typeReference) { bool isAutoCreatedType(ITypeDefOrRef typeRef) {
return typeReference is ArrayType || typeReference is PointerType || typeReference is FunctionPointerType; var ts = typeRef as TypeSpec;
if (ts == null)
return false;
var sig = ts.TypeSig;
if (sig == null)
return false;
return sig.IsSZArray || sig.IsArray || sig.IsPointer;
} }
public MTypeDef resolveType(TypeReference typeReference) { public MTypeDef resolveType(ITypeDefOrRef typeRef) {
var modules = findModules(typeReference); var modules = findModules(typeRef);
if (modules == null) if (modules == null)
return null; return null;
foreach (var module in modules) { foreach (var module in modules) {
var rv = module.resolveType(typeReference); var rv = module.resolveType(typeRef);
if (rv != null) if (rv != null)
return rv; return rv;
} }
if (isAutoCreatedType(typeReference)) if (isAutoCreatedType(typeRef))
return null; return null;
Log.e("Could not resolve TypeReference {0} ({1:X8}) (from {2} -> {3})", Log.e("Could not resolve TypeReference {0} ({1:X8}) (from {2} -> {3})",
Utils.removeNewlines(typeReference), Utils.removeNewlines(typeRef),
typeReference.MDToken.ToInt32(), typeRef.MDToken.ToInt32(),
typeReference.Module, typeRef.OwnerModule,
typeReference.Scope); typeRef.Scope);
return null; return null;
} }
public MMethodDef resolveMethod(MethodReference methodReference) { public MMethodDef resolveMethod(MemberRef methodRef) {
if (methodReference.DeclaringType == null) if (methodRef.DeclaringType == null)
return null; return null;
var modules = findModules(methodReference.DeclaringType); var modules = findModules(methodRef.DeclaringType);
if (modules == null) if (modules == null)
return null; return null;
foreach (var module in modules) { foreach (var module in modules) {
var rv = module.resolveMethod(methodReference); var rv = module.resolveMethod(methodRef);
if (rv != null) if (rv != null)
return rv; return rv;
} }
if (isAutoCreatedType(methodReference.DeclaringType)) if (isAutoCreatedType(methodRef.DeclaringType))
return null; return null;
Log.e("Could not resolve MethodReference {0} ({1:X8}) (from {2} -> {3})", Log.e("Could not resolve MethodReference {0} ({1:X8}) (from {2} -> {3})",
Utils.removeNewlines(methodReference), Utils.removeNewlines(methodRef),
methodReference.MDToken.ToInt32(), methodRef.MDToken.ToInt32(),
methodReference.DeclaringType.Module, methodRef.DeclaringType.OwnerModule,
methodReference.DeclaringType.Scope); methodRef.DeclaringType.Scope);
return null; return null;
} }
public MFieldDef resolveField(FieldReference fieldReference) { public MFieldDef resolveField(MemberRef fieldReference) {
if (fieldReference.DeclaringType == null) if (fieldReference.DeclaringType == null)
return null; return null;
var modules = findModules(fieldReference.DeclaringType); var modules = findModules(fieldReference.DeclaringType);
@ -499,7 +489,7 @@ namespace de4dot.code.renamer.asmmodules {
Log.e("Could not resolve FieldReference {0} ({1:X8}) (from {2} -> {3})", Log.e("Could not resolve FieldReference {0} ({1:X8}) (from {2} -> {3})",
Utils.removeNewlines(fieldReference), Utils.removeNewlines(fieldReference),
fieldReference.MDToken.ToInt32(), fieldReference.MDToken.ToInt32(),
fieldReference.DeclaringType.Module, fieldReference.DeclaringType.OwnerModule,
fieldReference.DeclaringType.Scope); fieldReference.DeclaringType.Scope);
return null; return null;
} }

View File

@ -23,22 +23,36 @@ using dot10.DotNet;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.renamer.asmmodules { namespace de4dot.code.renamer.asmmodules {
//TODO:
class TypeReferenceInstance {
public static TypeRef make(ITypeDefOrRef type, GenericInstSig git) {
return null;
}
}
//TODO:
class MethodReferenceInstance {
public static MemberRef make(IMethod method, GenericInstSig git) {
return null;
}
}
class TypeInfo { class TypeInfo {
public TypeReference typeReference; public ITypeDefOrRef typeReference;
public MTypeDef typeDef; public MTypeDef typeDef;
public TypeInfo(TypeReference typeReference, MTypeDef typeDef) { public TypeInfo(ITypeDefOrRef typeReference, MTypeDef typeDef) {
this.typeReference = typeReference; this.typeReference = typeReference;
this.typeDef = typeDef; this.typeDef = typeDef;
} }
public TypeInfo(TypeInfo other, GenericInstanceType git) { public TypeInfo(TypeInfo other, GenericInstSig git) {
this.typeReference = TypeReferenceInstance.make(other.typeReference, git); this.typeReference = TypeReferenceInstance.make(other.typeReference, git);
this.typeDef = other.typeDef; this.typeDef = other.typeDef;
} }
public override int GetHashCode() { public override int GetHashCode() {
return typeDef.GetHashCode() + return typeDef.GetHashCode() +
MemberReferenceHelper.typeHashCode(typeReference); new SigComparer().GetHashCode(typeReference);
} }
public override bool Equals(object obj) { public override bool Equals(object obj) {
@ -46,7 +60,7 @@ namespace de4dot.code.renamer.asmmodules {
if (other == null) if (other == null)
return false; return false;
return typeDef == other.typeDef && return typeDef == other.typeDef &&
MemberReferenceHelper.compareTypes(typeReference, other.typeReference); new SigComparer().Equals(typeReference, other.typeReference);
} }
public override string ToString() { public override string ToString() {
@ -62,14 +76,14 @@ namespace de4dot.code.renamer.asmmodules {
} }
public override int GetHashCode() { public override int GetHashCode() {
return MemberReferenceHelper.methodReferenceAndDeclaringTypeHashCode(methodDef.MethodDef); return MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(methodDef.MethodDef);
} }
public override bool Equals(object obj) { public override bool Equals(object obj) {
var other = obj as MethodDefKey; var other = obj as MethodDefKey;
if (other == null) if (other == null)
return false; return false;
return MemberReferenceHelper.compareMethodReferenceAndDeclaringType(methodDef.MethodDef, other.methodDef.MethodDef); return MethodEqualityComparer.CompareDeclaringTypes.Equals(methodDef.MethodDef, other.methodDef.MethodDef);
} }
} }
@ -88,12 +102,12 @@ namespace de4dot.code.renamer.asmmodules {
} }
class MethodInstances { class MethodInstances {
Dictionary<MethodReferenceKey, List<MethodInst>> methodInstances = new Dictionary<MethodReferenceKey, List<MethodInst>>(); Dictionary<IMethod, List<MethodInst>> methodInstances = new Dictionary<IMethod, List<MethodInst>>(MethodEqualityComparer.DontCompareDeclaringTypes);
public void initializeFrom(MethodInstances other, GenericInstanceType git) { public void initializeFrom(MethodInstances other, GenericInstSig git) {
foreach (var list in other.methodInstances.Values) { foreach (var list in other.methodInstances.Values) {
foreach (var methodInst in list) { foreach (var methodInst in list) {
MethodReference newMethod = MethodReferenceInstance.make(methodInst.methodReference, git); MemberRef newMethod = MethodReferenceInstance.make(methodInst.methodReference, git);
add(new MethodInst(methodInst.origMethodDef, newMethod)); add(new MethodInst(methodInst.origMethodDef, newMethod));
} }
} }
@ -101,15 +115,15 @@ namespace de4dot.code.renamer.asmmodules {
public void add(MethodInst methodInst) { public void add(MethodInst methodInst) {
List<MethodInst> list; List<MethodInst> list;
var key = new MethodReferenceKey(methodInst.methodReference); var key = methodInst.methodReference;
if (methodInst.origMethodDef.isNewSlot() || !methodInstances.TryGetValue(key, out list)) if (methodInst.origMethodDef.isNewSlot() || !methodInstances.TryGetValue(key, out list))
methodInstances[key] = list = new List<MethodInst>(); methodInstances[key] = list = new List<MethodInst>();
list.Add(methodInst); list.Add(methodInst);
} }
public List<MethodInst> lookup(MethodReference methodReference) { public List<MethodInst> lookup(IMethod methodReference) {
List<MethodInst> list; List<MethodInst> list;
methodInstances.TryGetValue(new MethodReferenceKey(methodReference), out list); methodInstances.TryGetValue(methodReference, out list);
return list; return list;
} }
@ -176,18 +190,18 @@ namespace de4dot.code.renamer.asmmodules {
} }
class InterfaceMethodInfos { class InterfaceMethodInfos {
Dictionary<TypeReferenceKey, InterfaceMethodInfo> interfaceMethods = new Dictionary<TypeReferenceKey, InterfaceMethodInfo>(); Dictionary<ITypeDefOrRef, InterfaceMethodInfo> interfaceMethods = new Dictionary<ITypeDefOrRef, InterfaceMethodInfo>(TypeEqualityComparer.Instance);
public IEnumerable<InterfaceMethodInfo> AllInfos { public IEnumerable<InterfaceMethodInfo> AllInfos {
get { return interfaceMethods.Values; } get { return interfaceMethods.Values; }
} }
public void initializeFrom(InterfaceMethodInfos other, GenericInstanceType git) { public void initializeFrom(InterfaceMethodInfos other, GenericInstSig git) {
foreach (var pair in other.interfaceMethods) { foreach (var pair in other.interfaceMethods) {
var oldTypeInfo = pair.Value.IFace; var oldTypeInfo = pair.Value.IFace;
var newTypeInfo = new TypeInfo(oldTypeInfo, git); var newTypeInfo = new TypeInfo(oldTypeInfo, git);
var oldKey = new TypeReferenceKey(oldTypeInfo.typeReference); var oldKey = oldTypeInfo.typeReference;
var newKey = new TypeReferenceKey(newTypeInfo.typeReference); var newKey = newTypeInfo.typeReference;
InterfaceMethodInfo newMethodsInfo = new InterfaceMethodInfo(newTypeInfo, other.interfaceMethods[oldKey]); InterfaceMethodInfo newMethodsInfo = new InterfaceMethodInfo(newTypeInfo, other.interfaceMethods[oldKey]);
if (interfaceMethods.ContainsKey(newKey)) if (interfaceMethods.ContainsKey(newKey))
@ -197,7 +211,7 @@ namespace de4dot.code.renamer.asmmodules {
} }
public void addInterface(TypeInfo iface) { public void addInterface(TypeInfo iface) {
var key = new TypeReferenceKey(iface.typeReference); var key = iface.typeReference;
if (!interfaceMethods.ContainsKey(key)) if (!interfaceMethods.ContainsKey(key))
interfaceMethods[key] = new InterfaceMethodInfo(iface); interfaceMethods[key] = new InterfaceMethodInfo(iface);
} }
@ -208,18 +222,16 @@ namespace de4dot.code.renamer.asmmodules {
} }
// Returns the previous classMethod, or null if none // Returns the previous classMethod, or null if none
public MMethodDef addMethod(TypeReference iface, MMethodDef ifaceMethod, MMethodDef classMethod) { public MMethodDef addMethod(ITypeDefOrRef iface, MMethodDef ifaceMethod, MMethodDef classMethod) {
InterfaceMethodInfo info; InterfaceMethodInfo info;
var key = new TypeReferenceKey(iface); if (!interfaceMethods.TryGetValue(iface, out info))
if (!interfaceMethods.TryGetValue(key, out info))
throw new ApplicationException("Could not find interface"); throw new ApplicationException("Could not find interface");
return info.addMethod(ifaceMethod, classMethod); return info.addMethod(ifaceMethod, classMethod);
} }
public void addMethodIfEmpty(TypeInfo iface, MMethodDef ifaceMethod, MMethodDef classMethod) { public void addMethodIfEmpty(TypeInfo iface, MMethodDef ifaceMethod, MMethodDef classMethod) {
InterfaceMethodInfo info; InterfaceMethodInfo info;
var key = new TypeReferenceKey(iface.typeReference); if (!interfaceMethods.TryGetValue(iface.typeReference, out info))
if (!interfaceMethods.TryGetValue(key, out info))
throw new ApplicationException("Could not find interface"); throw new ApplicationException("Could not find interface");
info.addMethodIfEmpty(ifaceMethod, classMethod); info.addMethodIfEmpty(ifaceMethod, classMethod);
} }
@ -303,13 +315,13 @@ namespace de4dot.code.renamer.asmmodules {
genericParams = MGenericParamDef.createGenericParamDefList(TypeDef.GenericParams); genericParams = MGenericParamDef.createGenericParamDefList(TypeDef.GenericParams);
} }
public void addInterface(MTypeDef ifaceDef, TypeReference iface) { public void addInterface(MTypeDef ifaceDef, ITypeDefOrRef iface) {
if (ifaceDef == null || iface == null) if (ifaceDef == null || iface == null)
return; return;
interfaces.Add(new TypeInfo(iface, ifaceDef)); interfaces.Add(new TypeInfo(iface, ifaceDef));
} }
public void addBaseType(MTypeDef baseDef, TypeReference baseRef) { public void addBaseType(MTypeDef baseDef, ITypeDefOrRef baseRef) {
if (baseDef == null || baseRef == null) if (baseDef == null || baseRef == null)
return; return;
baseType = new TypeInfo(baseRef, baseDef); baseType = new TypeInfo(baseRef, baseDef);
@ -335,35 +347,39 @@ namespace de4dot.code.renamer.asmmodules {
types.add(t); types.add(t);
} }
public MMethodDef find(MethodReference mr) { public MMethodDef findMethod(MemberRef mr) {
return methods.find(mr); return methods.find(mr);
} }
public MMethodDef findAny(MethodReference mr) { public MMethodDef findMethod(MethodDef md) {
return methods.find(md);
}
public MMethodDef findAnyMethod(MemberRef mr) {
return methods.findAny(mr); return methods.findAny(mr);
} }
public MFieldDef find(FieldReference fr) { public MFieldDef findField(MemberRef fr) {
return fields.find(fr); return fields.find(fr);
} }
public MFieldDef findAny(FieldReference fr) { public MFieldDef findAnyField(MemberRef fr) {
return fields.findAny(fr); return fields.findAny(fr);
} }
public MPropertyDef find(PropertyReference pr) { public MPropertyDef find(PropertyDef pr) {
return properties.find(pr); return properties.find(pr);
} }
public MPropertyDef findAny(PropertyReference pr) { public MPropertyDef findAny(PropertyDef pr) {
return properties.findAny(pr); return properties.findAny(pr);
} }
public MEventDef find(EventReference er) { public MEventDef find(EventDef er) {
return events.find(er); return events.find(er);
} }
public MEventDef findAny(EventReference er) { public MEventDef findAny(EventDef er) {
return events.findAny(er); return events.findAny(er);
} }
@ -401,7 +417,7 @@ namespace de4dot.code.renamer.asmmodules {
foreach (var propDef in properties.getValues()) { foreach (var propDef in properties.getValues()) {
foreach (var method in propDef.methodDefinitions()) { foreach (var method in propDef.methodDefinitions()) {
var methodDef = find(method); var methodDef = findMethod(method);
if (methodDef == null) if (methodDef == null)
throw new ApplicationException("Could not find property method"); throw new ApplicationException("Could not find property method");
methodDef.Property = propDef; methodDef.Property = propDef;
@ -414,7 +430,7 @@ namespace de4dot.code.renamer.asmmodules {
foreach (var eventDef in events.getValues()) { foreach (var eventDef in events.getValues()) {
foreach (var method in eventDef.methodDefinitions()) { foreach (var method in eventDef.methodDefinitions()) {
var methodDef = find(method); var methodDef = findMethod(method);
if (methodDef == null) if (methodDef == null)
throw new ApplicationException("Could not find event method"); throw new ApplicationException("Could not find event method");
methodDef.Event = eventDef; methodDef.Event = eventDef;
@ -443,8 +459,7 @@ namespace de4dot.code.renamer.asmmodules {
public bool isGlobalType() { public bool isGlobalType() {
if (!isNested()) if (!isNested())
return TypeDef.IsPublic; return TypeDef.IsPublic;
var mask = TypeDef.Attributes & TypeAttributes.VisibilityMask; switch (TypeDef.Visibility) {
switch (mask) {
case TypeAttributes.NestedPrivate: case TypeAttributes.NestedPrivate:
case TypeAttributes.NestedAssembly: case TypeAttributes.NestedAssembly:
case TypeAttributes.NestedFamANDAssem: case TypeAttributes.NestedFamANDAssem:
@ -489,7 +504,7 @@ namespace de4dot.code.renamer.asmmodules {
} }
void initializeInterfaces(TypeInfo typeInfo) { void initializeInterfaces(TypeInfo typeInfo) {
var git = typeInfo.typeReference as GenericInstanceType; var git = typeInfo.typeReference.ToGenericInstSig();
interfaceMethodInfos.initializeFrom(typeInfo.typeDef.interfaceMethodInfos, git); interfaceMethodInfos.initializeFrom(typeInfo.typeDef.interfaceMethodInfos, git);
foreach (var info in typeInfo.typeDef.allImplementedInterfaces.Keys) { foreach (var info in typeInfo.typeDef.allImplementedInterfaces.Keys) {
var newTypeInfo = new TypeInfo(info, git); var newTypeInfo = new TypeInfo(info, git);
@ -535,7 +550,7 @@ namespace de4dot.code.renamer.asmmodules {
var ifaceMethod = methodInst.origMethodDef; var ifaceMethod = methodInst.origMethodDef;
if (!ifaceMethod.isVirtual()) if (!ifaceMethod.isVirtual())
continue; continue;
var ifaceMethodReference = MethodReferenceInstance.make(methodInst.methodReference, ifaceInfo.typeReference as GenericInstanceType); var ifaceMethodReference = MethodReferenceInstance.make(methodInst.methodReference, ifaceInfo.typeReference.ToGenericInstSig());
MMethodDef classMethod; MMethodDef classMethod;
var key = new MethodReferenceKey(ifaceMethodReference); var key = new MethodReferenceKey(ifaceMethodReference);
if (!methodsDict.TryGetValue(key, out classMethod)) if (!methodsDict.TryGetValue(key, out classMethod))
@ -570,7 +585,7 @@ namespace de4dot.code.renamer.asmmodules {
var ifaceMethod = methodsList[0].origMethodDef; var ifaceMethod = methodsList[0].origMethodDef;
if (!ifaceMethod.isVirtual()) if (!ifaceMethod.isVirtual())
continue; continue;
var ifaceMethodRef = MethodReferenceInstance.make(ifaceMethod.MethodDef, ifaceInfo.typeReference as GenericInstanceType); var ifaceMethodRef = MethodReferenceInstance.make(ifaceMethod.MethodDef, ifaceInfo.typeReference.ToGenericInstSig());
MMethodDef classMethod; MMethodDef classMethod;
var key = new MethodReferenceKey(ifaceMethodRef); var key = new MethodReferenceKey(ifaceMethodRef);
if (!methodsDict.TryGetValue(key, out classMethod)) if (!methodsDict.TryGetValue(key, out classMethod))
@ -583,14 +598,14 @@ namespace de4dot.code.renamer.asmmodules {
//--- explicitly specified virtual methods into the interface in preference to those //--- explicitly specified virtual methods into the interface in preference to those
//--- inherited or chosen by name matching. //--- inherited or chosen by name matching.
methodsDict.Clear(); methodsDict.Clear();
var ifaceMethodsDict = new Dictionary<MethodReferenceAndDeclaringTypeKey, MMethodDef>(); var ifaceMethodsDict = new Dictionary<IMethod, MMethodDef>(MethodEqualityComparer.CompareDeclaringTypes);
foreach (var ifaceInfo in allImplementedInterfaces.Keys) { foreach (var ifaceInfo in allImplementedInterfaces.Keys) {
var git = ifaceInfo.typeReference as GenericInstanceType; var git = ifaceInfo.typeReference.ToGenericInstSig();
foreach (var ifaceMethod in ifaceInfo.typeDef.methods.getValues()) { foreach (var ifaceMethod in ifaceInfo.typeDef.methods.getValues()) {
MethodReference ifaceMethodReference = ifaceMethod.MethodDef; IMethod ifaceMethodReference = ifaceMethod.MethodDef;
if (git != null) if (git != null)
ifaceMethodReference = simpleClone(ifaceMethod.MethodDef, git); ifaceMethodReference = simpleClone(ifaceMethod.MethodDef, ifaceInfo.typeReference);
ifaceMethodsDict[new MethodReferenceAndDeclaringTypeKey(ifaceMethodReference)] = ifaceMethod; ifaceMethodsDict[ifaceMethodReference] = ifaceMethod;
} }
} }
foreach (var classMethod in methods.getValues()) { foreach (var classMethod in methods.getValues()) {
@ -598,14 +613,13 @@ namespace de4dot.code.renamer.asmmodules {
continue; continue;
foreach (var overrideMethod in classMethod.MethodDef.Overrides) { foreach (var overrideMethod in classMethod.MethodDef.Overrides) {
MMethodDef ifaceMethod; MMethodDef ifaceMethod;
var key = new MethodReferenceAndDeclaringTypeKey(overrideMethod); if (!ifaceMethodsDict.TryGetValue(overrideMethod.MethodDeclaration, out ifaceMethod)) {
if (!ifaceMethodsDict.TryGetValue(key, out ifaceMethod)) {
// We couldn't find the interface method (eg. interface not resolved) or // We couldn't find the interface method (eg. interface not resolved) or
// it overrides a base class method, and not an interface method. // it overrides a base class method, and not an interface method.
continue; continue;
} }
interfaceMethodInfos.addMethod(overrideMethod.DeclaringType, ifaceMethod, classMethod); interfaceMethodInfos.addMethod(overrideMethod.MethodDeclaration.DeclaringType, ifaceMethod, classMethod);
} }
} }
@ -687,23 +701,15 @@ namespace de4dot.code.renamer.asmmodules {
return baseType.typeDef.resolvedBaseClasses(); return baseType.typeDef.resolvedBaseClasses();
} }
MethodReference simpleClone(MethodReference methodReference, TypeReference declaringType) { MemberRef simpleClone(MethodDef methodRef, ITypeDefOrRef declaringType) {
var m = new MethodReference(methodReference.Name, methodReference.MethodReturnType.ReturnType, declaringType); var mr = new MemberRefUser(module.ModuleDefMD, methodRef.Name, methodRef.MethodSig, declaringType);
m.MethodReturnType.ReturnType = methodReference.MethodReturnType.ReturnType; return module.ModuleDefMD.UpdateRowId(mr);
m.HasThis = methodReference.HasThis;
m.ExplicitThis = methodReference.ExplicitThis;
m.CallingConvention = methodReference.CallingConvention;
foreach (var p in methodReference.Parameters)
m.Parameters.Add(new ParameterDefinition(p.Name, p.Attributes, p.ParameterType));
foreach (var gp in methodReference.GenericParameters)
m.GenericParameters.Add(new GenericParam(declaringType));
return m;
} }
void instantiateVirtualMembers(MethodNameGroups groups) { void instantiateVirtualMembers(MethodNameGroups groups) {
if (!TypeDef.IsInterface) { if (!TypeDef.IsInterface) {
if (baseType != null) if (baseType != null)
virtualMethodInstances.initializeFrom(baseType.typeDef.virtualMethodInstances, baseType.typeReference as GenericInstanceType); virtualMethodInstances.initializeFrom(baseType.typeDef.virtualMethodInstances, baseType.typeReference.ToGenericInstSig());
// Figure out which methods we override in the base class // Figure out which methods we override in the base class
foreach (var methodDef in methods.getValues()) { foreach (var methodDef in methods.getValues()) {

2
dot10

@ -1 +1 @@
Subproject commit b18f4dd6cc658c60fbb6d1a3d8862c58d5c53129 Subproject commit 5e38e6ffb1a33d25d48a5487dc47a14e2cb2583c