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