From 3db7a0fedf8ea30d50dac6144012141a83553fda Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 2 Nov 2011 02:55:36 +0100 Subject: [PATCH 1/3] Add updates cecil submodule --- cecil | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cecil b/cecil index 9d8fdc79..926f46f2 160000 --- a/cecil +++ b/cecil @@ -1 +1 @@ -Subproject commit 9d8fdc79d367f8359a59fbf63181fd3b3710f861 +Subproject commit 926f46f282a7f8de0b36f3e175568665afb5bad6 From 8b780a46969072de48b6a4969844ee2adf6cb1bd Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 2 Nov 2011 04:14:59 +0100 Subject: [PATCH 2/3] Add ScopeAndTokenKey. Make sure other keys are immutable. --- blocks/MemberReferenceHelper.cs | 64 ++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/blocks/MemberReferenceHelper.cs b/blocks/MemberReferenceHelper.cs index 092ed869..6b397749 100644 --- a/blocks/MemberReferenceHelper.cs +++ b/blocks/MemberReferenceHelper.cs @@ -44,8 +44,54 @@ namespace de4dot.blocks { TypeReference, } + public class ScopeAndTokenKey { + readonly IMetadataScope scope; + readonly int token; + + public ScopeAndTokenKey(TypeReference type) + : this(type.Scope, type.MetadataToken.ToInt32()) { + } + + public ScopeAndTokenKey(FieldReference field) + : this(field.DeclaringType == null ? null : field.DeclaringType.Scope, field.MetadataToken.ToInt32()) { + } + + public ScopeAndTokenKey(MethodReference method) + : this(method.DeclaringType == null ? null : method.DeclaringType.Scope, method.MetadataToken.ToInt32()) { + } + + public ScopeAndTokenKey(PropertyReference prop) + : this(prop.DeclaringType == null ? null : prop.DeclaringType.Scope, prop.MetadataToken.ToInt32()) { + } + + public ScopeAndTokenKey(EventReference evt) + : this(evt.DeclaringType == null ? null : evt.DeclaringType.Scope, evt.MetadataToken.ToInt32()) { + } + + public ScopeAndTokenKey(IMetadataScope scope, int token) { + this.scope = scope; + this.token = token; + } + + public override int GetHashCode() { + return token + MemberReferenceHelper.scopeHashCode(scope); + } + + public override bool Equals(object obj) { + var other = obj as ScopeAndTokenKey; + if (other == null) + return false; + return token == other.token && + MemberReferenceHelper.compareScope(scope, other.scope); + } + + public override string ToString() { + return string.Format("{0:X8} {1}", token, scope); + } + } + public class TypeReferenceKey { - TypeReference typeRef; + readonly TypeReference typeRef; public TypeReference TypeReference { get { return typeRef; } @@ -72,7 +118,7 @@ namespace de4dot.blocks { } public class FieldReferenceKey { - FieldReference fieldRef; + readonly FieldReference fieldRef; public FieldReference FieldReference { get { return fieldRef; } @@ -99,7 +145,7 @@ namespace de4dot.blocks { } public class PropertyReferenceKey { - PropertyReference propRef; + readonly PropertyReference propRef; public PropertyReference PropertyReference { get { return propRef; } @@ -126,7 +172,7 @@ namespace de4dot.blocks { } public class EventReferenceKey { - EventReference eventRef; + readonly EventReference eventRef; public EventReference EventReference { get { return eventRef; } @@ -153,7 +199,7 @@ namespace de4dot.blocks { } public class MethodReferenceKey { - MethodReference methodRef; + readonly MethodReference methodRef; public MethodReference MethodReference { get { return methodRef; } @@ -180,7 +226,7 @@ namespace de4dot.blocks { } public class FieldReferenceAndDeclaringTypeKey { - FieldReference fieldRef; + readonly FieldReference fieldRef; public FieldReference FieldReference { get { return fieldRef; } @@ -209,7 +255,7 @@ namespace de4dot.blocks { } public class MethodReferenceAndDeclaringTypeKey { - MethodReference methodRef; + readonly MethodReference methodRef; public MethodReference MethodReference { get { return methodRef; } @@ -292,7 +338,7 @@ namespace de4dot.blocks { return name; } - static bool compareScope(IMetadataScope a, IMetadataScope b) { + public static bool compareScope(IMetadataScope a, IMetadataScope b) { if (ReferenceEquals(a, b)) return true; if (a == null || b == null) @@ -300,7 +346,7 @@ namespace de4dot.blocks { return getCanonicalizedScopeName(a) == getCanonicalizedScopeName(b); } - static int scopeHashCode(IMetadataScope a) { + public static int scopeHashCode(IMetadataScope a) { if (a == null) return 0; return getCanonicalizedScopeName(a).GetHashCode(); From ccff408a00844f3d7fcbfc5e4605a4bf783e8469 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 2 Nov 2011 04:24:22 +0100 Subject: [PATCH 3/3] Update code so it can rename duplicate member references --- de4dot.code/renamer/DefinitionsRenamer.cs | 3 +- de4dot.code/renamer/MemberRefs.cs | 15 +- de4dot.code/renamer/Misc.cs | 199 +++++++++++++++------- de4dot.code/renamer/Module.cs | 8 +- 4 files changed, 150 insertions(+), 75 deletions(-) diff --git a/de4dot.code/renamer/DefinitionsRenamer.cs b/de4dot.code/renamer/DefinitionsRenamer.cs index 1bc8c060..ed0e6642 100644 --- a/de4dot.code/renamer/DefinitionsRenamer.cs +++ b/de4dot.code/renamer/DefinitionsRenamer.cs @@ -189,11 +189,12 @@ namespace de4dot.renamer { void findAllMemberReferences() { Log.v("Finding all MemberReferences"); + int index = 0; foreach (var module in modules) { if (modules.Count > 1) Log.v("Finding all MemberReferences ({0})", module.Filename); Log.indent(); - module.findAllMemberReferences(); + module.findAllMemberReferences(ref index); Log.deIndent(); } } diff --git a/de4dot.code/renamer/MemberRefs.cs b/de4dot.code/renamer/MemberRefs.cs index 21297f15..9d5aab3a 100644 --- a/de4dot.code/renamer/MemberRefs.cs +++ b/de4dot.code/renamer/MemberRefs.cs @@ -289,11 +289,11 @@ namespace de4dot.renamer { public Module module; string newNamespace = null; - DefDict events = new DefDict(); - DefDict fields = new DefDict(); - DefDict methods = new DefDict(); - DefDict properties = new DefDict(); - DefDict types = new DefDict(); + EventDefDict events = new EventDefDict(); + FieldDefDict fields = new FieldDefDict(); + MethodDefDict methods = new MethodDefDict(); + PropertyDefDict properties = new PropertyDefDict(); + TypeDefDict types = new TypeDefDict(); IList genericParams; public TypeDefinition TypeDefinition { get { return (TypeDefinition)MemberReference; } @@ -316,11 +316,6 @@ namespace de4dot.renamer { : base(typeDefinition, null, index) { this.module = module; genericParams = createGenericParamDefList(TypeDefinition.GenericParameters); - - fields.HandleDupe = (newOne, oldOne) => { - if (oldOne.FieldDefinition.IsLiteral && !newOne.FieldDefinition.IsLiteral) - fields.replaceOldWithNew(oldOne, newOne); - }; } public override bool isSame(MemberReference mr) { diff --git a/de4dot.code/renamer/Misc.cs b/de4dot.code/renamer/Misc.cs index 6f1c8665..a0f90e41 100644 --- a/de4dot.code/renamer/Misc.cs +++ b/de4dot.code/renamer/Misc.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; using Mono.Cecil; +using de4dot.blocks; namespace de4dot.renamer { interface IResolver { @@ -34,39 +35,23 @@ namespace de4dot.renamer { EventDef findEvent(MethodReference methodReference); } - class MyDict { - Dictionary dict = new Dictionary(StringComparer.Ordinal); - public T this[string key] { - get { - T t; - if (dict.TryGetValue(key, out t)) - return t; - return default(T); - } - set { - dict[key] = value; - } - } - - public IEnumerable getAll() { - foreach (var elem in dict.Values) - yield return elem; - } + interface RefDict where TRef : Ref where TMRef : MemberReference { + IEnumerable getAll(); + IEnumerable getSorted(); + TRef find(TMRef tmref); + void add(TRef tref); } - class DefDict where T : Ref { - MyDict> dict = new MyDict>(); - public Action HandleDupe { get; set; } + class TypeDefDict : RefDict { + Dictionary tokenToTypeDef = new Dictionary(); + Dictionary typeRefToDef = new Dictionary(); - public IEnumerable getAll() { - foreach (var list in dict.getAll()) { - foreach (var t in list) - yield return t; - } + public IEnumerable getAll() { + return tokenToTypeDef.Values; } - public IEnumerable getSorted() { - var list = new List(getAll()); + public IEnumerable getSorted() { + var list = new List(getAll()); list.Sort((a, b) => { if (a.Index < b.Index) return -1; if (a.Index > b.Index) return 1; @@ -75,46 +60,140 @@ namespace de4dot.renamer { return list; } - public T find(MemberReference mr) { - var list = dict[mr.Name]; - if (list == null) - return null; + public TypeDef find(TypeReference typeReference) { + TypeDef typeDef; + if (tokenToTypeDef.TryGetValue(new ScopeAndTokenKey(typeReference), out typeDef)) + return typeDef; - foreach (T t in list) { - if (t.isSame(mr)) - return t; - } - return null; + typeRefToDef.TryGetValue(new TypeReferenceKey(typeReference), out typeDef); + return typeDef; } - public void add(T t) { - var other = find(t.MemberReference); - if (other != null) { - handleDupe(t, other); - return; - } + public void add(TypeDef typeDef) { + tokenToTypeDef[new ScopeAndTokenKey(typeDef.TypeDefinition)] = typeDef; + typeRefToDef[new TypeReferenceKey(typeDef.TypeDefinition)] = typeDef; + } + } - var list = dict[t.MemberReference.Name]; - if (list == null) - dict[t.MemberReference.Name] = list = new List(); - list.Add(t); - return; + class FieldDefDict : RefDict { + Dictionary tokenToFieldDef = new Dictionary(); + Dictionary fieldRefToDef = new Dictionary(); + + public IEnumerable getAll() { + return tokenToFieldDef.Values; } - public void replaceOldWithNew(T oldOne, T newOne) { - if (find(newOne.MemberReference) != oldOne) - throw new ApplicationException("Not same member reference"); - - var list = dict[oldOne.MemberReference.Name]; - if (!list.Remove(oldOne)) - throw new ApplicationException("Could not remove old one"); - list.Add(newOne); + public IEnumerable getSorted() { + var list = new List(getAll()); + list.Sort((a, b) => { + if (a.Index < b.Index) return -1; + if (a.Index > b.Index) return 1; + return 0; + }); + return list; } - void handleDupe(T newOne, T oldOne) { - Log.v("Duplicate MemberReference found: {0} ({1:X8} vs {2:X8})", newOne.MemberReference, newOne.MemberReference.MetadataToken.ToUInt32(), oldOne.MemberReference.MetadataToken.ToUInt32()); - if (HandleDupe != null) - HandleDupe(newOne, oldOne); + public FieldDef find(FieldReference fieldReference) { + FieldDef fieldDef; + if (tokenToFieldDef.TryGetValue(new ScopeAndTokenKey(fieldReference), out fieldDef)) + return fieldDef; + + fieldRefToDef.TryGetValue(new FieldReferenceKey(fieldReference), out fieldDef); + return fieldDef; + } + + public void add(FieldDef fieldDef) { + tokenToFieldDef[new ScopeAndTokenKey(fieldDef.FieldDefinition)] = fieldDef; + fieldRefToDef[new FieldReferenceKey(fieldDef.FieldDefinition)] = fieldDef; + } + } + + class MethodDefDict : RefDict { + Dictionary tokenToMethodDef = new Dictionary(); + Dictionary methodRefToDef = new Dictionary(); + + public IEnumerable getAll() { + return tokenToMethodDef.Values; + } + + public IEnumerable getSorted() { + var list = new List(getAll()); + list.Sort((a, b) => { + if (a.Index < b.Index) return -1; + if (a.Index > b.Index) return 1; + return 0; + }); + return list; + } + + public MethodDef find(MethodReference methodReference) { + MethodDef methodDef; + if (tokenToMethodDef.TryGetValue(new ScopeAndTokenKey(methodReference), out methodDef)) + return methodDef; + + methodRefToDef.TryGetValue(new MethodReferenceKey(methodReference), out methodDef); + return methodDef; + } + + public void add(MethodDef methodDef) { + tokenToMethodDef[new ScopeAndTokenKey(methodDef.MethodDefinition)] = methodDef; + methodRefToDef[new MethodReferenceKey(methodDef.MethodDefinition)] = methodDef; + } + } + + class PropertyDefDict : RefDict { + Dictionary tokenToPropDef = new Dictionary(); + + public IEnumerable getAll() { + return tokenToPropDef.Values; + } + + public IEnumerable getSorted() { + var list = new List(getAll()); + list.Sort((a, b) => { + if (a.Index < b.Index) return -1; + if (a.Index > b.Index) return 1; + return 0; + }); + return list; + } + + public PropertyDef find(PropertyReference propertyReference) { + PropertyDef propDef; + tokenToPropDef.TryGetValue(new ScopeAndTokenKey(propertyReference), out propDef); + return propDef; + } + + public void add(PropertyDef propDef) { + tokenToPropDef[new ScopeAndTokenKey(propDef.PropertyDefinition)] = propDef; + } + } + + class EventDefDict : RefDict { + Dictionary tokenToEventDef = new Dictionary(); + + public IEnumerable getAll() { + return tokenToEventDef.Values; + } + + public IEnumerable getSorted() { + var list = new List(getAll()); + list.Sort((a, b) => { + if (a.Index < b.Index) return -1; + if (a.Index > b.Index) return 1; + return 0; + }); + return list; + } + + public EventDef find(EventReference eventReference) { + EventDef propDef; + tokenToEventDef.TryGetValue(new ScopeAndTokenKey(eventReference), out propDef); + return propDef; + } + + public void add(EventDef eventDef) { + tokenToEventDef[new ScopeAndTokenKey(eventDef.EventDefinition)] = eventDef; } } diff --git a/de4dot.code/renamer/Module.cs b/de4dot.code/renamer/Module.cs index daa184d4..2d26294a 100644 --- a/de4dot.code/renamer/Module.cs +++ b/de4dot.code/renamer/Module.cs @@ -27,7 +27,7 @@ namespace de4dot.renamer { class Module : IResolver { IObfuscatedFile obfuscatedFile; MemberRefFinder memberRefFinder; - DefDict allTypes = new DefDict(); + TypeDefDict allTypes = new TypeDefDict(); IList> typeRefsToRename = new List>(); IList> methodRefsToRename = new List>(); IList> fieldRefsToRename = new List>(); @@ -187,7 +187,7 @@ namespace de4dot.renamer { } } - public void findAllMemberReferences() { + public void findAllMemberReferences(ref int typeIndex) { memberRefFinder = new MemberRefFinder(); memberRefFinder.findAll(ModuleDefinition, ModuleDefinition.Types); allMethods = new List(memberRefFinder.methodDefinitions.Keys); @@ -195,7 +195,7 @@ namespace de4dot.renamer { var allTypesList = new List(); foreach (var type in new List(memberRefFinder.typeDefinitions.Keys)) { memberRefFinder.removeTypeDefinition(type); - var typeDef = new TypeDef(type, this); + var typeDef = new TypeDef(type, this, typeIndex++); allTypes.add(typeDef); allTypesList.Add(typeDef); @@ -302,7 +302,7 @@ namespace de4dot.renamer { } void rebuildAllTypesDict() { - var newAllTypes = new DefDict(); + var newAllTypes = new TypeDefDict(); foreach (var typeDef in allTypes.getAll()) newAllTypes.add(typeDef); allTypes = newAllTypes;