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) {
var key = typeRef.Namespace + "." + typeRef.Name;
var key = typeRef.Namespace + "." + typeRef.TypeName;
List<TypeResolver> list;
if (!types.TryGetValue(key, out list))
return null;

View File

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

View File

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

View File

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

View File

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

View File

@ -401,38 +401,35 @@ namespace de4dot.code.renamer.asmmodules {
void add(IEnumerable<Instruction> 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;
}
}

View File

@ -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<RefToDef<TypeReference, TypeDef>> typeRefsToRename = new List<RefToDef<TypeReference, TypeDef>>();
IList<RefToDef<MethodReference, MethodDef>> methodRefsToRename = new List<RefToDef<MethodReference, MethodDef>>();
IList<RefToDef<FieldReference, FieldDef>> fieldRefsToRename = new List<RefToDef<FieldReference, FieldDef>>();
IList<RefToDef<TypeRef, TypeDef>> typeRefsToRename = new List<RefToDef<TypeRef, TypeDef>>();
IList<RefToDef<MemberRef, MethodDef>> methodRefsToRename = new List<RefToDef<MemberRef, MethodDef>>();
IList<RefToDef<MemberRef, FieldDef>> fieldRefsToRename = new List<RefToDef<MemberRef, FieldDef>>();
List<CustomAttributeReference> customAttributeFieldReferences = new List<CustomAttributeReference>();
List<CustomAttributeReference> customAttributePropertyReferences = new List<CustomAttributeReference>();
List<MethodDef> 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<R, D> where R : MemberReference where D : R {
public class RefToDef<R, D> 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<RefToDef<TypeReference, TypeDef>> TypeRefsToRename {
public IEnumerable<RefToDef<TypeRef, TypeDef>> TypeRefsToRename {
get { return typeRefsToRename; }
}
public IEnumerable<RefToDef<MethodReference, MethodDef>> MethodRefsToRename {
public IEnumerable<RefToDef<MemberRef, MethodDef>> MethodRefsToRename {
get { return methodRefsToRename; }
}
public IEnumerable<RefToDef<FieldReference, FieldDef>> FieldRefsToRename {
public IEnumerable<RefToDef<MemberRef, FieldDef>> 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<MethodDef>(memberRefFinder.methodDefinitions.Keys);
memberRefFinder.findAll(ModuleDefMD);
allMethods = new List<MethodDef>(memberRefFinder.methodDefs.Keys);
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++);
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<TypeReference, TypeDef>(typeRef, typeDef.TypeDef));
typeRefsToRename.Add(new RefToDef<TypeRef, TypeDef>(typeRef, typeDef.TypeDef));
}
foreach (var methodRef in memberRefFinder.methodReferences.Keys) {
var methodDef = resolver.resolveMethod(methodRef);
if (methodDef != null)
methodRefsToRename.Add(new RefToDef<MethodReference, MethodDef>(methodRef, methodDef.MethodDef));
}
foreach (var fieldRef in memberRefFinder.fieldReferences.Keys) {
var fieldDef = resolver.resolveField(fieldRef);
if (fieldDef != null)
fieldRefsToRename.Add(new RefToDef<FieldReference, FieldDef>(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>(memberRef, methodDef.MethodDef));
}
else if (memberRef.IsFieldRef) {
var fieldDef = resolver.resolveField(memberRef);
if (fieldDef != null)
fieldRefsToRename.Add(new RefToDef<MemberRef, FieldDef>(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);
}
}
}

View File

@ -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<string, Module> modulesDict = new Dictionary<string, Module>(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<T> where T : class {
Dictionary<TypeReferenceSameVersionKey, T> dict = new Dictionary<TypeReferenceSameVersionKey, T>();
Dictionary<TypeReferenceKey, List<TypeReference>> refs = new Dictionary<TypeReferenceKey, List<TypeReference>>();
Dictionary<ITypeDefOrRef, T> dict = new Dictionary<ITypeDefOrRef, T>(new TypeEqualityComparer(SigComparerOptions.CompareAssemblyVersion));
Dictionary<ITypeDefOrRef, List<ITypeDefOrRef>> refs = new Dictionary<ITypeDefOrRef, List<ITypeDefOrRef>>(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<TypeReference> list;
if (!refs.TryGetValue(key2, out list))
refs[key2] = list = new List<TypeReference>();
List<ITypeDefOrRef> list;
if (!refs.TryGetValue(type, out list))
refs[type] = list = new List<ITypeDefOrRef>();
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<TypeReference> list;
if (!refs.TryGetValue(key2, out list)) {
public bool tryGetSimilarValue(ITypeDefOrRef type, out T value) {
List<ITypeDefOrRef> 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<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)
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<Module> findModules(TypeReference type) {
IEnumerable<Module> 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> { module };
@ -425,65 +409,71 @@ namespace de4dot.code.renamer.asmmodules {
throw new ApplicationException(string.Format("scope is an unsupported type: {0}", scope.GetType()));
}
IEnumerable<Module> findModules(AssemblyNameReference assemblyRef) {
var moduleHash = assemblyHash.lookup(assemblyRef.ToString());
IEnumerable<Module> findModules(AssemblyRef assemblyRef) {
var moduleHash = assemblyHash.lookup(assemblyRef.FullName);
if (moduleHash != null)
return moduleHash.Modules;
return null;
}
IEnumerable<Module> findModules(ModuleDef moduleDefinition) {
IEnumerable<Module> findModules(ModuleDef moduleDef) {
Module module;
if (modulesDict.TryGetValue(moduleDefinition, out module))
if (modulesDict.TryGetValue(moduleDef, out module))
return new List<Module> { 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;
}

View File

@ -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<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 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<MethodInst> 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<MethodInst>();
list.Add(methodInst);
}
public List<MethodInst> lookup(MethodReference methodReference) {
public List<MethodInst> lookup(IMethod methodReference) {
List<MethodInst> 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<TypeReferenceKey, InterfaceMethodInfo> interfaceMethods = new Dictionary<TypeReferenceKey, InterfaceMethodInfo>();
Dictionary<ITypeDefOrRef, InterfaceMethodInfo> interfaceMethods = new Dictionary<ITypeDefOrRef, InterfaceMethodInfo>(TypeEqualityComparer.Instance);
public IEnumerable<InterfaceMethodInfo> 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<MethodReferenceAndDeclaringTypeKey, MMethodDef>();
var ifaceMethodsDict = new Dictionary<IMethod, MMethodDef>(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()) {

2
dot10

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