From e99cfe5c245265765b4f2ce9327b805474ea7002 Mon Sep 17 00:00:00 2001 From: jous Date: Mon, 12 Jan 2026 00:34:02 +0100 Subject: [PATCH] sibir hook.h y gameprt.h modificados --- Client/common/include/GamePtr.h | 81 +++++++++++++++++++++ Client/common/include/Hook.h | 122 ++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 Client/common/include/GamePtr.h create mode 100644 Client/common/include/Hook.h diff --git a/Client/common/include/GamePtr.h b/Client/common/include/GamePtr.h new file mode 100644 index 0000000..c25ce69 --- /dev/null +++ b/Client/common/include/GamePtr.h @@ -0,0 +1,81 @@ +#ifndef COMMON_GAMEPTR_H +#define COMMON_GAMEPTR_H + +#include +#include +#include + +namespace Memory { + + class GamePtr_Manager { + public: + GamePtr_Manager(); + + static uintptr_t s_baseAddress; + }; + + template + class GamePtr { + public : + GamePtr(uintptr_t offset) : offset(offset + Memory::GamePtr_Manager::s_baseAddress){} + + T * GetPtr() const { + return reinterpret_cast (offset); + } + + T * operator->() const + { + return GetPtr(); + } + + operator T *() const + { + return GetPtr(); + } + + bool operator!() const { + return !GetPtr(); + } + + const T * GetConstPtr() const { + return reinterpret_cast (offset); + } + + uintptr_t GetUIntPtr() const + { + return offset; + } + private: + uintptr_t offset; + + GamePtr(); + GamePtr(GamePtr & rhs); + GamePtr & operator=(GamePtr & rhs); + }; + + template + class GameAddr{ + public: + GameAddr(uintptr_t offset) : offset(reinterpret_cast(offset + Memory::GamePtr_Manager::s_baseAddress)){} + + operator T() { + return reinterpret_cast(offset); + } + + uintptr_t GetUIntPtr(){ + return reinterpret_cast(offset); + } + private: + struct ConversionType {}; + + ConversionType * offset; + + GameAddr(); + GameAddr(GameAddr & rhs); + GameAddr & operator=(GameAddr & rhs); + }; + + +} + +#endif \ No newline at end of file diff --git a/Client/common/include/Hook.h b/Client/common/include/Hook.h new file mode 100644 index 0000000..c98e24d --- /dev/null +++ b/Client/common/include/Hook.h @@ -0,0 +1,122 @@ +#ifndef COMMON_HOOK_H +#define COMMON_HOOK_H + +#include +#include +#include "detours.h" // Asegúrate de tener detours.lib en tu proyecto +#include "Types.h" +#include "Exceptions.h" + +namespace Hooks { + + enum class CallConvention + { + stdcall_t, + cdecl_t, + fastcall_t // Añadido fastcall por si interceptas funciones internas del engine + }; + + // Helper para definir la convención de llamada + template + struct convention; + + template + struct convention + { + typedef retn (__stdcall *type)(args ...); + }; + + template + struct convention + { + typedef retn (__cdecl *type)(args ...); + }; + + // Fallout 4 usa mucho fastcall (__rcall en x64) + template + struct convention + { + typedef retn (__fastcall *type)(args ...); + }; + + template + class Hook + { + typedef typename convention::type type; + + uintptr_t orig_; // Usamos uintptr_t para compatibilidad x64 + type detour_; + + bool is_applied_; + bool has_open_transaction_; + + void transaction_begin() + { + if (DetourTransactionBegin() != NO_ERROR) + throw Exceptions::Core::Exceptions::DetourException("A pending transaction already exists"); + has_open_transaction_ = true; + } + + void transaction_commit() + { + if (DetourTransactionCommit() != NO_ERROR) + throw Exceptions::Core::Exceptions::DetourException("Error committing detour transaction"); + has_open_transaction_ = false; + } + + static void update_thread(HANDLE hThread) + { + DetourUpdateThread(hThread); + } + + public: + Hook() : orig_(0), detour_(0), is_applied_(false), has_open_transaction_(false) {} + + ~Hook() + { + if (has_open_transaction_) DetourTransactionAbort(); + remove(); + } + + // pFunc ahora acepta uintptr_t para que funcione con GameAddr::GetUIntPtr() + void apply(uintptr_t pFunc, type detour) + { + if (is_applied_) return; + + detour_ = detour; + orig_ = pFunc; + + transaction_begin(); + update_thread(GetCurrentThread()); + + // Detours requiere un puntero al puntero de la función original + DetourAttach(reinterpret_cast(&orig_), reinterpret_cast(detour_)); + + transaction_commit(); + is_applied_ = true; + } + + void remove() + { + if (!is_applied_) return; + + transaction_begin(); + update_thread(GetCurrentThread()); + DetourDetach(reinterpret_cast(&orig_), reinterpret_cast(detour_)); + transaction_commit(); + + is_applied_ = false; + } + + // Esta es la función que llamas desde tu lambda en main.cpp + retn call_orig(args ... p) + { + return reinterpret_cast(orig_)(p...); + } + + uintptr_t get_orig() const { return orig_; } + bool is_applied() const { return is_applied_; } + }; +} + +#endif \ No newline at end of file