diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index 1a32c110..4b3a6a3f 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -170,9 +170,10 @@ void Systems_Init() DetourUpdateThread(GetCurrentThread()); // Hook functions - for (const IDetour* pDetour : g_DetourVector) + for (const auto& elem : g_DetourMap) { - pDetour->Attach(); + const IDetour* detour = elem.second; + detour->Attach(); } // Patch instructions @@ -215,9 +216,10 @@ void Systems_Shutdown() DetourUpdateThread(GetCurrentThread()); // Unhook functions - for (const IDetour* pDetour : g_DetourVector) + for (const auto& elem : g_DetourMap) { - pDetour->Detach(); + const IDetour* detour = elem.second; + detour->Detach(); } // Commit the transaction @@ -342,11 +344,13 @@ void DetourInit() // Run the sigscan g_SigCache.SetDisabled(bNoSmap); g_SigCache.LoadCache(SIGDB_FILE); - for (const IDetour* pDetour : g_DetourVector) + for (const auto& elem : g_DetourMap) { - pDetour->GetCon(); // Constants. - pDetour->GetFun(); // Functions. - pDetour->GetVar(); // Variables. + const IDetour* detour = elem.second; + + detour->GetCon(); // Constants. + detour->GetFun(); // Functions. + detour->GetVar(); // Variables. if (bLogAdr) { @@ -355,7 +359,7 @@ void DetourInit() // Run the sigscan bInitDivider = true; spdlog::debug("+---------------------------------------------------------------------+\n"); } - pDetour->GetAdr(); + detour->GetAdr(); spdlog::debug("+---------------------------------------------------------------------+\n"); } } @@ -372,9 +376,11 @@ void DetourInit() // Run the sigscan void DetourAddress() // Test the sigscan results { spdlog::debug("+---------------------------------------------------------------------+\n"); - for (const IDetour* pDetour : g_DetourVector) + for (const auto& elem : g_DetourMap) { - pDetour->GetAdr(); + const IDetour* detour = elem.second; + + detour->GetAdr(); spdlog::debug("+---------------------------------------------------------------------+\n"); } } diff --git a/r5dev/thirdparty/detours/CMakeLists.txt b/r5dev/thirdparty/detours/CMakeLists.txt index ba2b7b09..da7f3793 100644 --- a/r5dev/thirdparty/detours/CMakeLists.txt +++ b/r5dev/thirdparty/detours/CMakeLists.txt @@ -7,6 +7,7 @@ add_sources( SOURCE_GROUP "Source" "src/creatwth.cpp" "src/detours.cpp" "src/disasm.cpp" + "src/idetour.cpp" "src/modules.cpp" ) diff --git a/r5dev/thirdparty/detours/include/idetour.h b/r5dev/thirdparty/detours/include/idetour.h index 40b5166c..84e4bf2e 100644 --- a/r5dev/thirdparty/detours/include/idetour.h +++ b/r5dev/thirdparty/detours/include/idetour.h @@ -1,10 +1,9 @@ #ifndef IDETOUR_H #define IDETOUR_H -#define ADDDETOUR(x,y) static std::size_t dummy_reg_##y = AddDetour( new x() ); -#define XREGISTER(x,y) ADDDETOUR(x, y) -#define REGISTER(x) XREGISTER(x, __COUNTER__) - +//----------------------------------------------------------------------------- +// Interface class for context hooks +//----------------------------------------------------------------------------- class IDetour { public: @@ -18,28 +17,11 @@ public: virtual void Detach(void) const = 0; }; -class VDetour : public IDetour -{ - virtual void GetAdr(void) const { } - virtual void GetFun(void) const { } - virtual void GetVar(void) const { } - virtual void GetCon(void) const { } +extern std::map g_DetourMap; +std::size_t AddDetour(IDetour* pDetour); - virtual void Attach(void) const { } - virtual void Detach(void) const { } -}; - -inline static std::vector g_DetourVector; -inline static std::unordered_set g_DetourSet; -inline std::size_t AddDetour(IDetour* pDetour) -{ - IDetour* pVFTable = reinterpret_cast(pDetour)[0]; - auto p = g_DetourSet.insert(pVFTable); // Only register if VFTable isn't already registered. - - assert(p.second); // Code bug: duplicate registration!!! (called 'REGISTER(...)' from a header file?). - p.second ? g_DetourVector.push_back(pDetour) : delete pDetour; - - return g_DetourVector.size(); -} +#define ADDDETOUR(x,y) static std::size_t dummy_reg_##y = AddDetour( new x() ); +#define XREGISTER(x,y) ADDDETOUR(x, y) +#define REGISTER(x) XREGISTER(x, __COUNTER__) #endif // IDETOUR_H diff --git a/r5dev/thirdparty/detours/src/idetour.cpp b/r5dev/thirdparty/detours/src/idetour.cpp new file mode 100644 index 00000000..45accf1a --- /dev/null +++ b/r5dev/thirdparty/detours/src/idetour.cpp @@ -0,0 +1,30 @@ +//===========================================================================// +// +// Purpose: Hook interface +// +//===========================================================================// +#include +#include +#include "../include/idetour.h" + +//----------------------------------------------------------------------------- +// Contains a VFTable pointer, and the class instance. A VFTable can only be +// used by one class instance. This is to avoid duplicate registrations. +//----------------------------------------------------------------------------- +std::map g_DetourMap; + +//----------------------------------------------------------------------------- +// Purpose: adds a detour context to the list +//----------------------------------------------------------------------------- +std::size_t AddDetour(IDetour* pDetour) +{ + const void* pVFTable = reinterpret_cast(pDetour)[0]; + auto p = g_DetourMap.emplace(pVFTable, pDetour); // Only register if VFTable isn't already registered. + + assert(p.second); // Code bug: duplicate registration!!! (called 'REGISTER(...)' from a header file?). + + if (!p.second) + delete pDetour; + + return g_DetourMap.size(); +}