新增 ObfuscationTypeMapper及相应的Instinct函数RegisterReflectionType
parent
3867a98d48
commit
a109511f9e
|
@ -1,5 +1,6 @@
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
|
||||||
namespace Obfuz.Emit
|
namespace Obfuz.Emit
|
||||||
|
@ -143,6 +144,9 @@ namespace Obfuz.Emit
|
||||||
_verifySecretKey = mod.Import(typeof(AssetUtility).GetMethod("VerifySecretKey", new[] { typeof(int), typeof(int) }));
|
_verifySecretKey = mod.Import(typeof(AssetUtility).GetMethod("VerifySecretKey", new[] { typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_verifySecretKey, "VerifySecretKey not found");
|
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>));
|
_staticDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultStaticEncryptionScope>));
|
||||||
_dynamicDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultDynamicEncryptionScope>));
|
_dynamicDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultDynamicEncryptionScope>));
|
||||||
if (_encryptionScopeProvider.IsDynamicSecretAssembly(mod))
|
if (_encryptionScopeProvider.IsDynamicSecretAssembly(mod))
|
||||||
|
@ -168,6 +172,8 @@ namespace Obfuz.Emit
|
||||||
private IMethod _initializeArray;
|
private IMethod _initializeArray;
|
||||||
private IMethod _verifySecretKey;
|
private IMethod _verifySecretKey;
|
||||||
|
|
||||||
|
private IMethod _obfuscationTypeMapperRegisterType;
|
||||||
|
|
||||||
public IMethod CastIntAsFloat => _castIntAsFloat;
|
public IMethod CastIntAsFloat => _castIntAsFloat;
|
||||||
public IMethod CastLongAsDouble => _castLongAsDouble;
|
public IMethod CastLongAsDouble => _castLongAsDouble;
|
||||||
public IMethod CastFloatAsInt => _castFloatAsInt;
|
public IMethod CastFloatAsInt => _castFloatAsInt;
|
||||||
|
@ -177,6 +183,8 @@ namespace Obfuz.Emit
|
||||||
|
|
||||||
public IMethod VerifySecretKey => _verifySecretKey;
|
public IMethod VerifySecretKey => _verifySecretKey;
|
||||||
|
|
||||||
|
public IMethod ObfuscationTypeMapperRegisterType => _obfuscationTypeMapperRegisterType;
|
||||||
|
|
||||||
public IMethod EncryptBlock => _defaultEncryptionServiceMetadataImporter.EncryptBlock;
|
public IMethod EncryptBlock => _defaultEncryptionServiceMetadataImporter.EncryptBlock;
|
||||||
public IMethod DecryptBlock => _defaultEncryptionServiceMetadataImporter.DecryptBlock;
|
public IMethod DecryptBlock => _defaultEncryptionServiceMetadataImporter.DecryptBlock;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ namespace Obfuz.ObfusPasses.Instinct
|
||||||
|
|
||||||
public override void Start()
|
public override void Start()
|
||||||
{
|
{
|
||||||
var ctx = ObfuscationPassContext.Current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop()
|
public override void Stop()
|
||||||
|
@ -92,11 +91,15 @@ namespace Obfuz.ObfusPasses.Instinct
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
||||||
|
var importer = ctx.moduleEntityManager.GetDefaultModuleMetadataImporter(callingMethod.Module, ctx.encryptionScopeProvider);
|
||||||
|
|
||||||
string methodName = methodDef.Name;
|
string methodName = methodDef.Name;
|
||||||
switch (methodName)
|
switch (methodName)
|
||||||
{
|
{
|
||||||
case "FullNameOf":
|
case "FullNameOf":
|
||||||
case "NameOf":
|
case "NameOf":
|
||||||
|
case "RegisterReflectionType":
|
||||||
{
|
{
|
||||||
MethodSpec methodSpec = (MethodSpec)method;
|
MethodSpec methodSpec = (MethodSpec)method;
|
||||||
GenericInstMethodSig gims = methodSpec.GenericInstMethodSig;
|
GenericInstMethodSig gims = methodSpec.GenericInstMethodSig;
|
||||||
|
@ -116,6 +119,14 @@ namespace Obfuz.ObfusPasses.Instinct
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Ldstr, typeName));
|
outputInstructions.Add(Instruction.Create(OpCodes.Ldstr, typeName));
|
||||||
break;
|
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}");
|
default: throw new NotSupportedException($"Unsupported instinct method: {methodDef.FullName}");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -27,5 +27,14 @@ namespace Obfuz
|
||||||
{
|
{
|
||||||
return typeof(T).Name;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: db6168acedd85984fa2c197fee1b0c15
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue