重构 rename policy

backup
walon 2025-04-07 10:27:19 +08:00
parent bb9d784090
commit 4122a42d78
10 changed files with 392 additions and 59 deletions

View File

@ -1,4 +1,5 @@
using System; using dnlib.DotNet;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -13,5 +14,155 @@ namespace Obfuz
{ {
return Path.GetFileNameWithoutExtension(moduleName); return Path.GetFileNameWithoutExtension(moduleName);
} }
public static TypeDef GetBaseTypeDef(TypeDef type)
{
ITypeDefOrRef baseType = type.BaseType;
if (baseType == null)
{
return null;
}
TypeDef baseTypeDef = baseType.ResolveTypeDef();
if (baseTypeDef != null)
{
return baseTypeDef;
}
if (baseType is TypeSpec baseTypeSpec)
{
GenericInstSig genericIns = baseTypeSpec.TypeSig.ToGenericInstSig();
return genericIns.GenericType.TypeDefOrRef.ResolveTypeDefThrow();
}
else
{
throw new Exception($"GetBaseTypeDef: {type} fail");
}
}
public static TypeDef GetTypeDefOrGenericTypeBase(ITypeDefOrRef type)
{
if (type.IsTypeDef)
{
return (TypeDef)type;
}
if (type.IsTypeRef)
{
return type.ResolveTypeDefThrow();
}
if (type.IsTypeSpec)
{
GenericInstSig gis = type.TryGetGenericInstSig();
return gis.GenericType.ToTypeDefOrRef().ResolveTypeDefThrow();
}
throw new NotSupportedException($"{type}");
}
public static bool IsInheritFromUnityObject(TypeDef typeDef)
{
TypeDef cur = typeDef;
while (true)
{
cur = GetBaseTypeDef(cur);
if (cur == null)
{
return false;
}
if (cur.Name == "Object" && cur.Namespace == "UnityEngine" && cur.Module.Name == "UnityEngine.CoreModule.dll")
{
return true;
}
}
}
public static bool IsScriptOrSerializableType(TypeDef type)
{
if (type.ContainsGenericParameter)
{
return false;
}
if (type.IsSerializable)
{
return true;
}
for (TypeDef parentType = GetBaseTypeDef(type); parentType != null; parentType = GetBaseTypeDef(parentType))
{
if ((parentType.Name == "MonoBehaviour" || parentType.Name == "ScriptableObject")
&& parentType.Namespace == "UnityEngine"
&& parentType.Module.Assembly.Name == "UnityEngine.CoreModule")
{
return true;
}
}
return false;
}
public static bool IsSerializableTypeSig(TypeSig typeSig)
{
typeSig = typeSig.RemovePinnedAndModifiers();
switch (typeSig.ElementType)
{
case ElementType.Boolean:
case ElementType.Char:
case ElementType.I1:
case ElementType.U1:
case ElementType.I2:
case ElementType.U2:
case ElementType.I4:
case ElementType.U4:
case ElementType.I8:
case ElementType.U8:
case ElementType.R4:
case ElementType.R8:
case ElementType.String:
return true;
case ElementType.Class:
return IsScriptOrSerializableType(typeSig.ToTypeDefOrRef().ResolveTypeDefThrow());
case ElementType.ValueType:
{
TypeDef typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow();
if (typeDef.IsEnum)
{
return true;
}
return typeDef.IsSerializable;
}
case ElementType.GenericInst:
{
GenericInstSig genericIns = typeSig.ToGenericInstSig();
TypeDef typeDef = genericIns.GenericType.ToTypeDefOrRef().ResolveTypeDefThrow();
return typeDef.FullName == "System.Collections.Generic.List`1" && IsSerializableTypeSig(genericIns.GenericArguments[0]);
}
case ElementType.SZArray:
{
return IsSerializableTypeSig(typeSig.RemovePinnedAndModifiers().Next);
}
default:
return false;
}
}
public static bool IsSerializableField(FieldDef field)
{
if (field.IsStatic)
{
return false;
}
var fieldSig = field.FieldSig.Type;
if (field.IsPublic)
{
return IsSerializableTypeSig(fieldSig);
}
if (field.CustomAttributes.Any(c => c.TypeFullName == "UnityEngine.SerializeField"))
{
//UnityEngine.Debug.Assert(IsSerializableTypeSig(fieldSig));
return true;
}
return false;
}
} }
} }

View File

@ -33,7 +33,7 @@ namespace Obfuz
{ {
_options = options; _options = options;
_assemblyCache = new AssemblyCache(new PathAssemblyResolver(options.AssemblySearchDirs.ToArray())); _assemblyCache = new AssemblyCache(new PathAssemblyResolver(options.AssemblySearchDirs.ToArray()));
_renamePolicy = new RenamePolicy(); _renamePolicy = new CombineRenamePolicy(new SystemRenamePolicy(), new UnityRenamePolicy(), new XmlConfigRenamePolicy());
_nameMaker = new NameMaker(); _nameMaker = new NameMaker();
} }

View File

@ -0,0 +1,44 @@
using dnlib.DotNet;
using System.Linq;
namespace Obfuz.Rename
{
public class CombineRenamePolicy : IRenamePolicy
{
private readonly IRenamePolicy[] _policies;
public CombineRenamePolicy(params IRenamePolicy[] policies)
{
_policies = policies;
}
public bool NeedRename(ModuleDefMD mod)
{
return _policies.All(policy => policy.NeedRename(mod));
}
public bool NeedRename(TypeDef typeDef)
{
return _policies.All(policy => policy.NeedRename(typeDef));
}
public bool NeedRename(MethodDef methodDef)
{
return _policies.All(policy => policy.NeedRename(methodDef));
}
public bool NeedRename(FieldDef fieldDef)
{
return _policies.All(policy => policy.NeedRename(fieldDef));
}
public bool NeedRename(PropertyDef propertyDef)
{
return _policies.All(policy => policy.NeedRename(propertyDef));
}
public bool NeedRename(EventDef eventDef)
{
return _policies.All(policy => policy.NeedRename(eventDef));
}
}
}

View File

@ -0,0 +1,19 @@
using dnlib.DotNet;
namespace Obfuz.Rename
{
public interface IRenamePolicy
{
bool NeedRename(ModuleDefMD mod);
bool NeedRename(TypeDef typeDef);
bool NeedRename(MethodDef methodDef);
bool NeedRename(FieldDef fieldDef);
bool NeedRename(PropertyDef propertyDef);
bool NeedRename(EventDef eventDef);
}
}

View File

@ -1,57 +0,0 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz.Rename
{
public interface IRenamePolicy
{
bool NeedRename(ModuleDefMD mod);
bool NeedRename(TypeDef typeDef);
bool NeedRename(MethodDef methodDef);
bool NeedRename(FieldDef fieldDef);
bool NeedRename(PropertyDef propertyDef);
bool NeedRename(EventDef eventDef);
}
public class RenamePolicy : IRenamePolicy
{
public bool NeedRename(ModuleDefMD mod)
{
return false;
}
public bool NeedRename(TypeDef typeDef)
{
return true;
}
public bool NeedRename(MethodDef methodDef)
{
return true;
}
public bool NeedRename(FieldDef fieldDef)
{
return true;
}
public bool NeedRename(PropertyDef propertyDef)
{
return true;
}
public bool NeedRename(EventDef eventDef)
{
return true;
}
}
}

View File

@ -0,0 +1,37 @@
using dnlib.DotNet;
namespace Obfuz.Rename
{
public abstract class RenamePolicyBase : IRenamePolicy
{
public virtual bool NeedRename(ModuleDefMD mod)
{
return true;
}
public virtual bool NeedRename(TypeDef typeDef)
{
return true;
}
public virtual bool NeedRename(MethodDef methodDef)
{
return true;
}
public virtual bool NeedRename(FieldDef fieldDef)
{
return true;
}
public virtual bool NeedRename(PropertyDef propertyDef)
{
return true;
}
public virtual bool NeedRename(EventDef eventDef)
{
return true;
}
}
}

View File

@ -74,6 +74,7 @@ namespace Obfuz
} }
} }
} }
// TODO handle typeof(XXX) in Attribute
} }
private bool IsSystemReservedType(TypeDef type) private bool IsSystemReservedType(TypeDef type)

View File

@ -0,0 +1,17 @@
using dnlib.DotNet;
namespace Obfuz.Rename
{
public class SystemRenamePolicy : RenamePolicyBase
{
public override bool NeedRename(TypeDef typeDef)
{
string name = typeDef.Name;
if (name == "<Module>")
{
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,84 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz.Rename
{
public class UnityRenamePolicy : RenamePolicyBase
{
private static HashSet<string> s_monoBehaviourEvents = new HashSet<string> {
"Awake",
"OnEnable",
"Start",
"FixedUpdate",
"Update",
"LateUpdate",
"OnDisable",
"OnDestroy",
"OnApplicationQuit",
"OnTriggerEnter",
"OnTriggerExit",
"OnTriggerStay",
"OnCollisionEnter",
"OnCollisionExit",
"OnCollisionStay",
"OnMouseDown",
"OnMouseUp",
"OnMouseEnter",
"OnMouseExit",
"OnMouseOver",
"OnMouseDrag",
"OnBecameVisible",
"OnBecameInvisible",
"OnGUI",
"OnPreRender",
"OnPostRender",
"OnRenderObject",
"OnDrawGizmos",
"OnDrawGizmosSelected",
"OnValidate",
"OnAnimatorIK",
"OnAnimatorMove",
"OnApplicationFocus",
"OnApplicationPause",
"OnAudioFilterRead",
"OnJointBreak",
"OnParticleCollision",
"OnTransformChildrenChanged",
"OnTransformParentChanged",
"OnRectTransformDimensionsChange",
"OnWillRenderObject"
};
public override bool NeedRename(TypeDef typeDef)
{
if (MetaUtil.IsScriptOrSerializableType(typeDef))
{
return false;
}
return true;
}
public override bool NeedRename(MethodDef methodDef)
{
if (MetaUtil.IsInheritFromUnityObject(methodDef.DeclaringType))
{
return !s_monoBehaviourEvents.Contains(methodDef.Name);
}
return true;
}
public override bool NeedRename(FieldDef fieldDef)
{
TypeDef typeDef = fieldDef.DeclaringType;
if (MetaUtil.IsScriptOrSerializableType(typeDef))
{
return !MetaUtil.IsSerializableField(fieldDef);
}
return true;
}
}
}

View File

@ -0,0 +1,37 @@
using dnlib.DotNet;
namespace Obfuz.Rename
{
public class XmlConfigRenamePolicy : RenamePolicyBase
{
public override bool NeedRename(ModuleDefMD mod)
{
return false;
}
public override bool NeedRename(TypeDef typeDef)
{
return true;
}
public override bool NeedRename(MethodDef methodDef)
{
return true;
}
public override bool NeedRename(FieldDef fieldDef)
{
return true;
}
public override bool NeedRename(PropertyDef propertyDef)
{
return true;
}
public override bool NeedRename(EventDef eventDef)
{
return true;
}
}
}