优化Rename typeRefs CustomAttributes的时间
parent
b379b0230f
commit
43f3666507
|
@ -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<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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,11 +154,6 @@ namespace Obfuz
|
|||
|
||||
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 (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<TypeDef, RefTypeDefMetas>();
|
||||
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<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)
|
||||
{
|
||||
List<CustomAttributeInfo> customAttributes = _customAttributeArgumentsWithTypeByMods[referenceMeMod];
|
||||
|
|
Loading…
Reference in New Issue