diff --git a/include/hooks.hpp b/include/hooks.hpp index 0fc2b157..cf7a95e4 100755 --- a/include/hooks.hpp +++ b/include/hooks.hpp @@ -37,7 +37,7 @@ public: ~VMTHook(); void Set(ptr_t inst, uint32_t offset = 0); void Release(); - void HookMethod(ptr_t func, uint32_t idx); + void HookMethod(ptr_t func, uint32_t idx, ptr_t *backup); void *GetMethod(uint32_t idx) const; void Apply(); diff --git a/include/hooks/HookedMethods.hpp b/include/hooks/HookedMethods.hpp index d45553fa..c56efaaa 100644 --- a/include/hooks/HookedMethods.hpp +++ b/include/hooks/HookedMethods.hpp @@ -14,93 +14,55 @@ union SDL_Event; struct SDL_Window; #endif +#define DECLARE_HOOKED_METHOD(name, rtype, ...) \ + namespace types { using name = rtype(*)(__VA_ARGS__); } \ + namespace methods { rtype name(__VA_ARGS__); } \ + namespace original { extern types::name name; } + +#define DEFINE_HOOKED_METHOD(name, rtype, ...) \ + types::name original::name{ nullptr }; \ + rtype name(__VA_ARGS__) + namespace hooked_methods { - -namespace types -{ // ClientMode -using CreateMove = bool(*)(void *, float, CUserCmd *); -using LevelInit = void(*)(void *, const char *); -using LevelShutdown = void(*)(void *); +DECLARE_HOOKED_METHOD(CreateMove, bool, void *, float, CUserCmd *); +DECLARE_HOOKED_METHOD(LevelInit, void, void *, const char *); +DECLARE_HOOKED_METHOD(LevelShutdown, void, void *); // ClientMode + 4 -using FireGameEvent = void(*)(void *_this, IGameEvent *event); +DECLARE_HOOKED_METHOD(FireGameEvent, void, void *, IGameEvent *); // IBaseClient -using DispatchUserMessage = bool(*)(void *, int, bf_read &); -using IN_KeyEvent = int(*)(void *, int, int, const char *); +DECLARE_HOOKED_METHOD(DispatchUserMessage, bool, void *, int, bf_read &); +DECLARE_HOOKED_METHOD(IN_KeyEvent, int, void *, int, ButtonCode_t, const char *); // IInput -using GetUserCmd = CUserCmd *(*)(IInput *, int); +DECLARE_HOOKED_METHOD(GetUserCmd, CUserCmd *, IInput *, int); // INetChannel -using SendNetMsg = bool(*)(INetChannel *, INetMessage &, bool, bool); -using CanPacket = bool(*)(INetChannel *); -using Shutdown = void(*)(INetChannel *, const char *); +DECLARE_HOOKED_METHOD(SendNetMsg, bool, INetChannel *, INetMessage &, bool, bool); +DECLARE_HOOKED_METHOD(CanPacket, bool, INetChannel *); +DECLARE_HOOKED_METHOD(Shutdown, void, INetChannel *, const char *); // ISteamFriends -using GetFriendPersonaName = const char *(*)(ISteamFriends *, CSteamID); +DECLARE_HOOKED_METHOD(GetFriendPersonaName, const char *, ISteamFriends *, CSteamID); // IEngineVGui -using Paint = void(*)(IEngineVGui *, PaintMode_t); +DECLARE_HOOKED_METHOD(Paint, void, IEngineVGui *, PaintMode_t); #if ENABLE_VISUALS // ClientMode -using OverrideView = void(*)(void *, CViewSetup *); +DECLARE_HOOKED_METHOD(OverrideView, void, void *, CViewSetup *); // IVModelRender -using DrawModelExecute = void(*)(IVModelRender *, const DrawModelState_t &, - const ModelRenderInfo_t &, matrix3x4_t *); +DECLARE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *, const DrawModelState_t &, +const ModelRenderInfo_t &, matrix3x4_t *); // IStudioRender -using BeginFrame = void(*)(IStudioRender *); +DECLARE_HOOKED_METHOD(BeginFrame, void, IStudioRender *); // IBaseClient -using FrameStageNotify = void(*)(void *, int); +DECLARE_HOOKED_METHOD(FrameStageNotify, void, void *, ClientFrameStage_t); // vgui::IPanel -using PaintTraverse = void(*)(vgui::IPanel *, unsigned int, bool, bool); +DECLARE_HOOKED_METHOD(PaintTraverse, void, vgui::IPanel *, unsigned int, bool, bool); // SDL -using SDL_GL_SwapWindow = void(*)(SDL_Window *window); -using SDL_PollEvent = int(*)(SDL_Event *event); +DECLARE_HOOKED_METHOD(SDL_GL_SwapWindow, void, SDL_Window *); +DECLARE_HOOKED_METHOD(SDL_PollEvent, int, SDL_Event *); // IUniformRandomStream -using RandomInt = int(*)(void *, int, int); +DECLARE_HOOKED_METHOD(RandomInt, int, IUniformRandomStream *, int, int); #endif -} - -namespace methods -{ -// ClientMode -bool CreateMove(void *, float, CUserCmd *); -void LevelInit(void *, const char *); -void LevelShutdown(void *); -// ClientMode + 4 -void FireGameEvent(void *_this, IGameEvent *event); -// IBaseClient -bool DispatchUserMessage(void *, int, bf_read &); -int IN_KeyEvent(void *, int, int, const char *); -// IInput -CUserCmd *GetUserCmd(IInput *, int); -// INetChannel -bool SendNetMsg(INetChannel *, INetMessage &, bool, bool); -bool CanPacket(INetChannel *); -void Shutdown(INetChannel *, const char *); -// ISteamFriends -const char *GetFriendPersonaName(ISteamFriends *_this, CSteamID steamID); -// IEngineVGui -void Paint(IEngineVGui *_this, PaintMode_t mode); - -#if ENABLE_VISUALS -// ClientMode -void OverrideView(void *, CViewSetup *); -// IVModelRender -void DrawModelExecute(IVModelRender *_this, const DrawModelState_t &state, - const ModelRenderInfo_t &info, matrix3x4_t *matrix); -// IStudioRender -void BeginFrame(IStudioRender *); -// IBaseClient -void FrameStageNotify(void *, int); -// vgui::IPanel -void PaintTraverse(vgui::IPanel *, unsigned int, bool, bool); -// SDL -void SDL_GL_SwapWindow(SDL_Window *window); -int SDL_PollEvent(SDL_Event *event); -// IUniformRandomStream -int RandomInt(void *, int, int); -#endif - -} } diff --git a/src/hooks.cpp b/src/hooks.cpp index 82611217..6a4bac7c 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -77,11 +77,13 @@ void *VMTHook::GetMethod(uint32_t idx) const return vtable_original[idx]; } -void VMTHook::HookMethod(ptr_t func, uint32_t idx) +void VMTHook::HookMethod(ptr_t func, uint32_t idx, ptr_t *backup) { logging::Info( "Hooking method %d of vtable 0x%08x, replacing 0x%08x with 0x%08x", idx, vtable_original, GetMethod(idx), func); + if (backup) + *backup = vtable_hooked[2 + idx]; vtable_hooked[2 + idx] = func; } diff --git a/src/hooks/CMakeLists.txt b/src/hooks/CMakeLists.txt index 7b815ce0..7755a538 100644 --- a/src/hooks/CMakeLists.txt +++ b/src/hooks/CMakeLists.txt @@ -1,11 +1,21 @@ target_sources(cathook PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/CanPacket.cpp" "${CMAKE_CURRENT_LIST_DIR}/CreateMove.cpp" + "${CMAKE_CURRENT_LIST_DIR}/DispatchUserMessage.cpp" + "${CMAKE_CURRENT_LIST_DIR}/FireGameEvent.cpp" + "${CMAKE_CURRENT_LIST_DIR}/GetFriendPersonaName.cpp" + "${CMAKE_CURRENT_LIST_DIR}/GetUserCmd.cpp" + "${CMAKE_CURRENT_LIST_DIR}/IN_KeyEvent.cpp" + "${CMAKE_CURRENT_LIST_DIR}/LevelInit.cpp" + "${CMAKE_CURRENT_LIST_DIR}/LevelShutdown.cpp" "${CMAKE_CURRENT_LIST_DIR}/nographics.cpp" - "${CMAKE_CURRENT_LIST_DIR}/others.cpp") + "${CMAKE_CURRENT_LIST_DIR}/others.cpp" + "${CMAKE_CURRENT_LIST_DIR}/Paint.cpp" + "${CMAKE_CURRENT_LIST_DIR}/PaintTraverse.cpp" + "${CMAKE_CURRENT_LIST_DIR}/sdl.cpp" + "${CMAKE_CURRENT_LIST_DIR}/SendNetMsg.cpp" + "${CMAKE_CURRENT_LIST_DIR}/Shutdown.cpp") if(EnableVisuals) - target_sources(cathook PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/Paint.cpp" - "${CMAKE_CURRENT_LIST_DIR}/PaintTraverse.cpp" - "${CMAKE_CURRENT_LIST_DIR}/sdl.cpp") + add_subdirectory(visual) endif() \ No newline at end of file diff --git a/src/hooks/CanPacket.cpp b/src/hooks/CanPacket.cpp index 06767b3e..868fb75d 100644 --- a/src/hooks/CanPacket.cpp +++ b/src/hooks/CanPacket.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(CanPacket, bool, INetChannel *this_) +{ + return original::CanPacket(this_); +} + +} diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 2521db6e..4fc3d73b 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -10,6 +10,18 @@ #include +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, CUserCmd *cmd) +{ + return original::CreateMove(this_, input_sample_time, cmd); +} + +} + class CMoveData; namespace engine_prediction { diff --git a/src/hooks/DispatchUserMessage.cpp b/src/hooks/DispatchUserMessage.cpp index 06767b3e..e80dfc86 100644 --- a/src/hooks/DispatchUserMessage.cpp +++ b/src/hooks/DispatchUserMessage.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(DispatchUserMessage, bool, void * this_, int type, bf_read &buffer) +{ + return original::DispatchUserMessage(this_, type, buffer); +} + +} \ No newline at end of file diff --git a/src/hooks/FireGameEvent.cpp b/src/hooks/FireGameEvent.cpp index 06767b3e..7d2ce057 100644 --- a/src/hooks/FireGameEvent.cpp +++ b/src/hooks/FireGameEvent.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(FireGameEvent, void, void *this_, IGameEvent *event) +{ + return original::FireGameEvent(this_, event); +} + +} \ No newline at end of file diff --git a/src/hooks/GetFriendPersonaName.cpp b/src/hooks/GetFriendPersonaName.cpp index 06767b3e..c373ab24 100644 --- a/src/hooks/GetFriendPersonaName.cpp +++ b/src/hooks/GetFriendPersonaName.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(GetFriendPersonaName, const char *, ISteamFriends *this_, CSteamID steam_id) +{ + return original::GetFriendPersonaName(this_, steam_id); +} + +} \ No newline at end of file diff --git a/src/hooks/GetUserCmd.cpp b/src/hooks/GetUserCmd.cpp index 06767b3e..cbb7c4f3 100644 --- a/src/hooks/GetUserCmd.cpp +++ b/src/hooks/GetUserCmd.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(GetUserCmd, CUserCmd *, IInput *this_, int sequence_number) +{ + return original::GetUserCmd(this_, sequence_number); +} + +} \ No newline at end of file diff --git a/src/hooks/IN_KeyEvent.cpp b/src/hooks/IN_KeyEvent.cpp index 06767b3e..fc8a11c8 100644 --- a/src/hooks/IN_KeyEvent.cpp +++ b/src/hooks/IN_KeyEvent.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(IN_KeyEvent, int, void *this_, int eventcode, ButtonCode_t keynum, const char *binding) +{ + return original::IN_KeyEvent(this_, eventcode, keynum, binding); +} + +} \ No newline at end of file diff --git a/src/hooks/LevelInit.cpp b/src/hooks/LevelInit.cpp index 06767b3e..a84cc107 100644 --- a/src/hooks/LevelInit.cpp +++ b/src/hooks/LevelInit.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(LevelInit, void, void *this_, const char *name) +{ + return original::LevelInit(this_, name); +} + +} \ No newline at end of file diff --git a/src/hooks/LevelShutdown.cpp b/src/hooks/LevelShutdown.cpp index 06767b3e..c7278dcf 100644 --- a/src/hooks/LevelShutdown.cpp +++ b/src/hooks/LevelShutdown.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(LevelShutdown, void, void *this_) +{ + return original::LevelShutdown(this_); +} + +} \ No newline at end of file diff --git a/src/hooks/Paint.cpp b/src/hooks/Paint.cpp index 86b8729b..107fd018 100755 --- a/src/hooks/Paint.cpp +++ b/src/hooks/Paint.cpp @@ -9,6 +9,16 @@ #include "hitrate.hpp" #include "hack.hpp" +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(Paint, void, IEngineVGui *this_, PaintMode_t mode) +{ + return original::Paint(this_, mode); +} + +} + static CatVar cursor_fix_experimental(CV_SWITCH, "experimental_cursor_fix", "1", "Cursor fix"); diff --git a/src/hooks/SendNetMsg.cpp b/src/hooks/SendNetMsg.cpp index 06767b3e..bd8c181a 100644 --- a/src/hooks/SendNetMsg.cpp +++ b/src/hooks/SendNetMsg.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(SendNetMsg, bool, INetChannel *this_, INetMessage &message, bool force_reliable, bool voice) +{ + return original::SendNetMsg(this_, message, force_reliable, voice); +} + +} \ No newline at end of file diff --git a/src/hooks/Shutdown.cpp b/src/hooks/Shutdown.cpp index 06767b3e..4115dca0 100644 --- a/src/hooks/Shutdown.cpp +++ b/src/hooks/Shutdown.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(Shutdown, void, INetChannel *this_, const char *reason) +{ + return original::Shutdown(this_, reason); +} + +} \ No newline at end of file diff --git a/src/hooks/visual/BeginFrame.cpp b/src/hooks/visual/BeginFrame.cpp index 06767b3e..2029d4a1 100644 --- a/src/hooks/visual/BeginFrame.cpp +++ b/src/hooks/visual/BeginFrame.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(BeginFrame, void, IStudioRender *this_) +{ + return original::BeginFrame(this_); +} + +} \ No newline at end of file diff --git a/src/hooks/visual/CMakeLists.txt b/src/hooks/visual/CMakeLists.txt new file mode 100644 index 00000000..0b3c30f9 --- /dev/null +++ b/src/hooks/visual/CMakeLists.txt @@ -0,0 +1,9 @@ +target_sources(cathook PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/BeginFrame.cpp" + "${CMAKE_CURRENT_LIST_DIR}/DrawModelExecute.cpp" + "${CMAKE_CURRENT_LIST_DIR}/FrameStageNotify.cpp" + "${CMAKE_CURRENT_LIST_DIR}/OverrideView.cpp" + "${CMAKE_CURRENT_LIST_DIR}/PaintTraverse.cpp" + "${CMAKE_CURRENT_LIST_DIR}/RandomInt.cpp" + "${CMAKE_CURRENT_LIST_DIR}/SDL_GL_SwapWindow.cpp" + "${CMAKE_CURRENT_LIST_DIR}/SDL_PollEvent.cpp") \ No newline at end of file diff --git a/src/hooks/visual/DrawModelExecute.cpp b/src/hooks/visual/DrawModelExecute.cpp index 06767b3e..30712bee 100644 --- a/src/hooks/visual/DrawModelExecute.cpp +++ b/src/hooks/visual/DrawModelExecute.cpp @@ -3,4 +3,15 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, const DrawModelState_t &state, + const ModelRenderInfo_t &info, matrix3x4_t *bone) +{ + return original::DrawModelExecute(this_, state, info, bone); +} + +} \ No newline at end of file diff --git a/src/hooks/visual/FrameStageNotify.cpp b/src/hooks/visual/FrameStageNotify.cpp index 06767b3e..fdd3e5b3 100644 --- a/src/hooks/visual/FrameStageNotify.cpp +++ b/src/hooks/visual/FrameStageNotify.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_, ClientFrameStage_t stage) +{ + return original::FrameStageNotify(this_, stage); +} + +} \ No newline at end of file diff --git a/src/hooks/visual/OverrideView.cpp b/src/hooks/visual/OverrideView.cpp index 06767b3e..030ad0a5 100644 --- a/src/hooks/visual/OverrideView.cpp +++ b/src/hooks/visual/OverrideView.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(OverrideView, void, void *this_, CViewSetup *setup) +{ + return original::OverrideView(this_, setup); +} + +} \ No newline at end of file diff --git a/src/hooks/visual/PaintTraverse.cpp b/src/hooks/visual/PaintTraverse.cpp index 06767b3e..45d59134 100644 --- a/src/hooks/visual/PaintTraverse.cpp +++ b/src/hooks/visual/PaintTraverse.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(PaintTraverse, void, vgui::IPanel *this_, unsigned int panel, bool force, bool allow_force) +{ + return original::PaintTraverse(this_, panel, force, allow_force); +} + +} \ No newline at end of file diff --git a/src/hooks/visual/RandomInt.cpp b/src/hooks/visual/RandomInt.cpp index 06767b3e..8a18d8a7 100644 --- a/src/hooks/visual/RandomInt.cpp +++ b/src/hooks/visual/RandomInt.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(RandomInt, int, IUniformRandomStream *this_, int min, int max) +{ + return original::RandomInt(this_, min, max); +} + +} \ No newline at end of file diff --git a/src/hooks/visual/SDL_GL_SwapWindow.cpp b/src/hooks/visual/SDL_GL_SwapWindow.cpp index 06767b3e..145023a3 100644 --- a/src/hooks/visual/SDL_GL_SwapWindow.cpp +++ b/src/hooks/visual/SDL_GL_SwapWindow.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(SDL_GL_SwapWindow, void, SDL_Window *window) +{ + return original::SDL_GL_SwapWindow(window); +} + +} \ No newline at end of file diff --git a/src/hooks/visual/SDL_PollEvent.cpp b/src/hooks/visual/SDL_PollEvent.cpp index 06767b3e..75d3cef6 100644 --- a/src/hooks/visual/SDL_PollEvent.cpp +++ b/src/hooks/visual/SDL_PollEvent.cpp @@ -3,4 +3,14 @@ Copyright (c) 2018 nullworks. All rights reserved. */ -#include "HookedMethods.hpp" \ No newline at end of file +#include "HookedMethods.hpp" + +namespace hooked_methods +{ + +DEFINE_HOOKED_METHOD(SDL_PollEvent, int, SDL_Event *event) +{ + return original::SDL_PollEvent(event); +} + +} \ No newline at end of file