From eee0ae787d72bb727d8cea3cef3a252d0a814829 Mon Sep 17 00:00:00 2001 From: Kenzzer <14257866+kenzzer@users.noreply.github.com> Date: Wed, 23 Apr 2025 07:52:56 +0000 Subject: [PATCH] expose khook to plugins --- AMBuildScript | 4 ++++ core/AMBuilder | 8 ++++++++ core/ISmmAPI.h | 1 + core/ISmmPlugin.h | 10 +++++++--- core/metamod.cpp | 32 +++++++++++++++++++++++++++++++- 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/AMBuildScript b/AMBuildScript index 8fadaa6..342bd17 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -31,6 +31,8 @@ class MMSConfig(object): self.versionlib = None self.all_targets = [] self.target_archs = set() + self.libsafetyhook = {} + self.libkhook = {} if builder.options.targets: target_archs = builder.options.targets.split(',') @@ -378,6 +380,8 @@ if builder.backend == 'amb2': 'support/buildbot/PackageScript', ] +builder.Build('core/khook/AMBuilder', { 'KHook': MMS }) +builder.Build('core/khook/third_party/safetyhook/AMBuilder', { 'SafetyHook': MMS }) builder.Build(BuildScripts, { 'MMS': MMS }) if builder.options.breakpad_dump: diff --git a/core/AMBuilder b/core/AMBuilder index 897b8e4..cbd9b46 100644 --- a/core/AMBuilder +++ b/core/AMBuilder @@ -9,6 +9,14 @@ for sdk_target in MMS.sdk_targets: binary = MMS.HL2Library(builder, cxx, name, sdk) binary.compiler.cxxincludes += [os.path.join(builder.sourcePath, 'core', 'khook', 'include')] + binary.compiler.defines += ['KHOOK_STANDALONE'] + for task in MMS.libkhook: + if task.target.arch == binary.compiler.target.arch: + binary.compiler.linkflags += [task.binary] + for task in MMS.libsafetyhook: + if task.target.arch == binary.compiler.target.arch: + binary.compiler.linkflags += [task.binary] + binary.sources += [ 'metamod.cpp', 'metamod_console.cpp', diff --git a/core/ISmmAPI.h b/core/ISmmAPI.h index b48c57a..4870041 100644 --- a/core/ISmmAPI.h +++ b/core/ISmmAPI.h @@ -56,6 +56,7 @@ typedef ConCommandBase ProviderConCommand; #endif #endif +#define MMIFACE_KHOOK "IKHook" /**< IKHook Pointer */ #define MMIFACE_SOURCEHOOK "ISourceHook" /**< ISourceHook Pointer */ #define MMIFACE_PLMANAGER "IPluginManager" /**< SourceMM Plugin Functions */ #define MMIFACE_SH_HOOKMANAUTOGEN "IHookManagerAutoGen" /**< SourceHook::IHookManagerAutoGen Pointer */ diff --git a/core/ISmmPlugin.h b/core/ISmmPlugin.h index 491d79e..86c226c 100644 --- a/core/ISmmPlugin.h +++ b/core/ISmmPlugin.h @@ -486,11 +486,15 @@ using namespace SourceMM; #define PL_EXPOSURE_FUNC(name, var) EXPOSE_SINGLE_INTERFACE_GLOBALVAR(ISmmPlugin, ISmmPlugin, METAMOD_PLAPI_NAME, var); #endif +namespace KHook { +class IKHook; +} + #define PLUGIN_EXPOSE(name, var) \ ISmmAPI *g_SMAPI = NULL; \ ISmmPlugin *g_PLAPI = NULL; \ PluginId g_PLID = (PluginId)0; \ - SourceHook::ISourceHook *g_SHPtr = NULL; \ + KHook::IKHook* __exported__khook = nullptr; \ PL_EXPOSURE_FUNC(name, var) @@ -502,7 +506,7 @@ using namespace SourceMM; * to use values like g_SHPtr in other files. */ #define PLUGIN_GLOBALVARS() \ - extern SourceHook::ISourceHook *g_SHPtr; \ + extern KHook::IKHook* __exported__khook; \ extern ISmmAPI *g_SMAPI; \ extern ISmmPlugin *g_PLAPI; \ extern PluginId g_PLID; @@ -512,7 +516,7 @@ using namespace SourceMM; */ #define PLUGIN_SAVEVARS() \ g_SMAPI = ismm; \ - g_SHPtr = static_cast(ismm->MetaFactory(MMIFACE_SOURCEHOOK, NULL, NULL)); \ + __exported__khook = static_cast(ismm->MetaFactory(MMIFACE_KHOOK, nullptr, nullptr)); \ g_PLAPI = static_cast(this); \ g_PLID = id; diff --git a/core/metamod.cpp b/core/metamod.cpp index 47c8a30..e680b7b 100644 --- a/core/metamod.cpp +++ b/core/metamod.cpp @@ -36,6 +36,7 @@ #include "metamod_util.h" #include "metamod_console.h" #include "provider/provider_base.h" +#include "khook.hpp" #include @@ -93,6 +94,31 @@ MetamodSource g_Metamod; PluginId g_PLID = Pl_Console; SourceMM::ISmmAPI *g_pMetamod = &g_Metamod; +#ifndef KHOOK_STANDALONE +static_assert(false, "KHOOK_STANDALONE wasn't defined!"); +#endif +class KHookImpl : public KHook::IKHook { +public: + virtual KHook::HookID_t SetupHook(void* function, void* hookPtr, void* removedFunctionMFP, KHook::Action* hookAction, void* overrideReturnPtr, void* originalReturnPtr, void* preMFP, void* postMFP, void* returnOverrideMFP, void* returnOriginalMFP, void* callOriginalMFP, bool async = false) override { + return KHook::SetupHook(function, hookPtr, removedFunctionMFP, hookAction, overrideReturnPtr, originalReturnPtr, preMFP, postMFP, returnOverrideMFP, returnOriginalMFP, callOriginalMFP, async); + } + virtual void RemoveHook(KHook::HookID_t id, bool async = false) override { + return KHook::RemoveHook(id, async); + } + virtual void* GetCurrent() override { + return KHook::GetCurrent(); + } + virtual void* GetOriginalFunction() override { + return KHook::GetOriginalFunction(); + } + virtual void* GetOriginalValuePtr(bool pop = false) override { + return KHook::GetOriginalValuePtr(pop); + } + virtual void* GetOverrideValuePtr(bool pop = false) override { + return KHook::GetOverrideValuePtr(pop); + } +} g_KHook; + /* Helper Macro */ #define IFACE_MACRO(orig,nam) \ CPluginManager::CPlugin *pl; \ @@ -806,7 +832,11 @@ void *MetamodSource::MetaFactory(const char *iface, int *ret, PluginId *id) } /* First check ours... we get first chance! */ - if (strcmp(iface, MMIFACE_SOURCEHOOK) == 0) + if (strcmp(iface, MMIFACE_KHOOK) == 0) + { + return static_cast(static_cast(&g_KHook)); + } + else if (strcmp(iface, MMIFACE_SOURCEHOOK) == 0) { return nullptr; }