新增 ObfuscationTypeMapper及相应的Instinct函数RegisterReflectionType

1.x
walon 2025-06-10 13:56:05 +08:00
parent 3867a98d48
commit a109511f9e
5 changed files with 116 additions and 1 deletions

View File

@ -1,5 +1,6 @@
using dnlib.DotNet;
using System;
using System.Reflection;
using UnityEngine.Assertions;
namespace Obfuz.Emit
@ -143,6 +144,9 @@ namespace Obfuz.Emit
_verifySecretKey = mod.Import(typeof(AssetUtility).GetMethod("VerifySecretKey", new[] { typeof(int), typeof(int) }));
Assert.IsNotNull(_verifySecretKey, "VerifySecretKey not found");
_obfuscationTypeMapperRegisterType = mod.Import(typeof(ObfuscationTypeMapper).GetMethod("RegisterType", 1, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null));
Assert.IsNotNull(_obfuscationTypeMapperRegisterType, "ObfuscationTypeMapper.RegisterType not found");
_staticDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultStaticEncryptionScope>));
_dynamicDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultDynamicEncryptionScope>));
if (_encryptionScopeProvider.IsDynamicSecretAssembly(mod))
@ -168,6 +172,8 @@ namespace Obfuz.Emit
private IMethod _initializeArray;
private IMethod _verifySecretKey;
private IMethod _obfuscationTypeMapperRegisterType;
public IMethod CastIntAsFloat => _castIntAsFloat;
public IMethod CastLongAsDouble => _castLongAsDouble;
public IMethod CastFloatAsInt => _castFloatAsInt;
@ -177,6 +183,8 @@ namespace Obfuz.Emit
public IMethod VerifySecretKey => _verifySecretKey;
public IMethod ObfuscationTypeMapperRegisterType => _obfuscationTypeMapperRegisterType;
public IMethod EncryptBlock => _defaultEncryptionServiceMetadataImporter.EncryptBlock;
public IMethod DecryptBlock => _defaultEncryptionServiceMetadataImporter.DecryptBlock;

View File

@ -25,7 +25,6 @@ namespace Obfuz.ObfusPasses.Instinct
public override void Start()
{
var ctx = ObfuscationPassContext.Current;
}
public override void Stop()
@ -92,11 +91,15 @@ namespace Obfuz.ObfusPasses.Instinct
return false;
}
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
var importer = ctx.moduleEntityManager.GetDefaultModuleMetadataImporter(callingMethod.Module, ctx.encryptionScopeProvider);
string methodName = methodDef.Name;
switch (methodName)
{
case "FullNameOf":
case "NameOf":
case "RegisterReflectionType":
{
MethodSpec methodSpec = (MethodSpec)method;
GenericInstMethodSig gims = methodSpec.GenericInstMethodSig;
@ -116,6 +119,14 @@ namespace Obfuz.ObfusPasses.Instinct
outputInstructions.Add(Instruction.Create(OpCodes.Ldstr, typeName));
break;
}
case "RegisterReflectionType":
{
string typeFullName = GetTypeFullName(type);
outputInstructions.Add(Instruction.Create(OpCodes.Ldstr, typeFullName));
var finalMethod = new MethodSpecUser((IMethodDefOrRef)importer.ObfuscationTypeMapperRegisterType, gims);
outputInstructions.Add(Instruction.Create(OpCodes.Call, finalMethod));
break;
}
default: throw new NotSupportedException($"Unsupported instinct method: {methodDef.FullName}");
}
break;

View File

@ -27,5 +27,14 @@ namespace Obfuz
{
return typeof(T).Name;
}
/// <summary>
/// register original type name to type mapping.
/// </summary>
/// <typeparam name="T"></typeparam>
public static void RegisterReflectionType<T>()
{
ObfuscationTypeMapper.RegisterType<T>(typeof(T).FullName);
}
}
}

View File

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz
{
public static class ObfuscationTypeMapper
{
private static readonly Dictionary<Type, string> _type2OriginalFullName = new Dictionary<Type, string>();
private static readonly Dictionary<Assembly, Dictionary<string, Type>> _originalFullName2Types = new Dictionary<Assembly, Dictionary<string, Type>>();
internal static void RegisterType<T>(string originalFullName)
{
RegisterType(typeof(T), originalFullName);
}
internal static void RegisterType(Type type, string originalFullName)
{
if (_type2OriginalFullName.ContainsKey(type))
{
throw new ArgumentException($"Type '{type.FullName}' is already registered with original name '{_type2OriginalFullName[type]}'.");
}
_type2OriginalFullName.Add(type, originalFullName);
Assembly assembly = type.Assembly;
if (!_originalFullName2Types.TryGetValue(assembly, out var originalFullName2Types))
{
originalFullName2Types = new Dictionary<string, Type>();
_originalFullName2Types[assembly] = originalFullName2Types;
}
if (originalFullName2Types.ContainsKey(originalFullName))
{
throw new ArgumentException($"Original full name '{originalFullName}' is already registered with type '{originalFullName2Types[originalFullName].FullName}'.");
}
originalFullName2Types.Add(originalFullName, type);
}
public static string GetOriginalTypeFullName(Type type)
{
return _type2OriginalFullName.TryGetValue(type, out string originalFullName)
? originalFullName
: throw new KeyNotFoundException($"Type '{type.FullName}' not found in the obfuscation mapping.");
}
public static string GetOriginalTypeFullNameOrCurrent(Type type)
{
if (_type2OriginalFullName.TryGetValue(type, out string originalFullName))
{
return originalFullName;
}
return type.FullName;
}
public static Type GetTypeByOriginalFullName(Assembly assembly, string originalFullName)
{
if (_originalFullName2Types.TryGetValue(assembly, out var n2t))
{
if (n2t.TryGetValue(originalFullName, out Type type))
{
return type;
}
}
return null;
}
public static void Clear()
{
_type2OriginalFullName.Clear();
_originalFullName2Types.Clear();
}
}
}

View File

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