确定性生成

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

View File

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

View File

@ -31,7 +31,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
{ {
var ctx = ObfuscationPassContext.Current; var ctx = ObfuscationPassContext.Current;
_dataObfuscatorPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles); _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() public override void Stop()

View File

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

View File

@ -12,14 +12,14 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
{ {
public class DefaultFieldEncryptor : FieldEncryptorBase public class DefaultFieldEncryptor : FieldEncryptorBase
{ {
private readonly IRandom _random; private readonly RandomCreator _randomCreator;
private readonly IEncryptor _encryptor; private readonly IEncryptor _encryptor;
private readonly GroupByModuleEntityManager _moduleEntityManager; private readonly GroupByModuleEntityManager _moduleEntityManager;
private readonly int _encryptionLevel; 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; _encryptor = encryptor;
_moduleEntityManager = moduleEntityManager; _moduleEntityManager = moduleEntityManager;
_encryptionLevel = encryptionLevel; _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) private FieldEncryptInfo GetFieldEncryptInfo(FieldDef field)
@ -76,8 +81,9 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
return info; return info;
} }
int encryptOps = GenerateEncryptionOperations(); IRandom random = CreateRandomForField(field);
int salt = GenerateSalt(); int encryptOps = GenerateEncryptionOperations(random);
int salt = GenerateSalt(random);
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);

View File

@ -30,7 +30,7 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
public override void Start() public override void Start()
{ {
var ctx = ObfuscationPassContext.Current; 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); _encryptionPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
} }

View File

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

View File

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

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine.UIElements;
namespace Obfuz.Utils namespace Obfuz.Utils
{ {
@ -24,5 +25,29 @@ namespace Obfuz.Utils
} }
return hash; 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;
}
}
} }
} }