新增EncryptionVM相关代码

backup
walon 2025-05-07 10:14:15 +08:00
parent 5e45a684aa
commit c00335fd41
10 changed files with 131 additions and 95 deletions

View File

@ -0,0 +1,23 @@
namespace Obfuz.Encryption
{
public class AddInstruction : EncryptInstructionBase
{
private readonly int _addValue;
private readonly int _opKeyIndex;
public AddInstruction(int addValue, int opKeyIndex)
{
_addValue = addValue;
_opKeyIndex = opKeyIndex;
}
public override int Encrypt(int value, int[] secretKey, int salt)
{
return value + secretKey[_opKeyIndex] + salt + _addValue;
}
public override int Decrypt(int value, int[] secretKey, int salt)
{
return value - secretKey[_opKeyIndex] - salt - _addValue;
}
}
}

View File

@ -0,0 +1,29 @@
namespace Obfuz.Encryption
{
public class BitRotateInstruction : EncryptInstructionBase
{
private readonly int _rotateBitNum;
private readonly int _opKeyIndex;
public BitRotateInstruction(int rotateBitNum, int opKeyIndex)
{
_rotateBitNum = rotateBitNum;
_opKeyIndex = opKeyIndex;
}
public override int Encrypt(int value, int[] secretKey, int salt)
{
uint part1 = (uint)value << _rotateBitNum;
uint part2 = (uint)value >> (32 - _rotateBitNum);
return ((int)(part1 | part2) ^ secretKey[_opKeyIndex]) + salt;
}
public override int Decrypt(int value, int[] secretKey, int salt)
{
uint value2 = (uint)((value - salt) ^ secretKey[_opKeyIndex]);
uint part1 = value2 >> _rotateBitNum;
uint part2 = value2 << (32 - _rotateBitNum);
return (int)(part1 | part2);
}
}
}

View File

@ -5,88 +5,6 @@ using System.Threading.Tasks;
namespace Obfuz.Encryption namespace Obfuz.Encryption
{ {
public interface IEncryptInstruction
{
int Encrypt(int value, int[] secretKey, int salt);
int Decrypt(int value, int[] secretKey, int salt);
}
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);
}
public class AddInstruction : EncryptInstructionBase
{
private readonly int _addValue;
private readonly int _opKeyIndex;
public AddInstruction(int addValue, int opKeyIndex)
{
_addValue = addValue;
_opKeyIndex = opKeyIndex;
}
public override int Encrypt(int value, int[] secretKey, int salt)
{
return value + secretKey[_opKeyIndex] + salt + _addValue;
}
public override int Decrypt(int value, int[] secretKey, int salt)
{
return value - secretKey[_opKeyIndex] - salt - _addValue;
}
}
public class XorInstruction : EncryptInstructionBase
{
private readonly int _xorValue;
private readonly int _opKeyIndex;
public XorInstruction(int xorValue, int opKeyIndex)
{
_xorValue = xorValue;
_opKeyIndex = opKeyIndex;
}
public override int Encrypt(int value, int[] secretKey, int salt)
{
return value ^ secretKey[_opKeyIndex] ^ salt ^ _xorValue;
}
public override int Decrypt(int value, int[] secretKey, int salt)
{
return value ^ secretKey[_opKeyIndex] ^ salt ^ _xorValue;
}
}
public class BitRotateInstruction : EncryptInstructionBase
{
private readonly int _rotateBitNum;
private readonly int _opKeyIndex;
public BitRotateInstruction(int rotateBitNum, int opKeyIndex)
{
_rotateBitNum = rotateBitNum;
_opKeyIndex = opKeyIndex;
}
public override int Encrypt(int value, int[] secretKey, int salt)
{
uint part1 = (uint)value << _rotateBitNum;
uint part2 = (uint)value >> (32 - _rotateBitNum);
return ((int)(part1 | part2) ^ secretKey[_opKeyIndex]) + salt;
}
public override int Decrypt(int value, int[] secretKey, int salt)
{
uint value2 = (uint)((value - salt) ^ secretKey[_opKeyIndex]);
uint part1 = value2 >> _rotateBitNum;
uint part2 = value2 << (32 - _rotateBitNum);
return (int)(part1 | part2);
}
}
public class EncryptFunction : EncryptInstructionBase public class EncryptFunction : EncryptInstructionBase
{ {

View File

@ -0,0 +1,8 @@
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);
}
}

View File

@ -10,6 +10,8 @@ namespace Obfuz.Encryption
{ {
public class VirtualMachine public class VirtualMachine
{ {
public const int SecretKeyLength = 1024;
public readonly int vmSeed; public readonly int vmSeed;
public readonly EncryptOpCode[] opCodes; public readonly EncryptOpCode[] opCodes;
@ -27,22 +29,27 @@ namespace Obfuz.Encryption
public class RandomVirtualMachineCreator : IVirtualMachineCreator public class RandomVirtualMachineCreator : IVirtualMachineCreator
{ {
private readonly int[] _debugSecretKey;
public RandomVirtualMachineCreator() public RandomVirtualMachineCreator()
{ {
_debugSecretKey = new int[VirtualMachine.SecretKeyLength];
for (int i = 0; i < _debugSecretKey.Length; i++)
{
_debugSecretKey[i] = i;
}
} }
private IEncryptInstruction CreateRandomInstruction(IRandom random, int opCodeCount) private IEncryptInstruction CreateRandomInstruction(IRandom random, int secretKeyLength)
{ {
switch (random.NextInt(3)) switch (random.NextInt(3))
{ {
case 0: case 0:
return new AddInstruction(random.NextInt(), random.NextInt(opCodeCount)); return new AddInstruction(random.NextInt(), random.NextInt(secretKeyLength));
case 1: case 1:
return new XorInstruction(random.NextInt(), random.NextInt(opCodeCount)); return new XorInstruction(random.NextInt(), random.NextInt(secretKeyLength));
case 2: case 2:
return new BitRotateInstruction(random.NextInt(32), random.NextInt(opCodeCount)); return new BitRotateInstruction(random.NextInt(32), random.NextInt(secretKeyLength));
default: default:
throw new System.Exception("Invalid instruction type"); throw new System.Exception("Invalid instruction type");
} }
@ -54,9 +61,12 @@ namespace Obfuz.Encryption
var insts = new IEncryptInstruction[opCodeCount]; var insts = new IEncryptInstruction[opCodeCount];
for (int i = 0; i < insts.Length; i++) 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); insts[i] = CreateRandomInstruction(r, opCodeCount);
} }
var function = new EncryptFunction(insts); var function = new EncryptFunction(insts);
Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _debugSecretKey, code), _debugSecretKey, code));
return new EncryptOpCode(code, function); return new EncryptOpCode(code, function);
} }
@ -191,6 +201,11 @@ namespace Obfuz.Encryption
return encInts; return encInts;
} }
public int[] Encrypt(byte[] bytes, int ops, int salt)
{
return Encrypt(bytes, 0, bytes.Length, ops, salt);
}
public byte[] Decrypt(int[] value, int offset, int byteLength, int ops, int salt) public byte[] Decrypt(int[] value, int offset, int byteLength, int ops, int salt)
{ {
if (byteLength == 0) if (byteLength == 0)
@ -209,6 +224,11 @@ namespace Obfuz.Encryption
return bytes; return bytes;
} }
public byte[] Decrypt(int[] value, int byteLength, int ops, int salt)
{
return Decrypt(value, 0, byteLength, ops, salt);
}
public int[] Encrypt(string value, int ops, int salt) public int[] Encrypt(string value, int ops, int salt)
{ {
if (value.Length == 0) if (value.Length == 0)

View File

@ -0,0 +1,9 @@
namespace Obfuz.Encryption
{
public interface IEncryptInstruction
{
int Encrypt(int value, int[] secretKey, int salt);
int Decrypt(int value, int[] secretKey, int salt);
}
}

View File

@ -0,0 +1,24 @@
namespace Obfuz.Encryption
{
public class XorInstruction : EncryptInstructionBase
{
private readonly int _xorValue;
private readonly int _opKeyIndex;
public XorInstruction(int xorValue, int opKeyIndex)
{
_xorValue = xorValue;
_opKeyIndex = opKeyIndex;
}
public override int Encrypt(int value, int[] secretKey, int salt)
{
return value ^ secretKey[_opKeyIndex] ^ salt ^ _xorValue;
}
public override int Decrypt(int value, int[] secretKey, int salt)
{
return value ^ secretKey[_opKeyIndex] ^ salt ^ _xorValue;
}
}
}

View File

@ -15,19 +15,19 @@ namespace Obfuz
_key = key; _key = key;
} }
public void EncryptBytes(byte[] data, int minorSecret) public void EncryptBlock(byte[] data, long ops, int salt)
{ {
for (int i = 0; i < data.Length; i++) for (int i = 0; i < data.Length; i++)
{ {
data[i] ^= (byte)(_key[i % _key.Length] ^ minorSecret); data[i] ^= (byte)(_key[i % _key.Length] ^ salt);
} }
} }
public void DecryptBytes(byte[] data, int minorSecret) public void DecryptBlock(byte[] data, long ops, int salt)
{ {
for (int i = 0; i < data.Length; i++) for (int i = 0; i < data.Length; i++)
{ {
data[i] ^= (byte)(_key[i % _key.Length] ^ minorSecret); data[i] ^= (byte)(_key[i % _key.Length] ^ salt);
} }
} }
} }

View File

@ -10,9 +10,14 @@ namespace Obfuz
{ {
private static readonly IEncryptor _encryptor = new DefaultEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D }); private static readonly IEncryptor _encryptor = new DefaultEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D });
public static void DecryptBytes(byte[] data, int minorSecret) public static void EncryptBlock(byte[] data, int salt)
{ {
_encryptor.EncryptBytes(data, minorSecret); _encryptor.EncryptBlock(data, salt);
}
public static void DecryptBlock(byte[] data, int salt)
{
_encryptor.DecryptBlock(data, salt);
} }
} }
} }

View File

@ -8,7 +8,7 @@ namespace Obfuz
{ {
public interface IEncryptor public interface IEncryptor
{ {
void EncryptBytes(byte[] data, int minorSecret); void EncryptBlock(byte[] data, long ops, int salt);
void DecryptBytes(byte[] data, int minorSecret); void DecryptBlock(byte[] data, long ops, int salt);
} }
} }