obfuz/Editor/Emit/MetadataImporter.cs

123 lines
4.5 KiB
C#
Raw Normal View History

2025-05-01 12:23:22 +08:00
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine.Assertions;
namespace Obfuz.Emit
{
2025-05-07 19:39:09 +08:00
public interface IModuleMetadataImporter
2025-05-01 12:23:22 +08:00
{
2025-05-07 19:39:09 +08:00
void Init(ModuleDef mod);
}
2025-05-01 12:23:22 +08:00
2025-05-07 19:39:09 +08:00
public abstract class ModuleMetadataImporterBase : IModuleMetadataImporter
{
public abstract void Init(ModuleDef mod);
}
2025-05-01 12:23:22 +08:00
2025-05-07 19:39:09 +08:00
public class DefaultModuleMetadataImporter : ModuleMetadataImporterBase
{
public override void Init(ModuleDef mod)
2025-05-01 12:23:22 +08:00
{
2025-05-07 19:39:09 +08:00
_module = mod;
2025-05-01 12:23:22 +08:00
var constUtilityType = typeof(ConstUtility);
2025-05-07 19:39:09 +08:00
_castIntAsFloat = mod.Import(constUtilityType.GetMethod("CastIntAsFloat"));
Assert.IsNotNull(_castIntAsFloat, "CastIntAsFloat not found");
_castLongAsDouble = mod.Import(constUtilityType.GetMethod("CastLongAsDouble"));
Assert.IsNotNull(_castLongAsDouble, "CastLongAsDouble not found");
_castFloatAsInt = mod.Import(constUtilityType.GetMethod("CastFloatAsInt"));
Assert.IsNotNull(_castFloatAsInt, "CastFloatAsInt not found");
_castDoubleAsLong = mod.Import(constUtilityType.GetMethod("CastDoubleAsLong"));
Assert.IsNotNull(_castDoubleAsLong, "CastDoubleAsLong not found");
2025-05-01 12:23:22 +08:00
2025-05-07 19:39:09 +08:00
_initializeArray = mod.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("InitializeArray", new[] { typeof(Array), typeof(RuntimeFieldHandle) }));
Assert.IsNotNull(_initializeArray);
_encryptBlock = mod.Import(typeof(EncryptionService).GetMethod("EncryptBlock", new[] { typeof(byte[]), typeof(long), typeof(int) }));
Assert.IsNotNull(_encryptBlock);
_decryptBlock = mod.Import(typeof(EncryptionService).GetMethod("DecryptBlock", new[] { typeof(byte[]), typeof(long), typeof(int) }));
Assert.IsNotNull(_decryptBlock);
2025-05-01 12:23:22 +08:00
}
2025-05-07 19:39:09 +08:00
private ModuleDef _module;
private IMethod _castIntAsFloat;
private IMethod _castLongAsDouble;
private IMethod _castFloatAsInt;
private IMethod _castDoubleAsLong;
private IMethod _initializeArray;
private IMethod _encryptBlock;
private IMethod _decryptBlock;
2025-05-01 12:23:22 +08:00
2025-05-07 19:39:09 +08:00
public IMethod CastIntAsFloat => _castIntAsFloat;
2025-05-01 12:23:22 +08:00
2025-05-07 19:39:09 +08:00
public IMethod CastLongAsDouble => _castLongAsDouble;
public IMethod CastFloatAsInt => _castFloatAsInt;
public IMethod CastDoubleAsLong => _castDoubleAsLong;
public IMethod InitializedArrayMethod => _initializeArray;
public IMethod EncryptBlock => _encryptBlock;
public IMethod DecryptBlock => _decryptBlock;
2025-05-01 12:23:22 +08:00
}
public class MetadataImporter
{
2025-05-07 19:39:09 +08:00
private readonly Dictionary<(ModuleDef, Type), IModuleMetadataImporter> _customModuleMetadataImporters = new Dictionary<(ModuleDef, Type), IModuleMetadataImporter>();
2025-05-01 12:23:22 +08:00
public static MetadataImporter Instance { get; private set; }
public static void Reset()
{
Instance = new MetadataImporter();
}
2025-05-07 19:39:09 +08:00
public DefaultModuleMetadataImporter GetDefaultModuleMetadataImporter(ModuleDef module)
{
return GetCustomModuleMetadataImporter<DefaultModuleMetadataImporter>(module);
}
public List<DefaultModuleMetadataImporter> GetDefaultModuleMetadataImporters()
{
return GetCustomModuleMetadataImporters<DefaultModuleMetadataImporter>();
}
public T GetCustomModuleMetadataImporter<T>(ModuleDef module, Func<ModuleDef, T> creator = null) where T : IModuleMetadataImporter
{
var key = (module, typeof(T));
if (!_customModuleMetadataImporters.TryGetValue(key, out var importer))
{
if (creator != null)
{
importer = creator(module);
}
else
{
importer = (IModuleMetadataImporter)Activator.CreateInstance(typeof(T), module);
}
importer.Init(module);
_customModuleMetadataImporters[key] = importer;
}
return (T)importer;
}
public List<T> GetCustomModuleMetadataImporters<T>()
2025-05-01 12:23:22 +08:00
{
2025-05-07 19:39:09 +08:00
var result = new List<T>();
foreach (var kvp in _customModuleMetadataImporters)
2025-05-01 12:23:22 +08:00
{
2025-05-07 19:39:09 +08:00
if (kvp.Key.Item2 == typeof(T))
{
result.Add((T)kvp.Value);
}
2025-05-01 12:23:22 +08:00
}
2025-05-07 19:39:09 +08:00
return result;
2025-05-01 12:23:22 +08:00
}
}
}