From 83c0b921e3a054e3c4f4e5a1b4ee30e027fa447b Mon Sep 17 00:00:00 2001 From: walon Date: Fri, 9 May 2025 20:18:24 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=92=8C=E9=87=8D=E6=9E=84Ca?= =?UTF-8?q?llObfus=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/Data/ConstFieldAllocator.cs | 2 +- Editor/Data/RvaDataAllocator.cs | 11 ++- Editor/Emit/EmitManager.cs | 4 +- .../{ProxyCallPass.cs => CallObfusPass.cs} | 15 ++-- ...llPolicyBase.cs => CallObfusPolicyBase.cs} | 2 +- ...bfuscatorBase.cs => CallObfuscatorBase.cs} | 2 +- ...CallAllocator.cs => CallProxyAllocator.cs} | 80 +++++++++++++------ ...licy.cs => ConfigurableCallObfusPolicy.cs} | 2 +- .../CallObfus/DefaultProxyCallObfuscator.cs | 16 ++-- ...ProxyCallPolicy.cs => ICallObfusPolicy.cs} | 2 +- ...xyCallObfuscator.cs => ICallObfuscator.cs} | 2 +- Editor/ObfuscatorBuilder.cs | 2 +- Editor/Settings/CallObfusSettings.cs | 13 +++ Editor/Settings/ObfuzSettings.cs | 3 + Editor/Settings/ObfuzSettingsProvider.cs | 3 + 15 files changed, 108 insertions(+), 51 deletions(-) rename Editor/ObfusPasses/CallObfus/{ProxyCallPass.cs => CallObfusPass.cs} (83%) rename Editor/ObfusPasses/CallObfus/{ProxyCallPolicyBase.cs => CallObfusPolicyBase.cs} (79%) rename Editor/ObfusPasses/CallObfus/{ProxyCallObfuscatorBase.cs => CallObfuscatorBase.cs} (81%) rename Editor/ObfusPasses/CallObfus/{ProxyCallAllocator.cs => CallProxyAllocator.cs} (77%) rename Editor/ObfusPasses/CallObfus/{ConfigProxyCallPolicy.cs => ConfigurableCallObfusPolicy.cs} (95%) rename Editor/ObfusPasses/CallObfus/{IProxyCallPolicy.cs => ICallObfusPolicy.cs} (89%) rename Editor/ObfusPasses/CallObfus/{IProxyCallObfuscator.cs => ICallObfuscator.cs} (89%) create mode 100644 Editor/Settings/CallObfusSettings.cs diff --git a/Editor/Data/ConstFieldAllocator.cs b/Editor/Data/ConstFieldAllocator.cs index fa6c44f..787de29 100644 --- a/Editor/Data/ConstFieldAllocator.cs +++ b/Editor/Data/ConstFieldAllocator.cs @@ -268,7 +268,7 @@ namespace Obfuz.Data private ModuleConstFieldAllocator GetModuleAllocator(ModuleDef mod) { - return EmitManager.Ins.GetEmitManager(mod, m => new ModuleConstFieldAllocator(_encryptor, _random, _rvaDataAllocator)); + return EmitManager.Ins.GetEmitManager(mod, () => new ModuleConstFieldAllocator(_encryptor, _random, _rvaDataAllocator)); } public FieldDef Allocate(ModuleDef mod, int value) diff --git a/Editor/Data/RvaDataAllocator.cs b/Editor/Data/RvaDataAllocator.cs index 3140196..70b0d8a 100644 --- a/Editor/Data/RvaDataAllocator.cs +++ b/Editor/Data/RvaDataAllocator.cs @@ -28,9 +28,9 @@ namespace Obfuz.Data public class ModuleRvaDataAllocator : ModuleEmitManagerBase { // randomized - const int maxRvaDataSize = 0x100; + const int maxRvaDataSize = 0x1000; - private readonly ModuleDef _module; + private ModuleDef _module; private readonly IRandom _random; private readonly IEncryptor _encryptor; @@ -69,16 +69,15 @@ namespace Obfuz.Data private readonly Dictionary _dataHolderTypeBySizes = new Dictionary(); - public ModuleRvaDataAllocator(ModuleDef mod, IRandom random, IEncryptor encryptor) + public ModuleRvaDataAllocator(IRandom random, IEncryptor encryptor) { - _module = mod; _random = random; _encryptor = encryptor; } public override void Init(ModuleDef mod) { - + _module = mod; } private (FieldDef, FieldDef) CreateDataHolderRvaField(TypeDef dataHolderType) @@ -297,7 +296,7 @@ namespace Obfuz.Data private ModuleRvaDataAllocator GetModuleRvaDataAllocator(ModuleDef mod) { - return EmitManager.Ins.GetEmitManager(mod, mod => new ModuleRvaDataAllocator(mod, _random, _encryptor)); + return EmitManager.Ins.GetEmitManager(mod, () => new ModuleRvaDataAllocator(_random, _encryptor)); } public RvaData Allocate(ModuleDef mod, int value) diff --git a/Editor/Emit/EmitManager.cs b/Editor/Emit/EmitManager.cs index 278a0df..aba9ea1 100644 --- a/Editor/Emit/EmitManager.cs +++ b/Editor/Emit/EmitManager.cs @@ -29,7 +29,7 @@ namespace Obfuz.Emit Ins = new EmitManager(); } - public T GetEmitManager(ModuleDef mod, Func creator = null) where T : IModuleEmitManager + public T GetEmitManager(ModuleDef mod, Func creator = null) where T : IModuleEmitManager { var key = (mod, typeof(T)); if (_moduleEmitManagers.TryGetValue(key, out var emitManager)) @@ -41,7 +41,7 @@ namespace Obfuz.Emit T newEmitManager; if (creator != null) { - newEmitManager = creator(mod); + newEmitManager = creator(); } else { diff --git a/Editor/ObfusPasses/CallObfus/ProxyCallPass.cs b/Editor/ObfusPasses/CallObfus/CallObfusPass.cs similarity index 83% rename from Editor/ObfusPasses/CallObfus/ProxyCallPass.cs rename to Editor/ObfusPasses/CallObfus/CallObfusPass.cs index 9c4c576..54387c4 100644 --- a/Editor/ObfusPasses/CallObfus/ProxyCallPass.cs +++ b/Editor/ObfusPasses/CallObfus/CallObfusPass.cs @@ -9,20 +9,23 @@ using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using UnityEngine.Assertions; +using Obfuz.Settings; namespace Obfuz.ObfusPasses.CallObfus { - public class ProxyCallPass : InstructionObfuscationPassBase + public class CallObfusPass : InstructionObfuscationPassBase { private readonly IRandom _random; - private readonly IProxyCallPolicy _dynamicProxyPolicy; - private readonly IProxyCallObfuscator _dynamicProxyObfuscator; + private readonly IEncryptor _encryptor; + private readonly ICallObfusPolicy _dynamicProxyPolicy; + private readonly ICallObfuscator _dynamicProxyObfuscator; - public ProxyCallPass() + public CallObfusPass(CallObfusSettings settings) { _random = new RandomWithKey(new byte[] { 0x1, 0x2, 0x3, 0x4 }, 0x5); - _dynamicProxyPolicy = new ConfigProxyCallPolicy(); - _dynamicProxyObfuscator = new DefaultProxyCallObfuscator(_random); + _encryptor = new DefaultEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D }); + _dynamicProxyPolicy = new ConfigurableCallObfusPolicy(); + _dynamicProxyObfuscator = new DefaultProxyCallObfuscator(_random, _encryptor); } public override void Stop(ObfuscationPassContext ctx) diff --git a/Editor/ObfusPasses/CallObfus/ProxyCallPolicyBase.cs b/Editor/ObfusPasses/CallObfus/CallObfusPolicyBase.cs similarity index 79% rename from Editor/ObfusPasses/CallObfus/ProxyCallPolicyBase.cs rename to Editor/ObfusPasses/CallObfus/CallObfusPolicyBase.cs index e3d0b21..fd547e0 100644 --- a/Editor/ObfusPasses/CallObfus/ProxyCallPolicyBase.cs +++ b/Editor/ObfusPasses/CallObfus/CallObfusPolicyBase.cs @@ -2,7 +2,7 @@ namespace Obfuz.ObfusPasses.CallObfus { - public abstract class ProxyCallPolicyBase : IProxyCallPolicy + public abstract class CallObfusPolicyBase : ICallObfusPolicy { public abstract bool NeedDynamicProxyCallInMethod(MethodDef method); diff --git a/Editor/ObfusPasses/CallObfus/ProxyCallObfuscatorBase.cs b/Editor/ObfusPasses/CallObfus/CallObfuscatorBase.cs similarity index 81% rename from Editor/ObfusPasses/CallObfus/ProxyCallObfuscatorBase.cs rename to Editor/ObfusPasses/CallObfus/CallObfuscatorBase.cs index 74b707d..bc78bea 100644 --- a/Editor/ObfusPasses/CallObfus/ProxyCallObfuscatorBase.cs +++ b/Editor/ObfusPasses/CallObfus/CallObfuscatorBase.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace Obfuz.ObfusPasses.CallObfus { - public abstract class ProxyCallObfuscatorBase : IProxyCallObfuscator + public abstract class CallObfuscatorBase : ICallObfuscator { public abstract void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List obfuscatedInstructions); public abstract void Done(); diff --git a/Editor/ObfusPasses/CallObfus/ProxyCallAllocator.cs b/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs similarity index 77% rename from Editor/ObfusPasses/CallObfus/ProxyCallAllocator.cs rename to Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs index ca09e1f..6b27a60 100644 --- a/Editor/ObfusPasses/CallObfus/ProxyCallAllocator.cs +++ b/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs @@ -1,5 +1,6 @@ using dnlib.DotNet; using dnlib.DotNet.Emit; +using Obfuz.Emit; using Obfuz.Utils; using System; using System.Collections.Generic; @@ -14,19 +15,24 @@ namespace Obfuz.ObfusPasses.CallObfus public struct ProxyCallMethodData { public readonly MethodDef proxyMethod; - public readonly int secret; + public readonly int encryptOps; + public readonly int salt; + public readonly int encryptedIndex; - public ProxyCallMethodData(MethodDef proxyMethod, int secret) + public ProxyCallMethodData(MethodDef proxyMethod, int encryptOps, int salt, int encryptedIndex) { this.proxyMethod = proxyMethod; - this.secret = secret; + this.encryptOps = encryptOps; + this.salt = salt; + this.encryptedIndex = encryptedIndex; } } - class ModuleDynamicProxyMethodAllocator + class ModuleCallProxyAllocator : IModuleEmitManager { - private readonly ModuleDef _module; + private ModuleDef _module; private readonly IRandom _random; + private readonly IEncryptor _encryptor; class MethodKey : IEquatable { @@ -55,7 +61,11 @@ namespace Obfuz.ObfusPasses.CallObfus class MethodProxyInfo { public MethodDef proxyMethod; - public int secret; + + public int index; + public int encryptedOps; + public int salt; + public int encryptedIndex; } private readonly Dictionary _methodProxys = new Dictionary(); @@ -72,7 +82,6 @@ namespace Obfuz.ObfusPasses.CallObfus class DispatchMethodInfo { public MethodDef methodDef; - public int secret; public List methods = new List(); } @@ -81,10 +90,15 @@ namespace Obfuz.ObfusPasses.CallObfus private TypeDef _proxyTypeDef; - public ModuleDynamicProxyMethodAllocator(ModuleDef module, IRandom random) + public ModuleCallProxyAllocator(IRandom random, IEncryptor encryptor) { - _module = module; _random = random; + _encryptor = encryptor; + } + + public void Init(ModuleDef mod) + { + _module = mod; } private TypeDef CreateProxyTypeDef() @@ -128,11 +142,21 @@ namespace Obfuz.ObfusPasses.CallObfus break; } } - // extra param for secret + // extra param for index methodSig.Params.Add(_module.CorLibTypes.Int32); return MethodSig.CreateStatic(methodSig.RetType, methodSig.Params.ToArray()); } + private int GenerateSalt() + { + return _random.NextInt(); + } + + private int GenerateEncryptOps() + { + return _random.NextInt(); + } + private DispatchMethodInfo GetDispatchMethod(IMethod method) { MethodSig methodSig = CreateDispatchMethodSig(method); @@ -146,7 +170,6 @@ namespace Obfuz.ObfusPasses.CallObfus var newDispatchMethodInfo = new DispatchMethodInfo { methodDef = CreateDispatchMethodInfo(methodSig), - secret = 0, }; dispatchMethods.Add(newDispatchMethodInfo); } @@ -159,15 +182,23 @@ namespace Obfuz.ObfusPasses.CallObfus if (!_methodProxys.TryGetValue(key, out var proxyInfo)) { var methodDispatcher = GetDispatchMethod(method); + + int index = methodDispatcher.methods.Count; + int encryptOps = GenerateEncryptOps(); + int salt = GenerateSalt(); + int encryptedIndex = _encryptor.Encrypt(index, encryptOps, salt); proxyInfo = new MethodProxyInfo() { proxyMethod = methodDispatcher.methodDef, - secret = methodDispatcher.methods.Count, + index = index, + encryptedOps = encryptOps, + salt = salt, + encryptedIndex = encryptedIndex, }; methodDispatcher.methods.Add(new CallInfo { method = method, callVir = callVir}); _methodProxys.Add(key, proxyInfo); } - return new ProxyCallMethodData(proxyInfo.proxyMethod, proxyInfo.secret); + return new ProxyCallMethodData(proxyInfo.proxyMethod, proxyInfo.encryptedOps, proxyInfo.salt, proxyInfo.encryptedIndex); } public void Done() @@ -175,7 +206,6 @@ namespace Obfuz.ObfusPasses.CallObfus foreach (DispatchMethodInfo dispatchMethod in _dispatchMethods.Values.SelectMany(ms => ms)) { var methodDef = dispatchMethod.methodDef; - var secret = dispatchMethod.secret; var methodSig = methodDef.MethodSig; @@ -204,34 +234,34 @@ namespace Obfuz.ObfusPasses.CallObfus } } - public class ProxyCallAllocator + public class CallProxyAllocator { private readonly IRandom _random; + private readonly IEncryptor _encryptor; - private readonly Dictionary _moduleAllocators = new Dictionary(); - - public ProxyCallAllocator(IRandom random) + public CallProxyAllocator(IRandom random, IEncryptor encryptor) { _random = random; + _encryptor = encryptor; + } + + private ModuleCallProxyAllocator GetModuleAllocator(ModuleDef mod) + { + return EmitManager.Ins.GetEmitManager(mod, () => new ModuleCallProxyAllocator(_random, _encryptor)); } public ProxyCallMethodData Allocate(ModuleDef mod, IMethod method, bool callVir) { - if (!_moduleAllocators.TryGetValue(mod, out var allocator)) - { - allocator = new ModuleDynamicProxyMethodAllocator(mod, _random); - _moduleAllocators.Add(mod, allocator); - } + ModuleCallProxyAllocator allocator = GetModuleAllocator(mod); return allocator.Allocate(method, callVir); } public void Done() { - foreach (var allocator in _moduleAllocators.Values) + foreach (var allocator in EmitManager.Ins.GetEmitManagers()) { allocator.Done(); } - _moduleAllocators.Clear(); } } } diff --git a/Editor/ObfusPasses/CallObfus/ConfigProxyCallPolicy.cs b/Editor/ObfusPasses/CallObfus/ConfigurableCallObfusPolicy.cs similarity index 95% rename from Editor/ObfusPasses/CallObfus/ConfigProxyCallPolicy.cs rename to Editor/ObfusPasses/CallObfus/ConfigurableCallObfusPolicy.cs index a80a547..b861d9a 100644 --- a/Editor/ObfusPasses/CallObfus/ConfigProxyCallPolicy.cs +++ b/Editor/ObfusPasses/CallObfus/ConfigurableCallObfusPolicy.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace Obfuz.ObfusPasses.CallObfus { - public class ConfigProxyCallPolicy : ProxyCallPolicyBase + public class ConfigurableCallObfusPolicy : CallObfusPolicyBase { public override bool NeedDynamicProxyCallInMethod(MethodDef method) { diff --git a/Editor/ObfusPasses/CallObfus/DefaultProxyCallObfuscator.cs b/Editor/ObfusPasses/CallObfus/DefaultProxyCallObfuscator.cs index 6df48b7..cadaf66 100644 --- a/Editor/ObfusPasses/CallObfus/DefaultProxyCallObfuscator.cs +++ b/Editor/ObfusPasses/CallObfus/DefaultProxyCallObfuscator.cs @@ -6,15 +6,17 @@ using Obfuz.Emit; namespace Obfuz.ObfusPasses.CallObfus { - public class DefaultProxyCallObfuscator : ProxyCallObfuscatorBase + public class DefaultProxyCallObfuscator : CallObfuscatorBase { private readonly IRandom _random; - private readonly ProxyCallAllocator _proxyCallAllocator; + private readonly IEncryptor _encryptor; + private readonly CallProxyAllocator _proxyCallAllocator; - public DefaultProxyCallObfuscator(IRandom random) + public DefaultProxyCallObfuscator(IRandom random, IEncryptor encryptor) { _random = random; - _proxyCallAllocator = new ProxyCallAllocator(random); + _encryptor = encryptor; + _proxyCallAllocator = new CallProxyAllocator(random, _encryptor); } public override void Done() @@ -26,7 +28,11 @@ namespace Obfuz.ObfusPasses.CallObfus { MethodSig sharedMethodSig = MetaUtil.ToSharedMethodSig(calledMethod.Module.CorLibTypes, MetaUtil.GetInflatedMethodSig(calledMethod)); ProxyCallMethodData proxyCallMethodData = _proxyCallAllocator.Allocate(callingMethod.Module, calledMethod, callVir); - obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.secret)); + DefaultModuleMetadataImporter importer = MetadataImporter.Instance.GetDefaultModuleMetadataImporter(callingMethod.Module); + obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.encryptedIndex)); + obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.encryptOps)); + obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.salt)); + obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, importer.DecryptInt)); obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, proxyCallMethodData.proxyMethod)); } } diff --git a/Editor/ObfusPasses/CallObfus/IProxyCallPolicy.cs b/Editor/ObfusPasses/CallObfus/ICallObfusPolicy.cs similarity index 89% rename from Editor/ObfusPasses/CallObfus/IProxyCallPolicy.cs rename to Editor/ObfusPasses/CallObfus/ICallObfusPolicy.cs index e03586f..df8d79b 100644 --- a/Editor/ObfusPasses/CallObfus/IProxyCallPolicy.cs +++ b/Editor/ObfusPasses/CallObfus/ICallObfusPolicy.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace Obfuz.ObfusPasses.CallObfus { - public interface IProxyCallPolicy + public interface ICallObfusPolicy { bool NeedDynamicProxyCallInMethod(MethodDef method); diff --git a/Editor/ObfusPasses/CallObfus/IProxyCallObfuscator.cs b/Editor/ObfusPasses/CallObfus/ICallObfuscator.cs similarity index 89% rename from Editor/ObfusPasses/CallObfus/IProxyCallObfuscator.cs rename to Editor/ObfusPasses/CallObfus/ICallObfuscator.cs index b133ecb..73dabf1 100644 --- a/Editor/ObfusPasses/CallObfus/IProxyCallObfuscator.cs +++ b/Editor/ObfusPasses/CallObfus/ICallObfuscator.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace Obfuz.ObfusPasses.CallObfus { - public interface IProxyCallObfuscator + public interface ICallObfuscator { void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List obfuscatedInstructions); diff --git a/Editor/ObfuscatorBuilder.cs b/Editor/ObfuscatorBuilder.cs index db5c495..091fc84 100644 --- a/Editor/ObfuscatorBuilder.cs +++ b/Editor/ObfuscatorBuilder.cs @@ -81,7 +81,7 @@ namespace Obfuz } if (obfuscationPasses.HasFlag(ObfuscationPassType.CallProxy)) { - builder.AddPass(new ProxyCallPass()); + builder.AddPass(new CallObfusPass(settings.callObfusSettings)); } if (obfuscationPasses.HasFlag(ObfuscationPassType.ConstEncryption)) { diff --git a/Editor/Settings/CallObfusSettings.cs b/Editor/Settings/CallObfusSettings.cs new file mode 100644 index 0000000..c2e546e --- /dev/null +++ b/Editor/Settings/CallObfusSettings.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Obfuz.Settings +{ + [Serializable] + public class CallObfusSettings + { + } +} diff --git a/Editor/Settings/ObfuzSettings.cs b/Editor/Settings/ObfuzSettings.cs index a1bf185..482c7af 100644 --- a/Editor/Settings/ObfuzSettings.cs +++ b/Editor/Settings/ObfuzSettings.cs @@ -32,6 +32,9 @@ namespace Obfuz.Settings [Tooltip("const encryption settings")] public ConstEncryptSettings constEncryptSettings; + [Tooltip("call obfuscation settings")] + public CallObfusSettings callObfusSettings; + public string ObfuzRootDir => $"Library/Obfuz"; public string GetObfuscatedAssemblyOutputDir(BuildTarget target) diff --git a/Editor/Settings/ObfuzSettingsProvider.cs b/Editor/Settings/ObfuzSettingsProvider.cs index 2976fd6..b133515 100644 --- a/Editor/Settings/ObfuzSettingsProvider.cs +++ b/Editor/Settings/ObfuzSettingsProvider.cs @@ -37,6 +37,7 @@ namespace Obfuz.Settings private SerializedProperty _symbolObfusSettings; private SerializedProperty _constEncryptSettings; + private SerializedProperty _callObfusSettings; public ObfuzSettingsProvider() : base("Project/Obfuz", SettingsScope.Project) { @@ -66,6 +67,7 @@ namespace Obfuz.Settings _symbolObfusSettings = _serializedObject.FindProperty("symbolObfusSettings"); _constEncryptSettings = _serializedObject.FindProperty("constEncryptSettings"); + _callObfusSettings = _serializedObject.FindProperty("callObfusSettings"); } public override void OnGUI(string searchContext) @@ -85,6 +87,7 @@ namespace Obfuz.Settings EditorGUILayout.PropertyField(_symbolObfusSettings); EditorGUILayout.PropertyField(_constEncryptSettings); + EditorGUILayout.PropertyField(_callObfusSettings); if (EditorGUI.EndChangeCheck())