From af60d0703d5c49c7e925d0e61ee5ce6fe7a669c1 Mon Sep 17 00:00:00 2001 From: walon Date: Sun, 11 May 2025 10:49:04 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=20EncryptionVM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/Encryption/IVirtualMachineCreator.cs | 2 +- .../Encryption/RandomVirtualMachineCreator.cs | 41 +++++++++---------- Editor/Encryption/VirtualMachine.cs | 6 +-- Editor/Obfuscator.cs | 3 +- Editor/Utils/KeyGenerator.cs | 18 +++++--- Editor/Utils/RandomWithKey.cs | 11 +---- 6 files changed, 40 insertions(+), 41 deletions(-) diff --git a/Editor/Encryption/IVirtualMachineCreator.cs b/Editor/Encryption/IVirtualMachineCreator.cs index e1098a5..6141fb9 100644 --- a/Editor/Encryption/IVirtualMachineCreator.cs +++ b/Editor/Encryption/IVirtualMachineCreator.cs @@ -2,6 +2,6 @@ { public interface IVirtualMachineCreator { - VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed); + VirtualMachine CreateVirtualMachine(int opCodeCount); } } diff --git a/Editor/Encryption/RandomVirtualMachineCreator.cs b/Editor/Encryption/RandomVirtualMachineCreator.cs index 0b33cbb..422e839 100644 --- a/Editor/Encryption/RandomVirtualMachineCreator.cs +++ b/Editor/Encryption/RandomVirtualMachineCreator.cs @@ -5,58 +5,57 @@ namespace Obfuz.Encryption { public class RandomVirtualMachineCreator : IVirtualMachineCreator { - private readonly int[] _debugSecretKey; + private readonly byte[] _byteSecretKey; + private readonly int[] _secretKey; + private readonly IRandom _random; - public RandomVirtualMachineCreator() + public RandomVirtualMachineCreator(byte[] secretKey) { - _debugSecretKey = new int[VirtualMachine.SecretKeyLength]; - for (int i = 0; i < _debugSecretKey.Length; i++) - { - _debugSecretKey[i] = i; - } + _byteSecretKey = secretKey; + _secretKey = KeyGenerator.ConvertToIntKey(secretKey); + _random = new RandomWithKey(secretKey, 0); } - private IEncryptInstruction CreateRandomInstruction(IRandom random, int secretKeyLength) + private IEncryptInstruction CreateRandomInstruction(int secretKeyLength) { - switch (random.NextInt(3)) + switch (_random.NextInt(3)) { case 0: - return new AddInstruction(random.NextInt(), random.NextInt(secretKeyLength)); + return new AddInstruction(_random.NextInt(), _random.NextInt(secretKeyLength)); case 1: - return new XorInstruction(random.NextInt(), random.NextInt(secretKeyLength)); + return new XorInstruction(_random.NextInt(), _random.NextInt(secretKeyLength)); case 2: - return new BitRotateInstruction(random.NextInt(32), random.NextInt(secretKeyLength)); + return new BitRotateInstruction(_random.NextInt(32), _random.NextInt(secretKeyLength)); default: throw new System.Exception("Invalid instruction type"); } } - private EncryptOpCode CreateEncryptOpCode(ushort code, IRandom r, int opCodeCount) + private EncryptOpCode CreateEncryptOpCode(ushort code, int opCodeCount) { Assert.IsTrue(code < opCodeCount); var insts = new IEncryptInstruction[opCodeCount]; for (int i = 0; i < insts.Length; i++) { - IEncryptInstruction inst = CreateRandomInstruction(r, VirtualMachine.SecretKeyLength); - Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _debugSecretKey, i), _debugSecretKey, i)); - insts[i] = CreateRandomInstruction(r, opCodeCount); + IEncryptInstruction inst = CreateRandomInstruction(VirtualMachine.SecretKeyLength); + Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _secretKey, i), _secretKey, i)); + insts[i] = CreateRandomInstruction(opCodeCount); } var function = new EncryptFunction(insts); - Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _debugSecretKey, code), _debugSecretKey, code)); + Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _secretKey, code), _secretKey, code)); return new EncryptOpCode(code, function); } - public VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed) + public VirtualMachine CreateVirtualMachine(int opCodeCount) { Assert.IsTrue(opCodeCount > 0); Assert.AreEqual(0, opCodeCount ^ (opCodeCount - 1)); - IRandom r = new RandomWithKey(new byte[] {1,2,3,4,5,6}, vmSeed); var opCodes = new EncryptOpCode[opCodeCount]; for (int i = 0; i < opCodes.Length; i++) { - opCodes[i] = CreateEncryptOpCode((ushort)i, r, opCodeCount); + opCodes[i] = CreateEncryptOpCode((ushort)i, opCodeCount); } - return new VirtualMachine(vmSeed, opCodes); + return new VirtualMachine(_byteSecretKey, opCodes); } } } diff --git a/Editor/Encryption/VirtualMachine.cs b/Editor/Encryption/VirtualMachine.cs index 8d4c543..2f44983 100644 --- a/Editor/Encryption/VirtualMachine.cs +++ b/Editor/Encryption/VirtualMachine.cs @@ -4,12 +4,12 @@ { public const int SecretKeyLength = 1024; - public readonly int vmSeed; + public readonly byte[] secretKey; public readonly EncryptOpCode[] opCodes; - public VirtualMachine(int vmSeed, EncryptOpCode[] opCodes) + public VirtualMachine(byte[] secretKey, EncryptOpCode[] opCodes) { - this.vmSeed = vmSeed; + this.secretKey = secretKey; this.opCodes = opCodes; } } diff --git a/Editor/Obfuscator.cs b/Editor/Obfuscator.cs index c788ca5..d42bd22 100644 --- a/Editor/Obfuscator.cs +++ b/Editor/Obfuscator.cs @@ -2,6 +2,7 @@ using dnlib.Protection; using Obfuz.Data; using Obfuz.Emit; +using Obfuz.Encryption; using Obfuz.ObfusPasses; using Obfuz.ObfusPasses.CleanUp; using Obfuz.Utils; @@ -39,7 +40,7 @@ namespace Obfuz string obfuscatedAssemblyOutputDir, List obfuscationPasses, string rawSecretKey, int globalRandomSeed) { - _secretKey = KeyGenerator.GenerateKey(rawSecretKey); + _secretKey = KeyGenerator.GenerateKey(rawSecretKey, VirtualMachine.SecretKeyLength); _globalRandomSeed = globalRandomSeed; _toObfuscatedAssemblyNames = toObfuscatedAssemblyNames; diff --git a/Editor/Utils/KeyGenerator.cs b/Editor/Utils/KeyGenerator.cs index e83ccb8..ee6f1f4 100644 --- a/Editor/Utils/KeyGenerator.cs +++ b/Editor/Utils/KeyGenerator.cs @@ -1,4 +1,5 @@ -using System; +using NUnit.Framework; +using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; @@ -9,14 +10,12 @@ namespace Obfuz.Utils { public static class KeyGenerator { - public const int KeyLength = 1024; - - public static byte[] GenerateKey(string initialString) + public static byte[] GenerateKey(string initialString, int keyLength) { byte[] initialBytes = Encoding.UTF8.GetBytes(initialString); using var sha512 = SHA512.Create(); byte[] hash = sha512.ComputeHash(initialBytes); - byte[] key = new byte[KeyLength]; + byte[] key = new byte[keyLength]; int bytesCopied = 0; while (bytesCopied < key.Length) { @@ -31,5 +30,14 @@ namespace Obfuz.Utils } return key; } + + public static int[] ConvertToIntKey(byte[] key) + { + Assert.AreEqual(0, key.Length % 4); + int align4Length = key.Length / 4; + int[] intKey = new int[align4Length]; + Buffer.BlockCopy(key, 0, intKey, 0, key.Length); + return intKey; + } } } diff --git a/Editor/Utils/RandomWithKey.cs b/Editor/Utils/RandomWithKey.cs index 8a0292e..4200613 100644 --- a/Editor/Utils/RandomWithKey.cs +++ b/Editor/Utils/RandomWithKey.cs @@ -21,19 +21,10 @@ namespace Obfuz.Utils public RandomWithKey(byte[] key, int seed) { - _key = ConvertToIntKey(key); + _key = KeyGenerator.ConvertToIntKey(key); _seed = seed; } - private static int[] ConvertToIntKey(byte[] key) - { - // ignore last bytes if not aligned to 4 - int align4Length = key.Length / 4; - int[] intKey = new int[align4Length]; - Buffer.BlockCopy(key, 0, intKey, 0, align4Length * 4); - return intKey; - } - public int NextInt(int min, int max) { return min + NextInt(max - min);