重构 EncryptionVirtualMachine
parent
af60d0703d
commit
f0818e3df1
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<ushort> DecodeOps(int ops)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
namespace Obfuz.Encryption
|
||||
{
|
||||
public interface IVirtualMachineCreator
|
||||
{
|
||||
VirtualMachine CreateVirtualMachine(int opCodeCount);
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Obfuz.Encryption
|
||||
{
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<string> notObfuscatedAssemblyNamesReferencingObfuscated,
|
||||
List<string> assemblySearchDirs,
|
||||
string obfuscatedAssemblyOutputDir,
|
||||
List<IObfuscationPass> obfuscationPasses, string rawSecretKey, int globalRandomSeed)
|
||||
List<IObfuscationPass> 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
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace Obfuz
|
|||
{
|
||||
private string _secretKey;
|
||||
private int _globalRandomSeed;
|
||||
private string _encryptionVmGenerationSecretKey;
|
||||
private List<string> _toObfuscatedAssemblyNames = new List<string>();
|
||||
private List<string> _notObfuscatedAssemblyNamesReferencingObfuscated = new List<string>();
|
||||
private List<string> _assemblySearchDirs = new List<string>();
|
||||
|
@ -34,6 +35,12 @@ namespace Obfuz
|
|||
set => _globalRandomSeed = value;
|
||||
}
|
||||
|
||||
public string EncryptionVmGenerationSecretKey
|
||||
{
|
||||
get => _encryptionVmGenerationSecretKey;
|
||||
set => _encryptionVmGenerationSecretKey = value;
|
||||
}
|
||||
|
||||
public List<string> 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());
|
||||
|
|
Loading…
Reference in New Issue