obfuz/Editor/Encryption/RandomVirtualMachineCreator.cs

63 lines
2.5 KiB
C#

using Obfuz.Utils;
using UnityEngine.Assertions;
namespace Obfuz.Encryption
{
public class RandomVirtualMachineCreator : IVirtualMachineCreator
{
private readonly int[] _debugSecretKey;
public RandomVirtualMachineCreator()
{
_debugSecretKey = new int[VirtualMachine.SecretKeyLength];
for (int i = 0; i < _debugSecretKey.Length; i++)
{
_debugSecretKey[i] = i;
}
}
private IEncryptInstruction CreateRandomInstruction(IRandom random, 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, IRandom r, 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);
}
var function = new EncryptFunction(insts);
Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _debugSecretKey, code), _debugSecretKey, code));
return new EncryptOpCode(code, function);
}
public VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed)
{
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);
}
return new VirtualMachine(vmSeed, opCodes);
}
}
}