From 6a4f84a9b0c4a1675dbbb9e967a4e3ef8d069cec Mon Sep 17 00:00:00 2001 From: walon Date: Mon, 14 Jul 2025 11:45:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8D=E6=B7=B7=E6=B7=86=E8=A2=ABBurstCompil?= =?UTF-8?q?e=E5=87=BD=E6=95=B0=E7=9B=B4=E6=8E=A5=E6=88=96=E8=80=85?= =?UTF-8?q?=E9=97=B4=E6=8E=A5=E8=B0=83=E7=94=A8=E7=9A=84=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=BD=86=E4=BB=8D=E7=84=B6?= =?UTF-8?q?=E6=B7=B7=E6=B7=86=E5=87=BD=E6=95=B0=E5=90=8D=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/ConstValues.cs | 1 + Editor/ObfuscationMethodWhitelist.cs | 20 ++-- Editor/Obfuscator.cs | 2 +- Editor/Utils/BurstCompileComputeCache.cs | 91 +++++++++++++++++++ Editor/Utils/BurstCompileComputeCache.cs.meta | 11 +++ 5 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 Editor/Utils/BurstCompileComputeCache.cs create mode 100644 Editor/Utils/BurstCompileComputeCache.cs.meta diff --git a/Editor/ConstValues.cs b/Editor/ConstValues.cs index ee05c77..90c3a3b 100644 --- a/Editor/ConstValues.cs +++ b/Editor/ConstValues.cs @@ -13,6 +13,7 @@ namespace Obfuz.Editor public const string ObfuzScopeFullName = "Obfuz.ObfuzScope"; public const string EncryptFieldAttributeFullName = "Obfuz.EncryptFieldAttribute"; + public const string GeneratedEncryptionVirtualMachineFullName = "Obfuz.EncryptionVM.GeneratedEncryptionVirtualMachine"; public const string EmbeddedAttributeFullName = "Microsoft.CodeAnalysis.EmbeddedAttribute"; diff --git a/Editor/ObfuscationMethodWhitelist.cs b/Editor/ObfuscationMethodWhitelist.cs index 35ba6df..4fe07f3 100644 --- a/Editor/ObfuscationMethodWhitelist.cs +++ b/Editor/ObfuscationMethodWhitelist.cs @@ -9,10 +9,12 @@ namespace Obfuz public class ObfuscationMethodWhitelist { private readonly ObfuzIgnoreScopeComputeCache _obfuzComputeCache; + private readonly BurstCompileComputeCache _burstCompileComputeCache; - public ObfuscationMethodWhitelist(ObfuzIgnoreScopeComputeCache obfuzComputeCache) + public ObfuscationMethodWhitelist(ObfuzIgnoreScopeComputeCache obfuzComputeCache, BurstCompileComputeCache burstCompileComputeCache) { _obfuzComputeCache = obfuzComputeCache; + _burstCompileComputeCache = burstCompileComputeCache; } public bool IsInWhiteList(ModuleDef module) @@ -31,7 +33,7 @@ namespace Obfuz private bool DoesMethodContainsRuntimeInitializeOnLoadMethodAttributeAndLoadTypeGreaterEqualAfterAssembliesLoaded(MethodDef method) { - CustomAttribute ca = method.CustomAttributes.Find("UnityEngine.RuntimeInitializeOnLoadMethodAttribute"); + CustomAttribute ca = method.CustomAttributes.Find(ConstValues.RuntimeInitializedOnLoadMethodAttributeFullName); if (ca != null && ca.ConstructorArguments.Count > 0) { RuntimeInitializeLoadType loadType = (RuntimeInitializeLoadType)ca.ConstructorArguments[0].Value; @@ -46,10 +48,10 @@ namespace Obfuz public bool IsInWhiteList(MethodDef method) { TypeDef typeDef = method.DeclaringType; - if (IsInWhiteList(typeDef)) - { - return true; - } + //if (IsInWhiteList(typeDef)) + //{ + // return true; + //} if (method.Name.StartsWith(ConstValues.ObfuzInternalSymbolNamePrefix)) { return true; @@ -58,12 +60,12 @@ namespace Obfuz { return true; } - CustomAttribute ca = method.CustomAttributes.Find("UnityEngine.RuntimeInitializeOnLoadMethodAttribute"); + CustomAttribute ca = method.CustomAttributes.Find(ConstValues.RuntimeInitializedOnLoadMethodAttributeFullName); if (DoesMethodContainsRuntimeInitializeOnLoadMethodAttributeAndLoadTypeGreaterEqualAfterAssembliesLoaded(method)) { return true; } - if (method.CustomAttributes.Find(ConstValues.BurstCompileFullName) != null) + if (method.CustomAttributes.Find(ConstValues.BurstCompileFullName) != null || _burstCompileComputeCache.IsBurstCompileMethodOrReferencedByBurstCompileMethod(method)) { return true; } @@ -98,7 +100,7 @@ namespace Obfuz //{ // return true; //} - if (type.FullName == "Obfuz.EncryptionVM.GeneratedEncryptionVirtualMachine") + if (type.FullName == ConstValues.GeneratedEncryptionVirtualMachineFullName) { return true; } diff --git a/Editor/Obfuscator.cs b/Editor/Obfuscator.cs index 9f4760b..95a5f83 100644 --- a/Editor/Obfuscator.cs +++ b/Editor/Obfuscator.cs @@ -299,7 +299,7 @@ namespace Obfuz obfuzIgnoreScopeComputeCache = obfuzIgnoreScopeComputeCache, - whiteList = new ObfuscationMethodWhitelist(obfuzIgnoreScopeComputeCache), + whiteList = new ObfuscationMethodWhitelist(obfuzIgnoreScopeComputeCache, new BurstCompileComputeCache(modulesToObfuscate, allObfuscationRelativeModules)), passPolicy = _passPolicy, }; ObfuscationPassContext.Current = _ctx; diff --git a/Editor/Utils/BurstCompileComputeCache.cs b/Editor/Utils/BurstCompileComputeCache.cs new file mode 100644 index 0000000..fb25a3b --- /dev/null +++ b/Editor/Utils/BurstCompileComputeCache.cs @@ -0,0 +1,91 @@ +using dnlib.DotNet; +using NUnit.Framework; +using System.Collections.Generic; + +namespace Obfuz.Utils +{ + public class BurstCompileComputeCache + { + private readonly List _modulesToObfuscate; + private readonly List _allObfuscationRelativeModules; + + private readonly HashSet _burstCompileMethods = new HashSet(); + private readonly HashSet _burstCompileRelativeMethods = new HashSet(); + public BurstCompileComputeCache(List modulesToObfuscate, List allObfuscationRelativeModules) + { + _modulesToObfuscate = modulesToObfuscate; + _allObfuscationRelativeModules = allObfuscationRelativeModules; + Build(); + } + + + private void BuildBurstCompileMethods() + { + foreach (var module in _allObfuscationRelativeModules) + { + foreach (var type in module.GetTypes()) + { + bool hasBurstCompileAttribute = MetaUtil.HasBurstCompileAttribute(type); + foreach (var method in type.Methods) + { + if (hasBurstCompileAttribute || MetaUtil.HasBurstCompileAttribute(method)) + { + _burstCompileMethods.Add(method); + } + } + } + } + } + + private void CollectBurstCompileReferencedMethods() + { + var modulesToObfuscateSet = new HashSet(_modulesToObfuscate); + var allObfuscationRelativeModulesSet = new HashSet(_allObfuscationRelativeModules); + + var pendingWalking = new Queue(_burstCompileMethods); + var visitedMethods = new HashSet(); + while (pendingWalking.Count > 0) + { + var method = pendingWalking.Dequeue(); + + if (!visitedMethods.Add(method)) + { + continue; // Skip already visited methods + } + if (modulesToObfuscateSet.Contains(method.Module)) + { + _burstCompileRelativeMethods.Add(method); + } + if (!method.HasBody) + { + continue; + } + // Check for calls to other methods + foreach (var instruction in method.Body.Instructions) + { + if (instruction.OpCode.Code == dnlib.DotNet.Emit.Code.Call || + instruction.OpCode.Code == dnlib.DotNet.Emit.Code.Callvirt) + { + MethodDef calledMethod = ((IMethod)instruction.Operand).ResolveMethodDef(); + if (calledMethod == null || !allObfuscationRelativeModulesSet.Contains(calledMethod.Module) || visitedMethods.Contains(calledMethod)) + { + continue; // Skip if the method could not be resolved + } + pendingWalking.Enqueue(calledMethod); + } + } + } + } + + private void Build() + { + BuildBurstCompileMethods(); + CollectBurstCompileReferencedMethods(); + } + + public bool IsBurstCompileMethodOrReferencedByBurstCompileMethod(MethodDef method) + { + return _burstCompileRelativeMethods.Contains(method); + } + } +} diff --git a/Editor/Utils/BurstCompileComputeCache.cs.meta b/Editor/Utils/BurstCompileComputeCache.cs.meta new file mode 100644 index 0000000..07dd651 --- /dev/null +++ b/Editor/Utils/BurstCompileComputeCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37efeee0ad0b5c34e84bd1b7b401672a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: