From c0954035da25d040ff32b24eefb46fa3e4fed512 Mon Sep 17 00:00:00 2001 From: Soreepeong Date: Fri, 10 Mar 2023 13:12:54 +0900 Subject: [PATCH] Fail fast on trying to dispose import hook that has been overwritten by something else --- .../Internal/FunctionPointerVariableHook.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Dalamud/Hooking/Internal/FunctionPointerVariableHook.cs b/Dalamud/Hooking/Internal/FunctionPointerVariableHook.cs index 3272f50b3..80bd65cf6 100644 --- a/Dalamud/Hooking/Internal/FunctionPointerVariableHook.cs +++ b/Dalamud/Hooking/Internal/FunctionPointerVariableHook.cs @@ -13,10 +13,12 @@ namespace Dalamud.Hooking.Internal; /// Delegate type to represents a function prototype. This must be the same prototype as original function do. internal class FunctionPointerVariableHook : Hook where T : Delegate { - private readonly IntPtr pfnOriginal; - private readonly T originalDelegate; + private readonly nint pfnDetour; private readonly T detourDelegate; + private nint pfnOriginal; + private T? originalDelegate; + private bool enabled = false; /// @@ -40,9 +42,8 @@ internal class FunctionPointerVariableHook : Hook where T : Delegate if (!HookManager.MultiHookTracker.TryGetValue(this.Address, out var indexList)) indexList = HookManager.MultiHookTracker[this.Address] = new(); - this.pfnOriginal = Marshal.ReadIntPtr(this.Address); - this.originalDelegate = Marshal.GetDelegateForFunctionPointer(this.pfnOriginal); this.detourDelegate = detour; + this.pfnDetour = Marshal.GetFunctionPointerForDelegate(detour); // Add afterwards, so the hookIdent starts at 0. indexList.Add(this); @@ -100,7 +101,10 @@ internal class FunctionPointerVariableHook : Hook where T : Delegate if (!NativeFunctions.VirtualProtect(this.Address, (UIntPtr)Marshal.SizeOf(), MemoryProtection.ExecuteReadWrite, out var oldProtect)) throw new Win32Exception(Marshal.GetLastWin32Error()); - Marshal.WriteIntPtr(this.Address, Marshal.GetFunctionPointerForDelegate(this.detourDelegate)); + this.pfnOriginal = Marshal.ReadIntPtr(this.Address); + this.originalDelegate = Marshal.GetDelegateForFunctionPointer(this.pfnOriginal); + Marshal.WriteIntPtr(this.Address, this.pfnDetour); + NativeFunctions.VirtualProtect(this.Address, (UIntPtr)Marshal.SizeOf(), oldProtect, out _); } } @@ -118,6 +122,9 @@ internal class FunctionPointerVariableHook : Hook where T : Delegate if (!NativeFunctions.VirtualProtect(this.Address, (UIntPtr)Marshal.SizeOf(), MemoryProtection.ExecuteReadWrite, out var oldProtect)) throw new Win32Exception(Marshal.GetLastWin32Error()); + if (Marshal.ReadIntPtr(this.Address) != this.pfnOriginal) + Environment.FailFast("Cannot disable this hook in a sane manner."); + Marshal.WriteIntPtr(this.Address, this.pfnOriginal); NativeFunctions.VirtualProtect(this.Address, (UIntPtr)Marshal.SizeOf(), oldProtect, out _); }