From bf79067e7520186c39670bc6ecdefec19778b997 Mon Sep 17 00:00:00 2001 From: walon Date: Tue, 13 May 2025 09:27:44 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A1=AE=E5=AE=9A=E6=80=A7=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/ObfusPasses/CallObfus/CallObfusPass.cs | 4 +- .../CallObfus/CallProxyAllocator.cs | 33 ++++++++------ .../CallObfus/DefaultCallProxyObfuscator.cs | 4 +- .../ConstEncrypt/ConstEncryptPass.cs | 2 +- .../ConstEncrypt/DefaultConstEncryptor.cs | 44 ++++++++++++------- .../FieldEncrypt/DefaultFieldEncryptor.cs | 24 ++++++---- .../FieldEncrypt/FieldEncryptPass.cs | 2 +- Editor/ObfuscationPassContext.cs | 3 +- Editor/Obfuscator.cs | 2 +- Editor/Utils/HashUtil.cs | 25 +++++++++++ 10 files changed, 95 insertions(+), 48 deletions(-) diff --git a/Editor/ObfusPasses/CallObfus/CallObfusPass.cs b/Editor/ObfusPasses/CallObfus/CallObfusPass.cs index b812beb..879a18a 100644 --- a/Editor/ObfusPasses/CallObfus/CallObfusPass.cs +++ b/Editor/ObfusPasses/CallObfus/CallObfusPass.cs @@ -17,7 +17,6 @@ namespace Obfuz.ObfusPasses.CallObfus { private readonly List _configFiles; private readonly int _obfuscationLevel; - private IRandom _random; private IEncryptor _encryptor; private IObfuscator _dynamicProxyObfuscator; private IObfuscationPolicy _dynamicProxyPolicy; @@ -38,9 +37,8 @@ namespace Obfuz.ObfusPasses.CallObfus public override void Start() { var ctx = ObfuscationPassContext.Current; - _random = ctx.globalRandom; _encryptor = ctx.encryptor; - _dynamicProxyObfuscator = new DefaultCallProxyObfuscator(_random, _encryptor, ctx.constFieldAllocator, ctx.moduleEntityManager, _obfuscationLevel); + _dynamicProxyObfuscator = new DefaultCallProxyObfuscator(ctx.localRandomCreator, _encryptor, ctx.constFieldAllocator, ctx.moduleEntityManager, _obfuscationLevel); _dynamicProxyPolicy = new ConfigurableObfuscationPolicy(ctx.toObfuscatedAssemblyNames, _configFiles); } diff --git a/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs b/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs index f883255..c4a679c 100644 --- a/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs +++ b/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs @@ -33,7 +33,7 @@ namespace Obfuz.ObfusPasses.CallObfus class ModuleCallProxyAllocator : IGroupByModuleEntity { private ModuleDef _module; - private readonly IRandom _random; + private readonly RandomCreator _randomCreator; private readonly IEncryptor _encryptor; private readonly int _encryptionLevel; @@ -93,9 +93,9 @@ namespace Obfuz.ObfusPasses.CallObfus private TypeDef _proxyTypeDef; - public ModuleCallProxyAllocator(IRandom random, IEncryptor encryptor, int encryptionLevel) + public ModuleCallProxyAllocator(RandomCreator randomCreator, IEncryptor encryptor, int encryptionLevel) { - _random = random; + _randomCreator = randomCreator; _encryptor = encryptor; _encryptionLevel = encryptionLevel; } @@ -151,14 +151,14 @@ namespace Obfuz.ObfusPasses.CallObfus return MethodSig.CreateStatic(methodSig.RetType, methodSig.Params.ToArray()); } - private int GenerateSalt() + private int GenerateSalt(IRandom random) { - return _random.NextInt(); + return random.NextInt(); } - private int GenerateEncryptOps() + private int GenerateEncryptOps(IRandom random) { - return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel); + return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel); } private DispatchMethodInfo GetDispatchMethod(IMethod method) @@ -180,6 +180,12 @@ namespace Obfuz.ObfusPasses.CallObfus return dispatchMethods.Last(); } + private IRandom CreateRandomForMethod(IMethod method, bool callVir) + { + int seed = MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method); + return _randomCreator(seed); + } + public ProxyCallMethodData Allocate(IMethod method, bool callVir) { var key = new MethodKey(method, callVir); @@ -188,8 +194,9 @@ namespace Obfuz.ObfusPasses.CallObfus var methodDispatcher = GetDispatchMethod(method); int index = methodDispatcher.methods.Count; - int encryptOps = GenerateEncryptOps(); - int salt = GenerateSalt(); + IRandom localRandom = CreateRandomForMethod(method, callVir); + int encryptOps = GenerateEncryptOps(localRandom); + int salt = GenerateSalt(localRandom); int encryptedIndex = _encryptor.Encrypt(index, encryptOps, salt); proxyInfo = new MethodProxyInfo() { @@ -240,14 +247,14 @@ namespace Obfuz.ObfusPasses.CallObfus public class CallProxyAllocator { - private readonly IRandom _random; + private readonly RandomCreator _randomCreator; private readonly IEncryptor _encryptor; private GroupByModuleEntityManager _moduleEntityManager; private readonly int _encryptionLevel; - public CallProxyAllocator(IRandom random, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) + public CallProxyAllocator(RandomCreator randomCreator, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) { - _random = random; + _randomCreator = randomCreator; _encryptor = encryptor; _moduleEntityManager = moduleEntityManager; _encryptionLevel = encryptionLevel; @@ -255,7 +262,7 @@ namespace Obfuz.ObfusPasses.CallObfus private ModuleCallProxyAllocator GetModuleAllocator(ModuleDef mod) { - return _moduleEntityManager.GetEntity(mod, () => new ModuleCallProxyAllocator(_random, _encryptor, _encryptionLevel)); + return _moduleEntityManager.GetEntity(mod, () => new ModuleCallProxyAllocator(_randomCreator, _encryptor, _encryptionLevel)); } public ProxyCallMethodData Allocate(ModuleDef mod, IMethod method, bool callVir) diff --git a/Editor/ObfusPasses/CallObfus/DefaultCallProxyObfuscator.cs b/Editor/ObfusPasses/CallObfus/DefaultCallProxyObfuscator.cs index a549bb8..c0733ac 100644 --- a/Editor/ObfusPasses/CallObfus/DefaultCallProxyObfuscator.cs +++ b/Editor/ObfusPasses/CallObfus/DefaultCallProxyObfuscator.cs @@ -15,12 +15,12 @@ namespace Obfuz.ObfusPasses.CallObfus private readonly CallProxyAllocator _proxyCallAllocator; private readonly GroupByModuleEntityManager _moduleEntityManager; - public DefaultCallProxyObfuscator(IRandom random, IEncryptor encryptor, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) + public DefaultCallProxyObfuscator(RandomCreator randomCreator, IEncryptor encryptor, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) { _encryptor = encryptor; _constFieldAllocator = constFieldAllocator; _moduleEntityManager = moduleEntityManager; - _proxyCallAllocator = new CallProxyAllocator(random, _encryptor, moduleEntityManager, encryptionLevel); + _proxyCallAllocator = new CallProxyAllocator(randomCreator, _encryptor, moduleEntityManager, encryptionLevel); } public override void Done() diff --git a/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs b/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs index ae40c67..3612b37 100644 --- a/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs +++ b/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs @@ -31,7 +31,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt { var ctx = ObfuscationPassContext.Current; _dataObfuscatorPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles); - _dataObfuscator = new DefaultConstEncryptor(ctx.globalRandom, ctx.encryptor, ctx.rvaDataAllocator, ctx.constFieldAllocator, ctx.moduleEntityManager, _encryptionLevel); + _dataObfuscator = new DefaultConstEncryptor(ctx.localRandomCreator, ctx.encryptor, ctx.rvaDataAllocator, ctx.constFieldAllocator, ctx.moduleEntityManager, _encryptionLevel); } public override void Stop() diff --git a/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs b/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs index b451c54..a314d66 100644 --- a/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs +++ b/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs @@ -12,16 +12,16 @@ namespace Obfuz.ObfusPasses.ConstEncrypt { public class DefaultConstEncryptor : IConstEncryptor { - private readonly IRandom _random; + private readonly RandomCreator _randomCreator; private readonly RvaDataAllocator _rvaDataAllocator; private readonly ConstFieldAllocator _constFieldAllocator; private readonly IEncryptor _encryptor; private readonly GroupByModuleEntityManager _moduleEntityManager; private readonly int _encryptionLevel; - public DefaultConstEncryptor(IRandom random, IEncryptor encryptor, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) + public DefaultConstEncryptor(RandomCreator randomCreator, IEncryptor encryptor, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) { - _random = random; + _randomCreator = randomCreator; _encryptor = encryptor; _rvaDataAllocator = rvaDataAllocator; _constFieldAllocator = constFieldAllocator; @@ -29,14 +29,19 @@ namespace Obfuz.ObfusPasses.ConstEncrypt _encryptionLevel = encryptionLevel; } - private int GenerateEncryptionOperations() + private IRandom CreateRandomForValue(int value) { - return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel); + return _randomCreator(value); } - public int GenerateSalt() + private int GenerateEncryptionOperations(IRandom random) { - return _random.NextInt(); + return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel); + } + + public int GenerateSalt(IRandom random) + { + return random.NextInt(); } private DefaultMetadataImporter GetModuleMetadataImporter(MethodDef method) @@ -53,8 +58,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - int ops = GenerateEncryptionOperations(); - int salt = GenerateSalt(); + IRandom random = CreateRandomForValue(value.GetHashCode()); + int ops = GenerateEncryptionOperations(random); + int salt = GenerateSalt(random); int encryptedValue = _encryptor.Encrypt(value, ops, salt); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); @@ -75,8 +81,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - int ops = GenerateEncryptionOperations(); - int salt = GenerateSalt(); + IRandom random = CreateRandomForValue(value.GetHashCode()); + int ops = GenerateEncryptionOperations(random); + int salt = GenerateSalt(random); long encryptedValue = _encryptor.Encrypt(value, ops, salt); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); @@ -97,8 +104,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - int ops = GenerateEncryptionOperations(); - int salt = GenerateSalt(); + IRandom random = CreateRandomForValue(value.GetHashCode()); + int ops = GenerateEncryptionOperations(random); + int salt = GenerateSalt(random); float encryptedValue = _encryptor.Encrypt(value, ops, salt); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); @@ -119,8 +127,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - int ops = GenerateEncryptionOperations(); - int salt = GenerateSalt(); + IRandom random = CreateRandomForValue(value.GetHashCode()); + int ops = GenerateEncryptionOperations(random); + int salt = GenerateSalt(random); double encryptedValue = _encryptor.Encrypt(value, ops, salt); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); @@ -167,8 +176,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - int ops = GenerateEncryptionOperations(); - int salt = GenerateSalt(); + IRandom random = CreateRandomForValue(HashUtil.ComputeHash(value)); + int ops = GenerateEncryptionOperations(random); + int salt = GenerateSalt(random); int stringByteLength = Encoding.UTF8.GetByteCount(value); byte[] encryptedValue = _encryptor.Encrypt(value, ops, salt); Assert.IsTrue(encryptedValue.Length % 4 == 0); diff --git a/Editor/ObfusPasses/FieldEncrypt/DefaultFieldEncryptor.cs b/Editor/ObfusPasses/FieldEncrypt/DefaultFieldEncryptor.cs index 51efea3..094c712 100644 --- a/Editor/ObfusPasses/FieldEncrypt/DefaultFieldEncryptor.cs +++ b/Editor/ObfusPasses/FieldEncrypt/DefaultFieldEncryptor.cs @@ -12,14 +12,14 @@ namespace Obfuz.ObfusPasses.FieldEncrypt { public class DefaultFieldEncryptor : FieldEncryptorBase { - private readonly IRandom _random; + private readonly RandomCreator _randomCreator; private readonly IEncryptor _encryptor; private readonly GroupByModuleEntityManager _moduleEntityManager; private readonly int _encryptionLevel; - public DefaultFieldEncryptor(IRandom random, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) + public DefaultFieldEncryptor(RandomCreator randomCreator, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) { - _random = random; + _randomCreator = randomCreator; _encryptor = encryptor; _moduleEntityManager = moduleEntityManager; _encryptionLevel = encryptionLevel; @@ -59,14 +59,19 @@ namespace Obfuz.ObfusPasses.FieldEncrypt } - private int GenerateEncryptionOperations() + private IRandom CreateRandomForField(FieldDef field) { - return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel); + return _randomCreator(FieldEqualityComparer.CompareDeclaringTypes.GetHashCode(field)); } - public int GenerateSalt() + private int GenerateEncryptionOperations(IRandom random) { - return _random.NextInt(); + return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel); + } + + public int GenerateSalt(IRandom random) + { + return random.NextInt(); } private FieldEncryptInfo GetFieldEncryptInfo(FieldDef field) @@ -76,8 +81,9 @@ namespace Obfuz.ObfusPasses.FieldEncrypt return info; } - int encryptOps = GenerateEncryptionOperations(); - int salt = GenerateSalt(); + IRandom random = CreateRandomForField(field); + int encryptOps = GenerateEncryptionOperations(random); + int salt = GenerateSalt(random); ElementType fieldType = field.FieldSig.Type.RemovePinnedAndModifiers().ElementType; long xorValueForZero = CalcXorValueForZero(fieldType, encryptOps, salt); diff --git a/Editor/ObfusPasses/FieldEncrypt/FieldEncryptPass.cs b/Editor/ObfusPasses/FieldEncrypt/FieldEncryptPass.cs index 3d12564..2f2cbc6 100644 --- a/Editor/ObfusPasses/FieldEncrypt/FieldEncryptPass.cs +++ b/Editor/ObfusPasses/FieldEncrypt/FieldEncryptPass.cs @@ -30,7 +30,7 @@ namespace Obfuz.ObfusPasses.FieldEncrypt public override void Start() { var ctx = ObfuscationPassContext.Current; - _memoryEncryptor = new DefaultFieldEncryptor(ctx.globalRandom, ctx.encryptor, ctx.moduleEntityManager, _encryptionLevel); + _memoryEncryptor = new DefaultFieldEncryptor(ctx.localRandomCreator, ctx.encryptor, ctx.moduleEntityManager, _encryptionLevel); _encryptionPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles); } diff --git a/Editor/ObfuscationPassContext.cs b/Editor/ObfuscationPassContext.cs index 0823548..e0254d1 100644 --- a/Editor/ObfuscationPassContext.cs +++ b/Editor/ObfuscationPassContext.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; namespace Obfuz { + public delegate IRandom RandomCreator(int seed); public class ObfuscationPassContext { @@ -31,7 +32,7 @@ namespace Obfuz public string obfuscatedAssemblyOutputDir; public IRandom globalRandom; - public Func localScopeRandomCreator; + public RandomCreator localRandomCreator; public IEncryptor encryptor; public ConstFieldAllocator constFieldAllocator; diff --git a/Editor/Obfuscator.cs b/Editor/Obfuscator.cs index 25370c8..e5e4b86 100644 --- a/Editor/Obfuscator.cs +++ b/Editor/Obfuscator.cs @@ -175,7 +175,7 @@ namespace Obfuz moduleEntityManager = moduleEntityManager, globalRandom = random, - localScopeRandomCreator = (seed) => new RandomWithKey(_intSecret, _randomSeed ^ seed), + localRandomCreator = (seed) => new RandomWithKey(_intSecret, _randomSeed ^ seed), encryptor = encryptor, rvaDataAllocator = rvaDataAllocator, constFieldAllocator = constFieldAllocator, diff --git a/Editor/Utils/HashUtil.cs b/Editor/Utils/HashUtil.cs index 64b1795..5cf8acb 100644 --- a/Editor/Utils/HashUtil.cs +++ b/Editor/Utils/HashUtil.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using UnityEngine.UIElements; namespace Obfuz.Utils { @@ -24,5 +25,29 @@ namespace Obfuz.Utils } return hash; } + + public static unsafe int ComputeHash(string s) + { + fixed (char* ptr = s) + { + int num = 352654597; + int num2 = num; + int* ptr2 = (int*)ptr; + int num3; + for (num3 = s.Length; num3 > 2; num3 -= 4) + { + num = ((num << 5) + num + (num >> 27)) ^ *ptr2; + num2 = ((num2 << 5) + num2 + (num2 >> 27)) ^ ptr2[1]; + ptr2 += 2; + } + + if (num3 > 0) + { + num = ((num << 5) + num + (num >> 27)) ^ *ptr2; + } + + return num + num2 * 1566083941; + } + } } }