From 0efdd5b213c20e03804c94bc46d8397f5c63764b Mon Sep 17 00:00:00 2001 From: walon Date: Fri, 16 May 2025 11:33:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8A=A8=E6=80=81=E5=92=8C?= =?UTF-8?q?=E9=9D=99=E6=80=81secret?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/Data/ConstFieldAllocator.cs | 24 +++++---- Editor/Data/RvaDataAllocator.cs | 26 ++++----- Editor/ObfusPasses/CallObfus/CallObfusPass.cs | 4 +- .../CallObfus/CallProxyAllocator.cs | 27 +++++----- .../CallObfus/DefaultCallProxyObfuscator.cs | 8 +-- .../ConstEncrypt/ConstEncryptPass.cs | 2 +- .../ConstEncrypt/DefaultConstEncryptor.cs | 51 +++++++++--------- .../FieldEncrypt/DefaultFieldEncryptor.cs | 30 +++++------ .../FieldEncrypt/FieldEncryptPass.cs | 2 +- Editor/ObfuscationPassContext.cs | 47 ++++++++++++++-- Editor/Obfuscator.cs | 54 +++++++++++++------ Editor/ObfuscatorBuilder.cs | 45 ++++++++++++---- Editor/Settings/SecretSettings.cs | 18 +++++-- Editor/Unity/ObfuzMenu.cs | 8 ++- 14 files changed, 224 insertions(+), 122 deletions(-) diff --git a/Editor/Data/ConstFieldAllocator.cs b/Editor/Data/ConstFieldAllocator.cs index f70e166..bdcead5 100644 --- a/Editor/Data/ConstFieldAllocator.cs +++ b/Editor/Data/ConstFieldAllocator.cs @@ -18,10 +18,12 @@ namespace Obfuz.Data public class ModuleConstFieldAllocator : IGroupByModuleEntity { private ModuleDef _module; - private readonly RandomCreator _randomCreator; - private readonly IEncryptor _encryptor; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private readonly RvaDataAllocator _rvaDataAllocator; private readonly GroupByModuleEntityManager _moduleEntityManager; + private EncryptionScopeInfo _encryptionScope; + private RandomCreator _randomCreator; + private IEncryptor _encryptor; private TypeDef _holderTypeDef; @@ -60,10 +62,9 @@ namespace Obfuz.Data private bool _done; - public ModuleConstFieldAllocator(IEncryptor encryptor, RandomCreator randomCreator, RvaDataAllocator rvaDataAllocator, GroupByModuleEntityManager moduleEntityManager) + public ModuleConstFieldAllocator(EncryptionScopeProvider encryptionScopeProvider, RvaDataAllocator rvaDataAllocator, GroupByModuleEntityManager moduleEntityManager) { - _encryptor = encryptor; - _randomCreator = randomCreator; + _encryptionScopeProvider = encryptionScopeProvider; _rvaDataAllocator = rvaDataAllocator; _moduleEntityManager = moduleEntityManager; } @@ -71,6 +72,9 @@ namespace Obfuz.Data public void Init(ModuleDef mod) { _module = mod; + _encryptionScope = _encryptionScopeProvider.GetScope(mod); + _randomCreator = _encryptionScope.localRandomCreator; + _encryptor = _encryptionScope.encryptor; } const int maxFieldCount = 1000; @@ -283,22 +287,20 @@ namespace Obfuz.Data public class ConstFieldAllocator { - private readonly IEncryptor _encryptor; - private readonly RandomCreator _randomCreator; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private readonly RvaDataAllocator _rvaDataAllocator; private readonly GroupByModuleEntityManager _moduleEntityManager; - public ConstFieldAllocator(IEncryptor encryptor, RandomCreator randomCreator, RvaDataAllocator rvaDataAllocator, GroupByModuleEntityManager moduleEntityManager) + public ConstFieldAllocator(EncryptionScopeProvider encryptionScopeProvider, RvaDataAllocator rvaDataAllocator, GroupByModuleEntityManager moduleEntityManager) { - _encryptor = encryptor; - _randomCreator = randomCreator; + _encryptionScopeProvider = encryptionScopeProvider; _rvaDataAllocator = rvaDataAllocator; _moduleEntityManager = moduleEntityManager; } private ModuleConstFieldAllocator GetModuleAllocator(ModuleDef mod) { - return _moduleEntityManager.GetEntity(mod, () => new ModuleConstFieldAllocator(_encryptor, _randomCreator, _rvaDataAllocator, _moduleEntityManager)); + return _moduleEntityManager.GetEntity(mod, () => new ModuleConstFieldAllocator(_encryptionScopeProvider, _rvaDataAllocator, _moduleEntityManager)); } public FieldDef Allocate(ModuleDef mod, int value) diff --git a/Editor/Data/RvaDataAllocator.cs b/Editor/Data/RvaDataAllocator.cs index 7a9fc56..3ca9e8a 100644 --- a/Editor/Data/RvaDataAllocator.cs +++ b/Editor/Data/RvaDataAllocator.cs @@ -31,10 +31,12 @@ namespace Obfuz.Data const int maxRvaDataSize = 0x1000; private ModuleDef _module; - private readonly IRandom _random; - private readonly IEncryptor _encryptor; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private readonly GroupByModuleEntityManager _moduleEntityManager; + private EncryptionScopeInfo _encryptionScope; + private IRandom _random; + class RvaField { public FieldDef holderDataField; @@ -71,16 +73,17 @@ namespace Obfuz.Data private readonly Dictionary _dataHolderTypeBySizes = new Dictionary(); private bool _done; - public ModuleRvaDataAllocator(IRandom random, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager) + public ModuleRvaDataAllocator(EncryptionScopeProvider encryptionScopeProvider, GroupByModuleEntityManager moduleEntityManager) { - _random = random; - _encryptor = encryptor; + _encryptionScopeProvider = encryptionScopeProvider; _moduleEntityManager = moduleEntityManager; } public override void Init(ModuleDef mod) { _module = mod; + _encryptionScope = _encryptionScopeProvider.GetScope(mod); + _random = _encryptionScope.localRandomCreator(HashUtil.ComputeHash(mod.Name)); } private (FieldDef, FieldDef) CreateDataHolderRvaField(TypeDef dataHolderType) @@ -277,7 +280,7 @@ namespace Obfuz.Data field.FillPaddingToEnd(); } byte[] data = field.bytes.ToArray(); - _encryptor.EncryptBlock(data, field.encryptionOps, field.salt); + _encryptionScope.encryptor.EncryptBlock(data, field.encryptionOps, field.salt); field.holderDataField.InitialValue = data; } } @@ -296,21 +299,18 @@ namespace Obfuz.Data public class RvaDataAllocator { - - private readonly IRandom _random; - private readonly IEncryptor _encryptor; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private readonly GroupByModuleEntityManager _moduleEntityManager; - public RvaDataAllocator(IRandom random, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager) + public RvaDataAllocator(EncryptionScopeProvider encryptionScopeProvider, GroupByModuleEntityManager moduleEntityManager) { - _random = random; - _encryptor = encryptor; + _encryptionScopeProvider = encryptionScopeProvider; _moduleEntityManager = moduleEntityManager; } private ModuleRvaDataAllocator GetModuleRvaDataAllocator(ModuleDef mod) { - return _moduleEntityManager.GetEntity(mod, () => new ModuleRvaDataAllocator(_random, _encryptor, _moduleEntityManager)); + return _moduleEntityManager.GetEntity(mod, () => new ModuleRvaDataAllocator(_encryptionScopeProvider, _moduleEntityManager)); } public RvaData Allocate(ModuleDef mod, int value) diff --git a/Editor/ObfusPasses/CallObfus/CallObfusPass.cs b/Editor/ObfusPasses/CallObfus/CallObfusPass.cs index 879a18a..10a6431 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 IEncryptor _encryptor; private IObfuscator _dynamicProxyObfuscator; private IObfuscationPolicy _dynamicProxyPolicy; @@ -37,8 +36,7 @@ namespace Obfuz.ObfusPasses.CallObfus public override void Start() { var ctx = ObfuscationPassContext.Current; - _encryptor = ctx.encryptor; - _dynamicProxyObfuscator = new DefaultCallProxyObfuscator(ctx.localRandomCreator, _encryptor, ctx.constFieldAllocator, ctx.moduleEntityManager, _obfuscationLevel); + _dynamicProxyObfuscator = new DefaultCallProxyObfuscator(ctx.encryptionScopeProvider, 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 36b1f53..dc56d94 100644 --- a/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs +++ b/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs @@ -34,9 +34,10 @@ namespace Obfuz.ObfusPasses.CallObfus class ModuleCallProxyAllocator : IGroupByModuleEntity { private ModuleDef _module; - private readonly RandomCreator _randomCreator; - private readonly IEncryptor _encryptor; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private readonly int _encryptionLevel; + + private EncryptionScopeInfo _encryptionScope; private bool _done; class MethodKey : IEquatable @@ -95,16 +96,16 @@ namespace Obfuz.ObfusPasses.CallObfus private TypeDef _proxyTypeDef; - public ModuleCallProxyAllocator(RandomCreator randomCreator, IEncryptor encryptor, int encryptionLevel) + public ModuleCallProxyAllocator(EncryptionScopeProvider encryptionScopeProvider, int encryptionLevel) { - _randomCreator = randomCreator; - _encryptor = encryptor; + _encryptionScopeProvider = encryptionScopeProvider; _encryptionLevel = encryptionLevel; } public void Init(ModuleDef mod) { _module = mod; + _encryptionScope = _encryptionScopeProvider.GetScope(mod); } private TypeDef CreateProxyTypeDef() @@ -160,7 +161,7 @@ namespace Obfuz.ObfusPasses.CallObfus private int GenerateEncryptOps(IRandom random) { - return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel); + return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptionScope.encryptor, _encryptionLevel); } private DispatchMethodInfo GetDispatchMethod(IMethod method) @@ -185,7 +186,7 @@ namespace Obfuz.ObfusPasses.CallObfus private IRandom CreateRandomForMethod(IMethod method, bool callVir) { int seed = MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method); - return _randomCreator(seed); + return _encryptionScope.localRandomCreator(seed); } public ProxyCallMethodData Allocate(IMethod method, bool callVir) @@ -203,7 +204,7 @@ namespace Obfuz.ObfusPasses.CallObfus IRandom localRandom = CreateRandomForMethod(method, callVir); int encryptOps = GenerateEncryptOps(localRandom); int salt = GenerateSalt(localRandom); - int encryptedIndex = _encryptor.Encrypt(index, encryptOps, salt); + int encryptedIndex = _encryptionScope.encryptor.Encrypt(index, encryptOps, salt); proxyInfo = new MethodProxyInfo() { proxyMethod = methodDispatcher.methodDef, @@ -259,22 +260,20 @@ namespace Obfuz.ObfusPasses.CallObfus public class CallProxyAllocator { - private readonly RandomCreator _randomCreator; - private readonly IEncryptor _encryptor; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private GroupByModuleEntityManager _moduleEntityManager; private readonly int _encryptionLevel; - public CallProxyAllocator(RandomCreator randomCreator, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) + public CallProxyAllocator(EncryptionScopeProvider encryptionScopeProvider, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) { - _randomCreator = randomCreator; - _encryptor = encryptor; + _encryptionScopeProvider = encryptionScopeProvider; _moduleEntityManager = moduleEntityManager; _encryptionLevel = encryptionLevel; } private ModuleCallProxyAllocator GetModuleAllocator(ModuleDef mod) { - return _moduleEntityManager.GetEntity(mod, () => new ModuleCallProxyAllocator(_randomCreator, _encryptor, _encryptionLevel)); + return _moduleEntityManager.GetEntity(mod, () => new ModuleCallProxyAllocator(_encryptionScopeProvider, _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 c0733ac..c0574f4 100644 --- a/Editor/ObfusPasses/CallObfus/DefaultCallProxyObfuscator.cs +++ b/Editor/ObfusPasses/CallObfus/DefaultCallProxyObfuscator.cs @@ -10,17 +10,17 @@ namespace Obfuz.ObfusPasses.CallObfus { public class DefaultCallProxyObfuscator : ObfuscatorBase { - private readonly IEncryptor _encryptor; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private readonly ConstFieldAllocator _constFieldAllocator; private readonly CallProxyAllocator _proxyCallAllocator; private readonly GroupByModuleEntityManager _moduleEntityManager; - public DefaultCallProxyObfuscator(RandomCreator randomCreator, IEncryptor encryptor, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) + public DefaultCallProxyObfuscator(EncryptionScopeProvider encryptionScopeProvider, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) { - _encryptor = encryptor; + _encryptionScopeProvider = encryptionScopeProvider; _constFieldAllocator = constFieldAllocator; _moduleEntityManager = moduleEntityManager; - _proxyCallAllocator = new CallProxyAllocator(randomCreator, _encryptor, moduleEntityManager, encryptionLevel); + _proxyCallAllocator = new CallProxyAllocator(encryptionScopeProvider, moduleEntityManager, encryptionLevel); } public override void Done() diff --git a/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs b/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs index 678a85e..2831004 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.localRandomCreator, ctx.encryptor, ctx.rvaDataAllocator, ctx.constFieldAllocator, ctx.moduleEntityManager, _encryptionLevel); + _dataObfuscator = new DefaultConstEncryptor(ctx.encryptionScopeProvider, 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 a2c58ec..634b15b 100644 --- a/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs +++ b/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs @@ -12,31 +12,29 @@ namespace Obfuz.ObfusPasses.ConstEncrypt { public class DefaultConstEncryptor : IConstEncryptor { - private readonly RandomCreator _randomCreator; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private readonly RvaDataAllocator _rvaDataAllocator; private readonly ConstFieldAllocator _constFieldAllocator; - private readonly IEncryptor _encryptor; private readonly GroupByModuleEntityManager _moduleEntityManager; private readonly int _encryptionLevel; - public DefaultConstEncryptor(RandomCreator randomCreator, IEncryptor encryptor, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) + public DefaultConstEncryptor(EncryptionScopeProvider encryptionScopeProvider, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) { - _randomCreator = randomCreator; - _encryptor = encryptor; + _encryptionScopeProvider = encryptionScopeProvider; _rvaDataAllocator = rvaDataAllocator; _constFieldAllocator = constFieldAllocator; _moduleEntityManager = moduleEntityManager; _encryptionLevel = encryptionLevel; } - private IRandom CreateRandomForValue(int value) + private IRandom CreateRandomForValue(EncryptionScopeInfo encryptionScope, int value) { - return _randomCreator(value); + return encryptionScope.localRandomCreator(value); } - private int GenerateEncryptionOperations(IRandom random) + private int GenerateEncryptionOperations(EncryptionScopeInfo encryptionScope, IRandom random) { - return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel); + return EncryptionUtil.GenerateEncryptionOpCodes(random, encryptionScope.encryptor, _encryptionLevel); } public int GenerateSalt(IRandom random) @@ -58,10 +56,11 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - IRandom random = CreateRandomForValue(value.GetHashCode()); - int ops = GenerateEncryptionOperations(random); + EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module); + IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode()); + int ops = GenerateEncryptionOperations(encryptionScope, random); int salt = GenerateSalt(random); - int encryptedValue = _encryptor.Encrypt(value, ops, salt); + int encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); DefaultMetadataImporter importer = GetModuleMetadataImporter(method); @@ -81,10 +80,11 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - IRandom random = CreateRandomForValue(value.GetHashCode()); - int ops = GenerateEncryptionOperations(random); + EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module); + IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode()); + int ops = GenerateEncryptionOperations(encryptionScope, random); int salt = GenerateSalt(random); - long encryptedValue = _encryptor.Encrypt(value, ops, salt); + long encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); DefaultMetadataImporter importer = GetModuleMetadataImporter(method); @@ -104,10 +104,11 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - IRandom random = CreateRandomForValue(value.GetHashCode()); - int ops = GenerateEncryptionOperations(random); + EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module); + IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode()); + int ops = GenerateEncryptionOperations(encryptionScope, random); int salt = GenerateSalt(random); - float encryptedValue = _encryptor.Encrypt(value, ops, salt); + float encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); DefaultMetadataImporter importer = GetModuleMetadataImporter(method); @@ -127,10 +128,11 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - IRandom random = CreateRandomForValue(value.GetHashCode()); - int ops = GenerateEncryptionOperations(random); + EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module); + IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode()); + int ops = GenerateEncryptionOperations(encryptionScope, random); int salt = GenerateSalt(random); - double encryptedValue = _encryptor.Encrypt(value, ops, salt); + double encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); DefaultMetadataImporter importer = GetModuleMetadataImporter(method); @@ -176,11 +178,12 @@ namespace Obfuz.ObfusPasses.ConstEncrypt return; } - IRandom random = CreateRandomForValue(HashUtil.ComputeHash(value)); - int ops = GenerateEncryptionOperations(random); + EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module); + IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode()); + int ops = GenerateEncryptionOperations(encryptionScope, random); int salt = GenerateSalt(random); int stringByteLength = Encoding.UTF8.GetByteCount(value); - byte[] encryptedValue = _encryptor.Encrypt(value, ops, salt); + byte[] encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt); Assert.IsTrue(encryptedValue.Length % 4 == 0); RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue); diff --git a/Editor/ObfusPasses/FieldEncrypt/DefaultFieldEncryptor.cs b/Editor/ObfusPasses/FieldEncrypt/DefaultFieldEncryptor.cs index 094c712..1989380 100644 --- a/Editor/ObfusPasses/FieldEncrypt/DefaultFieldEncryptor.cs +++ b/Editor/ObfusPasses/FieldEncrypt/DefaultFieldEncryptor.cs @@ -12,15 +12,13 @@ namespace Obfuz.ObfusPasses.FieldEncrypt { public class DefaultFieldEncryptor : FieldEncryptorBase { - private readonly RandomCreator _randomCreator; - private readonly IEncryptor _encryptor; + private readonly EncryptionScopeProvider _encryptionScopeProvider; private readonly GroupByModuleEntityManager _moduleEntityManager; private readonly int _encryptionLevel; - public DefaultFieldEncryptor(RandomCreator randomCreator, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) + public DefaultFieldEncryptor(EncryptionScopeProvider encryptionScopeProvider, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel) { - _randomCreator = randomCreator; - _encryptor = encryptor; + _encryptionScopeProvider = encryptionScopeProvider; _moduleEntityManager = moduleEntityManager; _encryptionLevel = encryptionLevel; } @@ -41,32 +39,32 @@ namespace Obfuz.ObfusPasses.FieldEncrypt private readonly Dictionary _fieldEncryptInfoCache = new Dictionary(); - private long CalcXorValueForZero(ElementType type, int encryptOps, int salt) + private long CalcXorValueForZero(IEncryptor encryptor, ElementType type, int encryptOps, int salt) { switch (type) { case ElementType.I4: case ElementType.U4: case ElementType.R4: - return _encryptor.Encrypt(0, encryptOps, salt); + return encryptor.Encrypt(0, encryptOps, salt); case ElementType.I8: case ElementType.U8: case ElementType.R8: - return _encryptor.Encrypt(0L, encryptOps, salt); + return encryptor.Encrypt(0L, encryptOps, salt); default: throw new NotSupportedException($"Unsupported field type: {type} for encryption"); } } - private IRandom CreateRandomForField(FieldDef field) + private IRandom CreateRandomForField(RandomCreator randomCreator, FieldDef field) { - return _randomCreator(FieldEqualityComparer.CompareDeclaringTypes.GetHashCode(field)); + return randomCreator(FieldEqualityComparer.CompareDeclaringTypes.GetHashCode(field)); } - private int GenerateEncryptionOperations(IRandom random) + private int GenerateEncryptionOperations(IRandom random, IEncryptor encryptor) { - return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel); + return EncryptionUtil.GenerateEncryptionOpCodes(random, encryptor, _encryptionLevel); } public int GenerateSalt(IRandom random) @@ -80,12 +78,14 @@ namespace Obfuz.ObfusPasses.FieldEncrypt { return info; } + EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(field.Module); - IRandom random = CreateRandomForField(field); - int encryptOps = GenerateEncryptionOperations(random); + IRandom random = CreateRandomForField(encryptionScope.localRandomCreator, field); + IEncryptor encryptor = encryptionScope.encryptor; + int encryptOps = GenerateEncryptionOperations(random, encryptor); int salt = GenerateSalt(random); ElementType fieldType = field.FieldSig.Type.RemovePinnedAndModifiers().ElementType; - long xorValueForZero = CalcXorValueForZero(fieldType, encryptOps, salt); + long xorValueForZero = CalcXorValueForZero(encryptor, fieldType, encryptOps, salt); info = new FieldEncryptInfo { diff --git a/Editor/ObfusPasses/FieldEncrypt/FieldEncryptPass.cs b/Editor/ObfusPasses/FieldEncrypt/FieldEncryptPass.cs index 04aece0..83b4494 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.localRandomCreator, ctx.encryptor, ctx.moduleEntityManager, _encryptionLevel); + _memoryEncryptor = new DefaultFieldEncryptor(ctx.encryptionScopeProvider, ctx.moduleEntityManager, _encryptionLevel); _encryptionPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles); } diff --git a/Editor/ObfuscationPassContext.cs b/Editor/ObfuscationPassContext.cs index e0254d1..12c327f 100644 --- a/Editor/ObfuscationPassContext.cs +++ b/Editor/ObfuscationPassContext.cs @@ -14,6 +14,48 @@ namespace Obfuz { public delegate IRandom RandomCreator(int seed); + public class EncryptionScopeInfo + { + public readonly byte[] byteSecret; + public readonly int[] intSecret; + public readonly IEncryptor encryptor; + public readonly RandomCreator localRandomCreator; + + public EncryptionScopeInfo(byte[] byteSecret, int[] intSecret, IEncryptor encryptor, RandomCreator localRandomCreator) + { + this.byteSecret = byteSecret; + this.intSecret = intSecret; + this.encryptor = encryptor; + this.localRandomCreator = localRandomCreator; + } + } + + public class EncryptionScopeProvider + { + private readonly EncryptionScopeInfo _defaultStaticScope; + private readonly EncryptionScopeInfo _defaultDynamicScope; + private readonly HashSet _dynamicSecretAssemblyNames; + + public EncryptionScopeProvider(EncryptionScopeInfo defaultStaticScope, EncryptionScopeInfo defaultDynamicScope, HashSet dynamicSecretAssemblyNames) + { + _defaultStaticScope = defaultStaticScope; + _defaultDynamicScope = defaultDynamicScope; + _dynamicSecretAssemblyNames = dynamicSecretAssemblyNames; + } + + public EncryptionScopeInfo GetScope(ModuleDef module) + { + if (_dynamicSecretAssemblyNames.Contains(module.Assembly.Name)) + { + return _defaultDynamicScope; + } + else + { + return _defaultStaticScope; + } + } + } + public class ObfuscationPassContext { public static ObfuscationPassContext Current { get; set; } @@ -31,10 +73,7 @@ namespace Obfuz public string obfuscatedAssemblyOutputDir; - public IRandom globalRandom; - public RandomCreator localRandomCreator; - - public IEncryptor encryptor; + public EncryptionScopeProvider encryptionScopeProvider; public ConstFieldAllocator constFieldAllocator; public RvaDataAllocator rvaDataAllocator; public NotObfuscatedMethodWhiteList whiteList; diff --git a/Editor/Obfuscator.cs b/Editor/Obfuscator.cs index 15ee177..06954d6 100644 --- a/Editor/Obfuscator.cs +++ b/Editor/Obfuscator.cs @@ -31,8 +31,13 @@ namespace Obfuz private readonly Pipeline _pipeline1 = new Pipeline(); private readonly Pipeline _pipeline2 = new Pipeline(); - private readonly byte[] _byteSecret; - private readonly int[] _intSecret; + + private readonly byte[] _defaultStaticByteSecret; + private readonly int[] _defaultStaticIntSecret; + private readonly byte[] _defaultDynamicByteSecret; + private readonly int[] _defaultDynamicIntSecret; + private readonly HashSet _dynamicSecretAssemblyNames; + private readonly int _randomSeed; private readonly string _encryptionVmGenerationSecret; private readonly int _encryptionVmOpCodeCount; @@ -42,9 +47,15 @@ namespace Obfuz public Obfuscator(ObfuscatorBuilder builder) { - _byteSecret = KeyGenerator.GenerateKey(builder.Secret, VirtualMachine.SecretKeyLength); - _intSecret = KeyGenerator.ConvertToIntKey(_byteSecret); - SaveKey(_byteSecret, builder.SecretOutputPath); + _defaultStaticByteSecret = KeyGenerator.GenerateKey(builder.DefaultStaticSecret, VirtualMachine.SecretKeyLength); + _defaultStaticIntSecret = KeyGenerator.ConvertToIntKey(_defaultStaticByteSecret); + SaveKey(_defaultStaticByteSecret, builder.DefaultStaticSecretOutputPath); + _defaultDynamicByteSecret = KeyGenerator.GenerateKey(builder.DefaultDynamicSecret, VirtualMachine.SecretKeyLength); + _defaultDynamicIntSecret = KeyGenerator.ConvertToIntKey(_defaultDynamicByteSecret); + SaveKey(_defaultDynamicByteSecret, builder.DefaultDynamicSecretOutputPath); + _dynamicSecretAssemblyNames = new HashSet(builder.DynamicSecretAssemblyNames); + + _randomSeed = builder.RandomSeed; _encryptionVmGenerationSecret = builder.EncryptionVmGenerationSecretKey; _encryptionVmOpCodeCount = builder.EncryptionVmOpCodeCount; @@ -98,7 +109,7 @@ namespace Obfuz OnPostObfuscation(pipeline); } - private IEncryptor CreateEncryptionVirtualMachine() + private IEncryptor CreateEncryptionVirtualMachine(byte[] secret) { var vmCreator = new VirtualMachineCreator(_encryptionVmGenerationSecret); var vm = vmCreator.CreateVirtualMachine(_encryptionVmOpCodeCount); @@ -112,7 +123,7 @@ namespace Obfuz { throw new Exception($"EncryptionVm CodeFile:`{_encryptionVmCodeFile}` not match with encryptionVM settings! Please run `Obfuz/GenerateVm` to update it!"); } - var vms = new VirtualMachineSimulator(vm, _byteSecret); + var vms = new VirtualMachineSimulator(vm, secret); var generatedVmTypes = AppDomain.CurrentDomain.GetAssemblies() .Select(assembly => assembly.GetType("Obfuz.EncryptionVM.GeneratedEncryptionVirtualMachine")) @@ -127,7 +138,7 @@ namespace Obfuz throw new Exception($"class Obfuz.EncryptionVM.GeneratedEncryptionVirtualMachine found in multiple assemblies! Please retain only one!"); } - var gvmInstance = (IEncryptor)Activator.CreateInstance(generatedVmTypes[0], new object[] { _byteSecret } ); + var gvmInstance = (IEncryptor)Activator.CreateInstance(generatedVmTypes[0], new object[] { secret } ); VerifyVm(vm, vms, gvmInstance); @@ -241,6 +252,20 @@ namespace Obfuz } } + private EncryptionScopeInfo CreateEncryptionScope(byte[] byteSecret, int[] intSecret) + { + IEncryptor encryption = CreateEncryptionVirtualMachine(byteSecret); + RandomCreator localRandomCreator = (seed) => new RandomWithKey(intSecret, _randomSeed ^ seed); + return new EncryptionScopeInfo(byteSecret, intSecret, encryption, localRandomCreator); + } + + private EncryptionScopeProvider CreateEncryptionScopeProvider() + { + var defaultStaticScope = CreateEncryptionScope(_defaultStaticByteSecret, _defaultStaticIntSecret); + var defaultDynamicScope = CreateEncryptionScope(_defaultDynamicByteSecret, _defaultDynamicIntSecret); + return new EncryptionScopeProvider(defaultStaticScope, defaultDynamicScope, _dynamicSecretAssemblyNames); + } + private void OnPreObfuscation(Pipeline pipeline) { AssemblyCache assemblyCache = new AssemblyCache(new PathAssemblyResolver(_assemblySearchDirs.ToArray())); @@ -248,12 +273,10 @@ namespace Obfuz List obfuscatedAndNotObfuscatedModules = new List(); LoadAssemblies(assemblyCache, toObfuscatedModules, obfuscatedAndNotObfuscatedModules); - var random = new RandomWithKey(_intSecret, _randomSeed); - RandomCreator localRandomCreator = (seed) => new RandomWithKey(_intSecret, _randomSeed ^ seed); - var encryptor = CreateEncryptionVirtualMachine(); + EncryptionScopeProvider encryptionScopeProvider = CreateEncryptionScopeProvider(); var moduleEntityManager = new GroupByModuleEntityManager(); - var rvaDataAllocator = new RvaDataAllocator(random, encryptor, moduleEntityManager); - var constFieldAllocator = new ConstFieldAllocator(encryptor, localRandomCreator, rvaDataAllocator, moduleEntityManager); + var rvaDataAllocator = new RvaDataAllocator(encryptionScopeProvider, moduleEntityManager); + var constFieldAllocator = new ConstFieldAllocator(encryptionScopeProvider, rvaDataAllocator, moduleEntityManager); _ctx = new ObfuscationPassContext { assemblyCache = assemblyCache, @@ -264,9 +287,8 @@ namespace Obfuz obfuscatedAssemblyOutputDir = _obfuscatedAssemblyOutputDir, moduleEntityManager = moduleEntityManager, - globalRandom = random, - localRandomCreator = localRandomCreator, - encryptor = encryptor, + encryptionScopeProvider = encryptionScopeProvider, + rvaDataAllocator = rvaDataAllocator, constFieldAllocator = constFieldAllocator, whiteList = new NotObfuscatedMethodWhiteList(), diff --git a/Editor/ObfuscatorBuilder.cs b/Editor/ObfuscatorBuilder.cs index 2406ecc..94d0d42 100644 --- a/Editor/ObfuscatorBuilder.cs +++ b/Editor/ObfuscatorBuilder.cs @@ -15,8 +15,12 @@ namespace Obfuz { public class ObfuscatorBuilder { - private string _secret; - private string _secretOutputPath; + private string _defaultStaticSecret; + private string _defaultStaticSecretOutputPath; + private string _defaultDynamicSecret; + private string _defaultDynamicSecretOutputPath; + private List _dynamicSecretAssemblyNames = new List(); + private int _randomSeed; private string _encryptionVmGenerationSecretKey; private int _encryptionVmOpCodeCount; @@ -32,16 +36,34 @@ namespace Obfuz private ObfuscationPassType _enabledObfuscationPasses; private List _obfuscationPasses = new List(); - public string Secret + public string DefaultStaticSecret { - get => _secret; - set => _secret = value; + get => _defaultStaticSecret; + set => _defaultStaticSecret = value; } - public string SecretOutputPath + public string DefaultStaticSecretOutputPath { - get => _secretOutputPath; - set => _secretOutputPath = value; + get => _defaultStaticSecretOutputPath; + set => _defaultStaticSecretOutputPath = value; + } + + public string DefaultDynamicSecret + { + get => _defaultDynamicSecret; + set => _defaultDynamicSecret = value; + } + + public string DefaultDynamicSecretOutputPath + { + get => _defaultDynamicSecretOutputPath; + set => _defaultDynamicSecretOutputPath = value; + } + + public List DynamicSecretAssemblyNames + { + get => _dynamicSecretAssemblyNames; + set => _dynamicSecretAssemblyNames = value; } public int RandomSeed @@ -151,8 +173,11 @@ namespace Obfuz : settings.assemblySettings.extraAssemblySearchDirs.ToList(); var builder = new ObfuscatorBuilder { - _secret = settings.secretSettings.secret, - _secretOutputPath = settings.secretSettings.secretOutputPath, + _defaultStaticSecret = settings.secretSettings.defaultStaticSecret, + _defaultStaticSecretOutputPath = settings.secretSettings.DefaultStaticSecretKeyOutputPath, + _defaultDynamicSecret = settings.secretSettings.defaultDynamicSecret, + _defaultDynamicSecretOutputPath = settings.secretSettings.DefaultDynamicSecretKeyOutputPath, + _dynamicSecretAssemblyNames = settings.secretSettings.dynamicSecretAssemblyNames.ToList(), _randomSeed = settings.secretSettings.randomSeed, _encryptionVmGenerationSecretKey = settings.encryptionVMSettings.codeGenerationSecret, _encryptionVmOpCodeCount = settings.encryptionVMSettings.encryptionOpCodeCount, diff --git a/Editor/Settings/SecretSettings.cs b/Editor/Settings/SecretSettings.cs index a4db265..c6653b0 100644 --- a/Editor/Settings/SecretSettings.cs +++ b/Editor/Settings/SecretSettings.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using UnityEngine; namespace Obfuz.Settings @@ -7,13 +8,22 @@ namespace Obfuz.Settings public class SecretSettings { - [Tooltip("secret key")] - public string secret = "Code Philosophy"; + [Tooltip("default static secret key")] + public string defaultStaticSecret = "Code Philosophy-Static"; - [Tooltip("secret key save path")] - public string secretOutputPath = $"Assets/Obfuz/secret.bytes"; + public string defaultDynamicSecret = "Code Philosophy-Dynamic"; + + [Tooltip("secret key output directory")] + public string secretOutputDir = $"Assets/Resources/Obfuz"; [Tooltip("random seed")] public int randomSeed = 0; + + [Tooltip("name of assemblies those use dynamic secret")] + public string[] dynamicSecretAssemblyNames; + + public string DefaultStaticSecretKeyOutputPath => Path.Combine(secretOutputDir, "defaultStaticSecret.bytes"); + + public string DefaultDynamicSecretKeyOutputPath => Path.Combine(secretOutputDir, "defaultDynamicSecret.bytes"); } } diff --git a/Editor/Unity/ObfuzMenu.cs b/Editor/Unity/ObfuzMenu.cs index f46460d..3aa9dbd 100644 --- a/Editor/Unity/ObfuzMenu.cs +++ b/Editor/Unity/ObfuzMenu.cs @@ -28,8 +28,12 @@ namespace Obfuz.Unity { SecretSettings settings = ObfuzSettings.Instance.secretSettings; - var secretBytes = KeyGenerator.GenerateKey(settings.secret, VirtualMachine.SecretKeyLength); - Obfuscator.SaveKey(secretBytes, settings.secretOutputPath); + var staticSecretBytes = KeyGenerator.GenerateKey(settings.defaultStaticSecret, VirtualMachine.SecretKeyLength); + Obfuscator.SaveKey(staticSecretBytes, settings.DefaultStaticSecretKeyOutputPath); + Debug.Log($"Save static secret key to {settings.DefaultStaticSecretKeyOutputPath}"); + var dynamicSecretBytes = KeyGenerator.GenerateKey(settings.defaultDynamicSecret, VirtualMachine.SecretKeyLength); + Obfuscator.SaveKey(dynamicSecretBytes, settings.DefaultDynamicSecretKeyOutputPath); + Debug.Log($"Save dynamic secret key to {settings.DefaultDynamicSecretKeyOutputPath}"); } [MenuItem("Obfuz/Documents/Quick Start")]