From 43f3666507b4c8b435ae32e614185d614d693fe0 Mon Sep 17 00:00:00 2001 From: walon Date: Tue, 15 Apr 2025 11:36:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96Rename=20typeRefs=20CustomAtt?= =?UTF-8?q?ributes=E7=9A=84=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/MetaUtil.cs | 205 +++++++++++++++++++++++ Editor/Rename/SymbolRename.cs | 302 ++++++---------------------------- 2 files changed, 251 insertions(+), 256 deletions(-) diff --git a/Editor/MetaUtil.cs b/Editor/MetaUtil.cs index b405cbe..19f47b4 100644 --- a/Editor/MetaUtil.cs +++ b/Editor/MetaUtil.cs @@ -169,5 +169,210 @@ namespace Obfuz { return type == ElementType.Class || type == ElementType.ValueType || type == ElementType.Object || type == ElementType.SZArray; } + + public static TypeSig RetargetTypeRefInTypeSig(TypeSig type) + { + TypeSig next = type.Next; + TypeSig newNext = next != null ? RetargetTypeRefInTypeSig(next) : null; + if (type.IsModifier || type.IsPinned) + { + if (next == newNext) + { + return type; + } + if (type is CModReqdSig cmrs) + { + return new CModReqdSig(cmrs.Modifier, newNext); + } + if (type is CModOptSig cmos) + { + return new CModOptSig(cmos.Modifier, newNext); + } + if (type is PinnedSig ps) + { + return new PinnedSig(newNext); + } + throw new System.NotSupportedException(type.ToString()); + } + switch (type.ElementType) + { + case ElementType.Ptr: + { + if (next == newNext) + { + return type; + } + return new PtrSig(newNext); + } + case ElementType.ValueType: + case ElementType.Class: + { + var vts = type as ClassOrValueTypeSig; + TypeDef typeDef = vts.TypeDefOrRef.ResolveTypeDefThrow(); + if (typeDef == vts.TypeDefOrRef) + { + return type; + } + return type.IsClassSig ? new ClassSig(typeDef) : new ValueTypeSig(typeDef); + } + case ElementType.Array: + { + if (next == newNext) + { + return type; + } + return new ArraySig(newNext); + } + case ElementType.SZArray: + { + if (next == newNext) + { + return type; + } + return new SZArraySig(newNext); + } + case ElementType.GenericInst: + { + var gis = type as GenericInstSig; + ClassOrValueTypeSig genericType = gis.GenericType; + ClassOrValueTypeSig newGenericType = (ClassOrValueTypeSig)RetargetTypeRefInTypeSig(genericType); + bool anyChange = genericType != newGenericType; + var genericArgs = new List(); + foreach (var arg in gis.GenericArguments) + { + TypeSig newArg = RetargetTypeRefInTypeSig(arg); + anyChange |= newArg != genericType; + genericArgs.Add(newArg); + } + if (!anyChange) + { + return type; + } + return new GenericInstSig(newGenericType, genericArgs); + } + case ElementType.FnPtr: + { + var fp = type as FnPtrSig; + MethodSig methodSig = fp.MethodSig; + TypeSig newReturnType = RetargetTypeRefInTypeSig(methodSig.RetType); + bool anyChange = newReturnType != methodSig.RetType; + var newArgs = new List(); + foreach (TypeSig arg in methodSig.Params) + { + TypeSig newArg = RetargetTypeRefInTypeSig(arg); + anyChange |= newArg != newReturnType; + } + if (!anyChange) + { + return type; + } + var newParamsAfterSentinel = new List(); + foreach (TypeSig arg in methodSig.ParamsAfterSentinel) + { + TypeSig newArg = RetargetTypeRefInTypeSig(arg); + anyChange |= newArg != arg; + newParamsAfterSentinel.Add(newArg); + } + + var newMethodSig = new MethodSig(methodSig.CallingConvention, methodSig.GenParamCount, newReturnType, newArgs, newParamsAfterSentinel); + return new FnPtrSig(newMethodSig); + } + case ElementType.ByRef: + { + if (next == newNext) + { + return type; + } + return new ByRefSig(newNext); + } + default: + { + return type; + } + } + } + + + public static object RetargetTypeRefInTypeSigOfValue(object oldValue) + { + if (oldValue == null) + { + return null; + } + string typeName = oldValue.GetType().FullName; + if (oldValue.GetType().IsPrimitive) + { + return oldValue; + } + if (oldValue is string || oldValue is UTF8String) + { + return oldValue; + } + if (oldValue is TypeSig typeSig) + { + return RetargetTypeRefInTypeSig(typeSig); + } + if (oldValue is CAArgument caValue) + { + TypeSig newType = RetargetTypeRefInTypeSig(caValue.Type); + object newValue = RetargetTypeRefInTypeSigOfValue(caValue.Value); + if (newType != caValue.Type || newValue != caValue.Value) + { + return new CAArgument(newType, newValue); + } + return oldValue; + } + if (oldValue is List oldArr) + { + bool anyChange = false; + var newArr = new List(); + foreach (CAArgument oldArg in oldArr) + { + if (TryRetargetTypeRefInArgument(oldArg, out var newArg)) + { + anyChange = true; + newArr.Add(newArg); + } + else + { + newArr.Add(oldArg); + } + } + return anyChange ? newArr : oldArr; + } + throw new NotSupportedException($"type:{oldValue.GetType()} value:{oldValue}"); + } + + + + public static bool TryRetargetTypeRefInArgument(CAArgument oldArg, out CAArgument newArg) + { + TypeSig newType = RetargetTypeRefInTypeSig(oldArg.Type); + object newValue = RetargetTypeRefInTypeSigOfValue(oldArg.Value); + if (newType != oldArg.Type || oldArg.Value != newValue) + { + newArg = new CAArgument(newType, newValue); + return true; + } + newArg = default; + return false; + } + + public static bool TryRetargetTypeRefInNamedArgument(CANamedArgument arg) + { + bool anyChange = false; + TypeSig newType = RetargetTypeRefInTypeSig(arg.Type); + if (newType != arg.Type) + { + anyChange = true; + arg.Type = newType; + } + if (TryRetargetTypeRefInArgument(arg.Argument, out var newArg)) + { + arg.Argument = newArg; + anyChange = true; + } + return anyChange; + } } } diff --git a/Editor/Rename/SymbolRename.cs b/Editor/Rename/SymbolRename.cs index ac2832b..8b31463 100644 --- a/Editor/Rename/SymbolRename.cs +++ b/Editor/Rename/SymbolRename.cs @@ -154,11 +154,6 @@ namespace Obfuz private void BuildRefTypeDefMetasMap(Dictionary refTypeDefMetasMap) { - //foreach (ObfuzAssemblyInfo ass in GetReferenceMeAssemblies(mod)) - //{ - // RenameTypeRefInCustomAttribute(ass.module, mod, type, oldFullName); - //} - foreach (ObfuzAssemblyInfo ass in _ctx.assemblies) { foreach (TypeRef typeRef in ass.module.GetTypeRefs()) @@ -174,10 +169,49 @@ namespace Obfuz } } + private void RetargetTypeRefInCustomAttributes() + { + foreach (CustomAttributeInfo cai in _customAttributeArgumentsWithTypeByMods.Values.SelectMany(cas => cas)) + { + CustomAttribute ca = cai.customAttributes[cai.index]; + bool anyChange = false; + if (cai.arguments != null) + { + for (int i = 0; i < cai.arguments.Count; i++) + { + CAArgument oldArg = cai.arguments[i]; + if (MetaUtil.TryRetargetTypeRefInArgument(oldArg, out CAArgument newArg)) + { + anyChange = true; + cai.arguments[i] = newArg; + } + } + } + if (cai.namedArguments != null) + { + for (int i = 0; i < cai.namedArguments.Count; i++) + { + if (MetaUtil.TryRetargetTypeRefInNamedArgument(cai.namedArguments[i])) + { + anyChange = true; + } + } + } + if (anyChange) + { + cai.customAttributes[cai.index] = new CustomAttribute(ca.Constructor, + cai.arguments != null ? cai.arguments : ca.ConstructorArguments, + cai.namedArguments != null ? cai.namedArguments : ca.NamedArguments); + } + } + } + private void RenameTypes() { Debug.Log("RenameTypes begin"); + RetargetTypeRefInCustomAttributes(); + var refTypeDefMetasMap = new Dictionary(); BuildRefTypeDefMetasMap(refTypeDefMetasMap); _ctx.assemblyCache.EnableTypeDefCache = false; @@ -196,7 +230,9 @@ namespace Obfuz } } } - _ctx.assemblyCache.EnableTypeDefCache = true; + + // clean cache + _ctx.assemblyCache.EnableTypeDefCache = true; Debug.Log("Rename Types end"); } @@ -382,10 +418,10 @@ namespace Obfuz ModuleDefMD mod = (ModuleDefMD)type.Module; //RenameTypeRefInCustomAttribute(mod, type, oldFullName, null); - foreach (ObfuzAssemblyInfo ass in GetReferenceMeAssemblies(mod)) - { - RenameTypeRefInCustomAttribute(ass.module, mod, type, oldFullName); - } + //foreach (ObfuzAssemblyInfo ass in GetReferenceMeAssemblies(mod)) + //{ + // RenameTypeRefInCustomAttribute(ass.module, mod, type, oldFullName); + //} if (refTypeDefMeta != null) { @@ -408,252 +444,6 @@ namespace Obfuz } - private TypeSig RenameTypeSig(TypeSig type, ModuleDefMD mod, string oldFullName) - { - TypeSig next = type.Next; - TypeSig newNext = next != null ? RenameTypeSig(next, mod, oldFullName) : null; - if (type.IsModifier || type.IsPinned) - { - if (next == newNext) - { - return type; - } - if (type is CModReqdSig cmrs) - { - return new CModReqdSig(cmrs.Modifier, newNext); - } - if (type is CModOptSig cmos) - { - return new CModOptSig(cmos.Modifier, newNext); - } - if (type is PinnedSig ps) - { - return new PinnedSig(newNext); - } - throw new System.NotSupportedException(type.ToString()); - } - switch (type.ElementType) - { - case ElementType.Ptr: - { - if (next == newNext) - { - return type; - } - return new PtrSig(newNext); - } - case ElementType.ValueType: - case ElementType.Class: - { - var vts = type as ClassOrValueTypeSig; - if (vts.DefinitionAssembly.Name != mod.Assembly.Name || vts.TypeDefOrRef.FullName != oldFullName) - { - return type; - } - TypeDef typeDef = vts.TypeDefOrRef.ResolveTypeDefThrow(); - if (typeDef == vts.TypeDefOrRef) - { - return type; - } - return type.IsClassSig ? new ClassSig(typeDef) : new ValueTypeSig(typeDef); - } - case ElementType.Array: - { - if (next == newNext) - { - return type; - } - return new ArraySig(newNext); - } - case ElementType.SZArray: - { - if (next == newNext) - { - return type; - } - return new SZArraySig(newNext); - } - case ElementType.GenericInst: - { - var gis = type as GenericInstSig; - ClassOrValueTypeSig genericType = gis.GenericType; - ClassOrValueTypeSig newGenericType = (ClassOrValueTypeSig)RenameTypeSig(genericType, mod, oldFullName); - bool anyChange = genericType != newGenericType; - var genericArgs = new List(); - foreach (var arg in gis.GenericArguments) - { - TypeSig newArg = RenameTypeSig(arg, mod, oldFullName); - anyChange |= newArg != genericType; - genericArgs.Add(newArg); - } - if (!anyChange) - { - return type; - } - return new GenericInstSig(newGenericType, genericArgs); - } - case ElementType.FnPtr: - { - var fp = type as FnPtrSig; - MethodSig methodSig = fp.MethodSig; - TypeSig newReturnType = RenameTypeSig(methodSig.RetType, mod, oldFullName); - bool anyChange = newReturnType != methodSig.RetType; - var newArgs = new List(); - foreach (TypeSig arg in methodSig.Params) - { - TypeSig newArg = RenameTypeSig (arg, mod, oldFullName); - anyChange |= newArg != newReturnType; - } - if (!anyChange) - { - return type; - } - var newParamsAfterSentinel = new List(); - foreach(TypeSig arg in methodSig.ParamsAfterSentinel) - { - TypeSig newArg = RenameTypeSig(arg, mod, oldFullName); - anyChange |= newArg != arg; - newParamsAfterSentinel.Add(newArg); - } - - var newMethodSig = new MethodSig(methodSig.CallingConvention, methodSig.GenParamCount, newReturnType, newArgs, newParamsAfterSentinel); - return new FnPtrSig(newMethodSig); - } - case ElementType.ByRef: - { - if (next == newNext) - { - return type; - } - return new ByRefSig(newNext); - } - default: - { - return type; - } - } - } - - - private object RenameTypeSigOfValue(object oldValue, ModuleDefMD mod, string oldFullName) - { - if (oldValue == null) - { - return null; - } - string typeName = oldValue.GetType().FullName; - if (oldValue.GetType().IsPrimitive) - { - return oldValue; - } - if (oldValue is string || oldValue is UTF8String) - { - return oldValue; - } - if (oldValue is TypeSig typeSig) - { - return RenameTypeSig(typeSig, mod, oldFullName); - } - if (oldValue is CAArgument caValue) - { - TypeSig newType = RenameTypeSig(caValue.Type, mod, oldFullName); - object newValue = RenameTypeSigOfValue(caValue.Value, mod, oldFullName); - if (newType != caValue.Type || newValue != caValue.Value) - { - return new CAArgument(newType, newValue); - } - return oldValue; - } - if (oldValue is List oldArr) - { - bool anyChange = false; - var newArr = new List(); - foreach (CAArgument oldArg in oldArr) - { - if (TryRenameArgument(mod, oldFullName, oldArg, out var newArg)) - { - anyChange = true; - newArr.Add(newArg); - } - else - { - newArr.Add(oldArg); - } - } - return anyChange ? newArr : oldArr; - } - throw new NotSupportedException($"type:{oldValue.GetType()} value:{oldValue}"); - } - - private bool TryRenameArgument(ModuleDefMD mod, string oldFullName, CAArgument oldArg, out CAArgument newArg) - { - TypeSig newType = RenameTypeSig(oldArg.Type, mod, oldFullName); - object newValue = RenameTypeSigOfValue(oldArg.Value, mod, oldFullName); - if (newType != oldArg.Type || oldArg.Value != newValue) - { - newArg = new CAArgument(newType, newValue); - return true; - } - newArg = default; - return false; - } - - private bool TryRenameArgument(ModuleDefMD mod, string oldFullName, CANamedArgument oldArg) - { - bool anyChange = false; - TypeSig newType = RenameTypeSig(oldArg.Type, mod, oldFullName); - if (newType != oldArg.Type) - { - anyChange = true; - oldArg.Type = newType; - } - if (TryRenameArgument(mod, oldFullName, oldArg.Argument, out var newArg)) - { - oldArg.Argument = newArg; - anyChange = true; - } - return anyChange; - } - - private void RenameTypeRefInCustomAttribute(ModuleDefMD referenceMeMod, ModuleDefMD mod, TypeDef typeDef, string oldFullName) - { - List customAttributes = _customAttributeArgumentsWithTypeByMods[referenceMeMod]; - foreach (CustomAttributeInfo cai in customAttributes) - { - CustomAttribute oldAttr = cai.customAttributes[cai.index]; - bool anyChange = false; - if (cai.arguments != null) - { - for (int i = 0; i < cai.arguments.Count; i++) - { - CAArgument oldArg = cai.arguments[i]; - if (TryRenameArgument(mod, oldFullName, oldArg, out CAArgument newArg)) - { - anyChange = true; - cai.arguments[cai.index] = newArg; - } - } - } - if (cai.namedArguments != null) - { - for (int i = 0; i < cai.namedArguments.Count; i++) - { - CANamedArgument oldArg = cai.namedArguments[i]; - if (TryRenameArgument(mod, oldFullName, oldArg)) - { - anyChange = true; - } - } - } - if (anyChange) - { - cai.customAttributes[cai.index] = new CustomAttribute(oldAttr.Constructor, - cai.arguments != null ? cai.arguments : oldAttr.ConstructorArguments, - cai.namedArguments != null ? cai.namedArguments : oldAttr.NamedArguments); - } - } - } - private void RenameFieldNameInCustomAttributes(ModuleDefMD referenceMeMod, ModuleDefMD mod, TypeDef declaringType, string oldFieldOrPropertyName, string newName) { List customAttributes = _customAttributeArgumentsWithTypeByMods[referenceMeMod];