From e1da238cb580fb030933ced4fb1a4a7e7c2d33a9 Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 6 Aug 2023 20:58:55 +0200 Subject: [PATCH 1/8] feat: IHookProvider service, no more static hook creation --- Dalamud/Hooking/Hook.cs | 54 +++++----- Dalamud/Hooking/IDalamudHook.cs | 2 +- .../Internal/HookProviderPluginScoped.cs | 99 +++++++++++++++++++ Dalamud/Plugin/Services/IHookProvider.cs | 97 ++++++++++++++++++ Dalamud/Utility/Signatures/SignatureHelper.cs | 20 ++-- 5 files changed, 238 insertions(+), 34 deletions(-) create mode 100644 Dalamud/Hooking/Internal/HookProviderPluginScoped.cs create mode 100644 Dalamud/Plugin/Services/IHookProvider.cs diff --git a/Dalamud/Hooking/Hook.cs b/Dalamud/Hooking/Hook.cs index 2e785191c..da65fedc7 100644 --- a/Dalamud/Hooking/Hook.cs +++ b/Dalamud/Hooking/Hook.cs @@ -12,7 +12,7 @@ namespace Dalamud.Hooking; /// This class is basically a thin wrapper around the LocalHook type to provide helper functions. /// /// Delegate type to represents a function prototype. This must be the same prototype as original function do. -public abstract class Hook : IDisposable, IDalamudHook where T : Delegate +public abstract class Hook : IDalamudHook where T : Delegate { #pragma warning disable SA1310 // ReSharper disable once InconsistentNaming @@ -70,6 +70,27 @@ public abstract class Hook : IDisposable, IDalamudHook where T : Delegate /// public virtual string BackendName => throw new NotImplementedException(); + + /// + /// Remove a hook from the current process. + /// + public virtual void Dispose() + { + if (this.IsDisposed) + return; + + this.IsDisposed = true; + } + + /// + /// Starts intercepting a call to the function. + /// + public virtual void Enable() => throw new NotImplementedException(); + + /// + /// Stops intercepting a call to the function. + /// + public virtual void Disable() => throw new NotImplementedException(); /// /// Creates a hook by rewriting import table address. @@ -77,7 +98,7 @@ public abstract class Hook : IDisposable, IDalamudHook where T : Delegate /// A memory address to install a hook. /// Callback function. Delegate must have a same original function prototype. /// The hook with the supplied parameters. - public static unsafe Hook FromFunctionPointerVariable(IntPtr address, T detour) + internal static Hook FromFunctionPointerVariable(IntPtr address, T detour) { return new FunctionPointerVariableHook(address, detour, Assembly.GetCallingAssembly()); } @@ -91,7 +112,7 @@ public abstract class Hook : IDisposable, IDalamudHook where T : Delegate /// Hint or ordinal. 0 to unspecify. /// Callback function. Delegate must have a same original function prototype. /// The hook with the supplied parameters. - public static unsafe Hook FromImport(ProcessModule? module, string moduleName, string functionName, uint hintOrOrdinal, T detour) + internal static unsafe Hook FromImport(ProcessModule? module, string moduleName, string functionName, uint hintOrOrdinal, T detour) { module ??= Process.GetCurrentProcess().MainModule; if (module == null) @@ -156,7 +177,7 @@ public abstract class Hook : IDisposable, IDalamudHook where T : Delegate /// A name of the exported function name (e.g. send). /// Callback function. Delegate must have a same original function prototype. /// The hook with the supplied parameters. - public static Hook FromSymbol(string moduleName, string exportName, T detour) + internal static Hook FromSymbol(string moduleName, string exportName, T detour) => FromSymbol(moduleName, exportName, detour, false); /// @@ -169,7 +190,7 @@ public abstract class Hook : IDisposable, IDalamudHook where T : Delegate /// Callback function. Delegate must have a same original function prototype. /// Use the MinHook hooking library instead of Reloaded. /// The hook with the supplied parameters. - public static Hook FromSymbol(string moduleName, string exportName, T detour, bool useMinHook) + internal static Hook FromSymbol(string moduleName, string exportName, T detour, bool useMinHook) { if (EnvironmentConfiguration.DalamudForceMinHook) useMinHook = true; @@ -198,7 +219,7 @@ public abstract class Hook : IDisposable, IDalamudHook where T : Delegate /// Callback function. Delegate must have a same original function prototype. /// Use the MinHook hooking library instead of Reloaded. /// The hook with the supplied parameters. - public static Hook FromAddress(IntPtr procAddress, T detour, bool useMinHook = false) + internal static Hook FromAddress(IntPtr procAddress, T detour, bool useMinHook = false) { if (EnvironmentConfiguration.DalamudForceMinHook) useMinHook = true; @@ -210,27 +231,6 @@ public abstract class Hook : IDisposable, IDalamudHook where T : Delegate return new ReloadedHook(procAddress, detour, Assembly.GetCallingAssembly()); } - /// - /// Remove a hook from the current process. - /// - public virtual void Dispose() - { - if (this.IsDisposed) - return; - - this.IsDisposed = true; - } - - /// - /// Starts intercepting a call to the function. - /// - public virtual void Enable() => throw new NotImplementedException(); - - /// - /// Stops intercepting a call to the function. - /// - public virtual void Disable() => throw new NotImplementedException(); - /// /// Check if this object has been disposed already. /// diff --git a/Dalamud/Hooking/IDalamudHook.cs b/Dalamud/Hooking/IDalamudHook.cs index 1104597a1..bd7084d86 100644 --- a/Dalamud/Hooking/IDalamudHook.cs +++ b/Dalamud/Hooking/IDalamudHook.cs @@ -5,7 +5,7 @@ namespace Dalamud.Hooking; /// /// Interface describing a generic hook. /// -public interface IDalamudHook +public interface IDalamudHook : IDisposable { /// /// Gets the address to hook. diff --git a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs b/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs new file mode 100644 index 000000000..fa4497799 --- /dev/null +++ b/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs @@ -0,0 +1,99 @@ +using System.Collections.Concurrent; +using System.Diagnostics; +using System.Linq; + +using Dalamud.Game; +using Dalamud.IoC; +using Dalamud.IoC.Internal; +using Dalamud.Plugin.Internal.Types; +using Dalamud.Plugin.Services; +using Dalamud.Utility.Signatures; +using Serilog; + +namespace Dalamud.Hooking.Internal; + +/// +/// Plugin-scoped version of a texture manager. +/// +[PluginInterface] +[InterfaceVersion("1.0")] +[ServiceManager.ScopedService] +#pragma warning disable SA1015 +[ResolveVia] +#pragma warning restore SA1015 +internal class HookProviderPluginScoped : IHookProvider, IServiceType, IDisposable +{ + private readonly LocalPlugin plugin; + private readonly SigScanner scanner; + + private readonly ConcurrentBag trackedHooks = new(); + + /// + /// Initializes a new instance of the class. + /// + /// Plugin this instance belongs to. + /// SigScanner instance for target module. + public HookProviderPluginScoped(LocalPlugin plugin, SigScanner scanner) + { + this.plugin = plugin; + this.scanner = scanner; + } + + /// + public void InitializeFromAttributes(object self) + { + foreach (var hook in SignatureHelper.Initialise(self)) + this.trackedHooks.Add(hook); + } + + /// + public Hook FromFunctionPointerVariable(IntPtr address, T detour) where T : Delegate + { + var hook = Hook.FromFunctionPointerVariable(address, detour); + this.trackedHooks.Add(hook); + return hook; + } + + /// + public Hook FromImport(ProcessModule? module, string moduleName, string functionName, uint hintOrOrdinal, T detour) where T : Delegate + { + var hook = Hook.FromImport(module, moduleName, functionName, hintOrOrdinal, detour); + this.trackedHooks.Add(hook); + return hook; + } + + /// + public Hook FromSymbol(string moduleName, string exportName, T detour, IHookProvider.HookBackend backend = IHookProvider.HookBackend.Automatic) where T : Delegate + { + var hook = Hook.FromSymbol(moduleName, exportName, detour, backend == IHookProvider.HookBackend.MinHook); + this.trackedHooks.Add(hook); + return hook; + } + + /// + public Hook FromAddress(IntPtr procAddress, T detour, IHookProvider.HookBackend backend = IHookProvider.HookBackend.Automatic) where T : Delegate + { + var hook = Hook.FromAddress(procAddress, detour, backend == IHookProvider.HookBackend.MinHook); + this.trackedHooks.Add(hook); + return hook; + } + + /// + public Hook FromSignature(string signature, T detour, IHookProvider.HookBackend backend = IHookProvider.HookBackend.Automatic) where T : Delegate + => this.FromAddress(this.scanner.ScanText(signature), detour); + + /// + public void Dispose() + { + var notDisposed = this.trackedHooks.Where(x => !x.IsDisposed).ToArray(); + if (notDisposed.Length != 0) + Log.Warning("{PluginName} is leaking {Num} hooks! Make sure that all of them are disposed properly.", this.plugin.InternalName, notDisposed.Length); + + foreach (var hook in notDisposed) + { + hook.Dispose(); + } + + this.trackedHooks.Clear(); + } +} diff --git a/Dalamud/Plugin/Services/IHookProvider.cs b/Dalamud/Plugin/Services/IHookProvider.cs new file mode 100644 index 000000000..dc7d29913 --- /dev/null +++ b/Dalamud/Plugin/Services/IHookProvider.cs @@ -0,0 +1,97 @@ +using System.Diagnostics; + +using Dalamud.Hooking; +using Dalamud.Utility.Signatures; + +namespace Dalamud.Plugin.Services; + +/// +/// Service responsible for the creation of hooks. +/// +public interface IHookProvider +{ + /// + /// Available hooking backends. + /// + public enum HookBackend + { + /// + /// Choose the best backend automatically. + /// + Automatic, + + /// + /// Use Reloaded hooks. + /// + Reloaded, + + /// + /// Use MinHook. + /// You should never have to use this without talking to us first. + /// + MinHook, + } + + /// + /// Initialize members decorated with the . + /// Errors for fallible signatures will be logged. + /// + /// The object to initialise. + public void InitializeFromAttributes(object self); + + /// + /// Creates a hook by rewriting import table address. + /// + /// A memory address to install a hook. + /// Callback function. Delegate must have a same original function prototype. + /// The hook with the supplied parameters. + /// Delegate of detour. + public Hook FromFunctionPointerVariable(IntPtr address, T detour) where T : Delegate; + + /// + /// Creates a hook by rewriting import table address. + /// + /// Module to check for. Current process' main module if null. + /// Name of the DLL, including the extension. + /// Decorated name of the function. + /// Hint or ordinal. 0 to unspecify. + /// Callback function. Delegate must have a same original function prototype. + /// The hook with the supplied parameters. + /// Delegate of detour. + public Hook FromImport(ProcessModule? module, string moduleName, string functionName, uint hintOrOrdinal, T detour) where T : Delegate; + + /// + /// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function. + /// The hook is not activated until Enable() method is called. + /// Please do not use MinHook unless you have thoroughly troubleshot why Reloaded does not work. + /// + /// A name of the module currently loaded in the memory. (e.g. ws2_32.dll). + /// A name of the exported function name (e.g. send). + /// Callback function. Delegate must have a same original function prototype. + /// Hooking library to use. + /// The hook with the supplied parameters. + /// Delegate of detour. + Hook FromSymbol(string moduleName, string exportName, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; + + /// + /// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function. + /// The hook is not activated until Enable() method is called. + /// Please do not use MinHook unless you have thoroughly troubleshot why Reloaded does not work. + /// + /// A memory address to install a hook. + /// Callback function. Delegate must have a same original function prototype. + /// Hooking library to use. + /// The hook with the supplied parameters. + /// Delegate of detour. + Hook FromAddress(IntPtr procAddress, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; + + /// + /// Creates a hook from a signature into the Dalamud target module. + /// + /// Signature of function to hook. + /// Callback function. Delegate must have a same original function prototype. + /// Hooking library to use. + /// The hook with the supplied parameters. + /// Delegate of detour. + Hook FromSignature(string signature, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; +} diff --git a/Dalamud/Utility/Signatures/SignatureHelper.cs b/Dalamud/Utility/Signatures/SignatureHelper.cs index bd99b8515..e133e5453 100755 --- a/Dalamud/Utility/Signatures/SignatureHelper.cs +++ b/Dalamud/Utility/Signatures/SignatureHelper.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; @@ -6,6 +7,7 @@ using System.Runtime.InteropServices; using Dalamud.Game; using Dalamud.Hooking; using Dalamud.Logging; +using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures.Wrappers; using Serilog; @@ -14,7 +16,7 @@ namespace Dalamud.Utility.Signatures; /// /// A utility class to help reduce signature boilerplate code. /// -public static class SignatureHelper +internal static class SignatureHelper { private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; @@ -24,7 +26,8 @@ public static class SignatureHelper /// /// The object to initialise. /// If warnings should be logged using . - public static void Initialise(object self, bool log = true) + /// Collection of created IDalamudHooks. + internal static IEnumerable Initialise(object self, bool log = true) { var scanner = Service.Get(); var selfType = self.GetType(); @@ -33,6 +36,8 @@ public static class SignatureHelper .Select(field => (field, field.GetCustomAttribute())) .Where(field => field.Item2 != null); + var createdHooks = new List(); + foreach (var (info, sig) in fields) { var wasWrapped = false; @@ -149,15 +154,16 @@ public static class SignatureHelper detour = del; } - var ctor = actualType.GetConstructor(new[] { typeof(IntPtr), hookDelegateType }); - if (ctor == null) + var creator = actualType.GetMethod("FromAddress", BindingFlags.Static | BindingFlags.NonPublic); + if (creator == null) { - Log.Error("Error in SignatureHelper: could not find Hook constructor"); + Log.Error("Error in SignatureHelper: could not find Hook creator"); continue; } - var hook = ctor.Invoke(new object?[] { ptr, detour }); + var hook = creator.Invoke(null, new object?[] { ptr, detour, IHookProvider.HookBackend.Automatic }) as IDalamudHook; info.SetValue(self, hook); + createdHooks.Add(hook); break; } @@ -182,5 +188,7 @@ public static class SignatureHelper } } } + + return createdHooks; } } From fe8ee19175df57334dd2e5aaea4899ea078c3a95 Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 6 Aug 2023 21:08:49 +0200 Subject: [PATCH 2/8] fix comment --- Dalamud/Hooking/Internal/HookProviderPluginScoped.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs b/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs index fa4497799..0e7ef4c7b 100644 --- a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs +++ b/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs @@ -13,7 +13,7 @@ using Serilog; namespace Dalamud.Hooking.Internal; /// -/// Plugin-scoped version of a texture manager. +/// Plugin-scoped version of service used to create hooks. /// [PluginInterface] [InterfaceVersion("1.0")] From 3f764d2e400bd585798f7e4ee58f6d4790573575 Mon Sep 17 00:00:00 2001 From: goat Date: Mon, 7 Aug 2023 23:57:31 +0200 Subject: [PATCH 3/8] pass on backend, spelling --- Dalamud/Hooking/Internal/HookProviderPluginScoped.cs | 4 ++-- Dalamud/Utility/Signatures/SignatureHelper.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs b/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs index 0e7ef4c7b..6fa700cef 100644 --- a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs +++ b/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs @@ -42,7 +42,7 @@ internal class HookProviderPluginScoped : IHookProvider, IServiceType, IDisposab /// public void InitializeFromAttributes(object self) { - foreach (var hook in SignatureHelper.Initialise(self)) + foreach (var hook in SignatureHelper.Initialize(self)) this.trackedHooks.Add(hook); } @@ -80,7 +80,7 @@ internal class HookProviderPluginScoped : IHookProvider, IServiceType, IDisposab /// public Hook FromSignature(string signature, T detour, IHookProvider.HookBackend backend = IHookProvider.HookBackend.Automatic) where T : Delegate - => this.FromAddress(this.scanner.ScanText(signature), detour); + => this.FromAddress(this.scanner.ScanText(signature), detour, backend); /// public void Dispose() diff --git a/Dalamud/Utility/Signatures/SignatureHelper.cs b/Dalamud/Utility/Signatures/SignatureHelper.cs index e133e5453..1cfd18330 100755 --- a/Dalamud/Utility/Signatures/SignatureHelper.cs +++ b/Dalamud/Utility/Signatures/SignatureHelper.cs @@ -27,7 +27,7 @@ internal static class SignatureHelper /// The object to initialise. /// If warnings should be logged using . /// Collection of created IDalamudHooks. - internal static IEnumerable Initialise(object self, bool log = true) + internal static IEnumerable Initialize(object self, bool log = true) { var scanner = Service.Get(); var selfType = self.GetType(); From f072a6fc40f710dbb30bbfe6b99360714053ee32 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 21 Sep 2023 21:47:06 +0200 Subject: [PATCH 4/8] Update Dalamud/Hooking/Internal/HookProviderPluginScoped.cs Co-authored-by: Haselnussbomber --- Dalamud/Hooking/Internal/HookProviderPluginScoped.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs b/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs index 0e7ef4c7b..0878bce28 100644 --- a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs +++ b/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs @@ -80,7 +80,7 @@ internal class HookProviderPluginScoped : IHookProvider, IServiceType, IDisposab /// public Hook FromSignature(string signature, T detour, IHookProvider.HookBackend backend = IHookProvider.HookBackend.Automatic) where T : Delegate - => this.FromAddress(this.scanner.ScanText(signature), detour); + => this.FromAddress(this.scanner.ScanText(signature), detour, backend); /// public void Dispose() From 173e9a3144d2ab93e9ee190da3fcb6694c6e84ec Mon Sep 17 00:00:00 2001 From: goat Date: Thu, 21 Sep 2023 22:07:09 +0200 Subject: [PATCH 5/8] IHookProvider => IGameInteropProvider --- ...d.cs => GameInteropProviderPluginScoped.cs} | 18 +++++++++--------- ...HookProvider.cs => IGameInteropProvider.cs} | 2 +- Dalamud/Utility/Signatures/SignatureHelper.cs | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) rename Dalamud/Hooking/Internal/{HookProviderPluginScoped.cs => GameInteropProviderPluginScoped.cs} (78%) rename Dalamud/Plugin/Services/{IHookProvider.cs => IGameInteropProvider.cs} (99%) diff --git a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs b/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs similarity index 78% rename from Dalamud/Hooking/Internal/HookProviderPluginScoped.cs rename to Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs index 6fa700cef..d6fc34b10 100644 --- a/Dalamud/Hooking/Internal/HookProviderPluginScoped.cs +++ b/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs @@ -19,9 +19,9 @@ namespace Dalamud.Hooking.Internal; [InterfaceVersion("1.0")] [ServiceManager.ScopedService] #pragma warning disable SA1015 -[ResolveVia] +[ResolveVia] #pragma warning restore SA1015 -internal class HookProviderPluginScoped : IHookProvider, IServiceType, IDisposable +internal class GameInteropProviderPluginScoped : IGameInteropProvider, IServiceType, IDisposable { private readonly LocalPlugin plugin; private readonly SigScanner scanner; @@ -29,11 +29,11 @@ internal class HookProviderPluginScoped : IHookProvider, IServiceType, IDisposab private readonly ConcurrentBag trackedHooks = new(); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Plugin this instance belongs to. /// SigScanner instance for target module. - public HookProviderPluginScoped(LocalPlugin plugin, SigScanner scanner) + public GameInteropProviderPluginScoped(LocalPlugin plugin, SigScanner scanner) { this.plugin = plugin; this.scanner = scanner; @@ -63,23 +63,23 @@ internal class HookProviderPluginScoped : IHookProvider, IServiceType, IDisposab } /// - public Hook FromSymbol(string moduleName, string exportName, T detour, IHookProvider.HookBackend backend = IHookProvider.HookBackend.Automatic) where T : Delegate + public Hook FromSymbol(string moduleName, string exportName, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate { - var hook = Hook.FromSymbol(moduleName, exportName, detour, backend == IHookProvider.HookBackend.MinHook); + var hook = Hook.FromSymbol(moduleName, exportName, detour, backend == IGameInteropProvider.HookBackend.MinHook); this.trackedHooks.Add(hook); return hook; } /// - public Hook FromAddress(IntPtr procAddress, T detour, IHookProvider.HookBackend backend = IHookProvider.HookBackend.Automatic) where T : Delegate + public Hook FromAddress(IntPtr procAddress, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate { - var hook = Hook.FromAddress(procAddress, detour, backend == IHookProvider.HookBackend.MinHook); + var hook = Hook.FromAddress(procAddress, detour, backend == IGameInteropProvider.HookBackend.MinHook); this.trackedHooks.Add(hook); return hook; } /// - public Hook FromSignature(string signature, T detour, IHookProvider.HookBackend backend = IHookProvider.HookBackend.Automatic) where T : Delegate + public Hook FromSignature(string signature, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate => this.FromAddress(this.scanner.ScanText(signature), detour, backend); /// diff --git a/Dalamud/Plugin/Services/IHookProvider.cs b/Dalamud/Plugin/Services/IGameInteropProvider.cs similarity index 99% rename from Dalamud/Plugin/Services/IHookProvider.cs rename to Dalamud/Plugin/Services/IGameInteropProvider.cs index dc7d29913..9451a60eb 100644 --- a/Dalamud/Plugin/Services/IHookProvider.cs +++ b/Dalamud/Plugin/Services/IGameInteropProvider.cs @@ -8,7 +8,7 @@ namespace Dalamud.Plugin.Services; /// /// Service responsible for the creation of hooks. /// -public interface IHookProvider +public interface IGameInteropProvider { /// /// Available hooking backends. diff --git a/Dalamud/Utility/Signatures/SignatureHelper.cs b/Dalamud/Utility/Signatures/SignatureHelper.cs index 1cfd18330..f011f8121 100755 --- a/Dalamud/Utility/Signatures/SignatureHelper.cs +++ b/Dalamud/Utility/Signatures/SignatureHelper.cs @@ -161,7 +161,7 @@ internal static class SignatureHelper continue; } - var hook = creator.Invoke(null, new object?[] { ptr, detour, IHookProvider.HookBackend.Automatic }) as IDalamudHook; + var hook = creator.Invoke(null, new object?[] { ptr, detour, IGameInteropProvider.HookBackend.Automatic }) as IDalamudHook; info.SetValue(self, hook); createdHooks.Add(hook); From e31234ffeccb863b8a24940bf568d6a1906b2c9f Mon Sep 17 00:00:00 2001 From: goat Date: Thu, 21 Sep 2023 22:09:38 +0200 Subject: [PATCH 6/8] prefix methods with Hook to improve clarity --- .../Internal/GameInteropProviderPluginScoped.cs | 12 ++++++------ Dalamud/Plugin/Services/IGameInteropProvider.cs | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs b/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs index d6fc34b10..96172e5b2 100644 --- a/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs +++ b/Dalamud/Hooking/Internal/GameInteropProviderPluginScoped.cs @@ -47,7 +47,7 @@ internal class GameInteropProviderPluginScoped : IGameInteropProvider, IServiceT } /// - public Hook FromFunctionPointerVariable(IntPtr address, T detour) where T : Delegate + public Hook HookFromFunctionPointerVariable(IntPtr address, T detour) where T : Delegate { var hook = Hook.FromFunctionPointerVariable(address, detour); this.trackedHooks.Add(hook); @@ -55,7 +55,7 @@ internal class GameInteropProviderPluginScoped : IGameInteropProvider, IServiceT } /// - public Hook FromImport(ProcessModule? module, string moduleName, string functionName, uint hintOrOrdinal, T detour) where T : Delegate + public Hook HookFromImport(ProcessModule? module, string moduleName, string functionName, uint hintOrOrdinal, T detour) where T : Delegate { var hook = Hook.FromImport(module, moduleName, functionName, hintOrOrdinal, detour); this.trackedHooks.Add(hook); @@ -63,7 +63,7 @@ internal class GameInteropProviderPluginScoped : IGameInteropProvider, IServiceT } /// - public Hook FromSymbol(string moduleName, string exportName, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate + public Hook HookFromSymbol(string moduleName, string exportName, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate { var hook = Hook.FromSymbol(moduleName, exportName, detour, backend == IGameInteropProvider.HookBackend.MinHook); this.trackedHooks.Add(hook); @@ -71,7 +71,7 @@ internal class GameInteropProviderPluginScoped : IGameInteropProvider, IServiceT } /// - public Hook FromAddress(IntPtr procAddress, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate + public Hook HookFromAddress(IntPtr procAddress, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate { var hook = Hook.FromAddress(procAddress, detour, backend == IGameInteropProvider.HookBackend.MinHook); this.trackedHooks.Add(hook); @@ -79,8 +79,8 @@ internal class GameInteropProviderPluginScoped : IGameInteropProvider, IServiceT } /// - public Hook FromSignature(string signature, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate - => this.FromAddress(this.scanner.ScanText(signature), detour, backend); + public Hook HookFromSignature(string signature, T detour, IGameInteropProvider.HookBackend backend = IGameInteropProvider.HookBackend.Automatic) where T : Delegate + => this.HookFromAddress(this.scanner.ScanText(signature), detour, backend); /// public void Dispose() diff --git a/Dalamud/Plugin/Services/IGameInteropProvider.cs b/Dalamud/Plugin/Services/IGameInteropProvider.cs index 9451a60eb..186663a9e 100644 --- a/Dalamud/Plugin/Services/IGameInteropProvider.cs +++ b/Dalamud/Plugin/Services/IGameInteropProvider.cs @@ -46,7 +46,7 @@ public interface IGameInteropProvider /// Callback function. Delegate must have a same original function prototype. /// The hook with the supplied parameters. /// Delegate of detour. - public Hook FromFunctionPointerVariable(IntPtr address, T detour) where T : Delegate; + public Hook HookFromFunctionPointerVariable(IntPtr address, T detour) where T : Delegate; /// /// Creates a hook by rewriting import table address. @@ -58,7 +58,7 @@ public interface IGameInteropProvider /// Callback function. Delegate must have a same original function prototype. /// The hook with the supplied parameters. /// Delegate of detour. - public Hook FromImport(ProcessModule? module, string moduleName, string functionName, uint hintOrOrdinal, T detour) where T : Delegate; + public Hook HookFromImport(ProcessModule? module, string moduleName, string functionName, uint hintOrOrdinal, T detour) where T : Delegate; /// /// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function. @@ -71,7 +71,7 @@ public interface IGameInteropProvider /// Hooking library to use. /// The hook with the supplied parameters. /// Delegate of detour. - Hook FromSymbol(string moduleName, string exportName, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; + Hook HookFromSymbol(string moduleName, string exportName, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; /// /// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function. @@ -83,7 +83,7 @@ public interface IGameInteropProvider /// Hooking library to use. /// The hook with the supplied parameters. /// Delegate of detour. - Hook FromAddress(IntPtr procAddress, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; + Hook HookFromAddress(IntPtr procAddress, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; /// /// Creates a hook from a signature into the Dalamud target module. @@ -93,5 +93,5 @@ public interface IGameInteropProvider /// Hooking library to use. /// The hook with the supplied parameters. /// Delegate of detour. - Hook FromSignature(string signature, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; + Hook HookFromSignature(string signature, T detour, HookBackend backend = HookBackend.Automatic) where T : Delegate; } From eb2a5f36f9184ce9cb2f4c5e008898c2690794e2 Mon Sep 17 00:00:00 2001 From: goat Date: Thu, 21 Sep 2023 22:11:18 +0200 Subject: [PATCH 7/8] fix spelling inconsistency --- Dalamud/Plugin/Services/IGameInteropProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Plugin/Services/IGameInteropProvider.cs b/Dalamud/Plugin/Services/IGameInteropProvider.cs index 186663a9e..29f42a655 100644 --- a/Dalamud/Plugin/Services/IGameInteropProvider.cs +++ b/Dalamud/Plugin/Services/IGameInteropProvider.cs @@ -36,7 +36,7 @@ public interface IGameInteropProvider /// Initialize members decorated with the . /// Errors for fallible signatures will be logged. /// - /// The object to initialise. + /// The object to initialize. public void InitializeFromAttributes(object self); /// From 1304c54effb42535dc1a0b78b9b0049ffa9c0ec6 Mon Sep 17 00:00:00 2001 From: goat Date: Sat, 23 Sep 2023 10:39:29 +0200 Subject: [PATCH 8/8] docs fixed --- Dalamud/Plugin/Services/IGameInteropProvider.cs | 4 +++- Dalamud/Utility/Signatures/SignatureHelper.cs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Dalamud/Plugin/Services/IGameInteropProvider.cs b/Dalamud/Plugin/Services/IGameInteropProvider.cs index 29f42a655..217e08445 100644 --- a/Dalamud/Plugin/Services/IGameInteropProvider.cs +++ b/Dalamud/Plugin/Services/IGameInteropProvider.cs @@ -34,13 +34,15 @@ public interface IGameInteropProvider /// /// Initialize members decorated with the . + /// Initialize any delegate members decorated with the . + /// Fill out any IntPtr members decorated with the with the resolved address. /// Errors for fallible signatures will be logged. /// /// The object to initialize. public void InitializeFromAttributes(object self); /// - /// Creates a hook by rewriting import table address. + /// Creates a hook by replacing the original address with an address pointing to a newly created jump to the detour. /// /// A memory address to install a hook. /// Callback function. Delegate must have a same original function prototype. diff --git a/Dalamud/Utility/Signatures/SignatureHelper.cs b/Dalamud/Utility/Signatures/SignatureHelper.cs index f011f8121..cabe672ce 100755 --- a/Dalamud/Utility/Signatures/SignatureHelper.cs +++ b/Dalamud/Utility/Signatures/SignatureHelper.cs @@ -21,10 +21,10 @@ internal static class SignatureHelper private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; /// - /// Initialises an object's fields and properties that are annotated with a + /// Initializes an object's fields and properties that are annotated with a /// . /// - /// The object to initialise. + /// The object to initialize. /// If warnings should be logged using . /// Collection of created IDalamudHooks. internal static IEnumerable Initialize(object self, bool log = true)