确定性生成

backup
walon 2025-05-13 09:27:44 +08:00
parent 62cabf939c
commit bf79067e75
10 changed files with 95 additions and 48 deletions

View File

@ -17,7 +17,6 @@ namespace Obfuz.ObfusPasses.CallObfus
{
private readonly List<string> _configFiles;
private readonly int _obfuscationLevel;
private IRandom _random;
private IEncryptor _encryptor;
private IObfuscator _dynamicProxyObfuscator;
private IObfuscationPolicy _dynamicProxyPolicy;
@ -38,9 +37,8 @@ namespace Obfuz.ObfusPasses.CallObfus
public override void Start()
{
var ctx = ObfuscationPassContext.Current;
_random = ctx.globalRandom;
_encryptor = ctx.encryptor;
_dynamicProxyObfuscator = new DefaultCallProxyObfuscator(_random, _encryptor, ctx.constFieldAllocator, ctx.moduleEntityManager, _obfuscationLevel);
_dynamicProxyObfuscator = new DefaultCallProxyObfuscator(ctx.localRandomCreator, _encryptor, ctx.constFieldAllocator, ctx.moduleEntityManager, _obfuscationLevel);
_dynamicProxyPolicy = new ConfigurableObfuscationPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
}

View File

@ -33,7 +33,7 @@ namespace Obfuz.ObfusPasses.CallObfus
class ModuleCallProxyAllocator : IGroupByModuleEntity
{
private ModuleDef _module;
private readonly IRandom _random;
private readonly RandomCreator _randomCreator;
private readonly IEncryptor _encryptor;
private readonly int _encryptionLevel;
@ -93,9 +93,9 @@ namespace Obfuz.ObfusPasses.CallObfus
private TypeDef _proxyTypeDef;
public ModuleCallProxyAllocator(IRandom random, IEncryptor encryptor, int encryptionLevel)
public ModuleCallProxyAllocator(RandomCreator randomCreator, IEncryptor encryptor, int encryptionLevel)
{
_random = random;
_randomCreator = randomCreator;
_encryptor = encryptor;
_encryptionLevel = encryptionLevel;
}
@ -151,14 +151,14 @@ namespace Obfuz.ObfusPasses.CallObfus
return MethodSig.CreateStatic(methodSig.RetType, methodSig.Params.ToArray());
}
private int GenerateSalt()
private int GenerateSalt(IRandom random)
{
return _random.NextInt();
return random.NextInt();
}
private int GenerateEncryptOps()
private int GenerateEncryptOps(IRandom random)
{
return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel);
return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel);
}
private DispatchMethodInfo GetDispatchMethod(IMethod method)
@ -180,6 +180,12 @@ namespace Obfuz.ObfusPasses.CallObfus
return dispatchMethods.Last();
}
private IRandom CreateRandomForMethod(IMethod method, bool callVir)
{
int seed = MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method);
return _randomCreator(seed);
}
public ProxyCallMethodData Allocate(IMethod method, bool callVir)
{
var key = new MethodKey(method, callVir);
@ -188,8 +194,9 @@ namespace Obfuz.ObfusPasses.CallObfus
var methodDispatcher = GetDispatchMethod(method);
int index = methodDispatcher.methods.Count;
int encryptOps = GenerateEncryptOps();
int salt = GenerateSalt();
IRandom localRandom = CreateRandomForMethod(method, callVir);
int encryptOps = GenerateEncryptOps(localRandom);
int salt = GenerateSalt(localRandom);
int encryptedIndex = _encryptor.Encrypt(index, encryptOps, salt);
proxyInfo = new MethodProxyInfo()
{
@ -240,14 +247,14 @@ namespace Obfuz.ObfusPasses.CallObfus
public class CallProxyAllocator
{
private readonly IRandom _random;
private readonly RandomCreator _randomCreator;
private readonly IEncryptor _encryptor;
private GroupByModuleEntityManager _moduleEntityManager;
private readonly int _encryptionLevel;
public CallProxyAllocator(IRandom random, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel)
public CallProxyAllocator(RandomCreator randomCreator, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel)
{
_random = random;
_randomCreator = randomCreator;
_encryptor = encryptor;
_moduleEntityManager = moduleEntityManager;
_encryptionLevel = encryptionLevel;
@ -255,7 +262,7 @@ namespace Obfuz.ObfusPasses.CallObfus
private ModuleCallProxyAllocator GetModuleAllocator(ModuleDef mod)
{
return _moduleEntityManager.GetEntity<ModuleCallProxyAllocator>(mod, () => new ModuleCallProxyAllocator(_random, _encryptor, _encryptionLevel));
return _moduleEntityManager.GetEntity<ModuleCallProxyAllocator>(mod, () => new ModuleCallProxyAllocator(_randomCreator, _encryptor, _encryptionLevel));
}
public ProxyCallMethodData Allocate(ModuleDef mod, IMethod method, bool callVir)

View File

@ -15,12 +15,12 @@ namespace Obfuz.ObfusPasses.CallObfus
private readonly CallProxyAllocator _proxyCallAllocator;
private readonly GroupByModuleEntityManager _moduleEntityManager;
public DefaultCallProxyObfuscator(IRandom random, IEncryptor encryptor, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel)
public DefaultCallProxyObfuscator(RandomCreator randomCreator, IEncryptor encryptor, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel)
{
_encryptor = encryptor;
_constFieldAllocator = constFieldAllocator;
_moduleEntityManager = moduleEntityManager;
_proxyCallAllocator = new CallProxyAllocator(random, _encryptor, moduleEntityManager, encryptionLevel);
_proxyCallAllocator = new CallProxyAllocator(randomCreator, _encryptor, moduleEntityManager, encryptionLevel);
}
public override void Done()

View File

@ -31,7 +31,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
{
var ctx = ObfuscationPassContext.Current;
_dataObfuscatorPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
_dataObfuscator = new DefaultConstEncryptor(ctx.globalRandom, ctx.encryptor, ctx.rvaDataAllocator, ctx.constFieldAllocator, ctx.moduleEntityManager, _encryptionLevel);
_dataObfuscator = new DefaultConstEncryptor(ctx.localRandomCreator, ctx.encryptor, ctx.rvaDataAllocator, ctx.constFieldAllocator, ctx.moduleEntityManager, _encryptionLevel);
}
public override void Stop()

View File

@ -12,16 +12,16 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
{
public class DefaultConstEncryptor : IConstEncryptor
{
private readonly IRandom _random;
private readonly RandomCreator _randomCreator;
private readonly RvaDataAllocator _rvaDataAllocator;
private readonly ConstFieldAllocator _constFieldAllocator;
private readonly IEncryptor _encryptor;
private readonly GroupByModuleEntityManager _moduleEntityManager;
private readonly int _encryptionLevel;
public DefaultConstEncryptor(IRandom random, IEncryptor encryptor, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel)
public DefaultConstEncryptor(RandomCreator randomCreator, IEncryptor encryptor, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel)
{
_random = random;
_randomCreator = randomCreator;
_encryptor = encryptor;
_rvaDataAllocator = rvaDataAllocator;
_constFieldAllocator = constFieldAllocator;
@ -29,14 +29,19 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
_encryptionLevel = encryptionLevel;
}
private int GenerateEncryptionOperations()
private IRandom CreateRandomForValue(int value)
{
return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel);
return _randomCreator(value);
}
public int GenerateSalt()
private int GenerateEncryptionOperations(IRandom random)
{
return _random.NextInt();
return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel);
}
public int GenerateSalt(IRandom random)
{
return random.NextInt();
}
private DefaultMetadataImporter GetModuleMetadataImporter(MethodDef method)
@ -53,8 +58,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
return;
}
int ops = GenerateEncryptionOperations();
int salt = GenerateSalt();
IRandom random = CreateRandomForValue(value.GetHashCode());
int ops = GenerateEncryptionOperations(random);
int salt = GenerateSalt(random);
int encryptedValue = _encryptor.Encrypt(value, ops, salt);
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
@ -75,8 +81,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
return;
}
int ops = GenerateEncryptionOperations();
int salt = GenerateSalt();
IRandom random = CreateRandomForValue(value.GetHashCode());
int ops = GenerateEncryptionOperations(random);
int salt = GenerateSalt(random);
long encryptedValue = _encryptor.Encrypt(value, ops, salt);
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
@ -97,8 +104,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
return;
}
int ops = GenerateEncryptionOperations();
int salt = GenerateSalt();
IRandom random = CreateRandomForValue(value.GetHashCode());
int ops = GenerateEncryptionOperations(random);
int salt = GenerateSalt(random);
float encryptedValue = _encryptor.Encrypt(value, ops, salt);
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
@ -119,8 +127,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
return;
}
int ops = GenerateEncryptionOperations();
int salt = GenerateSalt();
IRandom random = CreateRandomForValue(value.GetHashCode());
int ops = GenerateEncryptionOperations(random);
int salt = GenerateSalt(random);
double encryptedValue = _encryptor.Encrypt(value, ops, salt);
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
@ -167,8 +176,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
return;
}
int ops = GenerateEncryptionOperations();
int salt = GenerateSalt();
IRandom random = CreateRandomForValue(HashUtil.ComputeHash(value));
int ops = GenerateEncryptionOperations(random);
int salt = GenerateSalt(random);
int stringByteLength = Encoding.UTF8.GetByteCount(value);
byte[] encryptedValue = _encryptor.Encrypt(value, ops, salt);
Assert.IsTrue(encryptedValue.Length % 4 == 0);

View File

@ -12,14 +12,14 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
{
public class DefaultFieldEncryptor : FieldEncryptorBase
{
private readonly IRandom _random;
private readonly RandomCreator _randomCreator;
private readonly IEncryptor _encryptor;
private readonly GroupByModuleEntityManager _moduleEntityManager;
private readonly int _encryptionLevel;
public DefaultFieldEncryptor(IRandom random, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel)
public DefaultFieldEncryptor(RandomCreator randomCreator, IEncryptor encryptor, GroupByModuleEntityManager moduleEntityManager, int encryptionLevel)
{
_random = random;
_randomCreator = randomCreator;
_encryptor = encryptor;
_moduleEntityManager = moduleEntityManager;
_encryptionLevel = encryptionLevel;
@ -59,14 +59,19 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
}
private int GenerateEncryptionOperations()
private IRandom CreateRandomForField(FieldDef field)
{
return EncryptionUtil.GenerateEncryptionOpCodes(_random, _encryptor, _encryptionLevel);
return _randomCreator(FieldEqualityComparer.CompareDeclaringTypes.GetHashCode(field));
}
public int GenerateSalt()
private int GenerateEncryptionOperations(IRandom random)
{
return _random.NextInt();
return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptor, _encryptionLevel);
}
public int GenerateSalt(IRandom random)
{
return random.NextInt();
}
private FieldEncryptInfo GetFieldEncryptInfo(FieldDef field)
@ -76,8 +81,9 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
return info;
}
int encryptOps = GenerateEncryptionOperations();
int salt = GenerateSalt();
IRandom random = CreateRandomForField(field);
int encryptOps = GenerateEncryptionOperations(random);
int salt = GenerateSalt(random);
ElementType fieldType = field.FieldSig.Type.RemovePinnedAndModifiers().ElementType;
long xorValueForZero = CalcXorValueForZero(fieldType, encryptOps, salt);

View File

@ -30,7 +30,7 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
public override void Start()
{
var ctx = ObfuscationPassContext.Current;
_memoryEncryptor = new DefaultFieldEncryptor(ctx.globalRandom, ctx.encryptor, ctx.moduleEntityManager, _encryptionLevel);
_memoryEncryptor = new DefaultFieldEncryptor(ctx.localRandomCreator, ctx.encryptor, ctx.moduleEntityManager, _encryptionLevel);
_encryptionPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
}

View File

@ -12,6 +12,7 @@ using System.Threading.Tasks;
namespace Obfuz
{
public delegate IRandom RandomCreator(int seed);
public class ObfuscationPassContext
{
@ -31,7 +32,7 @@ namespace Obfuz
public string obfuscatedAssemblyOutputDir;
public IRandom globalRandom;
public Func<int, IRandom> localScopeRandomCreator;
public RandomCreator localRandomCreator;
public IEncryptor encryptor;
public ConstFieldAllocator constFieldAllocator;

View File

@ -175,7 +175,7 @@ namespace Obfuz
moduleEntityManager = moduleEntityManager,
globalRandom = random,
localScopeRandomCreator = (seed) => new RandomWithKey(_intSecret, _randomSeed ^ seed),
localRandomCreator = (seed) => new RandomWithKey(_intSecret, _randomSeed ^ seed),
encryptor = encryptor,
rvaDataAllocator = rvaDataAllocator,
constFieldAllocator = constFieldAllocator,

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine.UIElements;
namespace Obfuz.Utils
{
@ -24,5 +25,29 @@ namespace Obfuz.Utils
}
return hash;
}
public static unsafe int ComputeHash(string s)
{
fixed (char* ptr = s)
{
int num = 352654597;
int num2 = num;
int* ptr2 = (int*)ptr;
int num3;
for (num3 = s.Length; num3 > 2; num3 -= 4)
{
num = ((num << 5) + num + (num >> 27)) ^ *ptr2;
num2 = ((num2 << 5) + num2 + (num2 >> 27)) ^ ptr2[1];
ptr2 += 2;
}
if (num3 > 0)
{
num = ((num << 5) + num + (num >> 27)) ^ *ptr2;
}
return num + num2 * 1566083941;
}
}
}
}