支持 obfuscationLevel和encryptionLevel
parent
b1a19e9ef7
commit
db86070fdb
|
@ -19,27 +19,17 @@ namespace Obfuz.EncryptionVM
|
||||||
public VirtualMachineCodeGenerator(string vmCodeGenerateSecretKey, int opCodeCount)
|
public VirtualMachineCodeGenerator(string vmCodeGenerateSecretKey, int opCodeCount)
|
||||||
{
|
{
|
||||||
_opCodeCount = opCodeCount;
|
_opCodeCount = opCodeCount;
|
||||||
_opCodeBits = GetBitCount(opCodeCount - 1);
|
_opCodeBits = EncryptionUtil.GetBitCount(opCodeCount - 1);
|
||||||
_vm = new VirtualMachineCreator(vmCodeGenerateSecretKey).CreateVirtualMachine(opCodeCount);
|
_vm = new VirtualMachineCreator(vmCodeGenerateSecretKey).CreateVirtualMachine(opCodeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VirtualMachineCodeGenerator(VirtualMachine vm)
|
public VirtualMachineCodeGenerator(VirtualMachine vm)
|
||||||
{
|
{
|
||||||
_opCodeCount = vm.opCodes.Length;
|
_opCodeCount = vm.opCodes.Length;
|
||||||
_opCodeBits = GetBitCount(_opCodeCount - 1);
|
_opCodeBits = EncryptionUtil.GetBitCount(_opCodeCount - 1);
|
||||||
_vm = vm;
|
_vm = vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetBitCount(int value)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
while (value > 0)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
value >>= 1;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ValidateMatch(string outputFile)
|
public bool ValidateMatch(string outputFile)
|
||||||
{
|
{
|
||||||
|
@ -143,11 +133,11 @@ namespace Obfuz.EncryptionVM
|
||||||
public class GeneratedEncryptionVirtualMachine : Obfuz.EncryptorBase
|
public class GeneratedEncryptionVirtualMachine : Obfuz.EncryptorBase
|
||||||
{");
|
{");
|
||||||
lines.Add(@$"
|
lines.Add(@$"
|
||||||
private const int OpCodeBits = {_opCodeBits};
|
private const int kOpCodeBits = {_opCodeBits};
|
||||||
|
|
||||||
private const int OpCodeCount = {_opCodeCount};
|
private const int kOpCodeCount = {_opCodeCount};
|
||||||
|
|
||||||
private const int OpCodeMask = {_opCodeCount - 1};
|
private const int kOpCodeMask = {_opCodeCount - 1};
|
||||||
");
|
");
|
||||||
lines.Add(@"
|
lines.Add(@"
|
||||||
|
|
||||||
|
@ -158,13 +148,15 @@ namespace Obfuz.EncryptionVM
|
||||||
this._secretKey = ConvertToIntKey(secretKey);
|
this._secretKey = ConvertToIntKey(secretKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int OpCodeCount => kOpCodeCount;
|
||||||
|
|
||||||
public override int Encrypt(int value, int opts, int salt)
|
public override int Encrypt(int value, int opts, int salt)
|
||||||
{
|
{
|
||||||
while (opts > 0)
|
while (opts > 0)
|
||||||
{
|
{
|
||||||
int opCode = opts & OpCodeMask;
|
int opCode = opts & kOpCodeMask;
|
||||||
value = ExecuteEncrypt(value, opCode, salt);
|
value = ExecuteEncrypt(value, opCode, salt);
|
||||||
opts >>= OpCodeBits;
|
opts >>= kOpCodeBits;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -173,9 +165,9 @@ namespace Obfuz.EncryptionVM
|
||||||
{
|
{
|
||||||
while (opts > 0)
|
while (opts > 0)
|
||||||
{
|
{
|
||||||
int opCode = opts & OpCodeMask;
|
int opCode = opts & kOpCodeMask;
|
||||||
value = ExecuteDecrypt(value, opCode, salt);
|
value = ExecuteDecrypt(value, opCode, salt);
|
||||||
opts >>= OpCodeBits;
|
opts >>= kOpCodeBits;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ namespace Obfuz.EncryptionVM
|
||||||
private readonly EncryptionInstructionWithOpCode[] _opCodes;
|
private readonly EncryptionInstructionWithOpCode[] _opCodes;
|
||||||
private readonly int[] _secretKey;
|
private readonly int[] _secretKey;
|
||||||
|
|
||||||
|
public override int OpCodeCount => _opCodes.Length;
|
||||||
|
|
||||||
public VirtualMachineSimulator(VirtualMachine vm, byte[] byteSecretKey)
|
public VirtualMachineSimulator(VirtualMachine vm, byte[] byteSecretKey)
|
||||||
{
|
{
|
||||||
_opCodes = vm.opCodes;
|
_opCodes = vm.opCodes;
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
public class CallObfusPass : BasicBlockObfuscationPassBase
|
public class CallObfusPass : BasicBlockObfuscationPassBase
|
||||||
{
|
{
|
||||||
private readonly List<string> _configFiles;
|
private readonly List<string> _configFiles;
|
||||||
|
private readonly int _obfuscationLevel;
|
||||||
private IRandom _random;
|
private IRandom _random;
|
||||||
private IEncryptor _encryptor;
|
private IEncryptor _encryptor;
|
||||||
private IObfuscator _dynamicProxyObfuscator;
|
private IObfuscator _dynamicProxyObfuscator;
|
||||||
|
@ -24,6 +25,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
public CallObfusPass(CallObfusSettings settings)
|
public CallObfusPass(CallObfusSettings settings)
|
||||||
{
|
{
|
||||||
_configFiles = settings.configFiles.ToList();
|
_configFiles = settings.configFiles.ToList();
|
||||||
|
_obfuscationLevel = settings.callObfuscationLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop(ObfuscationPassContext ctx)
|
public override void Stop(ObfuscationPassContext ctx)
|
||||||
|
@ -35,7 +37,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
{
|
{
|
||||||
_random = ctx.random;
|
_random = ctx.random;
|
||||||
_encryptor = ctx.encryptor;
|
_encryptor = ctx.encryptor;
|
||||||
_dynamicProxyObfuscator = new DefaultCallProxyObfuscator(_random, _encryptor, ctx.constFieldAllocator);
|
_dynamicProxyObfuscator = new DefaultCallProxyObfuscator(_random, _encryptor, ctx.constFieldAllocator, _obfuscationLevel);
|
||||||
_dynamicProxyPolicy = new ConfigurableObfuscationPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
|
_dynamicProxyPolicy = new ConfigurableObfuscationPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
private ModuleDef _module;
|
private ModuleDef _module;
|
||||||
private readonly IRandom _random;
|
private readonly IRandom _random;
|
||||||
private readonly IEncryptor _encryptor;
|
private readonly IEncryptor _encryptor;
|
||||||
|
private readonly int _encryptionLevel;
|
||||||
|
|
||||||
class MethodKey : IEquatable<MethodKey>
|
class MethodKey : IEquatable<MethodKey>
|
||||||
{
|
{
|
||||||
|
@ -92,10 +93,11 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
|
||||||
private TypeDef _proxyTypeDef;
|
private TypeDef _proxyTypeDef;
|
||||||
|
|
||||||
public ModuleCallProxyAllocator(IRandom random, IEncryptor encryptor)
|
public ModuleCallProxyAllocator(IRandom random, IEncryptor encryptor, int encryptionLevel)
|
||||||
{
|
{
|
||||||
_random = random;
|
_random = random;
|
||||||
_encryptor = encryptor;
|
_encryptor = encryptor;
|
||||||
|
_encryptionLevel = encryptionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init(ModuleDef mod)
|
public void Init(ModuleDef mod)
|
||||||
|
@ -156,7 +158,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
|
||||||
private int GenerateEncryptOps()
|
private int GenerateEncryptOps()
|
||||||
{
|
{
|
||||||
return _random.NextInt();
|
return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DispatchMethodInfo GetDispatchMethod(IMethod method)
|
private DispatchMethodInfo GetDispatchMethod(IMethod method)
|
||||||
|
@ -240,16 +242,18 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
{
|
{
|
||||||
private readonly IRandom _random;
|
private readonly IRandom _random;
|
||||||
private readonly IEncryptor _encryptor;
|
private readonly IEncryptor _encryptor;
|
||||||
|
private readonly int _encryptionLevel;
|
||||||
|
|
||||||
public CallProxyAllocator(IRandom random, IEncryptor encryptor)
|
public CallProxyAllocator(IRandom random, IEncryptor encryptor, int encryptionLevel)
|
||||||
{
|
{
|
||||||
_random = random;
|
_random = random;
|
||||||
_encryptor = encryptor;
|
_encryptor = encryptor;
|
||||||
|
_encryptionLevel = encryptionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModuleCallProxyAllocator GetModuleAllocator(ModuleDef mod)
|
private ModuleCallProxyAllocator GetModuleAllocator(ModuleDef mod)
|
||||||
{
|
{
|
||||||
return GroupByModuleEntityManager.Ins.GetEntity<ModuleCallProxyAllocator>(mod, () => new ModuleCallProxyAllocator(_random, _encryptor));
|
return GroupByModuleEntityManager.Ins.GetEntity<ModuleCallProxyAllocator>(mod, () => new ModuleCallProxyAllocator(_random, _encryptor, _encryptionLevel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProxyCallMethodData Allocate(ModuleDef mod, IMethod method, bool callVir)
|
public ProxyCallMethodData Allocate(ModuleDef mod, IMethod method, bool callVir)
|
||||||
|
|
|
@ -10,17 +10,15 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
{
|
{
|
||||||
public class DefaultCallProxyObfuscator : ObfuscatorBase
|
public class DefaultCallProxyObfuscator : ObfuscatorBase
|
||||||
{
|
{
|
||||||
private readonly IRandom _random;
|
|
||||||
private readonly IEncryptor _encryptor;
|
private readonly IEncryptor _encryptor;
|
||||||
private readonly ConstFieldAllocator _constFieldAllocator;
|
private readonly ConstFieldAllocator _constFieldAllocator;
|
||||||
private readonly CallProxyAllocator _proxyCallAllocator;
|
private readonly CallProxyAllocator _proxyCallAllocator;
|
||||||
|
|
||||||
public DefaultCallProxyObfuscator(IRandom random, IEncryptor encryptor, ConstFieldAllocator constFieldAllocator)
|
public DefaultCallProxyObfuscator(IRandom random, IEncryptor encryptor, ConstFieldAllocator constFieldAllocator, int encryptionLevel)
|
||||||
{
|
{
|
||||||
_random = random;
|
|
||||||
_encryptor = encryptor;
|
_encryptor = encryptor;
|
||||||
_constFieldAllocator = constFieldAllocator;
|
_constFieldAllocator = constFieldAllocator;
|
||||||
_proxyCallAllocator = new CallProxyAllocator(random, _encryptor);
|
_proxyCallAllocator = new CallProxyAllocator(random, _encryptor, encryptionLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Done()
|
public override void Done()
|
||||||
|
|
|
@ -16,18 +16,20 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
public class ConstEncryptPass : BasicBlockObfuscationPassBase
|
public class ConstEncryptPass : BasicBlockObfuscationPassBase
|
||||||
{
|
{
|
||||||
private readonly List<string> _configFiles;
|
private readonly List<string> _configFiles;
|
||||||
|
private readonly int _encryptionLevel;
|
||||||
private IEncryptPolicy _dataObfuscatorPolicy;
|
private IEncryptPolicy _dataObfuscatorPolicy;
|
||||||
private IConstEncryptor _dataObfuscator;
|
private IConstEncryptor _dataObfuscator;
|
||||||
|
|
||||||
public ConstEncryptPass(ConstEncryptSettings settings)
|
public ConstEncryptPass(ConstEncryptSettings settings)
|
||||||
{
|
{
|
||||||
_configFiles = settings.configFiles.ToList();
|
_configFiles = settings.configFiles.ToList();
|
||||||
|
_encryptionLevel = settings.encryptionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Start(ObfuscationPassContext ctx)
|
public override void Start(ObfuscationPassContext ctx)
|
||||||
{
|
{
|
||||||
_dataObfuscatorPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
|
_dataObfuscatorPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
|
||||||
_dataObfuscator = new DefaultConstEncryptor(ctx.random, ctx.encryptor, ctx.rvaDataAllocator, ctx.constFieldAllocator);
|
_dataObfuscator = new DefaultConstEncryptor(ctx.random, ctx.encryptor, ctx.rvaDataAllocator, ctx.constFieldAllocator, _encryptionLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop(ObfuscationPassContext ctx)
|
public override void Stop(ObfuscationPassContext ctx)
|
||||||
|
|
|
@ -16,18 +16,20 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
private readonly RvaDataAllocator _rvaDataAllocator;
|
private readonly RvaDataAllocator _rvaDataAllocator;
|
||||||
private readonly ConstFieldAllocator _constFieldAllocator;
|
private readonly ConstFieldAllocator _constFieldAllocator;
|
||||||
private readonly IEncryptor _encryptor;
|
private readonly IEncryptor _encryptor;
|
||||||
|
private readonly int _encryptionLevel;
|
||||||
|
|
||||||
public DefaultConstEncryptor(IRandom random, IEncryptor encryptor, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator)
|
public DefaultConstEncryptor(IRandom random, IEncryptor encryptor, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator, int encryptionLevel)
|
||||||
{
|
{
|
||||||
_random = random;
|
_random = random;
|
||||||
_encryptor = encryptor;
|
_encryptor = encryptor;
|
||||||
_rvaDataAllocator = rvaDataAllocator;
|
_rvaDataAllocator = rvaDataAllocator;
|
||||||
_constFieldAllocator = constFieldAllocator;
|
_constFieldAllocator = constFieldAllocator;
|
||||||
|
_encryptionLevel = encryptionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GenerateEncryptionOperations()
|
private int GenerateEncryptionOperations()
|
||||||
{
|
{
|
||||||
return _random.NextInt();
|
return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GenerateSalt()
|
public int GenerateSalt()
|
||||||
|
|
|
@ -14,11 +14,13 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
{
|
{
|
||||||
private readonly IRandom _random;
|
private readonly IRandom _random;
|
||||||
private readonly IEncryptor _encryptor;
|
private readonly IEncryptor _encryptor;
|
||||||
|
private readonly int _encryptionLevel;
|
||||||
|
|
||||||
public DefaultFieldEncryptor(IRandom random, IEncryptor encryptor)
|
public DefaultFieldEncryptor(IRandom random, IEncryptor encryptor, int encryptionLevel)
|
||||||
{
|
{
|
||||||
_random = random;
|
_random = random;
|
||||||
_encryptor = encryptor;
|
_encryptor = encryptor;
|
||||||
|
_encryptionLevel = encryptionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DefaultMetadataImporter GetMetadataImporter(MethodDef method)
|
private DefaultMetadataImporter GetMetadataImporter(MethodDef method)
|
||||||
|
@ -54,6 +56,17 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int GenerateEncryptionOperations()
|
||||||
|
{
|
||||||
|
return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GenerateSalt()
|
||||||
|
{
|
||||||
|
return _random.NextInt();
|
||||||
|
}
|
||||||
|
|
||||||
private FieldEncryptInfo GetFieldEncryptInfo(FieldDef field)
|
private FieldEncryptInfo GetFieldEncryptInfo(FieldDef field)
|
||||||
{
|
{
|
||||||
if (_fieldEncryptInfoCache.TryGetValue(field, out var info))
|
if (_fieldEncryptInfoCache.TryGetValue(field, out var info))
|
||||||
|
@ -61,8 +74,8 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encryptOps = _random.NextInt();
|
int encryptOps = GenerateEncryptionOperations();
|
||||||
int salt = _random.NextInt();
|
int salt = GenerateSalt();
|
||||||
ElementType fieldType = field.FieldSig.Type.RemovePinnedAndModifiers().ElementType;
|
ElementType fieldType = field.FieldSig.Type.RemovePinnedAndModifiers().ElementType;
|
||||||
long xorValueForZero = CalcXorValueForZero(fieldType, encryptOps, salt);
|
long xorValueForZero = CalcXorValueForZero(fieldType, encryptOps, salt);
|
||||||
|
|
||||||
|
|
|
@ -13,19 +13,21 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
public class FieldEncryptPass : InstructionObfuscationPassBase
|
public class FieldEncryptPass : InstructionObfuscationPassBase
|
||||||
{
|
{
|
||||||
private readonly List<string> _configFiles;
|
private readonly List<string> _configFiles;
|
||||||
|
private readonly int _encryptionLevel;
|
||||||
private IEncryptPolicy _encryptionPolicy;
|
private IEncryptPolicy _encryptionPolicy;
|
||||||
private IFieldEncryptor _memoryEncryptor;
|
private IFieldEncryptor _memoryEncryptor;
|
||||||
|
|
||||||
public FieldEncryptPass(FieldEncryptSettings settings)
|
public FieldEncryptPass(FieldEncryptSettings settings)
|
||||||
{
|
{
|
||||||
_configFiles = settings.configFiles.ToList();
|
_configFiles = settings.configFiles.ToList();
|
||||||
|
_encryptionLevel = settings.encryptionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool NeedProcessNotObfuscatedAssembly => true;
|
protected override bool NeedProcessNotObfuscatedAssembly => true;
|
||||||
|
|
||||||
public override void Start(ObfuscationPassContext ctx)
|
public override void Start(ObfuscationPassContext ctx)
|
||||||
{
|
{
|
||||||
_memoryEncryptor = new DefaultFieldEncryptor(ctx.random, ctx.encryptor);
|
_memoryEncryptor = new DefaultFieldEncryptor(ctx.random, ctx.encryptor, _encryptionLevel);
|
||||||
_encryptionPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
|
_encryptionPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace Obfuz
|
||||||
private int _globalRandomSeed;
|
private int _globalRandomSeed;
|
||||||
private string _encryptionVmGenerationSecretKey;
|
private string _encryptionVmGenerationSecretKey;
|
||||||
private int _encryptionVmOpCodeCount;
|
private int _encryptionVmOpCodeCount;
|
||||||
public string _encryptionVmCodeFile;
|
private string _encryptionVmCodeFile;
|
||||||
|
|
||||||
private List<string> _toObfuscatedAssemblyNames = new List<string>();
|
private List<string> _toObfuscatedAssemblyNames = new List<string>();
|
||||||
private List<string> _notObfuscatedAssemblyNamesReferencingObfuscated = new List<string>();
|
private List<string> _notObfuscatedAssemblyNamesReferencingObfuscated = new List<string>();
|
||||||
|
|
|
@ -10,6 +10,10 @@ namespace Obfuz.Settings
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class CallObfusSettings
|
public class CallObfusSettings
|
||||||
{
|
{
|
||||||
|
[Tooltip("The obfuscation level for the obfuscation. Higher levels provide more security but may impact performance.")]
|
||||||
|
[Range(1, 4)]
|
||||||
|
public int callObfuscationLevel = 1;
|
||||||
|
|
||||||
[Tooltip("config xml files")]
|
[Tooltip("config xml files")]
|
||||||
public string[] configFiles;
|
public string[] configFiles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@ namespace Obfuz.Settings
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ConstEncryptSettings
|
public class ConstEncryptSettings
|
||||||
{
|
{
|
||||||
|
[Tooltip("The encryption level for the obfuscation. Higher levels provide more security but may impact performance.")]
|
||||||
|
[Range(1, 4)]
|
||||||
|
public int encryptionLevel = 1;
|
||||||
|
|
||||||
[Tooltip("config xml files")]
|
[Tooltip("config xml files")]
|
||||||
public string[] configFiles;
|
public string[] configFiles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@ namespace Obfuz.Settings
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class FieldEncryptSettings
|
public class FieldEncryptSettings
|
||||||
{
|
{
|
||||||
|
[Tooltip("The encryption level for the obfuscation. Higher levels provide more security but may impact performance.")]
|
||||||
|
[Range(1, 4)]
|
||||||
|
public int encryptionLevel = 1;
|
||||||
|
|
||||||
[Tooltip("config xml files")]
|
[Tooltip("config xml files")]
|
||||||
public string[] configFiles;
|
public string[] configFiles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Obfuz.Utils
|
||||||
|
{
|
||||||
|
public static class EncryptionUtil
|
||||||
|
{
|
||||||
|
public static int GetBitCount(int value)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
while (value > 0)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
value >>= 1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GenerateEncryptionOpCodes(IRandom random, IEncryptor encryptor, int encryptionLevel)
|
||||||
|
{
|
||||||
|
if (encryptionLevel <= 0 || encryptionLevel > 4)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Invalid encryption level: {encryptionLevel}, should be in range [1,4]");
|
||||||
|
}
|
||||||
|
int vmOpCodeCount = encryptor.OpCodeCount;
|
||||||
|
long ops = 0;
|
||||||
|
for (int i = 0; i < encryptionLevel; i++)
|
||||||
|
{
|
||||||
|
ops *= vmOpCodeCount;
|
||||||
|
// first op code can't be 0
|
||||||
|
int op = random.NextInt(i == 0 ? 1 : 0, vmOpCodeCount);
|
||||||
|
ops |= (uint)op;
|
||||||
|
if (ops > uint.MaxValue)
|
||||||
|
{
|
||||||
|
throw new Exception($"OpCode overflow. encryptionLevel:{encryptionLevel}, vmOpCodeCount:{vmOpCodeCount}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (int)ops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,11 +33,7 @@ namespace Obfuz.Utils
|
||||||
|
|
||||||
public static int[] ConvertToIntKey(byte[] key)
|
public static int[] ConvertToIntKey(byte[] key)
|
||||||
{
|
{
|
||||||
Assert.AreEqual(0, key.Length % 4);
|
return EncryptorBase.ConvertToIntKey(key);
|
||||||
int align4Length = key.Length / 4;
|
|
||||||
int[] intKey = new int[align4Length];
|
|
||||||
Buffer.BlockCopy(key, 0, intKey, 0, key.Length);
|
|
||||||
return intKey;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ namespace Obfuz
|
||||||
{
|
{
|
||||||
public abstract class EncryptorBase : IEncryptor
|
public abstract class EncryptorBase : IEncryptor
|
||||||
{
|
{
|
||||||
|
public abstract int OpCodeCount { get; }
|
||||||
|
|
||||||
public static int[] ConvertToIntKey(byte[] key)
|
public static int[] ConvertToIntKey(byte[] key)
|
||||||
{
|
{
|
||||||
Assert.AreEqual(0, key.Length % 4);
|
Assert.AreEqual(0, key.Length % 4);
|
||||||
|
|
|
@ -6,6 +6,8 @@ namespace Obfuz
|
||||||
{
|
{
|
||||||
public interface IEncryptor
|
public interface IEncryptor
|
||||||
{
|
{
|
||||||
|
int OpCodeCount { get; }
|
||||||
|
|
||||||
void EncryptBlock(byte[] data, int ops, int salt);
|
void EncryptBlock(byte[] data, int ops, int salt);
|
||||||
void DecryptBlock(byte[] data, int ops, int salt);
|
void DecryptBlock(byte[] data, int ops, int salt);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ namespace Obfuz
|
||||||
{
|
{
|
||||||
private readonly byte[] _key;
|
private readonly byte[] _key;
|
||||||
|
|
||||||
|
public override int OpCodeCount => 256;
|
||||||
|
|
||||||
public NullEncryptor(byte[] key)
|
public NullEncryptor(byte[] key)
|
||||||
{
|
{
|
||||||
_key = key;
|
_key = key;
|
||||||
|
|
Loading…
Reference in New Issue