From 542585b1f74cf21ee6317b762e507f3af47afca6 Mon Sep 17 00:00:00 2001 From: walon Date: Wed, 14 May 2025 10:46:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20GeneratedEncryptionVirtual?= =?UTF-8?q?Machine=20Decrypt=E6=97=B6=E6=B2=A1=E6=9C=89=E9=80=86=E5=BA=8Fo?= =?UTF-8?q?ps=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/Data/ConstFieldAllocator.cs | 11 +++++++ Editor/Data/RvaDataAllocator.cs | 14 +++++++-- .../VirtualMachineCodeGenerator.cs | 11 ++++++- .../EncryptionVM/VirtualMachineSimulator.cs | 20 ++++++------- .../CallObfus/CallProxyAllocator.cs | 11 +++++++ .../ConstEncrypt/ConstEncryptPass.cs | 2 +- .../ConstEncrypt/DefaultConstEncryptor.cs | 2 -- .../ConstEncrypt/IConstEncryptor.cs | 3 -- .../Policies/SystemRenamePolicy.cs | 2 +- Editor/Obfuscator.cs | 30 ++++++++++++++++--- Editor/Utils/EncryptionUtil.cs | 4 +-- 11 files changed, 84 insertions(+), 26 deletions(-) diff --git a/Editor/Data/ConstFieldAllocator.cs b/Editor/Data/ConstFieldAllocator.cs index f490195..aacd5c9 100644 --- a/Editor/Data/ConstFieldAllocator.cs +++ b/Editor/Data/ConstFieldAllocator.cs @@ -5,6 +5,7 @@ using Obfuz.Utils; using System; using System.Collections.Generic; using System.Linq; +using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; using UnityEngine; @@ -31,6 +32,7 @@ namespace Obfuz.Data private readonly Dictionary _field2Fields = new Dictionary(); private readonly List _holderTypeDefs = new List(); + private bool _done; public ModuleConstFieldAllocator(IEncryptor encryptor, IRandom random, RvaDataAllocator rvaDataAllocator, GroupByModuleEntityManager moduleEntityManager) @@ -89,6 +91,10 @@ namespace Obfuz.Data private FieldDef AllocateAny(object value) { + if (_done) + { + throw new Exception("can't Allocate after done"); + } if (!_allocatedFields.TryGetValue(value, out var field)) { field = CreateConstFieldInfo(value); @@ -248,6 +254,11 @@ namespace Obfuz.Data public void Done() { + if (_done) + { + throw new Exception("Already done"); + } + _done = true; foreach (var typeDef in _holderTypeDefs) { CreateCCtorOfRvaTypeDef(typeDef); diff --git a/Editor/Data/RvaDataAllocator.cs b/Editor/Data/RvaDataAllocator.cs index a67b0e7..7a9fc56 100644 --- a/Editor/Data/RvaDataAllocator.cs +++ b/Editor/Data/RvaDataAllocator.cs @@ -69,6 +69,7 @@ namespace Obfuz.Data private TypeDef _rvaTypeDef; private readonly Dictionary _dataHolderTypeBySizes = new Dictionary(); + private bool _done; public ModuleRvaDataAllocator(IRandom random, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager) { @@ -99,10 +100,10 @@ namespace Obfuz.Data } - var holderField = new FieldDefUser($"$RVA_Data{_rvaTypeDef.Fields.Count}", new FieldSig(dataHolderType.ToTypeSig()), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA); + var holderField = new FieldDefUser($"$RVA_Data{_rvaFields.Count}", new FieldSig(dataHolderType.ToTypeSig()), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA); holderField.DeclaringType = _rvaTypeDef; - var runtimeValueField = new FieldDefUser($"$RVA_Value{_rvaTypeDef.Fields.Count}", new FieldSig(new SZArraySig(_module.CorLibTypes.Byte)), FieldAttributes.Static); + var runtimeValueField = new FieldDefUser($"$RVA_Value{_rvaFields.Count}", new FieldSig(new SZArraySig(_module.CorLibTypes.Byte)), FieldAttributes.Static); runtimeValueField.DeclaringType = _rvaTypeDef; return (holderField, runtimeValueField); } @@ -145,6 +146,10 @@ namespace Obfuz.Data private RvaField GetRvaField(int preservedSize, int alignment) { + if (_done) + { + throw new Exception("can't GetRvaField after done"); + } Assert.IsTrue(preservedSize % alignment == 0); // for big size, create a new field if (preservedSize >= maxRvaDataSize) @@ -279,6 +284,11 @@ namespace Obfuz.Data public void Done() { + if (_done) + { + throw new Exception("can't call Done twice"); + } + _done = true; SetFieldsRVA(); CreateCCtorOfRvaTypeDef(); } diff --git a/Editor/EncryptionVM/VirtualMachineCodeGenerator.cs b/Editor/EncryptionVM/VirtualMachineCodeGenerator.cs index 1c826db..2845ef4 100644 --- a/Editor/EncryptionVM/VirtualMachineCodeGenerator.cs +++ b/Editor/EncryptionVM/VirtualMachineCodeGenerator.cs @@ -152,12 +152,21 @@ namespace Obfuz.EncryptionVM public override int Encrypt(int value, int opts, int salt) { + int revertOps = 0; while (opts > 0) { int opCode = opts & kOpCodeMask; - value = ExecuteEncrypt(value, opCode, salt); + revertOps <<= kOpCodeBits; + revertOps |= opCode; opts >>= kOpCodeBits; } + + while (revertOps > 0) + { + int opCode = revertOps & kOpCodeMask; + value = ExecuteEncrypt(value, opCode, salt); + revertOps >>= kOpCodeBits; + } return value; } diff --git a/Editor/EncryptionVM/VirtualMachineSimulator.cs b/Editor/EncryptionVM/VirtualMachineSimulator.cs index 67796dd..6f39359 100644 --- a/Editor/EncryptionVM/VirtualMachineSimulator.cs +++ b/Editor/EncryptionVM/VirtualMachineSimulator.cs @@ -57,24 +57,24 @@ namespace Obfuz.EncryptionVM } } - private List DecodeOps(int ops) + private List DecodeOps(uint ops) { - var codes = new List(); + var codes = new List(); while (ops > 0) { - var code = (ushort)(ops % _opCodes.Length); + uint code = ops % (uint)_opCodes.Length; codes.Add(code); - ops >>= 16; + ops /= (uint)_opCodes.Length; } return codes; } public override int Encrypt(int value, int ops, int salt) { - var codes = DecodeOps(ops); - foreach (var code in codes) + var codes = DecodeOps((uint)ops); + for (int i = codes.Count - 1; i >= 0; i--) { - var opCode = _opCodes[code]; + var opCode = _opCodes[codes[i]]; value = opCode.Encrypt(value, _secretKey, salt); } return value; @@ -82,10 +82,10 @@ namespace Obfuz.EncryptionVM public override int Decrypt(int value, int ops, int salt) { - var codes = DecodeOps(ops); - for (int i = codes.Count - 1; i >= 0; i--) + var codes = DecodeOps((uint)ops); + foreach (var code in codes) { - var opCode = _opCodes[codes[i]]; + var opCode = _opCodes[code]; value = opCode.Decrypt(value, _secretKey, salt); } return value; diff --git a/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs b/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs index c4a679c..ec1831c 100644 --- a/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs +++ b/Editor/ObfusPasses/CallObfus/CallProxyAllocator.cs @@ -36,6 +36,7 @@ namespace Obfuz.ObfusPasses.CallObfus private readonly RandomCreator _randomCreator; private readonly IEncryptor _encryptor; private readonly int _encryptionLevel; + private bool _done; class MethodKey : IEquatable { @@ -188,6 +189,10 @@ namespace Obfuz.ObfusPasses.CallObfus public ProxyCallMethodData Allocate(IMethod method, bool callVir) { + if (_done) + { + throw new Exception("can't Allocate after done"); + } var key = new MethodKey(method, callVir); if (!_methodProxys.TryGetValue(key, out var proxyInfo)) { @@ -214,6 +219,12 @@ namespace Obfuz.ObfusPasses.CallObfus public void Done() { + if (_done) + { + throw new Exception("Already done"); + } + _done = true; + foreach (DispatchMethodInfo dispatchMethod in _dispatchMethods.Values.SelectMany(ms => ms)) { var methodDef = dispatchMethod.methodDef; diff --git a/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs b/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs index 3612b37..678a85e 100644 --- a/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs +++ b/Editor/ObfusPasses/ConstEncrypt/ConstEncryptPass.cs @@ -36,7 +36,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt public override void Stop() { - _dataObfuscator.Done(); + } protected override bool NeedObfuscateMethod(MethodDef method) diff --git a/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs b/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs index a314d66..a2c58ec 100644 --- a/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs +++ b/Editor/ObfusPasses/ConstEncrypt/DefaultConstEncryptor.cs @@ -196,8 +196,6 @@ namespace Obfuz.ObfusPasses.ConstEncrypt public void Done() { - _rvaDataAllocator.Done(); - _constFieldAllocator.Done(); } } } diff --git a/Editor/ObfusPasses/ConstEncrypt/IConstEncryptor.cs b/Editor/ObfusPasses/ConstEncrypt/IConstEncryptor.cs index 31f6869..7043aec 100644 --- a/Editor/ObfusPasses/ConstEncrypt/IConstEncryptor.cs +++ b/Editor/ObfusPasses/ConstEncrypt/IConstEncryptor.cs @@ -18,8 +18,6 @@ namespace Obfuz.ObfusPasses.ConstEncrypt void ObfuscateString(MethodDef method, bool needCacheValue, string value, List obfuscatedInstructions); void ObfuscateBytes(MethodDef method, bool needCacheValue, byte[] value, List obfuscatedInstructions); - - void Done(); } public abstract class ConstEncryptorBase : IConstEncryptor @@ -30,6 +28,5 @@ namespace Obfuz.ObfusPasses.ConstEncrypt public abstract void ObfuscateInt(MethodDef method, bool needCacheValue, int value, List obfuscatedInstructions); public abstract void ObfuscateLong(MethodDef method, bool needCacheValue, long value, List obfuscatedInstructions); public abstract void ObfuscateString(MethodDef method, bool needCacheValue, string value, List obfuscatedInstructions); - public abstract void Done(); } } diff --git a/Editor/ObfusPasses/SymbolObfus/Policies/SystemRenamePolicy.cs b/Editor/ObfusPasses/SymbolObfus/Policies/SystemRenamePolicy.cs index c3ab962..bda6302 100644 --- a/Editor/ObfusPasses/SymbolObfus/Policies/SystemRenamePolicy.cs +++ b/Editor/ObfusPasses/SymbolObfus/Policies/SystemRenamePolicy.cs @@ -8,7 +8,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus.Policies public override bool NeedRename(TypeDef typeDef) { string name = typeDef.Name; - if (name == "") + if (name == "" || name == "ObfuzIgnoreAttribute") { return false; } diff --git a/Editor/Obfuscator.cs b/Editor/Obfuscator.cs index e5e4b86..8535365 100644 --- a/Editor/Obfuscator.cs +++ b/Editor/Obfuscator.cs @@ -129,16 +129,18 @@ namespace Obfuz var gvmInstance = (IEncryptor)Activator.CreateInstance(generatedVmTypes[0], new object[] { _byteSecret } ); int testValue = 11223344; + string testString = "hello,world"; for (int i = 0; i < vm.opCodes.Length; i++) { - int encryptedValueOfVms = vms.Encrypt(testValue, i, i); - int decryptedValueOfVms = vms.Decrypt(encryptedValueOfVms, i, i); + int ops = i * vm.opCodes.Length + i; + int encryptedValueOfVms = vms.Encrypt(testValue, ops, i); + int decryptedValueOfVms = vms.Decrypt(encryptedValueOfVms, ops, i); if (decryptedValueOfVms != testValue) { throw new Exception($"VirtualMachineSimulator decrypt failed! opCode:{i}, originalValue:{testValue} decryptedValue:{decryptedValueOfVms}"); } - int encryptedValueOfGvm = gvmInstance.Encrypt(testValue, i, i); - int decryptedValueOfGvm = gvmInstance.Decrypt(encryptedValueOfGvm, i, i); + int encryptedValueOfGvm = gvmInstance.Encrypt(testValue, ops, i); + int decryptedValueOfGvm = gvmInstance.Decrypt(encryptedValueOfGvm, ops, i); if (encryptedValueOfGvm != encryptedValueOfVms) { throw new Exception($"encryptedValue not match! opCode:{i}, originalValue:{testValue} encryptedValue VirtualMachineSimulator:{encryptedValueOfVms} GeneratedEncryptionVirtualMachine:{encryptedValueOfGvm}"); @@ -147,6 +149,23 @@ namespace Obfuz { throw new Exception($"GeneratedEncryptionVirtualMachine decrypt failed! opCode:{i}, originalValue:{testValue} decryptedValue:{decryptedValueOfGvm}"); } + + byte[] encryptedStrOfVms = vms.Encrypt(testString, ops, i); + string descryptedStrOfVms = vms.DecryptString(encryptedStrOfVms, 0, encryptedStrOfVms.Length, ops, i); + if (descryptedStrOfVms != testString) + { + throw new Exception($"VirtualMachineSimulator decrypt string failed! opCode:{i}, originalValue:{testString} decryptedValue:{descryptedStrOfVms}"); + } + byte[] encryptedStrOfGvm = gvmInstance.Encrypt(testString, ops, i); + string descryptedStrOfGvm = gvmInstance.DecryptString(encryptedStrOfGvm, 0, encryptedStrOfGvm.Length, ops, i); + if (!encryptedStrOfGvm.SequenceEqual(encryptedStrOfVms)) + { + throw new Exception($"encryptedValue not match! opCode:{i}, originalValue:{testString} encryptedValue VirtualMachineSimulator:{encryptedStrOfVms} GeneratedEncryptionVirtualMachine:{encryptedStrOfGvm}"); + } + if (descryptedStrOfGvm != testString) + { + throw new Exception($"GeneratedEncryptionVirtualMachine decrypt string failed! opCode:{i}, originalValue:{testString} decryptedValue:{descryptedStrOfGvm}"); + } } return vms; @@ -223,6 +242,9 @@ namespace Obfuz private void OnPostObfuscation(Pipeline pipeline) { pipeline.Stop(); + + _ctx.constFieldAllocator.Done(); + _ctx.rvaDataAllocator.Done(); WriteAssemblies(); } } diff --git a/Editor/Utils/EncryptionUtil.cs b/Editor/Utils/EncryptionUtil.cs index edab9f0..5199a6a 100644 --- a/Editor/Utils/EncryptionUtil.cs +++ b/Editor/Utils/EncryptionUtil.cs @@ -30,8 +30,8 @@ namespace Obfuz.Utils for (int i = 0; i < encryptionLevel; i++) { ops *= vmOpCodeCount; - // first op code can't be 0 - int op = random.NextInt(i == 0 ? 1 : 0, vmOpCodeCount); + // don't use 0 + int op = random.NextInt(1, vmOpCodeCount); ops |= (uint)op; if (ops > uint.MaxValue) {