优化Rename typeRefs CustomAttributes的时间

backup
walon 2025-04-15 11:36:13 +08:00
parent b379b0230f
commit 43f3666507
2 changed files with 251 additions and 256 deletions

View File

@ -169,5 +169,210 @@ namespace Obfuz
{ {
return type == ElementType.Class || type == ElementType.ValueType || type == ElementType.Object || type == ElementType.SZArray; 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<TypeSig>();
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<TypeSig>();
foreach (TypeSig arg in methodSig.Params)
{
TypeSig newArg = RetargetTypeRefInTypeSig(arg);
anyChange |= newArg != newReturnType;
}
if (!anyChange)
{
return type;
}
var newParamsAfterSentinel = new List<TypeSig>();
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<CAArgument> oldArr)
{
bool anyChange = false;
var newArr = new List<CAArgument>();
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;
}
} }
} }

View File

@ -154,11 +154,6 @@ namespace Obfuz
private void BuildRefTypeDefMetasMap(Dictionary<TypeDef, RefTypeDefMetas> refTypeDefMetasMap) private void BuildRefTypeDefMetasMap(Dictionary<TypeDef, RefTypeDefMetas> refTypeDefMetasMap)
{ {
//foreach (ObfuzAssemblyInfo ass in GetReferenceMeAssemblies(mod))
//{
// RenameTypeRefInCustomAttribute(ass.module, mod, type, oldFullName);
//}
foreach (ObfuzAssemblyInfo ass in _ctx.assemblies) foreach (ObfuzAssemblyInfo ass in _ctx.assemblies)
{ {
foreach (TypeRef typeRef in ass.module.GetTypeRefs()) 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() private void RenameTypes()
{ {
Debug.Log("RenameTypes begin"); Debug.Log("RenameTypes begin");
RetargetTypeRefInCustomAttributes();
var refTypeDefMetasMap = new Dictionary<TypeDef, RefTypeDefMetas>(); var refTypeDefMetasMap = new Dictionary<TypeDef, RefTypeDefMetas>();
BuildRefTypeDefMetasMap(refTypeDefMetasMap); BuildRefTypeDefMetasMap(refTypeDefMetasMap);
_ctx.assemblyCache.EnableTypeDefCache = false; _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"); Debug.Log("Rename Types end");
} }
@ -382,10 +418,10 @@ namespace Obfuz
ModuleDefMD mod = (ModuleDefMD)type.Module; ModuleDefMD mod = (ModuleDefMD)type.Module;
//RenameTypeRefInCustomAttribute(mod, type, oldFullName, null); //RenameTypeRefInCustomAttribute(mod, type, oldFullName, null);
foreach (ObfuzAssemblyInfo ass in GetReferenceMeAssemblies(mod)) //foreach (ObfuzAssemblyInfo ass in GetReferenceMeAssemblies(mod))
{ //{
RenameTypeRefInCustomAttribute(ass.module, mod, type, oldFullName); // RenameTypeRefInCustomAttribute(ass.module, mod, type, oldFullName);
} //}
if (refTypeDefMeta != null) 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<TypeSig>();
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<TypeSig>();
foreach (TypeSig arg in methodSig.Params)
{
TypeSig newArg = RenameTypeSig (arg, mod, oldFullName);
anyChange |= newArg != newReturnType;
}
if (!anyChange)
{
return type;
}
var newParamsAfterSentinel = new List<TypeSig>();
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<CAArgument> oldArr)
{
bool anyChange = false;
var newArr = new List<CAArgument>();
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<CustomAttributeInfo> 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) private void RenameFieldNameInCustomAttributes(ModuleDefMD referenceMeMod, ModuleDefMD mod, TypeDef declaringType, string oldFieldOrPropertyName, string newName)
{ {
List<CustomAttributeInfo> customAttributes = _customAttributeArgumentsWithTypeByMods[referenceMeMod]; List<CustomAttributeInfo> customAttributes = _customAttributeArgumentsWithTypeByMods[referenceMeMod];