diff --git a/Editor/Encryption/EncryptInstructionBase.cs b/Editor/Encryption/EncryptInstructionBase.cs deleted file mode 100644 index be52283..0000000 --- a/Editor/Encryption/EncryptInstructionBase.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Obfuz.Encryption -{ - public abstract class EncryptInstructionBase : IEncryptInstruction - { - public abstract int Encrypt(int value, int[] secretKey, int salt); - public abstract int Decrypt(int value, int[] secretKey, int salt); - } -} diff --git a/Editor/Encryption/EncryptOpCode.cs b/Editor/Encryption/EncryptionInstructionWithOpCode.cs similarity index 70% rename from Editor/Encryption/EncryptOpCode.cs rename to Editor/Encryption/EncryptionInstructionWithOpCode.cs index 0a7ef72..c31aa3a 100644 --- a/Editor/Encryption/EncryptOpCode.cs +++ b/Editor/Encryption/EncryptionInstructionWithOpCode.cs @@ -1,12 +1,12 @@ namespace Obfuz.Encryption { - public class EncryptOpCode + public class EncryptionInstructionWithOpCode { public readonly ushort code; - public readonly EncryptFunction function; + public readonly IEncryptionInstruction function; - public EncryptOpCode(ushort code, EncryptFunction function) + public EncryptionInstructionWithOpCode(ushort code, IEncryptionInstruction function) { this.code = code; this.function = function; diff --git a/Editor/Encryption/EncryptionVirtualMachine.cs b/Editor/Encryption/EncryptionVirtualMachine.cs new file mode 100644 index 0000000..d3d1c48 --- /dev/null +++ b/Editor/Encryption/EncryptionVirtualMachine.cs @@ -0,0 +1,16 @@ +namespace Obfuz.Encryption +{ + public class EncryptionVirtualMachine + { + public const int SecretKeyLength = 1024; + + public readonly int[] secretKey; + public readonly EncryptionInstructionWithOpCode[] opCodes; + + public EncryptionVirtualMachine(int[] secretKey, EncryptionInstructionWithOpCode[] opCodes) + { + this.secretKey = secretKey; + this.opCodes = opCodes; + } + } +} diff --git a/Editor/Encryption/EncryptionVirtualMachineCreator.cs b/Editor/Encryption/EncryptionVirtualMachineCreator.cs new file mode 100644 index 0000000..c3c4c53 --- /dev/null +++ b/Editor/Encryption/EncryptionVirtualMachineCreator.cs @@ -0,0 +1,56 @@ +using Obfuz.Encryption.Instructions; +using Obfuz.Utils; +using UnityEngine.Assertions; + +namespace Obfuz.Encryption +{ + public class EncryptionVirtualMachineCreator + { + private readonly int[] _vmGenerationSecretKey; + private readonly byte[] _encryptionSecretKey; + private readonly IRandom _random; + + public const int CodeGenerationSecretKeyLength = 1024; + + public EncryptionVirtualMachineCreator(string vmGenerationSecretKey, byte[] encryptionSecretKey) + { + _vmGenerationSecretKey = KeyGenerator.ConvertToIntKey(KeyGenerator.GenerateKey(vmGenerationSecretKey, CodeGenerationSecretKeyLength)); + _encryptionSecretKey = encryptionSecretKey; + _random = new RandomWithKey(encryptionSecretKey, 0); + } + + private IEncryptionInstruction CreateRandomInstruction(int intSecretKeyLength) + { + switch (_random.NextInt(3)) + { + case 0: + return new AddInstruction(_random.NextInt(), _random.NextInt(intSecretKeyLength)); + case 1: + return new XorInstruction(_random.NextInt(), _random.NextInt(intSecretKeyLength)); + case 2: + return new BitRotateInstruction(_random.NextInt(32), _random.NextInt(intSecretKeyLength)); + default: + throw new System.Exception("Invalid instruction type"); + } + } + + private EncryptionInstructionWithOpCode CreateEncryptOpCode(ushort code) + { + IEncryptionInstruction inst = CreateRandomInstruction(EncryptionVirtualMachine.SecretKeyLength / sizeof(int)); + Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _vmGenerationSecretKey, 0x12345678), _vmGenerationSecretKey, 0x12345678)); + return new EncryptionInstructionWithOpCode(code, inst); + } + + public EncryptionVirtualMachine CreateVirtualMachine(int opCodeCount) + { + Assert.IsTrue(opCodeCount > 0); + Assert.AreEqual(0, opCodeCount & (opCodeCount - 1)); + var opCodes = new EncryptionInstructionWithOpCode[opCodeCount]; + for (int i = 0; i < opCodes.Length; i++) + { + opCodes[i] = CreateEncryptOpCode((ushort)i); + } + return new EncryptionVirtualMachine(_vmGenerationSecretKey, opCodes); + } + } +} diff --git a/Editor/Encryption/EncryptionVirtualMachineSimulator.cs b/Editor/Encryption/EncryptionVirtualMachineSimulator.cs index 8161a3c..119ae93 100644 --- a/Editor/Encryption/EncryptionVirtualMachineSimulator.cs +++ b/Editor/Encryption/EncryptionVirtualMachineSimulator.cs @@ -12,15 +12,26 @@ namespace Obfuz.Encryption public class EncryptionVirtualMachineSimulator : EncryptorBase { - private readonly EncryptOpCode[] _opCodes; + private readonly EncryptionInstructionWithOpCode[] _opCodes; private readonly int[] _secretKey; - public EncryptionVirtualMachineSimulator(EncryptOpCode[] opCodes, int[] secretKey) + public EncryptionVirtualMachineSimulator(EncryptionVirtualMachine vm) { - _opCodes = opCodes; - // should be power of 2 - Assert.AreEqual(0, opCodes.Length ^ (opCodes.Length - 1)); - _secretKey = secretKey; + _opCodes = vm.opCodes; + _secretKey = vm.secretKey; + + VerifyInstructions(); + } + + private void VerifyInstructions() + { + int value = 0x11223344; + for (int i = 0; i < _opCodes.Length; i++) + { + int encryptedValue = _opCodes[i].Encrypt(value, _secretKey, i); + int decryptedValue = _opCodes[i].Decrypt(encryptedValue, _secretKey, i); + Assert.AreEqual(value, decryptedValue); + } } private List DecodeOps(int ops) diff --git a/Editor/Encryption/IEncryptInstruction.cs b/Editor/Encryption/IEncryptInstruction.cs deleted file mode 100644 index e2fd265..0000000 --- a/Editor/Encryption/IEncryptInstruction.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Obfuz.Encryption -{ - public interface IEncryptInstruction - { - int Encrypt(int value, int[] secretKey, int salt); - - int Decrypt(int value, int[] secretKey, int salt); - } -} diff --git a/Editor/Encryption/IEncryptionInstruction.cs b/Editor/Encryption/IEncryptionInstruction.cs new file mode 100644 index 0000000..bb3b667 --- /dev/null +++ b/Editor/Encryption/IEncryptionInstruction.cs @@ -0,0 +1,15 @@ +namespace Obfuz.Encryption +{ + public interface IEncryptionInstruction + { + int Encrypt(int value, int[] secretKey, int salt); + + int Decrypt(int value, int[] secretKey, int salt); + } + + public abstract class EncryptionInstructionBase : IEncryptionInstruction + { + public abstract int Encrypt(int value, int[] secretKey, int salt); + public abstract int Decrypt(int value, int[] secretKey, int salt); + } +} diff --git a/Editor/Encryption/IVirtualMachineCreator.cs b/Editor/Encryption/IVirtualMachineCreator.cs deleted file mode 100644 index 6141fb9..0000000 --- a/Editor/Encryption/IVirtualMachineCreator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Obfuz.Encryption -{ - public interface IVirtualMachineCreator - { - VirtualMachine CreateVirtualMachine(int opCodeCount); - } -} diff --git a/Editor/Encryption/AddInstruction.cs b/Editor/Encryption/Instructions/AddInstruction.cs similarity index 84% rename from Editor/Encryption/AddInstruction.cs rename to Editor/Encryption/Instructions/AddInstruction.cs index 598cc5b..2b3de74 100644 --- a/Editor/Encryption/AddInstruction.cs +++ b/Editor/Encryption/Instructions/AddInstruction.cs @@ -1,6 +1,6 @@ -namespace Obfuz.Encryption +namespace Obfuz.Encryption.Instructions { - public class AddInstruction : EncryptInstructionBase + public class AddInstruction : EncryptionInstructionBase { private readonly int _addValue; private readonly int _opKeyIndex; diff --git a/Editor/Encryption/BitRotateInstruction.cs b/Editor/Encryption/Instructions/BitRotateInstruction.cs similarity index 88% rename from Editor/Encryption/BitRotateInstruction.cs rename to Editor/Encryption/Instructions/BitRotateInstruction.cs index 14f41a3..dab8252 100644 --- a/Editor/Encryption/BitRotateInstruction.cs +++ b/Editor/Encryption/Instructions/BitRotateInstruction.cs @@ -1,6 +1,6 @@ -namespace Obfuz.Encryption +namespace Obfuz.Encryption.Instructions { - public class BitRotateInstruction : EncryptInstructionBase + public class BitRotateInstruction : EncryptionInstructionBase { private readonly int _rotateBitNum; private readonly int _opKeyIndex; diff --git a/Editor/Encryption/EncryptFunction.cs b/Editor/Encryption/Instructions/EncryptFunction.cs similarity index 75% rename from Editor/Encryption/EncryptFunction.cs rename to Editor/Encryption/Instructions/EncryptFunction.cs index 8e6e398..192e5f1 100644 --- a/Editor/Encryption/EncryptFunction.cs +++ b/Editor/Encryption/Instructions/EncryptFunction.cs @@ -3,14 +3,14 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Obfuz.Encryption +namespace Obfuz.Encryption.Instructions { - public class EncryptFunction : EncryptInstructionBase + public class EncryptFunction : EncryptionInstructionBase { - private readonly IEncryptInstruction[] _instructions; + private readonly IEncryptionInstruction[] _instructions; - public EncryptFunction(IEncryptInstruction[] instructions) + public EncryptFunction(IEncryptionInstruction[] instructions) { _instructions = instructions; } diff --git a/Editor/Encryption/XorInstruction.cs b/Editor/Encryption/Instructions/XorInstruction.cs similarity index 84% rename from Editor/Encryption/XorInstruction.cs rename to Editor/Encryption/Instructions/XorInstruction.cs index 2df5a6e..4e8fcc2 100644 --- a/Editor/Encryption/XorInstruction.cs +++ b/Editor/Encryption/Instructions/XorInstruction.cs @@ -1,6 +1,6 @@ -namespace Obfuz.Encryption +namespace Obfuz.Encryption.Instructions { - public class XorInstruction : EncryptInstructionBase + public class XorInstruction : EncryptionInstructionBase { private readonly int _xorValue; private readonly int _opKeyIndex; diff --git a/Editor/Encryption/OpCodeSetFactory.cs b/Editor/Encryption/OpCodeSetFactory.cs deleted file mode 100644 index 7c4164e..0000000 --- a/Editor/Encryption/OpCodeSetFactory.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Obfuz.Encryption -{ - -} diff --git a/Editor/Encryption/RandomVirtualMachineCreator.cs b/Editor/Encryption/RandomVirtualMachineCreator.cs deleted file mode 100644 index 422e839..0000000 --- a/Editor/Encryption/RandomVirtualMachineCreator.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Obfuz.Utils; -using UnityEngine.Assertions; - -namespace Obfuz.Encryption -{ - public class RandomVirtualMachineCreator : IVirtualMachineCreator - { - private readonly byte[] _byteSecretKey; - private readonly int[] _secretKey; - private readonly IRandom _random; - - public RandomVirtualMachineCreator(byte[] secretKey) - { - _byteSecretKey = secretKey; - _secretKey = KeyGenerator.ConvertToIntKey(secretKey); - _random = new RandomWithKey(secretKey, 0); - } - - private IEncryptInstruction CreateRandomInstruction(int secretKeyLength) - { - switch (_random.NextInt(3)) - { - case 0: - return new AddInstruction(_random.NextInt(), _random.NextInt(secretKeyLength)); - case 1: - return new XorInstruction(_random.NextInt(), _random.NextInt(secretKeyLength)); - case 2: - return new BitRotateInstruction(_random.NextInt(32), _random.NextInt(secretKeyLength)); - default: - throw new System.Exception("Invalid instruction type"); - } - } - - 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(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, _secretKey, code), _secretKey, code)); - return new EncryptOpCode(code, function); - } - - public VirtualMachine CreateVirtualMachine(int opCodeCount) - { - Assert.IsTrue(opCodeCount > 0); - Assert.AreEqual(0, opCodeCount ^ (opCodeCount - 1)); - var opCodes = new EncryptOpCode[opCodeCount]; - for (int i = 0; i < opCodes.Length; i++) - { - opCodes[i] = CreateEncryptOpCode((ushort)i, opCodeCount); - } - return new VirtualMachine(_byteSecretKey, opCodes); - } - } -} diff --git a/Editor/Encryption/VirtualMachine.cs b/Editor/Encryption/VirtualMachine.cs deleted file mode 100644 index 2f44983..0000000 --- a/Editor/Encryption/VirtualMachine.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Obfuz.Encryption -{ - public class VirtualMachine - { - public const int SecretKeyLength = 1024; - - public readonly byte[] secretKey; - public readonly EncryptOpCode[] opCodes; - - public VirtualMachine(byte[] secretKey, EncryptOpCode[] opCodes) - { - this.secretKey = secretKey; - this.opCodes = opCodes; - } - } -} diff --git a/Editor/Obfuscator.cs b/Editor/Obfuscator.cs index d42bd22..ff643d6 100644 --- a/Editor/Obfuscator.cs +++ b/Editor/Obfuscator.cs @@ -31,6 +31,7 @@ namespace Obfuz private readonly Pipeline _pipeline = new Pipeline(); private readonly byte[] _secretKey; private readonly int _globalRandomSeed; + private readonly string _encryptionVmSecretKey; private ObfuscationPassContext _ctx; @@ -38,10 +39,11 @@ namespace Obfuz List notObfuscatedAssemblyNamesReferencingObfuscated, List assemblySearchDirs, string obfuscatedAssemblyOutputDir, - List obfuscationPasses, string rawSecretKey, int globalRandomSeed) + List obfuscationPasses, string rawSecretKey, int globalRandomSeed, string encryptionVmSecretKey) { - _secretKey = KeyGenerator.GenerateKey(rawSecretKey, VirtualMachine.SecretKeyLength); + _secretKey = KeyGenerator.GenerateKey(rawSecretKey, EncryptionVirtualMachine.SecretKeyLength); _globalRandomSeed = globalRandomSeed; + _encryptionVmSecretKey = encryptionVmSecretKey; _toObfuscatedAssemblyNames = toObfuscatedAssemblyNames; _notObfuscatedAssemblyNamesReferencingObfuscated = notObfuscatedAssemblyNamesReferencingObfuscated; @@ -63,13 +65,20 @@ namespace Obfuz OnPostObfuscation(); } + private IEncryptor CreateEncryptionVirtualMachine() + { + var vmCreator = new EncryptionVirtualMachineCreator(_encryptionVmSecretKey, _secretKey); + var vm = vmCreator.CreateVirtualMachine(1); + return new EncryptionVirtualMachineSimulator(vm); + } + private void OnPreObfuscation() { LoadAssemblies(); var random = new RandomWithKey(_secretKey, _globalRandomSeed); - var encryptor = new NullEncryptor(_secretKey); + var encryptor = CreateEncryptionVirtualMachine(); var rvaDataAllocator = new RvaDataAllocator(random, encryptor); var constFieldAllocator = new ConstFieldAllocator(encryptor, random, rvaDataAllocator); _ctx = new ObfuscationPassContext diff --git a/Editor/ObfuscatorBuilder.cs b/Editor/ObfuscatorBuilder.cs index 04ffcd4..6dc8619 100644 --- a/Editor/ObfuscatorBuilder.cs +++ b/Editor/ObfuscatorBuilder.cs @@ -15,6 +15,7 @@ namespace Obfuz { private string _secretKey; private int _globalRandomSeed; + private string _encryptionVmGenerationSecretKey; private List _toObfuscatedAssemblyNames = new List(); private List _notObfuscatedAssemblyNamesReferencingObfuscated = new List(); private List _assemblySearchDirs = new List(); @@ -34,6 +35,12 @@ namespace Obfuz set => _globalRandomSeed = value; } + public string EncryptionVmGenerationSecretKey + { + get => _encryptionVmGenerationSecretKey; + set => _encryptionVmGenerationSecretKey = value; + } + public List ToObfuscatedAssemblyNames { get => _toObfuscatedAssemblyNames; @@ -75,7 +82,7 @@ namespace Obfuz _notObfuscatedAssemblyNamesReferencingObfuscated, _assemblySearchDirs, _obfuscatedAssemblyOutputDir, - _obfuscationPasses, _secretKey, _globalRandomSeed); + _obfuscationPasses, _secretKey, _globalRandomSeed, _encryptionVmGenerationSecretKey); } public static ObfuscatorBuilder FromObfuzSettings(ObfuzSettings settings, BuildTarget target) @@ -84,12 +91,17 @@ namespace Obfuz { _secretKey = settings.secretKey, _globalRandomSeed = settings.globalRandomSeed, + _encryptionVmGenerationSecretKey = settings.encryptionVMSettings.codeGenerationSecretKey, _toObfuscatedAssemblyNames = settings.toObfuscatedAssemblyNames.ToList(), _notObfuscatedAssemblyNamesReferencingObfuscated = settings.notObfuscatedAssemblyNamesReferencingObfuscated.ToList(), _assemblySearchDirs = settings.extraAssemblySearchDirs.ToList(), _obfuscatedAssemblyOutputDir = settings.GetObfuscatedAssemblyOutputDir(target), }; ObfuscationPassType obfuscationPasses = settings.enabledObfuscationPasses; + if (obfuscationPasses.HasFlag(ObfuscationPassType.ConstEncrypt)) + { + builder.AddPass(new ConstEncryptPass(settings.constEncryptSettings)); + } if (obfuscationPasses.HasFlag(ObfuscationPassType.FieldEncrypt)) { builder.AddPass(new FieldEncryptPass(settings.fieldEncryptSettings)); @@ -98,10 +110,6 @@ namespace Obfuz { builder.AddPass(new CallObfusPass(settings.callObfusSettings)); } - if (obfuscationPasses.HasFlag(ObfuscationPassType.ConstEncrypt)) - { - builder.AddPass(new ConstEncryptPass(settings.constEncryptSettings)); - } if (obfuscationPasses.HasFlag(ObfuscationPassType.ExprObfus)) { builder.AddPass(new ExprObfusPass());