重构 EncryptionVM
parent
a7db16475a
commit
af60d0703d
|
@ -2,6 +2,6 @@
|
|||
{
|
||||
public interface IVirtualMachineCreator
|
||||
{
|
||||
VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed);
|
||||
VirtualMachine CreateVirtualMachine(int opCodeCount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,58 +5,57 @@ namespace Obfuz.Encryption
|
|||
{
|
||||
public class RandomVirtualMachineCreator : IVirtualMachineCreator
|
||||
{
|
||||
private readonly int[] _debugSecretKey;
|
||||
private readonly byte[] _byteSecretKey;
|
||||
private readonly int[] _secretKey;
|
||||
private readonly IRandom _random;
|
||||
|
||||
public RandomVirtualMachineCreator()
|
||||
public RandomVirtualMachineCreator(byte[] secretKey)
|
||||
{
|
||||
_debugSecretKey = new int[VirtualMachine.SecretKeyLength];
|
||||
for (int i = 0; i < _debugSecretKey.Length; i++)
|
||||
{
|
||||
_debugSecretKey[i] = i;
|
||||
}
|
||||
_byteSecretKey = secretKey;
|
||||
_secretKey = KeyGenerator.ConvertToIntKey(secretKey);
|
||||
_random = new RandomWithKey(secretKey, 0);
|
||||
}
|
||||
|
||||
private IEncryptInstruction CreateRandomInstruction(IRandom random, int secretKeyLength)
|
||||
private IEncryptInstruction CreateRandomInstruction(int secretKeyLength)
|
||||
{
|
||||
switch (random.NextInt(3))
|
||||
switch (_random.NextInt(3))
|
||||
{
|
||||
case 0:
|
||||
return new AddInstruction(random.NextInt(), random.NextInt(secretKeyLength));
|
||||
return new AddInstruction(_random.NextInt(), _random.NextInt(secretKeyLength));
|
||||
case 1:
|
||||
return new XorInstruction(random.NextInt(), random.NextInt(secretKeyLength));
|
||||
return new XorInstruction(_random.NextInt(), _random.NextInt(secretKeyLength));
|
||||
case 2:
|
||||
return new BitRotateInstruction(random.NextInt(32), random.NextInt(secretKeyLength));
|
||||
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)
|
||||
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(r, VirtualMachine.SecretKeyLength);
|
||||
Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _debugSecretKey, i), _debugSecretKey, i));
|
||||
insts[i] = CreateRandomInstruction(r, opCodeCount);
|
||||
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, _debugSecretKey, code), _debugSecretKey, code));
|
||||
Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _secretKey, code), _secretKey, code));
|
||||
return new EncryptOpCode(code, function);
|
||||
}
|
||||
|
||||
public VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed)
|
||||
public VirtualMachine CreateVirtualMachine(int opCodeCount)
|
||||
{
|
||||
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);
|
||||
opCodes[i] = CreateEncryptOpCode((ushort)i, opCodeCount);
|
||||
}
|
||||
return new VirtualMachine(vmSeed, opCodes);
|
||||
return new VirtualMachine(_byteSecretKey, opCodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
{
|
||||
public const int SecretKeyLength = 1024;
|
||||
|
||||
public readonly int vmSeed;
|
||||
public readonly byte[] secretKey;
|
||||
public readonly EncryptOpCode[] opCodes;
|
||||
|
||||
public VirtualMachine(int vmSeed, EncryptOpCode[] opCodes)
|
||||
public VirtualMachine(byte[] secretKey, EncryptOpCode[] opCodes)
|
||||
{
|
||||
this.vmSeed = vmSeed;
|
||||
this.secretKey = secretKey;
|
||||
this.opCodes = opCodes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using dnlib.Protection;
|
||||
using Obfuz.Data;
|
||||
using Obfuz.Emit;
|
||||
using Obfuz.Encryption;
|
||||
using Obfuz.ObfusPasses;
|
||||
using Obfuz.ObfusPasses.CleanUp;
|
||||
using Obfuz.Utils;
|
||||
|
@ -39,7 +40,7 @@ namespace Obfuz
|
|||
string obfuscatedAssemblyOutputDir,
|
||||
List<IObfuscationPass> obfuscationPasses, string rawSecretKey, int globalRandomSeed)
|
||||
{
|
||||
_secretKey = KeyGenerator.GenerateKey(rawSecretKey);
|
||||
_secretKey = KeyGenerator.GenerateKey(rawSecretKey, VirtualMachine.SecretKeyLength);
|
||||
_globalRandomSeed = globalRandomSeed;
|
||||
|
||||
_toObfuscatedAssemblyNames = toObfuscatedAssemblyNames;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
@ -9,14 +10,12 @@ namespace Obfuz.Utils
|
|||
{
|
||||
public static class KeyGenerator
|
||||
{
|
||||
public const int KeyLength = 1024;
|
||||
|
||||
public static byte[] GenerateKey(string initialString)
|
||||
public static byte[] GenerateKey(string initialString, int keyLength)
|
||||
{
|
||||
byte[] initialBytes = Encoding.UTF8.GetBytes(initialString);
|
||||
using var sha512 = SHA512.Create();
|
||||
byte[] hash = sha512.ComputeHash(initialBytes);
|
||||
byte[] key = new byte[KeyLength];
|
||||
byte[] key = new byte[keyLength];
|
||||
int bytesCopied = 0;
|
||||
while (bytesCopied < key.Length)
|
||||
{
|
||||
|
@ -31,5 +30,14 @@ namespace Obfuz.Utils
|
|||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public static int[] ConvertToIntKey(byte[] key)
|
||||
{
|
||||
Assert.AreEqual(0, key.Length % 4);
|
||||
int align4Length = key.Length / 4;
|
||||
int[] intKey = new int[align4Length];
|
||||
Buffer.BlockCopy(key, 0, intKey, 0, key.Length);
|
||||
return intKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,19 +21,10 @@ namespace Obfuz.Utils
|
|||
|
||||
public RandomWithKey(byte[] key, int seed)
|
||||
{
|
||||
_key = ConvertToIntKey(key);
|
||||
_key = KeyGenerator.ConvertToIntKey(key);
|
||||
_seed = seed;
|
||||
}
|
||||
|
||||
private static int[] ConvertToIntKey(byte[] key)
|
||||
{
|
||||
// ignore last bytes if not aligned to 4
|
||||
int align4Length = key.Length / 4;
|
||||
int[] intKey = new int[align4Length];
|
||||
Buffer.BlockCopy(key, 0, intKey, 0, align4Length * 4);
|
||||
return intKey;
|
||||
}
|
||||
|
||||
public int NextInt(int min, int max)
|
||||
{
|
||||
return min + NextInt(max - min);
|
||||
|
|
Loading…
Reference in New Issue