diff --git a/Torch/Managers/PatchManager/AssemblyMemory.cs b/Torch/Managers/PatchManager/AssemblyMemory.cs index 0998384..4504993 100644 --- a/Torch/Managers/PatchManager/AssemblyMemory.cs +++ b/Torch/Managers/PatchManager/AssemblyMemory.cs @@ -3,11 +3,17 @@ using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Torch.Utils; namespace Torch.Managers.PatchManager { internal class AssemblyMemory { +#pragma warning disable 649 + [ReflectedMethod(Name = "GetMethodDescriptor")] + private static Func _getMethodHandle; +#pragma warning restore 649 + /// /// Gets the address, in RAM, where the body of a method starts. /// @@ -16,9 +22,8 @@ namespace Torch.Managers.PatchManager public static long GetMethodBodyStart(MethodBase method) { RuntimeMethodHandle handle; - if (method is DynamicMethod) - handle = (RuntimeMethodHandle)typeof(DynamicMethod).GetMethod("GetMethodDescriptor", BindingFlags.NonPublic | BindingFlags.Instance) - .Invoke(method, new object[0]); + if (method is DynamicMethod dyn) + handle = _getMethodHandle.Invoke(dyn); else handle = method.MethodHandle; RuntimeHelpers.PrepareMethod(handle); diff --git a/Torch/Managers/PatchManager/DecoratedMethod.cs b/Torch/Managers/PatchManager/DecoratedMethod.cs index 326f004..75d09ff 100644 --- a/Torch/Managers/PatchManager/DecoratedMethod.cs +++ b/Torch/Managers/PatchManager/DecoratedMethod.cs @@ -8,6 +8,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using NLog; using Torch.Managers.PatchManager.Transpile; +using Torch.Utils; namespace Torch.Managers.PatchManager { @@ -76,21 +77,25 @@ namespace Torch.Managers.PatchManager private const string INSTANCE_PARAMETER = "__instance"; private const string RESULT_PARAMETER = "__result"; +#pragma warning disable 649 + [ReflectedStaticMethod(Type = typeof(RuntimeHelpers), Name = "_CompileMethod", OverrideTypeNames = new[] { "System.IRuntimeMethodInfo" })] + private static Action _compileDynamicMethod; + [ReflectedMethod(Name = "GetMethodInfo")] + private static Func _getMethodInfo; + [ReflectedMethod(Name = "GetMethodDescriptor")] + private static Func _getMethodHandle; +#pragma warning restore 649 + public DynamicMethod ComposePatchedMethod() { - var method = AllocatePatchMethod(); + DynamicMethod method = AllocatePatchMethod(); var generator = new LoggingIlGenerator(method.GetILGenerator()); EmitPatched(generator); // Force it to compile - const BindingFlags nonPublicInstance = BindingFlags.NonPublic | BindingFlags.Instance; - const BindingFlags nonPublicStatic = BindingFlags.NonPublic | BindingFlags.Static; - var compileMethod = typeof(RuntimeHelpers).GetMethod("_CompileMethod", nonPublicStatic); - var getMethodDescriptor = typeof(DynamicMethod).GetMethod("GetMethodDescriptor", nonPublicInstance); - var handle = (RuntimeMethodHandle)getMethodDescriptor.Invoke(method, new object[0]); - var getMethodInfo = typeof(RuntimeMethodHandle).GetMethod("GetMethodInfo", nonPublicInstance); - var runtimeMethodInfo = getMethodInfo.Invoke(handle, new object[0]); - compileMethod.Invoke(null, new[] { runtimeMethodInfo }); + RuntimeMethodHandle handle = _getMethodHandle.Invoke(method); + object runtimeMethodInfo = _getMethodInfo.Invoke(handle); + _compileDynamicMethod.Invoke(runtimeMethodInfo); return method; } #endregion