obfuz/Editor/Encryption/RandomVirtualMachineCreator.cs

62 lines
2.4 KiB
C#
Raw Normal View History

2025-05-11 10:37:42 +08:00
using Obfuz.Utils;
using UnityEngine.Assertions;
namespace Obfuz.Encryption
{
public class RandomVirtualMachineCreator : IVirtualMachineCreator
{
2025-05-11 10:49:04 +08:00
private readonly byte[] _byteSecretKey;
private readonly int[] _secretKey;
private readonly IRandom _random;
2025-05-11 10:37:42 +08:00
2025-05-11 10:49:04 +08:00
public RandomVirtualMachineCreator(byte[] secretKey)
2025-05-11 10:37:42 +08:00
{
2025-05-11 10:49:04 +08:00
_byteSecretKey = secretKey;
_secretKey = KeyGenerator.ConvertToIntKey(secretKey);
_random = new RandomWithKey(secretKey, 0);
2025-05-11 10:37:42 +08:00
}
2025-05-11 10:49:04 +08:00
private IEncryptInstruction CreateRandomInstruction(int secretKeyLength)
2025-05-11 10:37:42 +08:00
{
2025-05-11 10:49:04 +08:00
switch (_random.NextInt(3))
2025-05-11 10:37:42 +08:00
{
case 0:
2025-05-11 10:49:04 +08:00
return new AddInstruction(_random.NextInt(), _random.NextInt(secretKeyLength));
2025-05-11 10:37:42 +08:00
case 1:
2025-05-11 10:49:04 +08:00
return new XorInstruction(_random.NextInt(), _random.NextInt(secretKeyLength));
2025-05-11 10:37:42 +08:00
case 2:
2025-05-11 10:49:04 +08:00
return new BitRotateInstruction(_random.NextInt(32), _random.NextInt(secretKeyLength));
2025-05-11 10:37:42 +08:00
default:
throw new System.Exception("Invalid instruction type");
}
}
2025-05-11 10:49:04 +08:00
private EncryptOpCode CreateEncryptOpCode(ushort code, int opCodeCount)
2025-05-11 10:37:42 +08:00
{
Assert.IsTrue(code < opCodeCount);
var insts = new IEncryptInstruction[opCodeCount];
for (int i = 0; i < insts.Length; i++)
{
2025-05-11 10:49:04 +08:00
IEncryptInstruction inst = CreateRandomInstruction(VirtualMachine.SecretKeyLength);
Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _secretKey, i), _secretKey, i));
insts[i] = CreateRandomInstruction(opCodeCount);
2025-05-11 10:37:42 +08:00
}
var function = new EncryptFunction(insts);
2025-05-11 10:49:04 +08:00
Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _secretKey, code), _secretKey, code));
2025-05-11 10:37:42 +08:00
return new EncryptOpCode(code, function);
}
2025-05-11 10:49:04 +08:00
public VirtualMachine CreateVirtualMachine(int opCodeCount)
2025-05-11 10:37:42 +08:00
{
Assert.IsTrue(opCodeCount > 0);
Assert.AreEqual(0, opCodeCount ^ (opCodeCount - 1));
var opCodes = new EncryptOpCode[opCodeCount];
for (int i = 0; i < opCodes.Length; i++)
{
2025-05-11 10:49:04 +08:00
opCodes[i] = CreateEncryptOpCode((ushort)i, opCodeCount);
2025-05-11 10:37:42 +08:00
}
2025-05-11 10:49:04 +08:00
return new VirtualMachine(_byteSecretKey, opCodes);
2025-05-11 10:37:42 +08:00
}
}
}