修复 GeneratedEncryptionVirtualMachine Decrypt时没有逆序ops的bug
parent
cabc6c2980
commit
542585b1f7
|
@ -5,6 +5,7 @@ using Obfuz.Utils;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
@ -31,6 +32,7 @@ namespace Obfuz.Data
|
|||
private readonly Dictionary<FieldDef, ConstFieldInfo> _field2Fields = new Dictionary<FieldDef, ConstFieldInfo>();
|
||||
|
||||
private readonly List<TypeDef> _holderTypeDefs = new List<TypeDef>();
|
||||
private bool _done;
|
||||
|
||||
|
||||
public ModuleConstFieldAllocator(IEncryptor encryptor, IRandom random, RvaDataAllocator rvaDataAllocator, GroupByModuleEntityManager moduleEntityManager)
|
||||
|
@ -89,6 +91,10 @@ namespace Obfuz.Data
|
|||
|
||||
private FieldDef AllocateAny(object value)
|
||||
{
|
||||
if (_done)
|
||||
{
|
||||
throw new Exception("can't Allocate after done");
|
||||
}
|
||||
if (!_allocatedFields.TryGetValue(value, out var field))
|
||||
{
|
||||
field = CreateConstFieldInfo(value);
|
||||
|
@ -248,6 +254,11 @@ namespace Obfuz.Data
|
|||
|
||||
public void Done()
|
||||
{
|
||||
if (_done)
|
||||
{
|
||||
throw new Exception("Already done");
|
||||
}
|
||||
_done = true;
|
||||
foreach (var typeDef in _holderTypeDefs)
|
||||
{
|
||||
CreateCCtorOfRvaTypeDef(typeDef);
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace Obfuz.Data
|
|||
private TypeDef _rvaTypeDef;
|
||||
|
||||
private readonly Dictionary<int, TypeDef> _dataHolderTypeBySizes = new Dictionary<int, TypeDef>();
|
||||
private bool _done;
|
||||
|
||||
public ModuleRvaDataAllocator(IRandom random, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager)
|
||||
{
|
||||
|
@ -99,10 +100,10 @@ namespace Obfuz.Data
|
|||
}
|
||||
|
||||
|
||||
var holderField = new FieldDefUser($"$RVA_Data{_rvaTypeDef.Fields.Count}", new FieldSig(dataHolderType.ToTypeSig()), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA);
|
||||
var holderField = new FieldDefUser($"$RVA_Data{_rvaFields.Count}", new FieldSig(dataHolderType.ToTypeSig()), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA);
|
||||
holderField.DeclaringType = _rvaTypeDef;
|
||||
|
||||
var runtimeValueField = new FieldDefUser($"$RVA_Value{_rvaTypeDef.Fields.Count}", new FieldSig(new SZArraySig(_module.CorLibTypes.Byte)), FieldAttributes.Static);
|
||||
var runtimeValueField = new FieldDefUser($"$RVA_Value{_rvaFields.Count}", new FieldSig(new SZArraySig(_module.CorLibTypes.Byte)), FieldAttributes.Static);
|
||||
runtimeValueField.DeclaringType = _rvaTypeDef;
|
||||
return (holderField, runtimeValueField);
|
||||
}
|
||||
|
@ -145,6 +146,10 @@ namespace Obfuz.Data
|
|||
|
||||
private RvaField GetRvaField(int preservedSize, int alignment)
|
||||
{
|
||||
if (_done)
|
||||
{
|
||||
throw new Exception("can't GetRvaField after done");
|
||||
}
|
||||
Assert.IsTrue(preservedSize % alignment == 0);
|
||||
// for big size, create a new field
|
||||
if (preservedSize >= maxRvaDataSize)
|
||||
|
@ -279,6 +284,11 @@ namespace Obfuz.Data
|
|||
|
||||
public void Done()
|
||||
{
|
||||
if (_done)
|
||||
{
|
||||
throw new Exception("can't call Done twice");
|
||||
}
|
||||
_done = true;
|
||||
SetFieldsRVA();
|
||||
CreateCCtorOfRvaTypeDef();
|
||||
}
|
||||
|
|
|
@ -152,12 +152,21 @@ namespace Obfuz.EncryptionVM
|
|||
|
||||
public override int Encrypt(int value, int opts, int salt)
|
||||
{
|
||||
int revertOps = 0;
|
||||
while (opts > 0)
|
||||
{
|
||||
int opCode = opts & kOpCodeMask;
|
||||
value = ExecuteEncrypt(value, opCode, salt);
|
||||
revertOps <<= kOpCodeBits;
|
||||
revertOps |= opCode;
|
||||
opts >>= kOpCodeBits;
|
||||
}
|
||||
|
||||
while (revertOps > 0)
|
||||
{
|
||||
int opCode = revertOps & kOpCodeMask;
|
||||
value = ExecuteEncrypt(value, opCode, salt);
|
||||
revertOps >>= kOpCodeBits;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,24 +57,24 @@ namespace Obfuz.EncryptionVM
|
|||
}
|
||||
}
|
||||
|
||||
private List<ushort> DecodeOps(int ops)
|
||||
private List<uint> DecodeOps(uint ops)
|
||||
{
|
||||
var codes = new List<ushort>();
|
||||
var codes = new List<uint>();
|
||||
while (ops > 0)
|
||||
{
|
||||
var code = (ushort)(ops % _opCodes.Length);
|
||||
uint code = ops % (uint)_opCodes.Length;
|
||||
codes.Add(code);
|
||||
ops >>= 16;
|
||||
ops /= (uint)_opCodes.Length;
|
||||
}
|
||||
return codes;
|
||||
}
|
||||
|
||||
public override int Encrypt(int value, int ops, int salt)
|
||||
{
|
||||
var codes = DecodeOps(ops);
|
||||
foreach (var code in codes)
|
||||
var codes = DecodeOps((uint)ops);
|
||||
for (int i = codes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var opCode = _opCodes[code];
|
||||
var opCode = _opCodes[codes[i]];
|
||||
value = opCode.Encrypt(value, _secretKey, salt);
|
||||
}
|
||||
return value;
|
||||
|
@ -82,10 +82,10 @@ namespace Obfuz.EncryptionVM
|
|||
|
||||
public override int Decrypt(int value, int ops, int salt)
|
||||
{
|
||||
var codes = DecodeOps(ops);
|
||||
for (int i = codes.Count - 1; i >= 0; i--)
|
||||
var codes = DecodeOps((uint)ops);
|
||||
foreach (var code in codes)
|
||||
{
|
||||
var opCode = _opCodes[codes[i]];
|
||||
var opCode = _opCodes[code];
|
||||
value = opCode.Decrypt(value, _secretKey, salt);
|
||||
}
|
||||
return value;
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
private readonly RandomCreator _randomCreator;
|
||||
private readonly IEncryptor _encryptor;
|
||||
private readonly int _encryptionLevel;
|
||||
private bool _done;
|
||||
|
||||
class MethodKey : IEquatable<MethodKey>
|
||||
{
|
||||
|
@ -188,6 +189,10 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
|
||||
public ProxyCallMethodData Allocate(IMethod method, bool callVir)
|
||||
{
|
||||
if (_done)
|
||||
{
|
||||
throw new Exception("can't Allocate after done");
|
||||
}
|
||||
var key = new MethodKey(method, callVir);
|
||||
if (!_methodProxys.TryGetValue(key, out var proxyInfo))
|
||||
{
|
||||
|
@ -214,6 +219,12 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
|
||||
public void Done()
|
||||
{
|
||||
if (_done)
|
||||
{
|
||||
throw new Exception("Already done");
|
||||
}
|
||||
_done = true;
|
||||
|
||||
foreach (DispatchMethodInfo dispatchMethod in _dispatchMethods.Values.SelectMany(ms => ms))
|
||||
{
|
||||
var methodDef = dispatchMethod.methodDef;
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
|||
|
||||
public override void Stop()
|
||||
{
|
||||
_dataObfuscator.Done();
|
||||
|
||||
}
|
||||
|
||||
protected override bool NeedObfuscateMethod(MethodDef method)
|
||||
|
|
|
@ -196,8 +196,6 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
|||
|
||||
public void Done()
|
||||
{
|
||||
_rvaDataAllocator.Done();
|
||||
_constFieldAllocator.Done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
|||
void ObfuscateString(MethodDef method, bool needCacheValue, string value, List<Instruction> obfuscatedInstructions);
|
||||
|
||||
void ObfuscateBytes(MethodDef method, bool needCacheValue, byte[] value, List<Instruction> obfuscatedInstructions);
|
||||
|
||||
void Done();
|
||||
}
|
||||
|
||||
public abstract class ConstEncryptorBase : IConstEncryptor
|
||||
|
@ -30,6 +28,5 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
|||
public abstract void ObfuscateInt(MethodDef method, bool needCacheValue, int value, List<Instruction> obfuscatedInstructions);
|
||||
public abstract void ObfuscateLong(MethodDef method, bool needCacheValue, long value, List<Instruction> obfuscatedInstructions);
|
||||
public abstract void ObfuscateString(MethodDef method, bool needCacheValue, string value, List<Instruction> obfuscatedInstructions);
|
||||
public abstract void Done();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus.Policies
|
|||
public override bool NeedRename(TypeDef typeDef)
|
||||
{
|
||||
string name = typeDef.Name;
|
||||
if (name == "<Module>")
|
||||
if (name == "<Module>" || name == "ObfuzIgnoreAttribute")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -129,16 +129,18 @@ namespace Obfuz
|
|||
var gvmInstance = (IEncryptor)Activator.CreateInstance(generatedVmTypes[0], new object[] { _byteSecret } );
|
||||
|
||||
int testValue = 11223344;
|
||||
string testString = "hello,world";
|
||||
for (int i = 0; i < vm.opCodes.Length; i++)
|
||||
{
|
||||
int encryptedValueOfVms = vms.Encrypt(testValue, i, i);
|
||||
int decryptedValueOfVms = vms.Decrypt(encryptedValueOfVms, i, i);
|
||||
int ops = i * vm.opCodes.Length + i;
|
||||
int encryptedValueOfVms = vms.Encrypt(testValue, ops, i);
|
||||
int decryptedValueOfVms = vms.Decrypt(encryptedValueOfVms, ops, i);
|
||||
if (decryptedValueOfVms != testValue)
|
||||
{
|
||||
throw new Exception($"VirtualMachineSimulator decrypt failed! opCode:{i}, originalValue:{testValue} decryptedValue:{decryptedValueOfVms}");
|
||||
}
|
||||
int encryptedValueOfGvm = gvmInstance.Encrypt(testValue, i, i);
|
||||
int decryptedValueOfGvm = gvmInstance.Decrypt(encryptedValueOfGvm, i, i);
|
||||
int encryptedValueOfGvm = gvmInstance.Encrypt(testValue, ops, i);
|
||||
int decryptedValueOfGvm = gvmInstance.Decrypt(encryptedValueOfGvm, ops, i);
|
||||
if (encryptedValueOfGvm != encryptedValueOfVms)
|
||||
{
|
||||
throw new Exception($"encryptedValue not match! opCode:{i}, originalValue:{testValue} encryptedValue VirtualMachineSimulator:{encryptedValueOfVms} GeneratedEncryptionVirtualMachine:{encryptedValueOfGvm}");
|
||||
|
@ -147,6 +149,23 @@ namespace Obfuz
|
|||
{
|
||||
throw new Exception($"GeneratedEncryptionVirtualMachine decrypt failed! opCode:{i}, originalValue:{testValue} decryptedValue:{decryptedValueOfGvm}");
|
||||
}
|
||||
|
||||
byte[] encryptedStrOfVms = vms.Encrypt(testString, ops, i);
|
||||
string descryptedStrOfVms = vms.DecryptString(encryptedStrOfVms, 0, encryptedStrOfVms.Length, ops, i);
|
||||
if (descryptedStrOfVms != testString)
|
||||
{
|
||||
throw new Exception($"VirtualMachineSimulator decrypt string failed! opCode:{i}, originalValue:{testString} decryptedValue:{descryptedStrOfVms}");
|
||||
}
|
||||
byte[] encryptedStrOfGvm = gvmInstance.Encrypt(testString, ops, i);
|
||||
string descryptedStrOfGvm = gvmInstance.DecryptString(encryptedStrOfGvm, 0, encryptedStrOfGvm.Length, ops, i);
|
||||
if (!encryptedStrOfGvm.SequenceEqual(encryptedStrOfVms))
|
||||
{
|
||||
throw new Exception($"encryptedValue not match! opCode:{i}, originalValue:{testString} encryptedValue VirtualMachineSimulator:{encryptedStrOfVms} GeneratedEncryptionVirtualMachine:{encryptedStrOfGvm}");
|
||||
}
|
||||
if (descryptedStrOfGvm != testString)
|
||||
{
|
||||
throw new Exception($"GeneratedEncryptionVirtualMachine decrypt string failed! opCode:{i}, originalValue:{testString} decryptedValue:{descryptedStrOfGvm}");
|
||||
}
|
||||
}
|
||||
|
||||
return vms;
|
||||
|
@ -223,6 +242,9 @@ namespace Obfuz
|
|||
private void OnPostObfuscation(Pipeline pipeline)
|
||||
{
|
||||
pipeline.Stop();
|
||||
|
||||
_ctx.constFieldAllocator.Done();
|
||||
_ctx.rvaDataAllocator.Done();
|
||||
WriteAssemblies();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ namespace Obfuz.Utils
|
|||
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);
|
||||
// don't use 0
|
||||
int op = random.NextInt(1, vmOpCodeCount);
|
||||
ops |= (uint)op;
|
||||
if (ops > uint.MaxValue)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue