From c99628a88a9293e4b9fae0fbf6c3a339abb3f6a0 Mon Sep 17 00:00:00 2001 From: Nemirtingas Date: Mon, 19 Aug 2019 18:57:55 +0200 Subject: [PATCH] Added hook retry. Handed hook detection to a thread that can then retry. With that, don't need to wait for loadLibrary. Will remove all those commented functions in another version. --- overlay_experimental/Hook_Manager.cpp | 161 ++++++++++++-------------- overlay_experimental/Hook_Manager.h | 18 +-- 2 files changed, 85 insertions(+), 94 deletions(-) diff --git a/overlay_experimental/Hook_Manager.cpp b/overlay_experimental/Hook_Manager.cpp index f776df66..170b7dc2 100644 --- a/overlay_experimental/Hook_Manager.cpp +++ b/overlay_experimental/Hook_Manager.cpp @@ -17,23 +17,18 @@ #include #ifdef STEAM_WIN32 -decltype(LoadLibraryA )* _LoadLibraryA = LoadLibraryA; -decltype(LoadLibraryW )* _LoadLibraryW = LoadLibraryW; -decltype(LoadLibraryExA )* _LoadLibraryExA = LoadLibraryExA; -decltype(LoadLibraryExW )* _LoadLibraryExW = LoadLibraryExW; - -decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present; -decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present; -decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx; -decltype(wglMakeCurrent)* _wglMakeCurrent; +static decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present; +static decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present; +static decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx; +static decltype(wglMakeCurrent)* _wglMakeCurrent; HRESULT STDMETHODCALLTYPE Hook_Manager::MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags) { Hook_Manager& inst = Hook_Manager::Inst(); if (!inst.stop_retry()) { - IUnknown* pDevice; - _this->GetDevice(__uuidof(ID3D10Device), (void**)& pDevice); + IUnknown* pDevice = nullptr; + _this->GetDevice(__uuidof(ID3D10Device), (void**)&pDevice); if (pDevice) { DX10_Hook* hook = DX10_Hook::Inst(); @@ -324,7 +319,7 @@ void Hook_Manager::hook_opengl() } } -void Hook_Manager::create_hookA(const char* libname) +void Hook_Manager::create_hook(const char* libname) { if (!_stricmp(libname, "d3d9.dll")) Hook_Manager::Inst().hook_dx9(); @@ -338,47 +333,47 @@ void Hook_Manager::create_hookA(const char* libname) Hook_Manager::Inst().hook_opengl(); } -void Hook_Manager::create_hookW(const wchar_t *libname) -{ - if (!_wcsicmp(libname, L"d3d9.dll")) - Hook_Manager::Inst().hook_dx9(); - else if (!_wcsicmp(libname, L"d3d10.dll")) - Hook_Manager::Inst().hook_dx10(); - else if (!_wcsicmp(libname, L"d3d11.dll")) - Hook_Manager::Inst().hook_dx11(); - else if (!_wcsicmp(libname, L"d3d12.dll")) - Hook_Manager::Inst().hook_dx12(); - else if (!_wcsicmp(libname, L"opengl32.dll")) - Hook_Manager::Inst().hook_opengl(); -} - -HMODULE WINAPI Hook_Manager::MyLoadLibraryA(LPCTSTR lpLibFileName) -{ - auto res = _LoadLibraryA(lpLibFileName); - Hook_Manager::Inst().create_hookA(lpLibFileName); - return res; -} - -HMODULE WINAPI Hook_Manager::MyLoadLibraryW(LPCWSTR lpLibFileName) -{ - auto res = _LoadLibraryW(lpLibFileName); - Hook_Manager::Inst().create_hookW(lpLibFileName); - return res; -} - -HMODULE WINAPI Hook_Manager::MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -{ - auto res = _LoadLibraryA(lpLibFileName); - Hook_Manager::Inst().create_hookA(lpLibFileName); - return res; -} - -HMODULE WINAPI Hook_Manager::MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -{ - auto res = _LoadLibraryExW(lpLibFileName, hFile, dwFlags); - Hook_Manager::Inst().create_hookW(lpLibFileName); - return res; -} +//void Hook_Manager::create_hookW(const wchar_t *libname) +//{ +// if (!_wcsicmp(libname, L"d3d9.dll")) +// Hook_Manager::Inst().hook_dx9(); +// else if (!_wcsicmp(libname, L"d3d10.dll")) +// Hook_Manager::Inst().hook_dx10(); +// else if (!_wcsicmp(libname, L"d3d11.dll")) +// Hook_Manager::Inst().hook_dx11(); +// else if (!_wcsicmp(libname, L"d3d12.dll")) +// Hook_Manager::Inst().hook_dx12(); +// else if (!_wcsicmp(libname, L"opengl32.dll")) +// Hook_Manager::Inst().hook_opengl(); +//} +// +//HMODULE WINAPI Hook_Manager::MyLoadLibraryA(LPCTSTR lpLibFileName) +//{ +// auto res = _LoadLibraryA(lpLibFileName); +// Hook_Manager::Inst().create_hookA(lpLibFileName); +// return res; +//} +// +//HMODULE WINAPI Hook_Manager::MyLoadLibraryW(LPCWSTR lpLibFileName) +//{ +// auto res = _LoadLibraryW(lpLibFileName); +// Hook_Manager::Inst().create_hookW(lpLibFileName); +// return res; +//} +// +//HMODULE WINAPI Hook_Manager::MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +//{ +// auto res = _LoadLibraryA(lpLibFileName); +// Hook_Manager::Inst().create_hookA(lpLibFileName); +// return res; +//} +// +//HMODULE WINAPI Hook_Manager::MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +//{ +// auto res = _LoadLibraryExW(lpLibFileName, hFile, dwFlags); +// Hook_Manager::Inst().create_hookW(lpLibFileName); +// return res; +//} bool Hook_Manager::stop_retry() { @@ -394,25 +389,33 @@ bool Hook_Manager::stop_retry() return stop; } -void Hook_Manager::HookLoadLibrary() +void Hook_Manager::find_renderer(Hook_Manager* _this) { - if (!_renderer_found && !_loadlibrary_hooked) + _this->rendererdetect_hook = new Base_Hook(); + _this->AddHook(_this->rendererdetect_hook); + + std::vector const libraries = { "opengl32.dll", "d3d12.dll", "d3d11.dll", "d3d10.dll", "d3d9.dll" }; + + while (!_this->_renderer_found && !_this->stop_retry()) { - _loadlibrary_hooked = true; + std::vector::const_iterator it = libraries.begin(); + while (it != libraries.end()) + { + it = std::find_if(it, libraries.end(), [](std::string const& name) { + auto x = GetModuleHandle(name.c_str()); + if (x != NULL) + return true; + return false; + }); - rendererdetect_hook = new Base_Hook(); - AddHook(rendererdetect_hook); + if (it == libraries.end()) + break; - rendererdetect_hook->BeginHook(); + _this->create_hook(it->c_str()); + ++it; + } - rendererdetect_hook->HookFuncs( - std::pair((PVOID*)& _LoadLibraryA, &Hook_Manager::MyLoadLibraryA), - std::pair((PVOID*)& _LoadLibraryW, &Hook_Manager::MyLoadLibraryW), - std::pair((PVOID*)& _LoadLibraryExA, &Hook_Manager::MyLoadLibraryExA), - std::pair((PVOID*)& _LoadLibraryExW, &Hook_Manager::MyLoadLibraryExW) - ); - - rendererdetect_hook->EndHook(); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } @@ -444,24 +447,7 @@ Hook_Manager& Hook_Manager::Inst() void Hook_Manager::HookRenderer() { #ifdef STEAM_WIN32 - HookLoadLibrary(); - std::vector const libraries = { "opengl32.dll", "d3d12.dll", "d3d11.dll", "d3d10.dll", "d3d9.dll" }; - std::vector::const_iterator it = libraries.begin(); - while (it != libraries.end()) - { - it = std::find_if(it, libraries.end(), [](std::string const& name) { - auto x = GetModuleHandle(name.c_str()); - if (x != 0 && x != INVALID_HANDLE_VALUE) - return true; - return false; - }); - - if (it == libraries.end()) - break; - - create_hookA(it->c_str()); - ++it; - } + _hook_thread = new std::thread(&Hook_Manager::find_renderer, this); #endif } @@ -471,6 +457,9 @@ void Hook_Manager::FoundRenderer(Base_Hook* hook) { _renderer_found = true; + _hook_thread->join(); + delete _hook_thread; + // Remove all hooks that are unused _hooks.erase(std::remove_if(_hooks.begin(), _hooks.end(), [&hook](Base_Hook* it_hook) { if (hook != it_hook) @@ -480,8 +469,6 @@ void Hook_Manager::FoundRenderer(Base_Hook* hook) } return false; }), _hooks.end()); - - _loadlibrary_hooked = false; } } diff --git a/overlay_experimental/Hook_Manager.h b/overlay_experimental/Hook_Manager.h index 6ba20a03..ec0318e9 100644 --- a/overlay_experimental/Hook_Manager.h +++ b/overlay_experimental/Hook_Manager.h @@ -6,6 +6,7 @@ #ifndef NO_OVERLAY #include +#include #if defined(_WIN32) || defined(WIN32) #include @@ -31,6 +32,7 @@ protected: // If you do that, you should consider moving the renderer hooks to its own class and keep this one generic ? std::vector _hooks; + std::thread *_hook_thread; unsigned int _hook_retries; bool _renderer_found; // Is the renderer hooked ? bool _ogl_hooked; // wglMakeCurrent is hooked ? (opengl) @@ -44,7 +46,7 @@ protected: void hook_opengl(); bool stop_retry(); - void HookLoadLibrary(); + //void HookLoadLibrary(); #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) bool _loadlibrary_hooked; // Are the LoadLibrary functions hooked ? @@ -66,13 +68,15 @@ protected: // Setup DX12 Device and get vtable void hook_dx12(); - void create_hookA(const char* libname); - void create_hookW(const wchar_t* libname); + void create_hook(const char* libname); + //void create_hookW(const wchar_t* libname); - static HMODULE WINAPI MyLoadLibraryA(LPCTSTR lpLibFileName); - static HMODULE WINAPI MyLoadLibraryW(LPCWSTR lpLibFileName); - static HMODULE WINAPI MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); - static HMODULE WINAPI MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); + static void find_renderer(Hook_Manager* _this); + + //static HMODULE WINAPI MyLoadLibraryA(LPCTSTR lpLibFileName); + //static HMODULE WINAPI MyLoadLibraryW(LPCWSTR lpLibFileName); + //static HMODULE WINAPI MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); + //static HMODULE WINAPI MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); // If this is called, then DX10, DX11 or DX12 will be used to render overlay static HRESULT STDMETHODCALLTYPE MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags); // If any of theses is called, then DX9 will be used to render overlay