重构 Encryptor
parent
69e6068dd0
commit
a7db16475a
|
@ -38,7 +38,7 @@ namespace Obfuz.Data
|
|||
{
|
||||
public FieldDef holderDataField;
|
||||
public FieldDef runtimeValueField;
|
||||
public long encryptionOps;
|
||||
public int encryptionOps;
|
||||
public uint size;
|
||||
public List<byte> bytes;
|
||||
public int salt;
|
||||
|
@ -134,7 +134,7 @@ namespace Obfuz.Data
|
|||
runtimeValueField = runtimeValueField,
|
||||
size = dataHolderType.ClassSize,
|
||||
bytes = new List<byte>((int)dataHolderType.ClassSize),
|
||||
encryptionOps = _random.NextLong(),
|
||||
encryptionOps = _random.NextInt(),
|
||||
salt = _random.NextInt(),
|
||||
};
|
||||
_rvaFields.Add(newRvaField);
|
||||
|
@ -252,7 +252,7 @@ namespace Obfuz.Data
|
|||
ins.Add(Instruction.Create(OpCodes.Call, importer.InitializedArrayMethod));
|
||||
|
||||
// EncryptionService.DecryptBlock(array, field.encryptionOps, field.salt);
|
||||
ins.Add(Instruction.Create(OpCodes.Ldc_I8, field.encryptionOps));
|
||||
ins.Add(Instruction.CreateLdcI4(field.encryptionOps));
|
||||
ins.Add(Instruction.Create(OpCodes.Ldc_I4, field.salt));
|
||||
ins.Add(Instruction.Create(OpCodes.Call, importer.DecryptBlock));
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ namespace Obfuz.Emit
|
|||
Assert.IsNotNull(_initializeArray);
|
||||
|
||||
Type encryptionService = typeof(EncryptionService);
|
||||
_encryptBlock = mod.Import(encryptionService.GetMethod("EncryptBlock", new[] { typeof(byte[]), typeof(long), typeof(int) }));
|
||||
_encryptBlock = mod.Import(encryptionService.GetMethod("EncryptBlock", new[] { typeof(byte[]), typeof(int), typeof(int) }));
|
||||
Assert.IsNotNull(_encryptBlock);
|
||||
_decryptBlock = mod.Import(encryptionService.GetMethod("DecryptBlock", new[] { typeof(byte[]), typeof(long), typeof(int) }));
|
||||
_decryptBlock = mod.Import(encryptionService.GetMethod("DecryptBlock", new[] { typeof(byte[]), typeof(int), typeof(int) }));
|
||||
Assert.IsNotNull(_decryptBlock);
|
||||
_encryptInt = mod.Import(encryptionService.GetMethod("Encrypt", new[] { typeof(int), typeof(int), typeof(int) }));
|
||||
Assert.IsNotNull(_encryptInt);
|
||||
|
|
|
@ -1,257 +0,0 @@
|
|||
using Obfuz.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Obfuz.Encryption
|
||||
{
|
||||
public class VirtualMachine
|
||||
{
|
||||
public const int SecretKeyLength = 1024;
|
||||
|
||||
public readonly int vmSeed;
|
||||
public readonly EncryptOpCode[] opCodes;
|
||||
|
||||
public VirtualMachine(int vmSeed, EncryptOpCode[] opCodes)
|
||||
{
|
||||
this.vmSeed = vmSeed;
|
||||
this.opCodes = opCodes;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IVirtualMachineCreator
|
||||
{
|
||||
VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public class EncryptVirtualMachineSimulator
|
||||
{
|
||||
private readonly EncryptOpCode[] _opCodes;
|
||||
private readonly int[] _secretKey;
|
||||
|
||||
public EncryptVirtualMachineSimulator(EncryptOpCode[] opCodes, int[] secretKey)
|
||||
{
|
||||
_opCodes = opCodes;
|
||||
// should be power of 2
|
||||
Assert.AreEqual(0, opCodes.Length ^ (opCodes.Length - 1));
|
||||
_secretKey = secretKey;
|
||||
}
|
||||
|
||||
private List<ushort> DecodeOps(int ops)
|
||||
{
|
||||
var codes = new List<ushort>();
|
||||
while (ops > 0)
|
||||
{
|
||||
var code = (ushort)(ops % _opCodes.Length);
|
||||
codes.Add(code);
|
||||
ops >>= 16;
|
||||
}
|
||||
return codes;
|
||||
}
|
||||
|
||||
public int Encrypt(int value, int ops, int salt)
|
||||
{
|
||||
var codes = DecodeOps(ops);
|
||||
foreach (var code in codes)
|
||||
{
|
||||
var opCode = _opCodes[code];
|
||||
value = opCode.Encrypt(value, _secretKey, salt);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public int Decrypt(int value, int ops, int salt)
|
||||
{
|
||||
var codes = DecodeOps(ops);
|
||||
for (int i = codes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var opCode = _opCodes[codes[i]];
|
||||
value = opCode.Decrypt(value, _secretKey, salt);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public long Encrypt(long value, int ops, int salt)
|
||||
{
|
||||
int low = (int)(value & 0xFFFFFFFF);
|
||||
int high = (int)((value >> 32) & 0xFFFFFFFF);
|
||||
var codes = DecodeOps(ops);
|
||||
|
||||
// TODO we should encrypt high with encLow
|
||||
int encLow = Encrypt(low, ops, salt);
|
||||
int encHigh = Encrypt(high, ops, salt);
|
||||
|
||||
return ((long)encHigh << 32) | (long)(uint)(encLow);
|
||||
}
|
||||
|
||||
public long Decrypt(long value, int ops, int salt)
|
||||
{
|
||||
int low = (int)(value & 0xFFFFFFFF);
|
||||
int high = (int)((value >> 32) & 0xFFFFFFFF);
|
||||
var codes = DecodeOps(ops);
|
||||
|
||||
// TODO we should encrypt high with encLow
|
||||
int decLow = Decrypt(low, ops, salt);
|
||||
int decHigh = Decrypt(high, ops, salt);
|
||||
|
||||
return ((long)decHigh << 32) | (long)(uint)(decLow);
|
||||
}
|
||||
|
||||
public float Encrypt(float value, int ops, int salt)
|
||||
{
|
||||
int intValue = UnsafeUtility.As<float, int>(ref value);
|
||||
int encValue = Encrypt(intValue, ops, salt);
|
||||
return UnsafeUtility.As<int, float>(ref encValue);
|
||||
}
|
||||
|
||||
public float Decrypt(float value, int ops, int salt)
|
||||
{
|
||||
int intValue = UnsafeUtility.As<float, int>(ref value);
|
||||
int decValue = Decrypt(intValue, ops, salt);
|
||||
return UnsafeUtility.As<int, float>(ref decValue);
|
||||
}
|
||||
|
||||
public double Encrypt(double value, int ops, int salt)
|
||||
{
|
||||
long longValue = UnsafeUtility.As<double, long>(ref value);
|
||||
long encValue = Encrypt(longValue, ops, salt);
|
||||
return UnsafeUtility.As<long, double>(ref encValue);
|
||||
}
|
||||
|
||||
public double Decrypt(double value, int ops, int salt)
|
||||
{
|
||||
long longValue = UnsafeUtility.As<double, long>(ref value);
|
||||
long decValue = Decrypt(longValue, ops, salt);
|
||||
return UnsafeUtility.As<long, double>(ref decValue);
|
||||
}
|
||||
|
||||
public unsafe byte[] Encrypt(byte[] bytes, int offset, int length, int ops, int salt)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
// align size to 4
|
||||
int align4Length = (length + 3) & ~3;
|
||||
byte[] encInts = new byte[align4Length];
|
||||
Buffer.BlockCopy(bytes, offset, encInts, 0, length);
|
||||
|
||||
int intLength = align4Length >> 2;
|
||||
fixed (byte* intArr = &bytes[0])
|
||||
{
|
||||
for (int i = 0; i < intLength; i++)
|
||||
{
|
||||
int* ele = (int*)intArr + i;
|
||||
*ele = Encrypt(*ele, ops, salt);
|
||||
}
|
||||
}
|
||||
return encInts;
|
||||
}
|
||||
|
||||
public unsafe byte[] Decrypt(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
int align4Length = (length + 3) & ~3;
|
||||
int intLength = align4Length >> 2;
|
||||
byte[] decInts = new byte[align4Length];
|
||||
fixed (byte* intArr = &decInts[0])
|
||||
{
|
||||
for (int i = 0; i < intLength; i++)
|
||||
{
|
||||
int* ele = (int*)intArr + i;
|
||||
*ele = Decrypt(*ele, ops, salt);
|
||||
}
|
||||
}
|
||||
return decInts;
|
||||
}
|
||||
|
||||
public byte[] Encrypt(byte[] bytes, int ops, int salt)
|
||||
{
|
||||
return Encrypt(bytes, 0, bytes.Length, ops, salt);
|
||||
}
|
||||
|
||||
public byte[] Encrypt(string value, int ops, int salt)
|
||||
{
|
||||
if (value.Length == 0)
|
||||
{
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value);
|
||||
return Encrypt(bytes, 0, bytes.Length, ops, salt);
|
||||
}
|
||||
|
||||
public string DecryptString(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return System.Text.Encoding.UTF8.GetString(Decrypt(value, offset, length, ops, salt));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Obfuz.Encryption
|
||||
{
|
||||
|
||||
public class EncryptionVirtualMachineSimulator : EncryptorBase
|
||||
{
|
||||
private readonly EncryptOpCode[] _opCodes;
|
||||
private readonly int[] _secretKey;
|
||||
|
||||
public EncryptionVirtualMachineSimulator(EncryptOpCode[] opCodes, int[] secretKey)
|
||||
{
|
||||
_opCodes = opCodes;
|
||||
// should be power of 2
|
||||
Assert.AreEqual(0, opCodes.Length ^ (opCodes.Length - 1));
|
||||
_secretKey = secretKey;
|
||||
}
|
||||
|
||||
private List<ushort> DecodeOps(int ops)
|
||||
{
|
||||
var codes = new List<ushort>();
|
||||
while (ops > 0)
|
||||
{
|
||||
var code = (ushort)(ops % _opCodes.Length);
|
||||
codes.Add(code);
|
||||
ops >>= 16;
|
||||
}
|
||||
return codes;
|
||||
}
|
||||
|
||||
public override int Encrypt(int value, int ops, int salt)
|
||||
{
|
||||
var codes = DecodeOps(ops);
|
||||
foreach (var code in codes)
|
||||
{
|
||||
var opCode = _opCodes[code];
|
||||
value = opCode.Encrypt(value, _secretKey, salt);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public override int Decrypt(int value, int ops, int salt)
|
||||
{
|
||||
var codes = DecodeOps(ops);
|
||||
for (int i = codes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var opCode = _opCodes[codes[i]];
|
||||
value = opCode.Decrypt(value, _secretKey, salt);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Obfuz.Encryption
|
||||
{
|
||||
public interface IVirtualMachineCreator
|
||||
{
|
||||
VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
namespace Obfuz.Encryption
|
||||
{
|
||||
public class VirtualMachine
|
||||
{
|
||||
public const int SecretKeyLength = 1024;
|
||||
|
||||
public readonly int vmSeed;
|
||||
public readonly EncryptOpCode[] opCodes;
|
||||
|
||||
public VirtualMachine(int vmSeed, EncryptOpCode[] opCodes)
|
||||
{
|
||||
this.vmSeed = vmSeed;
|
||||
this.opCodes = opCodes;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,7 +68,7 @@ namespace Obfuz
|
|||
|
||||
|
||||
var random = new RandomWithKey(_secretKey, _globalRandomSeed);
|
||||
var encryptor = new DefaultEncryptor(_secretKey);
|
||||
var encryptor = new NullEncryptor(_secretKey);
|
||||
var rvaDataAllocator = new RvaDataAllocator(random, encryptor);
|
||||
var constFieldAllocator = new ConstFieldAllocator(encryptor, random, rvaDataAllocator);
|
||||
_ctx = new ObfuscationPassContext
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obfuz.Settings
|
||||
{
|
||||
[Serializable]
|
||||
public class EncryptionVMSettings
|
||||
{
|
||||
[Tooltip("secret key for generating encryption virtual machine source code")]
|
||||
public string codeGenerationSecretKey = "Obfuz";
|
||||
|
||||
[Tooltip("encryption virtual machine source code output dir")]
|
||||
public string codeOutputDir = "Assets/Obfuz";
|
||||
}
|
||||
}
|
|
@ -32,6 +32,9 @@ namespace Obfuz.Settings
|
|||
[Tooltip("global random seed")]
|
||||
public int globalRandomSeed = 0;
|
||||
|
||||
[Tooltip("encryption virtual machine settings")]
|
||||
public EncryptionVMSettings encryptionVMSettings;
|
||||
|
||||
[Tooltip("symbol obfuscation settings")]
|
||||
public SymbolObfusSettings symbolObfusSettings;
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ namespace Obfuz.Settings
|
|||
private SerializedProperty _enabledObfuscationPasses;
|
||||
private SerializedProperty _secretKey;
|
||||
private SerializedProperty _globalRandomSeed;
|
||||
|
||||
private SerializedProperty _encryptionVMSettings;
|
||||
|
||||
private SerializedProperty _symbolObfusSettings;
|
||||
private SerializedProperty _constEncryptSettings;
|
||||
|
@ -71,6 +73,8 @@ namespace Obfuz.Settings
|
|||
_secretKey = _serializedObject.FindProperty("secretKey");
|
||||
_globalRandomSeed = _serializedObject.FindProperty("globalRandomSeed");
|
||||
|
||||
_encryptionVMSettings = _serializedObject.FindProperty("encryptionVMSettings");
|
||||
|
||||
_symbolObfusSettings = _serializedObject.FindProperty("symbolObfusSettings");
|
||||
_constEncryptSettings = _serializedObject.FindProperty("constEncryptSettings");
|
||||
_fieldEncryptSettings = _serializedObject.FindProperty("fieldEncryptSettings");
|
||||
|
@ -95,6 +99,8 @@ namespace Obfuz.Settings
|
|||
EditorGUILayout.PropertyField(_secretKey);
|
||||
EditorGUILayout.PropertyField(_globalRandomSeed);
|
||||
|
||||
EditorGUILayout.PropertyField(_encryptionVMSettings);
|
||||
|
||||
EditorGUILayout.PropertyField(_symbolObfusSettings);
|
||||
EditorGUILayout.PropertyField(_constEncryptSettings);
|
||||
EditorGUILayout.PropertyField(_fieldEncryptSettings);
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Obfuz.Settings
|
|||
[Tooltip("prefix for obfuscated name to avoid name confliction with original name")]
|
||||
public string obfuscatedNamePrefix = "$";
|
||||
|
||||
[Tooltip("obfuscate same namespace to same name")]
|
||||
[Tooltip("obfuscate same namespace to one name")]
|
||||
public bool useConsistentNamespaceObfuscation = true;
|
||||
|
||||
[Tooltip("path of mapping.xml")]
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Obfuz
|
||||
{
|
||||
public class DefaultEncryptor : IEncryptor
|
||||
{
|
||||
private readonly byte[] _key;
|
||||
|
||||
public DefaultEncryptor(byte[] key)
|
||||
{
|
||||
_key = key;
|
||||
}
|
||||
|
||||
public void EncryptBlock(byte[] data, long ops, int salt)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] ^= (byte)(_key[i % _key.Length] ^ salt);
|
||||
}
|
||||
}
|
||||
|
||||
public void DecryptBlock(byte[] data, long ops, int salt)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] ^= (byte)(_key[i % _key.Length] ^ salt);
|
||||
}
|
||||
}
|
||||
|
||||
public int Encrypt(int value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public int Decrypt(int value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public long Encrypt(long value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public long Decrypt(long value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public float Encrypt(float value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public float Decrypt(float value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public double Encrypt(double value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public double Decrypt(double value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public byte[] Encrypt(byte[] value, int offset, int length, int opts, int salt)
|
||||
{
|
||||
int align4Length = (length + 3) & ~3;
|
||||
var encryptedBytes = new byte[align4Length];
|
||||
Buffer.BlockCopy(value, offset, encryptedBytes, 0, length);
|
||||
return encryptedBytes;
|
||||
}
|
||||
|
||||
public byte[] Decrypt(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
byte[] byteArr = new byte[length];
|
||||
Buffer.BlockCopy(value, 0, byteArr, 0, length);
|
||||
return byteArr;
|
||||
}
|
||||
|
||||
public byte[] Encrypt(string value, int ops, int salt)
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
||||
return Encrypt(bytes, 0, bytes.Length, ops, salt);
|
||||
}
|
||||
|
||||
public string DecryptString(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
byte[] bytes = new byte[length];
|
||||
Buffer.BlockCopy(value, 0, bytes, 0, length);
|
||||
return Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,14 +8,14 @@ namespace Obfuz
|
|||
{
|
||||
public static class EncryptionService
|
||||
{
|
||||
private static readonly IEncryptor _encryptor = new DefaultEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D });
|
||||
private static readonly IEncryptor _encryptor = new NullEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D });
|
||||
|
||||
public static void EncryptBlock(byte[] data, long ops, int salt)
|
||||
public static void EncryptBlock(byte[] data, int ops, int salt)
|
||||
{
|
||||
_encryptor.EncryptBlock(data, ops, salt);
|
||||
}
|
||||
|
||||
public static void DecryptBlock(byte[] data, long ops, int salt)
|
||||
public static void DecryptBlock(byte[] data, int ops, int salt)
|
||||
{
|
||||
_encryptor.DecryptBlock(data, ops, salt);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
|
||||
namespace Obfuz
|
||||
{
|
||||
public abstract class EncryptorBase : IEncryptor
|
||||
{
|
||||
public abstract int Encrypt(int value, int opts, int salt);
|
||||
public abstract int Decrypt(int value, int opts, int salt);
|
||||
|
||||
public virtual long Encrypt(long value, int opts, int salt)
|
||||
{
|
||||
int low = (int)value;
|
||||
int high = (int)(value >> 32);
|
||||
int encryptedLow = Encrypt(low, opts, salt);
|
||||
int encryptedHigh = Encrypt(high, opts, salt);
|
||||
return ((long)encryptedHigh << 32) | (uint)encryptedLow;
|
||||
}
|
||||
|
||||
public virtual long Decrypt(long value, int opts, int salt)
|
||||
{
|
||||
int low = (int)value;
|
||||
int high = (int)(value >> 32);
|
||||
int decryptedLow = Decrypt(low, opts, salt);
|
||||
int decryptedHigh = Decrypt(high, opts, salt);
|
||||
return ((long)decryptedHigh << 32) | (uint)decryptedLow;
|
||||
}
|
||||
|
||||
public virtual float Encrypt(float value, int opts, int salt)
|
||||
{
|
||||
ref int intValue = ref UnsafeUtility.As<float, int>(ref value);
|
||||
intValue = Encrypt(intValue, opts, salt);
|
||||
return value;
|
||||
}
|
||||
|
||||
public virtual float Decrypt(float value, int opts, int salt)
|
||||
{
|
||||
ref int intValue = ref UnsafeUtility.As<float, int>(ref value);
|
||||
intValue = Decrypt(intValue, opts, salt);
|
||||
return value;
|
||||
}
|
||||
|
||||
public virtual double Encrypt(double value, int opts, int salt)
|
||||
{
|
||||
ref long longValue = ref UnsafeUtility.As<double, long>(ref value);
|
||||
longValue = Encrypt(longValue, opts, salt);
|
||||
return value;
|
||||
}
|
||||
|
||||
public virtual double Decrypt(double value, int opts, int salt)
|
||||
{
|
||||
ref long longValue = ref UnsafeUtility.As<double, long>(ref value);
|
||||
longValue = Decrypt(longValue, opts, salt);
|
||||
return value;
|
||||
}
|
||||
|
||||
public virtual unsafe byte[] Encrypt(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
|
||||
var encryptedBytes = new byte[length];
|
||||
int intArrLength = length >> 2;
|
||||
|
||||
// align to 4
|
||||
if ((offset & 0x3) != 0)
|
||||
{
|
||||
Buffer.BlockCopy(value, offset, encryptedBytes, 0, length);
|
||||
|
||||
// encrypt int
|
||||
|
||||
fixed (byte* dstBytePtr = &encryptedBytes[0])
|
||||
{
|
||||
int* dstIntPtr = (int*)dstBytePtr;
|
||||
|
||||
for (int i = 0; i < intArrLength; i++)
|
||||
{
|
||||
dstIntPtr[i] = Encrypt(dstIntPtr[i], ops, salt);
|
||||
}
|
||||
}
|
||||
for (int i = intArrLength * 4; i < length; i++)
|
||||
{
|
||||
encryptedBytes[i] = (byte)(encryptedBytes[i] ^ salt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// encrypt int
|
||||
fixed (byte* srcBytePtr = &value[offset])
|
||||
{
|
||||
fixed (byte* dstBytePtr = &encryptedBytes[0])
|
||||
{
|
||||
int* srcIntPtr = (int*)srcBytePtr;
|
||||
int* dstIntPtr = (int*)dstBytePtr;
|
||||
|
||||
for (int i = 0; i < intArrLength; i++)
|
||||
{
|
||||
dstIntPtr[i] = Encrypt(srcIntPtr[i], ops, salt);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = intArrLength * 4; i < length; i++)
|
||||
{
|
||||
encryptedBytes[i] = (byte)(value[offset + i] ^ salt);
|
||||
}
|
||||
}
|
||||
return encryptedBytes;
|
||||
}
|
||||
|
||||
public unsafe virtual byte[] Decrypt(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
var decryptedBytes = new byte[length];
|
||||
int intArrLength = length >> 2;
|
||||
|
||||
// align to 4
|
||||
if ((offset & 0x3) != 0)
|
||||
{
|
||||
Buffer.BlockCopy(value, offset, decryptedBytes, 0, length);
|
||||
|
||||
// encrypt int
|
||||
|
||||
fixed (byte* dstBytePtr = &decryptedBytes[0])
|
||||
{
|
||||
int* dstIntPtr = (int*)dstBytePtr;
|
||||
|
||||
for (int i = 0; i < intArrLength; i++)
|
||||
{
|
||||
dstIntPtr[i] = Decrypt(dstIntPtr[i], ops, salt);
|
||||
}
|
||||
}
|
||||
for (int i = intArrLength * 4; i < length; i++)
|
||||
{
|
||||
decryptedBytes[i] = (byte)(decryptedBytes[i] ^ salt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// encrypt int
|
||||
fixed (byte* srcBytePtr = &value[offset])
|
||||
{
|
||||
fixed (byte* dstBytePtr = &decryptedBytes[0])
|
||||
{
|
||||
int* srcIntPtr = (int*)srcBytePtr;
|
||||
int* dstIntPtr = (int*)dstBytePtr;
|
||||
|
||||
for (int i = 0; i < intArrLength; i++)
|
||||
{
|
||||
dstIntPtr[i] = Decrypt(srcIntPtr[i], ops, salt);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = intArrLength * 4; i < length; i++)
|
||||
{
|
||||
decryptedBytes[i] = (byte)(value[offset + i] ^ salt);
|
||||
}
|
||||
}
|
||||
return decryptedBytes;
|
||||
}
|
||||
|
||||
public virtual byte[] Encrypt(string value, int ops, int salt)
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
||||
return Encrypt(bytes, 0, bytes.Length, ops, salt);
|
||||
}
|
||||
|
||||
public virtual string DecryptString(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
byte[] bytes = Decrypt(value, offset, length, ops, salt);
|
||||
return Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
|
||||
public virtual unsafe void EncryptBlock(byte[] data, int ops, int salt)
|
||||
{
|
||||
int length = data.Length;
|
||||
int intArrLength = length >> 2;
|
||||
|
||||
fixed (byte* dstBytePtr = &data[0])
|
||||
{
|
||||
int* dstIntPtr = (int*)dstBytePtr;
|
||||
|
||||
for (int i = 0; i < intArrLength; i++)
|
||||
{
|
||||
dstIntPtr[i] = Encrypt(dstIntPtr[i], ops, salt);
|
||||
}
|
||||
}
|
||||
for (int i = intArrLength * 4; i < length; i++)
|
||||
{
|
||||
data[i] = (byte)(data[i] ^ salt);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual unsafe void DecryptBlock(byte[] data, int ops, int salt)
|
||||
{
|
||||
int length = data.Length;
|
||||
int intArrLength = length >> 2;
|
||||
|
||||
fixed (byte* dstBytePtr = &data[0])
|
||||
{
|
||||
int* dstIntPtr = (int*)dstBytePtr;
|
||||
|
||||
for (int i = 0; i < intArrLength; i++)
|
||||
{
|
||||
dstIntPtr[i] = Decrypt(dstIntPtr[i], ops, salt);
|
||||
}
|
||||
}
|
||||
for (int i = intArrLength * 4; i < length; i++)
|
||||
{
|
||||
data[i] = (byte)(data[i] ^ salt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Obfuz
|
||||
{
|
||||
public interface IEncryptor
|
||||
{
|
||||
void EncryptBlock(byte[] data, long ops, int salt);
|
||||
void DecryptBlock(byte[] data, long ops, int salt);
|
||||
void EncryptBlock(byte[] data, int ops, int salt);
|
||||
void DecryptBlock(byte[] data, int ops, int salt);
|
||||
|
||||
int Encrypt(int value, int opts, int salt);
|
||||
int Decrypt(int value, int opts, int salt);
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Obfuz
|
||||
{
|
||||
public class NullEncryptor : EncryptorBase
|
||||
{
|
||||
private readonly byte[] _key;
|
||||
|
||||
public NullEncryptor(byte[] key)
|
||||
{
|
||||
_key = key;
|
||||
}
|
||||
|
||||
public override int Encrypt(int value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override int Decrypt(int value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override long Encrypt(long value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override long Decrypt(long value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override float Encrypt(float value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override float Decrypt(float value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override double Encrypt(double value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override double Decrypt(double value, int opts, int salt)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public override byte[] Encrypt(byte[] value, int offset, int length, int opts, int salt)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
var encryptedBytes = new byte[length];
|
||||
Buffer.BlockCopy(value, offset, encryptedBytes, 0, length);
|
||||
return encryptedBytes;
|
||||
}
|
||||
|
||||
public override byte[] Decrypt(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
byte[] byteArr = new byte[length];
|
||||
Buffer.BlockCopy(value, 0, byteArr, 0, length);
|
||||
return byteArr;
|
||||
}
|
||||
|
||||
public override byte[] Encrypt(string value, int ops, int salt)
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(value);
|
||||
}
|
||||
|
||||
public override string DecryptString(byte[] value, int offset, int length, int ops, int salt)
|
||||
{
|
||||
return Encoding.UTF8.GetString(value, offset, length);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue