diff --git a/AssemblyData/methodsrewriter/AssemblyResolver.cs b/AssemblyData/methodsrewriter/AssemblyResolver.cs index 843a5572..a52cc7ce 100644 --- a/AssemblyData/methodsrewriter/AssemblyResolver.cs +++ b/AssemblyData/methodsrewriter/AssemblyResolver.cs @@ -49,7 +49,7 @@ namespace AssemblyData.methodsrewriter { } TypeResolver getTypeResolver(ITypeDefOrRef typeRef) { - var key = typeRef.Namespace + "." + typeRef.Name; + var key = typeRef.Namespace + "." + typeRef.TypeName; List list; if (!types.TryGetValue(key, out list)) return null; diff --git a/de4dot.code/DeobfuscatorContext.cs b/de4dot.code/DeobfuscatorContext.cs index 3882eced..96d61182 100644 --- a/de4dot.code/DeobfuscatorContext.cs +++ b/de4dot.code/DeobfuscatorContext.cs @@ -48,63 +48,52 @@ namespace de4dot.code { dataDict.Remove(name); } -#if PORT - static TypeReference getNonGenericTypeReference(TypeReference typeReference) { - if (typeReference == null) - return null; - if (!typeReference.IsGenericInstance) - return typeReference; - var type = (GenericInstanceType)typeReference; - return type.ElementType; + static ITypeDefOrRef getNonGenericTypeReference(ITypeDefOrRef typeRef) { + var ts = typeRef as TypeSpec; + if (ts == null) + return typeRef; + var gis = ts.TypeSig.RemovePinnedAndModifiers() as GenericInstSig; + if (gis == null || gis.GenericType == null) + return typeRef; + return gis.GenericType.TypeDefOrRef; } - public TypeDef resolve(TypeReference type) { + public TypeDef resolveType(ITypeDefOrRef type) { if (type == null) return null; - var typeDef = getNonGenericTypeReference(type) as TypeDef; + type = getNonGenericTypeReference(type); + + var typeDef = type as TypeDef; if (typeDef != null) 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) 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) return null; - foreach (var m in type.Methods) { - if (MemberReferenceHelper.compareMethodReference(method, m)) - return m; - } - - return null; + return type.Resolve(method) as MethodDef; } - public FieldDef resolve(FieldReference field) { + public FieldDef resolveField(MemberRef field) { if (field == 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) return null; - foreach (var f in type.Fields) { - if (MemberReferenceHelper.compareFieldReference(field, f)) - return f; - } - - return null; + return type.Resolve(field) as FieldDef; } -#endif } } diff --git a/de4dot.code/IDeobfuscatorContext.cs b/de4dot.code/IDeobfuscatorContext.cs index 4e7a2611..112a2b5e 100644 --- a/de4dot.code/IDeobfuscatorContext.cs +++ b/de4dot.code/IDeobfuscatorContext.cs @@ -25,10 +25,8 @@ namespace de4dot.code { void setData(string name, object data); object getData(string name); void clearData(string name); -#if PORT - TypeDef resolve(TypeRef type); - MethodDef resolve(IMethod method); - FieldDef resolve(IField field); -#endif + TypeDef resolveType(ITypeDefOrRef type); + MethodDef resolveMethod(MemberRef method); + FieldDef resolveField(MemberRef field); } } diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 6d624005..992ec427 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -273,20 +273,20 @@ - - - - + + + + - - - - - - - - - + + + + + + + + + diff --git a/de4dot.code/renamer/asmmodules/IResolver.cs b/de4dot.code/renamer/asmmodules/IResolver.cs index 927445ab..f0f402b4 100644 --- a/de4dot.code/renamer/asmmodules/IResolver.cs +++ b/de4dot.code/renamer/asmmodules/IResolver.cs @@ -21,7 +21,7 @@ using dot10.DotNet; namespace de4dot.code.renamer.asmmodules { interface IResolver { - MTypeDef resolveType(TypeRef typeReference); + MTypeDef resolveType(ITypeDefOrRef typeReference); MMethodDef resolveMethod(MemberRef methodReference); MFieldDef resolveField(MemberRef fieldReference); } diff --git a/de4dot.code/renamer/asmmodules/MemberRefFinder.cs b/de4dot.code/renamer/asmmodules/MemberRefFinder.cs index a9ff6e9b..e689f75d 100644 --- a/de4dot.code/renamer/asmmodules/MemberRefFinder.cs +++ b/de4dot.code/renamer/asmmodules/MemberRefFinder.cs @@ -401,38 +401,35 @@ namespace de4dot.code.renamer.asmmodules { void add(IEnumerable instrs) { if (instrs == null) return; - foreach (var instr in instrs) - add(instr); - } + foreach (var instr in instrs) { + 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) { - if (instr == null) - return; - switch (instr.OpCode.OperandType) { - case OperandType.InlineTok: - case OperandType.InlineType: - case OperandType.InlineMethod: - case OperandType.InlineField: - push(instr.Operand); - break; + case OperandType.InlineSig: + add(instr.Operand as CallingConventionSig); + break; - case OperandType.InlineSig: - add(instr.Operand as CallingConventionSig); - break; - - case OperandType.InlineVar: - case OperandType.ShortInlineVar: - var local = instr.Operand as Local; - if (local != null) { - add(local); + case OperandType.InlineVar: + case OperandType.ShortInlineVar: + var local = instr.Operand as Local; + if (local != null) { + add(local); + break; + } + var arg = instr.Operand as Parameter; + if (arg != null) { + add(arg); + break; + } break; } - var arg = instr.Operand as Parameter; - if (arg != null) { - add(arg); - break; - } - break; } } diff --git a/de4dot.code/renamer/asmmodules/Module.cs b/de4dot.code/renamer/asmmodules/Module.cs index ff4093f7..d575e824 100644 --- a/de4dot.code/renamer/asmmodules/Module.cs +++ b/de4dot.code/renamer/asmmodules/Module.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; using dot10.DotNet; +using dot10.DotNet.MD; using de4dot.blocks; namespace de4dot.code.renamer.asmmodules { @@ -27,9 +28,9 @@ namespace de4dot.code.renamer.asmmodules { IObfuscatedFile obfuscatedFile; TypeDefDict types = new TypeDefDict(); MemberRefFinder memberRefFinder; - IList> typeRefsToRename = new List>(); - IList> methodRefsToRename = new List>(); - IList> fieldRefsToRename = new List>(); + IList> typeRefsToRename = new List>(); + IList> methodRefsToRename = new List>(); + IList> fieldRefsToRename = new List>(); List customAttributeFieldReferences = new List(); List customAttributePropertyReferences = new List(); List allMethods; @@ -37,15 +38,15 @@ namespace de4dot.code.renamer.asmmodules { public class CustomAttributeReference { public CustomAttribute cattr; public int index; - public MemberReference reference; - public CustomAttributeReference(CustomAttribute cattr, int index, MemberReference reference) { + public IMemberRef reference; + public CustomAttributeReference(CustomAttribute cattr, int index, IMemberRef reference) { this.cattr = cattr; this.index = index; this.reference = reference; } } - public class RefToDef where R : MemberReference where D : R { + public class RefToDef where R : ICodedToken where D : ICodedToken { public R reference; public D definition; public RefToDef(R reference, D definition) { @@ -54,15 +55,15 @@ namespace de4dot.code.renamer.asmmodules { } } - public IEnumerable> TypeRefsToRename { + public IEnumerable> TypeRefsToRename { get { return typeRefsToRename; } } - public IEnumerable> MethodRefsToRename { + public IEnumerable> MethodRefsToRename { get { return methodRefsToRename; } } - public IEnumerable> FieldRefsToRename { + public IEnumerable> FieldRefsToRename { get { return fieldRefsToRename; } } @@ -100,11 +101,11 @@ namespace de4dot.code.renamer.asmmodules { public void findAllMemberReferences(ref int typeIndex) { memberRefFinder = new MemberRefFinder(); - memberRefFinder.findAll(ModuleDefMD, ModuleDefMD.Types); - allMethods = new List(memberRefFinder.methodDefinitions.Keys); + memberRefFinder.findAll(ModuleDefMD); + allMethods = new List(memberRefFinder.methodDefs.Keys); var allTypesList = new List(); - foreach (var type in memberRefFinder.typeDefinitions.Keys) { + foreach (var type in memberRefFinder.typeDefs.Keys) { var typeDef = new MTypeDef(type, this, typeIndex++); types.add(typeDef); allTypesList.Add(typeDef); @@ -131,36 +132,37 @@ namespace de4dot.code.renamer.asmmodules { } public void resolveAllRefs(IResolver resolver) { - foreach (var typeRef in memberRefFinder.typeReferences.Keys) { + foreach (var typeRef in memberRefFinder.typeRefs.Keys) { var typeDef = resolver.resolveType(typeRef); if (typeDef != null) - typeRefsToRename.Add(new RefToDef(typeRef, typeDef.TypeDef)); + typeRefsToRename.Add(new RefToDef(typeRef, typeDef.TypeDef)); } - foreach (var methodRef in memberRefFinder.methodReferences.Keys) { - var methodDef = resolver.resolveMethod(methodRef); - if (methodDef != null) - methodRefsToRename.Add(new RefToDef(methodRef, methodDef.MethodDef)); - } - - foreach (var fieldRef in memberRefFinder.fieldReferences.Keys) { - var fieldDef = resolver.resolveField(fieldRef); - if (fieldDef != null) - fieldRefsToRename.Add(new RefToDef(fieldRef, fieldDef.FieldDef)); + foreach (var memberRef in memberRefFinder.memberRefs.Keys) { + if (memberRef.IsMethodRef) { + var methodDef = resolver.resolveMethod(memberRef); + if (methodDef != null) + methodRefsToRename.Add(new RefToDef(memberRef, methodDef.MethodDef)); + } + else if (memberRef.IsFieldRef) { + var fieldDef = resolver.resolveField(memberRef); + if (fieldDef != null) + fieldRefsToRename.Add(new RefToDef(memberRef, fieldDef.FieldDef)); + } } foreach (var cattr in memberRefFinder.customAttributes.Keys) { - try { - var typeDef = resolver.resolveType(cattr.AttributeType); - if (typeDef == null) - continue; + var typeDef = resolver.resolveType(cattr.AttributeType); + if (typeDef == null) + continue; - for (int i = 0; i < cattr.Fields.Count; i++) { - var field = cattr.Fields[i]; - var fieldDef = findFieldByName(typeDef, field.Name); + for (int i = 0; i < cattr.NamedArguments.Count; i++) { + var namedArg = cattr.NamedArguments[i]; + if (namedArg.IsField) { + var fieldDef = findField(typeDef, namedArg.Name, namedArg.Type); if (fieldDef == null) { 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), typeDef.TypeDef.MDToken.ToInt32()); continue; @@ -168,13 +170,11 @@ namespace de4dot.code.renamer.asmmodules { customAttributeFieldReferences.Add(new CustomAttributeReference(cattr, i, fieldDef.FieldDef)); } - - for (int i = 0; i < cattr.Properties.Count; i++) { - var prop = cattr.Properties[i]; - var propDef = findPropertyByName(typeDef, prop.Name); + else { + var propDef = findProperty(typeDef, namedArg.Name, namedArg.Type); if (propDef == null) { 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), typeDef.TypeDef.MDToken.ToInt32()); continue; @@ -183,15 +183,15 @@ namespace de4dot.code.renamer.asmmodules { 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) { 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; } @@ -202,10 +202,12 @@ namespace de4dot.code.renamer.asmmodules { return null; } - static MPropertyDef findPropertyByName(MTypeDef typeDef, string name) { + static MPropertyDef findProperty(MTypeDef typeDef, UTF8String name, TypeSig propType) { while (typeDef != null) { 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; } @@ -225,31 +227,32 @@ namespace de4dot.code.renamer.asmmodules { types = newTypes; } - static TypeReference getNonGenericTypeReference(TypeReference typeReference) { - if (typeReference == null) - return null; - if (!typeReference.IsGenericInstance) - return typeReference; - var type = (GenericInstanceType)typeReference; - return type.ElementType; + static ITypeDefOrRef getNonGenericTypeReference(ITypeDefOrRef typeRef) { + var ts = typeRef as TypeSpec; + if (ts == null) + return typeRef; + var gis = ts.TypeSig.RemovePinnedAndModifiers() as GenericInstSig; + if (gis == null || gis.GenericType == null) + return typeRef; + return gis.GenericType.TypeDefOrRef; } - public MTypeDef resolveType(TypeReference typeReference) { + public MTypeDef resolveType(ITypeDefOrRef typeReference) { return this.types.find(getNonGenericTypeReference(typeReference)); } - public MMethodDef resolveMethod(MethodReference methodReference) { - var typeDef = this.types.find(getNonGenericTypeReference(methodReference.DeclaringType)); + public MMethodDef resolveMethod(MemberRef methodRef) { + var typeDef = this.types.find(getNonGenericTypeReference(methodRef.DeclaringType)); if (typeDef == null) return null; - return typeDef.find(methodReference); + return typeDef.findMethod(methodRef); } - public MFieldDef resolveField(FieldReference fieldReference) { - var typeDef = this.types.find(getNonGenericTypeReference(fieldReference.DeclaringType)); + public MFieldDef resolveField(MemberRef fieldRef) { + var typeDef = this.types.find(getNonGenericTypeReference(fieldRef.DeclaringType)); if (typeDef == null) return null; - return typeDef.find(fieldReference); + return typeDef.findField(fieldRef); } } } diff --git a/de4dot.code/renamer/asmmodules/Modules.cs b/de4dot.code/renamer/asmmodules/Modules.cs index 3d435032..57140e26 100644 --- a/de4dot.code/renamer/asmmodules/Modules.cs +++ b/de4dot.code/renamer/asmmodules/Modules.cs @@ -62,9 +62,9 @@ namespace de4dot.code.renamer.asmmodules { } string getModuleKey(Module module) { - if (module.ModuleDef.Assembly != null) - return module.ModuleDef.Assembly.ToString(); - return Utils.getBaseName(module.ModuleDef.FullyQualifiedName); + if (module.ModuleDefMD.Assembly != null) + return module.ModuleDefMD.Assembly.ToString(); + return Utils.getBaseName(module.ModuleDefMD.Location); } public ModuleHash lookup(string assemblyName) { @@ -80,16 +80,16 @@ namespace de4dot.code.renamer.asmmodules { Module mainModule = null; public void add(Module module) { - var asm = module.ModuleDef.Assembly; - if (asm != null && ReferenceEquals(asm.MainModule, module.ModuleDef)) { + var asm = module.ModuleDefMD.Assembly; + if (asm != null && ReferenceEquals(asm.ManifestModule, module.ModuleDefMD)) { 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.ModuleDef.FullyQualifiedName, - mainModule.ModuleDef.FullyQualifiedName)); + module.ModuleDefMD.Location, + mainModule.ModuleDefMD.Location)); } mainModule = module; } @@ -110,7 +110,7 @@ namespace de4dot.code.renamer.asmmodules { IDictionary modulesDict = new Dictionary(StringComparer.Ordinal); public void add(Module module) { - var moduleName = module.ModuleDef.Name; + var moduleName = module.ModuleDefMD.Name.String; if (lookup(moduleName) != null) throw new ApplicationException(string.Format("Module \"{0}\" was found twice", moduleName)); modulesDict[moduleName] = module; @@ -140,9 +140,9 @@ namespace de4dot.code.renamer.asmmodules { if (initializeCalled) throw new ApplicationException("initialize() has been called"); Module otherModule; - if (modulesDict.TryGetValue(module.ModuleDef, out otherModule)) + if (modulesDict.TryGetValue(module.ModuleDefMD, out otherModule)) return; - modulesDict[module.ModuleDef] = module; + modulesDict[module.ModuleDefMD] = module; modules.Add(module); assemblyHash.add(module); } @@ -205,12 +205,10 @@ namespace de4dot.code.renamer.asmmodules { // Initialize interfaces foreach (var typeDef in allTypes) { - if (typeDef.TypeDef.Interfaces == null) - continue; - foreach (var iface in typeDef.TypeDef.Interfaces) { - var ifaceTypeDef = resolveType(iface) ?? resolveOther(iface); + foreach (var iface in typeDef.TypeDef.InterfaceImpls) { + var ifaceTypeDef = resolveType(iface.Interface) ?? resolveOther(iface.Interface); if (ifaceTypeDef != null) - typeDef.addInterface(ifaceTypeDef, iface); + typeDef.addInterface(ifaceTypeDef, iface.Interface); } } @@ -231,10 +229,10 @@ namespace de4dot.code.renamer.asmmodules { } class AssemblyKeyDictionary where T : class { - Dictionary dict = new Dictionary(); - Dictionary> refs = new Dictionary>(); + Dictionary dict = new Dictionary(new TypeEqualityComparer(SigComparerOptions.CompareAssemblyVersion)); + Dictionary> refs = new Dictionary>(TypeEqualityComparer.Instance); - public T this[TypeReference type] { + public T this[ITypeDefOrRef type] { get { T value; if (tryGetValue(type, out value)) @@ -242,39 +240,35 @@ namespace de4dot.code.renamer.asmmodules { throw new KeyNotFoundException(); } set { - var key = new TypeReferenceSameVersionKey(type); - dict[key] = value; + dict[type] = value; if (value != null) { - var key2 = new TypeReferenceKey(type); - List list; - if (!refs.TryGetValue(key2, out list)) - refs[key2] = list = new List(); + List list; + if (!refs.TryGetValue(type, out list)) + refs[type] = list = new List(); list.Add(type); } } } - public bool tryGetValue(TypeReference type, out T value) { - return dict.TryGetValue(new TypeReferenceSameVersionKey(type), out value); + public bool tryGetValue(ITypeDefOrRef type, out T value) { + return dict.TryGetValue(type, out value); } - public bool tryGetSimilarValue(TypeReference type, out T value) { - var key2 = new TypeReferenceKey(type); - List list; - if (!refs.TryGetValue(key2, out list)) { + public bool tryGetSimilarValue(ITypeDefOrRef type, out T value) { + List list; + if (!refs.TryGetValue(type, out list)) { value = default(T); return false; } // Find a type whose version is >= type's version and closest to it. - TypeReference foundType = null; - var typeAsmName = MemberReferenceHelper.getAssemblyNameReference(type.Scope); - AssemblyNameReference foundAsmName = null; + ITypeDefOrRef foundType = null; + var typeAsmName = type.DefinitionAssembly; + IAssembly foundAsmName = null; foreach (var otherRef in list) { - var key = new TypeReferenceSameVersionKey(otherRef); - if (!dict.TryGetValue(key, out value)) + if (!dict.TryGetValue(otherRef, out value)) continue; if (typeAsmName == null) { @@ -282,11 +276,11 @@ namespace de4dot.code.renamer.asmmodules { break; } - var otherAsmName = MemberReferenceHelper.getAssemblyNameReference(otherRef.Scope); + var otherAsmName = otherRef.DefinitionAssembly; if (otherAsmName == null) continue; // 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; if (typeAsmName.Version > otherAsmName.Version) continue; // old version @@ -304,40 +298,28 @@ namespace de4dot.code.renamer.asmmodules { } if (foundType != null) { - value = dict[new TypeReferenceSameVersionKey(foundType)]; + value = dict[foundType]; return true; } value = default(T); 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 typeToTypeDefDict = new AssemblyKeyDictionary(); - public MTypeDef resolveOther(TypeReference type) { + public MTypeDef resolveOther(ITypeDefOrRef type) { + if (type == null) + return null; + type = type.ScopeType; if (type == null) return null; - type = type.GetElementType(); MTypeDef typeDef; if (typeToTypeDefDict.tryGetValue(type, out typeDef)) return typeDef; - var typeDefinition = deobfuscatorContext.resolve(type); + var typeDefinition = deobfuscatorContext.resolveType(type); if (typeDefinition == null) { typeToTypeDefDict.tryGetSimilarValue(type, out typeDef); typeToTypeDefDict[type] = typeDef; @@ -354,11 +336,11 @@ namespace de4dot.code.renamer.asmmodules { typeDef = new MTypeDef(typeDefinition, null, 0); typeDef.addMembers(); - foreach (var iface in typeDef.TypeDef.Interfaces) { - var ifaceDef = resolveOther(iface); + foreach (var iface in typeDef.TypeDef.InterfaceImpls) { + var ifaceDef = resolveOther(iface.Interface); if (ifaceDef == null) continue; - typeDef.addInterface(ifaceDef, iface); + typeDef.addInterface(ifaceDef, iface.Interface); } var baseDef = resolveOther(typeDef.TypeDef.BaseType); if (baseDef != null) @@ -383,40 +365,42 @@ namespace de4dot.code.renamer.asmmodules { } public void cleanUp() { +#if PORT foreach (var module in DotNetUtils.typeCaches.invalidateAll()) AssemblyResolver.Instance.removeModule(module); +#endif } // Returns null if it's a non-loaded module/assembly - IEnumerable findModules(TypeReference type) { + IEnumerable findModules(ITypeDefOrRef type) { var scope = type.Scope; if (scope == null) return null; - if (scope is AssemblyNameReference) - return findModules((AssemblyNameReference)scope); + if (scope.ScopeType == ScopeType.AssemblyRef) + return findModules((AssemblyRef)scope); - if (scope is ModuleDef) { + if (scope.ScopeType == ScopeType.ModuleDef) { var modules = findModules((ModuleDef)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 (scope.ScopeType == ScopeType.ModuleRef) { + var moduleRef = (ModuleRef)scope; + if (moduleRef.Name == type.OwnerModule.Name) { + var modules = findModules(type.OwnerModule); if (modules != null) return modules; } - var asm = type.Module.Assembly; + var asm = type.OwnerModule.Assembly; if (asm == null) return null; - var moduleHash = assemblyHash.lookup(asm.ToString()); + var moduleHash = assemblyHash.lookup(asm.FullName); if (moduleHash == null) return null; - var module = moduleHash.lookup(moduleReference.Name); + var module = moduleHash.lookup(moduleRef.Name.String); if (module == null) return null; return new List { module }; @@ -425,65 +409,71 @@ namespace de4dot.code.renamer.asmmodules { throw new ApplicationException(string.Format("scope is an unsupported type: {0}", scope.GetType())); } - IEnumerable findModules(AssemblyNameReference assemblyRef) { - var moduleHash = assemblyHash.lookup(assemblyRef.ToString()); + IEnumerable findModules(AssemblyRef assemblyRef) { + var moduleHash = assemblyHash.lookup(assemblyRef.FullName); if (moduleHash != null) return moduleHash.Modules; return null; } - IEnumerable findModules(ModuleDef moduleDefinition) { + IEnumerable findModules(ModuleDef moduleDef) { Module module; - if (modulesDict.TryGetValue(moduleDefinition, out module)) + if (modulesDict.TryGetValue(moduleDef, out module)) return new List { module }; return null; } - bool isAutoCreatedType(TypeReference typeReference) { - return typeReference is ArrayType || typeReference is PointerType || typeReference is FunctionPointerType; + bool isAutoCreatedType(ITypeDefOrRef typeRef) { + 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) { - var modules = findModules(typeReference); + public MTypeDef resolveType(ITypeDefOrRef typeRef) { + var modules = findModules(typeRef); if (modules == null) return null; foreach (var module in modules) { - var rv = module.resolveType(typeReference); + var rv = module.resolveType(typeRef); if (rv != null) return rv; } - if (isAutoCreatedType(typeReference)) + if (isAutoCreatedType(typeRef)) return null; Log.e("Could not resolve TypeReference {0} ({1:X8}) (from {2} -> {3})", - Utils.removeNewlines(typeReference), - typeReference.MDToken.ToInt32(), - typeReference.Module, - typeReference.Scope); + Utils.removeNewlines(typeRef), + typeRef.MDToken.ToInt32(), + typeRef.OwnerModule, + typeRef.Scope); return null; } - public MMethodDef resolveMethod(MethodReference methodReference) { - if (methodReference.DeclaringType == null) + public MMethodDef resolveMethod(MemberRef methodRef) { + if (methodRef.DeclaringType == null) return null; - var modules = findModules(methodReference.DeclaringType); + var modules = findModules(methodRef.DeclaringType); if (modules == null) return null; foreach (var module in modules) { - var rv = module.resolveMethod(methodReference); + var rv = module.resolveMethod(methodRef); if (rv != null) return rv; } - if (isAutoCreatedType(methodReference.DeclaringType)) + if (isAutoCreatedType(methodRef.DeclaringType)) return null; Log.e("Could not resolve MethodReference {0} ({1:X8}) (from {2} -> {3})", - Utils.removeNewlines(methodReference), - methodReference.MDToken.ToInt32(), - methodReference.DeclaringType.Module, - methodReference.DeclaringType.Scope); + Utils.removeNewlines(methodRef), + methodRef.MDToken.ToInt32(), + methodRef.DeclaringType.OwnerModule, + methodRef.DeclaringType.Scope); return null; } - public MFieldDef resolveField(FieldReference fieldReference) { + public MFieldDef resolveField(MemberRef fieldReference) { if (fieldReference.DeclaringType == null) return null; 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})", Utils.removeNewlines(fieldReference), fieldReference.MDToken.ToInt32(), - fieldReference.DeclaringType.Module, + fieldReference.DeclaringType.OwnerModule, fieldReference.DeclaringType.Scope); return null; } diff --git a/de4dot.code/renamer/asmmodules/TypeDef.cs b/de4dot.code/renamer/asmmodules/TypeDef.cs index 4cc6cbbb..def42bb8 100644 --- a/de4dot.code/renamer/asmmodules/TypeDef.cs +++ b/de4dot.code/renamer/asmmodules/TypeDef.cs @@ -23,22 +23,36 @@ using dot10.DotNet; using de4dot.blocks; 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 { - public TypeReference typeReference; + public ITypeDefOrRef typeReference; public MTypeDef typeDef; - public TypeInfo(TypeReference typeReference, MTypeDef typeDef) { + public TypeInfo(ITypeDefOrRef typeReference, MTypeDef typeDef) { this.typeReference = typeReference; this.typeDef = typeDef; } - public TypeInfo(TypeInfo other, GenericInstanceType git) { + public TypeInfo(TypeInfo other, GenericInstSig git) { this.typeReference = TypeReferenceInstance.make(other.typeReference, git); this.typeDef = other.typeDef; } public override int GetHashCode() { return typeDef.GetHashCode() + - MemberReferenceHelper.typeHashCode(typeReference); + new SigComparer().GetHashCode(typeReference); } public override bool Equals(object obj) { @@ -46,7 +60,7 @@ namespace de4dot.code.renamer.asmmodules { if (other == null) return false; return typeDef == other.typeDef && - MemberReferenceHelper.compareTypes(typeReference, other.typeReference); + new SigComparer().Equals(typeReference, other.typeReference); } public override string ToString() { @@ -62,14 +76,14 @@ namespace de4dot.code.renamer.asmmodules { } public override int GetHashCode() { - return MemberReferenceHelper.methodReferenceAndDeclaringTypeHashCode(methodDef.MethodDef); + return MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(methodDef.MethodDef); } public override bool Equals(object obj) { var other = obj as MethodDefKey; if (other == null) 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 { - Dictionary> methodInstances = new Dictionary>(); + Dictionary> methodInstances = new Dictionary>(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 methodInst in list) { - MethodReference newMethod = MethodReferenceInstance.make(methodInst.methodReference, git); + MemberRef newMethod = MethodReferenceInstance.make(methodInst.methodReference, git); add(new MethodInst(methodInst.origMethodDef, newMethod)); } } @@ -101,15 +115,15 @@ namespace de4dot.code.renamer.asmmodules { public void add(MethodInst methodInst) { List list; - var key = new MethodReferenceKey(methodInst.methodReference); + var key = methodInst.methodReference; if (methodInst.origMethodDef.isNewSlot() || !methodInstances.TryGetValue(key, out list)) methodInstances[key] = list = new List(); list.Add(methodInst); } - public List lookup(MethodReference methodReference) { + public List lookup(IMethod methodReference) { List list; - methodInstances.TryGetValue(new MethodReferenceKey(methodReference), out list); + methodInstances.TryGetValue(methodReference, out list); return list; } @@ -176,18 +190,18 @@ namespace de4dot.code.renamer.asmmodules { } class InterfaceMethodInfos { - Dictionary interfaceMethods = new Dictionary(); + Dictionary interfaceMethods = new Dictionary(TypeEqualityComparer.Instance); public IEnumerable AllInfos { get { return interfaceMethods.Values; } } - public void initializeFrom(InterfaceMethodInfos other, GenericInstanceType git) { + public void initializeFrom(InterfaceMethodInfos other, GenericInstSig git) { foreach (var pair in other.interfaceMethods) { var oldTypeInfo = pair.Value.IFace; var newTypeInfo = new TypeInfo(oldTypeInfo, git); - var oldKey = new TypeReferenceKey(oldTypeInfo.typeReference); - var newKey = new TypeReferenceKey(newTypeInfo.typeReference); + var oldKey = oldTypeInfo.typeReference; + var newKey = newTypeInfo.typeReference; InterfaceMethodInfo newMethodsInfo = new InterfaceMethodInfo(newTypeInfo, other.interfaceMethods[oldKey]); if (interfaceMethods.ContainsKey(newKey)) @@ -197,7 +211,7 @@ namespace de4dot.code.renamer.asmmodules { } public void addInterface(TypeInfo iface) { - var key = new TypeReferenceKey(iface.typeReference); + var key = iface.typeReference; if (!interfaceMethods.ContainsKey(key)) interfaceMethods[key] = new InterfaceMethodInfo(iface); } @@ -208,18 +222,16 @@ namespace de4dot.code.renamer.asmmodules { } // 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; - var key = new TypeReferenceKey(iface); - if (!interfaceMethods.TryGetValue(key, out info)) + if (!interfaceMethods.TryGetValue(iface, out info)) throw new ApplicationException("Could not find interface"); return info.addMethod(ifaceMethod, classMethod); } public void addMethodIfEmpty(TypeInfo iface, MMethodDef ifaceMethod, MMethodDef classMethod) { InterfaceMethodInfo info; - var key = new TypeReferenceKey(iface.typeReference); - if (!interfaceMethods.TryGetValue(key, out info)) + if (!interfaceMethods.TryGetValue(iface.typeReference, out info)) throw new ApplicationException("Could not find interface"); info.addMethodIfEmpty(ifaceMethod, classMethod); } @@ -303,13 +315,13 @@ namespace de4dot.code.renamer.asmmodules { genericParams = MGenericParamDef.createGenericParamDefList(TypeDef.GenericParams); } - public void addInterface(MTypeDef ifaceDef, TypeReference iface) { + public void addInterface(MTypeDef ifaceDef, ITypeDefOrRef iface) { if (ifaceDef == null || iface == null) return; 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) return; baseType = new TypeInfo(baseRef, baseDef); @@ -335,35 +347,39 @@ namespace de4dot.code.renamer.asmmodules { types.add(t); } - public MMethodDef find(MethodReference mr) { + public MMethodDef findMethod(MemberRef 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); } - public MFieldDef find(FieldReference fr) { + public MFieldDef findField(MemberRef fr) { return fields.find(fr); } - public MFieldDef findAny(FieldReference fr) { + public MFieldDef findAnyField(MemberRef fr) { return fields.findAny(fr); } - public MPropertyDef find(PropertyReference pr) { + public MPropertyDef find(PropertyDef pr) { return properties.find(pr); } - public MPropertyDef findAny(PropertyReference pr) { + public MPropertyDef findAny(PropertyDef pr) { return properties.findAny(pr); } - public MEventDef find(EventReference er) { + public MEventDef find(EventDef er) { return events.find(er); } - public MEventDef findAny(EventReference er) { + public MEventDef findAny(EventDef er) { return events.findAny(er); } @@ -401,7 +417,7 @@ namespace de4dot.code.renamer.asmmodules { foreach (var propDef in properties.getValues()) { foreach (var method in propDef.methodDefinitions()) { - var methodDef = find(method); + var methodDef = findMethod(method); if (methodDef == null) throw new ApplicationException("Could not find property method"); methodDef.Property = propDef; @@ -414,7 +430,7 @@ namespace de4dot.code.renamer.asmmodules { foreach (var eventDef in events.getValues()) { foreach (var method in eventDef.methodDefinitions()) { - var methodDef = find(method); + var methodDef = findMethod(method); if (methodDef == null) throw new ApplicationException("Could not find event method"); methodDef.Event = eventDef; @@ -443,8 +459,7 @@ namespace de4dot.code.renamer.asmmodules { public bool isGlobalType() { if (!isNested()) return TypeDef.IsPublic; - var mask = TypeDef.Attributes & TypeAttributes.VisibilityMask; - switch (mask) { + switch (TypeDef.Visibility) { case TypeAttributes.NestedPrivate: case TypeAttributes.NestedAssembly: case TypeAttributes.NestedFamANDAssem: @@ -489,7 +504,7 @@ namespace de4dot.code.renamer.asmmodules { } void initializeInterfaces(TypeInfo typeInfo) { - var git = typeInfo.typeReference as GenericInstanceType; + var git = typeInfo.typeReference.ToGenericInstSig(); interfaceMethodInfos.initializeFrom(typeInfo.typeDef.interfaceMethodInfos, git); foreach (var info in typeInfo.typeDef.allImplementedInterfaces.Keys) { var newTypeInfo = new TypeInfo(info, git); @@ -535,7 +550,7 @@ namespace de4dot.code.renamer.asmmodules { var ifaceMethod = methodInst.origMethodDef; if (!ifaceMethod.isVirtual()) continue; - var ifaceMethodReference = MethodReferenceInstance.make(methodInst.methodReference, ifaceInfo.typeReference as GenericInstanceType); + var ifaceMethodReference = MethodReferenceInstance.make(methodInst.methodReference, ifaceInfo.typeReference.ToGenericInstSig()); MMethodDef classMethod; var key = new MethodReferenceKey(ifaceMethodReference); if (!methodsDict.TryGetValue(key, out classMethod)) @@ -570,7 +585,7 @@ namespace de4dot.code.renamer.asmmodules { var ifaceMethod = methodsList[0].origMethodDef; if (!ifaceMethod.isVirtual()) continue; - var ifaceMethodRef = MethodReferenceInstance.make(ifaceMethod.MethodDef, ifaceInfo.typeReference as GenericInstanceType); + var ifaceMethodRef = MethodReferenceInstance.make(ifaceMethod.MethodDef, ifaceInfo.typeReference.ToGenericInstSig()); MMethodDef classMethod; var key = new MethodReferenceKey(ifaceMethodRef); 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 //--- inherited or chosen by name matching. methodsDict.Clear(); - var ifaceMethodsDict = new Dictionary(); + var ifaceMethodsDict = new Dictionary(MethodEqualityComparer.CompareDeclaringTypes); 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()) { - MethodReference ifaceMethodReference = ifaceMethod.MethodDef; + IMethod ifaceMethodReference = ifaceMethod.MethodDef; if (git != null) - ifaceMethodReference = simpleClone(ifaceMethod.MethodDef, git); - ifaceMethodsDict[new MethodReferenceAndDeclaringTypeKey(ifaceMethodReference)] = ifaceMethod; + ifaceMethodReference = simpleClone(ifaceMethod.MethodDef, ifaceInfo.typeReference); + ifaceMethodsDict[ifaceMethodReference] = ifaceMethod; } } foreach (var classMethod in methods.getValues()) { @@ -598,14 +613,13 @@ namespace de4dot.code.renamer.asmmodules { continue; foreach (var overrideMethod in classMethod.MethodDef.Overrides) { MMethodDef ifaceMethod; - var key = new MethodReferenceAndDeclaringTypeKey(overrideMethod); - if (!ifaceMethodsDict.TryGetValue(key, out ifaceMethod)) { + if (!ifaceMethodsDict.TryGetValue(overrideMethod.MethodDeclaration, out ifaceMethod)) { // We couldn't find the interface method (eg. interface not resolved) or // it overrides a base class method, and not an interface method. 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(); } - MethodReference simpleClone(MethodReference methodReference, TypeReference declaringType) { - var m = new MethodReference(methodReference.Name, methodReference.MethodReturnType.ReturnType, declaringType); - m.MethodReturnType.ReturnType = methodReference.MethodReturnType.ReturnType; - 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; + MemberRef simpleClone(MethodDef methodRef, ITypeDefOrRef declaringType) { + var mr = new MemberRefUser(module.ModuleDefMD, methodRef.Name, methodRef.MethodSig, declaringType); + return module.ModuleDefMD.UpdateRowId(mr); } void instantiateVirtualMembers(MethodNameGroups groups) { if (!TypeDef.IsInterface) { 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 foreach (var methodDef in methods.getValues()) { diff --git a/dot10 b/dot10 index b18f4dd6..5e38e6ff 160000 --- a/dot10 +++ b/dot10 @@ -1 +1 @@ -Subproject commit b18f4dd6cc658c60fbb6d1a3d8862c58d5c53129 +Subproject commit 5e38e6ffb1a33d25d48a5487dc47a14e2cb2583c