RvaData初始化时校验密钥的正确性,避免程序集混淆时使用的密钥与运行时加载的密钥不匹配的失误!

before-split
walon 2025-05-23 11:45:37 +08:00
parent f5b45a0543
commit 3425abceb5
4 changed files with 56 additions and 2 deletions

View File

@ -228,6 +228,24 @@ namespace Obfuz.Data
return new RvaData(field.runtimeValueField, offset, value.Length); return new RvaData(field.runtimeValueField, offset, value.Length);
} }
private void AddVerifyCodes(IList<Instruction> insts, DefaultMetadataImporter importer)
{
int verifyIntValue = 0x12345678;
IRandom verifyRandom = _encryptionScope.localRandomCreator(verifyIntValue);
int verifyOps = EncryptionUtil.GenerateEncryptionOpCodes(verifyRandom, _encryptionScope.encryptor, 4);
int verifySalt = verifyRandom.NextInt();
int encryptedVerifyIntValue = _encryptionScope.encryptor.Encrypt(verifyIntValue, verifyOps, verifySalt);
insts.Add(Instruction.Create(OpCodes.Ldc_I4, verifyIntValue));
insts.Add(Instruction.CreateLdcI4(encryptedVerifyIntValue));
insts.Add(Instruction.CreateLdcI4(verifyOps));
insts.Add(Instruction.CreateLdcI4(verifySalt));
insts.Add(Instruction.Create(OpCodes.Call, importer.DecryptInt));
insts.Add(Instruction.Create(OpCodes.Call, importer.VerifySecretKey));
}
private void CreateCCtorOfRvaTypeDef() private void CreateCCtorOfRvaTypeDef()
{ {
if (_rvaTypeDef == null) if (_rvaTypeDef == null)
@ -246,6 +264,7 @@ namespace Obfuz.Data
var ins = body.Instructions; var ins = body.Instructions;
DefaultMetadataImporter importer = _moduleEntityManager.GetDefaultModuleMetadataImporter(mod, _encryptionScopeProvider); DefaultMetadataImporter importer = _moduleEntityManager.GetDefaultModuleMetadataImporter(mod, _encryptionScopeProvider);
AddVerifyCodes(ins, importer);
foreach (var field in _rvaFields) foreach (var field in _rvaFields)
{ {
// ldc // ldc
@ -260,7 +279,7 @@ namespace Obfuz.Data
ins.Add(Instruction.Create(OpCodes.Dup)); ins.Add(Instruction.Create(OpCodes.Dup));
ins.Add(Instruction.Create(OpCodes.Stsfld, field.runtimeValueField)); ins.Add(Instruction.Create(OpCodes.Stsfld, field.runtimeValueField));
ins.Add(Instruction.Create(OpCodes.Ldtoken, field.holderDataField)); ins.Add(Instruction.Create(OpCodes.Ldtoken, field.holderDataField));
ins.Add(Instruction.Create(OpCodes.Call, importer.InitializedArrayMethod)); ins.Add(Instruction.Create(OpCodes.Call, importer.InitializedArray));
// EncryptionService.DecryptBlock(array, field.encryptionOps, field.salt); // EncryptionService.DecryptBlock(array, field.encryptionOps, field.salt);
ins.Add(Instruction.CreateLdcI4(field.encryptionOps)); ins.Add(Instruction.CreateLdcI4(field.encryptionOps));

View File

@ -134,6 +134,8 @@ namespace Obfuz.Emit
_initializeArray = mod.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("InitializeArray", new[] { typeof(Array), typeof(RuntimeFieldHandle) })); _initializeArray = mod.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("InitializeArray", new[] { typeof(Array), typeof(RuntimeFieldHandle) }));
Assert.IsNotNull(_initializeArray); Assert.IsNotNull(_initializeArray);
_verifySecretKey = mod.Import(typeof(AssetUtility).GetMethod("VerifySecretKey", new[] { typeof(int), typeof(int) }));
Assert.IsNotNull(_verifySecretKey, "VerifySecretKey not found");
_staticDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultStaticEncryptionScope>)); _staticDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultStaticEncryptionScope>));
_dynamicDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultDynamicEncryptionScope>)); _dynamicDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultDynamicEncryptionScope>));
@ -158,13 +160,16 @@ namespace Obfuz.Emit
private IMethod _castFloatAsInt; private IMethod _castFloatAsInt;
private IMethod _castDoubleAsLong; private IMethod _castDoubleAsLong;
private IMethod _initializeArray; private IMethod _initializeArray;
private IMethod _verifySecretKey;
public IMethod CastIntAsFloat => _castIntAsFloat; public IMethod CastIntAsFloat => _castIntAsFloat;
public IMethod CastLongAsDouble => _castLongAsDouble; public IMethod CastLongAsDouble => _castLongAsDouble;
public IMethod CastFloatAsInt => _castFloatAsInt; public IMethod CastFloatAsInt => _castFloatAsInt;
public IMethod CastDoubleAsLong => _castDoubleAsLong; public IMethod CastDoubleAsLong => _castDoubleAsLong;
public IMethod InitializedArrayMethod => _initializeArray; public IMethod InitializedArray => _initializeArray;
public IMethod VerifySecretKey => _verifySecretKey;
public IMethod EncryptBlock => _defaultEncryptionServiceMetadataImporter.EncryptBlock; public IMethod EncryptBlock => _defaultEncryptionServiceMetadataImporter.EncryptBlock;
public IMethod DecryptBlock => _defaultEncryptionServiceMetadataImporter.DecryptBlock; public IMethod DecryptBlock => _defaultEncryptionServiceMetadataImporter.DecryptBlock;

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz
{
public static class AssetUtility
{
public static void VerifySecretKey(int expectedValue, int actualValue)
{
if (expectedValue != actualValue)
{
throw new Exception($"VerifySecretKey failed. Your secret key is unmatched with secret key used by current assembly in obfuscation");
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 72fb691c46a883f4ea3b3dfe7d2280f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: