From 40615d07a71de421093b4eee77c61bb3ca5a2c8b Mon Sep 17 00:00:00 2001 From: Nemirtingas Date: Fri, 16 Aug 2019 10:36:44 +0200 Subject: [PATCH] Reworked how renderers are hooked. Some games doesn't initialise Steam before initalizing their Renderer (even if the doc says to) . So instead of waiting for the game to initialize it, hook to the rendering functions and deduce which implementation should be used. --- overlay_experimental/DX10_Hook.cpp | 40 +-- overlay_experimental/DX10_Hook.h | 4 +- overlay_experimental/DX11_Hook.cpp | 45 +-- overlay_experimental/DX11_Hook.h | 4 +- overlay_experimental/DX12_Hook.cpp | 27 +- overlay_experimental/DX12_Hook.h | 4 +- overlay_experimental/DX9_Hook.cpp | 59 ++-- overlay_experimental/DX9_Hook.h | 8 +- overlay_experimental/Hook_Manager.cpp | 388 +++++++++++++++++++++----- overlay_experimental/Hook_Manager.h | 69 ++++- overlay_experimental/OpenGL_Hook.cpp | 33 ++- overlay_experimental/OpenGL_Hook.h | 6 +- 12 files changed, 497 insertions(+), 190 deletions(-) diff --git a/overlay_experimental/DX10_Hook.cpp b/overlay_experimental/DX10_Hook.cpp index de6e118..4fdc274 100644 --- a/overlay_experimental/DX10_Hook.cpp +++ b/overlay_experimental/DX10_Hook.cpp @@ -17,11 +17,12 @@ void DX10_Hook::start_hook() if (!_hooked) { Hook_Manager::Inst().FoundRenderer(this); - Hook_Manager::Inst().FoundHook(this); IDXGISwapChain* pSwapChain; ID3D10Device* pDevice; DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; + decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain = + (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D10CreateDeviceAndSwapChain"); SwapChainDesc.BufferCount = 1; SwapChainDesc.BufferDesc.Width = 1; SwapChainDesc.BufferDesc.Height = 1; @@ -128,16 +129,16 @@ void DX10_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain) // return res; //} -HRESULT WINAPI DX10_Hook::MyD3D10CreateDeviceAndSwapChain(IDXGIAdapter* pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, UINT SDKVersion, - DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IDXGISwapChain** ppSwapChain, ID3D10Device** ppDevice) -{ - auto res = hook->D3D10CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice); - - if (SUCCEEDED(res)) - hook->hook_dx10(SDKVersion); - - return res; -} +//HRESULT WINAPI DX10_Hook::MyD3D10CreateDeviceAndSwapChain(IDXGIAdapter* pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, UINT SDKVersion, +// DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IDXGISwapChain** ppSwapChain, ID3D10Device** ppDevice) +//{ +// auto res = hook->D3D10CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice); +// +// if (SUCCEEDED(res)) +// hook->hook_dx10(SDKVersion); +// +// return res; +//} ///////////////////////////////////////////////////////////////////////////////////// HRESULT STDMETHODCALLTYPE DX10_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags) @@ -168,14 +169,14 @@ DX10_Hook::DX10_Hook(): // Hook to D3D10CreateDevice and D3D10CreateDeviceAndSwapChain so we know when it gets called. // If its called, then DX10 will be used to render the overlay. //_D3D10CreateDevice = (decltype(_D3D10CreateDevice))GetProcAddress(_dll, "D3D10CreateDevice"); - D3D10CreateDeviceAndSwapChain = (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D10CreateDeviceAndSwapChain"); - - BeginHook(); - HookFuncs( - //std::make_pair(&(PVOID&)_D3D10CreateDevice, &DX10_Hook::MyD3D10CreateDevice), - std::make_pair(&(PVOID&)D3D10CreateDeviceAndSwapChain, &DX10_Hook::MyD3D10CreateDeviceAndSwapChain) - ); - EndHook(); + //D3D10CreateDeviceAndSwapChain = (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D10CreateDeviceAndSwapChain"); + // + //BeginHook(); + //HookFuncs( + // //std::make_pair(&(PVOID&)_D3D10CreateDevice, &DX10_Hook::MyD3D10CreateDevice), + // std::make_pair(&(PVOID&)D3D10CreateDeviceAndSwapChain, &DX10_Hook::MyD3D10CreateDeviceAndSwapChain) + //); + //EndHook(); } DX10_Hook::~DX10_Hook() @@ -193,6 +194,7 @@ void DX10_Hook::Create() if (hook == nullptr) { hook = new DX10_Hook; + hook->start_hook(); // Register the hook to the Hook Manager Hook_Manager::Inst().AddHook(hook); } diff --git a/overlay_experimental/DX10_Hook.h b/overlay_experimental/DX10_Hook.h index a4869f2..d23338a 100644 --- a/overlay_experimental/DX10_Hook.h +++ b/overlay_experimental/DX10_Hook.h @@ -37,10 +37,10 @@ private: // Hook functions so we know we use DX10 //static decltype(D3D10CreateDevice) MyD3D10CreateDevice; - static decltype(D3D10CreateDeviceAndSwapChain) MyD3D10CreateDeviceAndSwapChain; + //static decltype(D3D10CreateDeviceAndSwapChain) MyD3D10CreateDeviceAndSwapChain; //decltype(D3D10CreateDevice)* _D3D10CreateDevice; - decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain; + //decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain; public: static void Create(); // Initialize DX10 Hook. diff --git a/overlay_experimental/DX11_Hook.cpp b/overlay_experimental/DX11_Hook.cpp index ebc0fe9..41ffd9c 100644 --- a/overlay_experimental/DX11_Hook.cpp +++ b/overlay_experimental/DX11_Hook.cpp @@ -27,11 +27,12 @@ void DX11_Hook::start_hook() if (!_hooked) { Hook_Manager::Inst().FoundRenderer(this); - Hook_Manager::Inst().FoundHook(this); IDXGISwapChain* pSwapChain; ID3D11Device* pDevice; DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; + decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain = + (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D11CreateDeviceAndSwapChain"); SwapChainDesc.BufferCount = 1; SwapChainDesc.BufferDesc.Width = 1; SwapChainDesc.BufferDesc.Height = 1; @@ -143,18 +144,18 @@ void DX11_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain) // return res; //} -HRESULT WINAPI DX11_Hook::MyD3D11CreateDeviceAndSwapChain(__in_opt IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, - __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, - __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, __out_opt IDXGISwapChain** ppSwapChain, __out_opt ID3D11Device** ppDevice, - __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, __out_opt ID3D11DeviceContext** ppImmediateContext) -{ - auto res = hook->D3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); - - if (SUCCEEDED(res)) - hook->hook_dx11(SDKVersion); - - return res; -} +//HRESULT WINAPI DX11_Hook::MyD3D11CreateDeviceAndSwapChain(__in_opt IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, +// __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, +// __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, __out_opt IDXGISwapChain** ppSwapChain, __out_opt ID3D11Device** ppDevice, +// __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, __out_opt ID3D11DeviceContext** ppImmediateContext) +//{ +// auto res = hook->D3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); +// +// if (SUCCEEDED(res)) +// hook->hook_dx11(SDKVersion); +// +// return res; +//} ///////////////////////////////////////////////////////////////////////////////////// HRESULT STDMETHODCALLTYPE DX11_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags) @@ -186,15 +187,14 @@ DX11_Hook::DX11_Hook(): // Hook to D3D11CreateDevice and D3D11CreateDeviceAndSwapChain so we know when it gets called. // If its called, then DX11 will be used to render the overlay. //D3D11CreateDevice = (decltype(D3D11CreateDevice))GetProcAddress(_dll, "D3D11CreateDevice"); - D3D11CreateDeviceAndSwapChain = (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D11CreateDeviceAndSwapChain"); - - BeginHook(); - HookFuncs( - //std::make_pair(&(PVOID&)D3D11CreateDevice, &DX11_Hook::MyD3D11CreateDevice), - std::make_pair(&(PVOID&)D3D11CreateDeviceAndSwapChain, &DX11_Hook::MyD3D11CreateDeviceAndSwapChain) - ); - EndHook(); - + //D3D11CreateDeviceAndSwapChain = (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D11CreateDeviceAndSwapChain"); + // + //BeginHook(); + //HookFuncs( + // //std::make_pair(&(PVOID&)D3D11CreateDevice, &DX11_Hook::MyD3D11CreateDevice), + // std::make_pair(&(PVOID&)D3D11CreateDeviceAndSwapChain, &DX11_Hook::MyD3D11CreateDeviceAndSwapChain) + //); + //EndHook(); } DX11_Hook::~DX11_Hook() @@ -212,6 +212,7 @@ void DX11_Hook::Create() if (hook == nullptr) { hook = new DX11_Hook; + hook->start_hook(); // Register the hook to the Hook Manager Hook_Manager::Inst().AddHook(hook); } diff --git a/overlay_experimental/DX11_Hook.h b/overlay_experimental/DX11_Hook.h index d32b032..031ee9c 100644 --- a/overlay_experimental/DX11_Hook.h +++ b/overlay_experimental/DX11_Hook.h @@ -37,10 +37,10 @@ private: // Hook functions so we know we use DX11 //static decltype(D3D11CreateDevice) MyD3D11CreateDevice; - static decltype(D3D11CreateDeviceAndSwapChain) MyD3D11CreateDeviceAndSwapChain; + //static decltype(D3D11CreateDeviceAndSwapChain) MyD3D11CreateDeviceAndSwapChain; //decltype(D3D11CreateDevice)* D3D11CreateDevice; - decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain; + //decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain; public: static void Create(); // Initialize DX11 Hook. diff --git a/overlay_experimental/DX12_Hook.cpp b/overlay_experimental/DX12_Hook.cpp index 5453193..924e9fe 100644 --- a/overlay_experimental/DX12_Hook.cpp +++ b/overlay_experimental/DX12_Hook.cpp @@ -96,19 +96,19 @@ void DX12_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain) ///////////////////////////////////////////////////////////////////////////////////// // DirectX 12 Initialization functions -HRESULT WINAPI DX12_Hook::MyD3D12CreateDevice( - _In_opt_ IUnknown* pAdapter, - D3D_FEATURE_LEVEL MinimumFeatureLevel, - _In_ REFIID riid, // Expected: ID3D12Device - _COM_Outptr_opt_ void** ppDevice) -{ - auto res = hook->D3D12CreateDevice(pAdapter, MinimumFeatureLevel, riid, ppDevice); - - if (SUCCEEDED(res)) - hook->hook_dx12(MinimumFeatureLevel); - - return res; -} +//HRESULT WINAPI DX12_Hook::MyD3D12CreateDevice( +// _In_opt_ IUnknown* pAdapter, +// D3D_FEATURE_LEVEL MinimumFeatureLevel, +// _In_ REFIID riid, // Expected: ID3D12Device +// _COM_Outptr_opt_ void** ppDevice) +//{ +// auto res = hook->D3D12CreateDevice(pAdapter, MinimumFeatureLevel, riid, ppDevice); +// +// if (SUCCEEDED(res)) +// hook->hook_dx12(MinimumFeatureLevel); +// +// return res; +//} ///////////////////////////////////////////////////////////////////////////////////// HRESULT STDMETHODCALLTYPE DX12_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags) @@ -166,6 +166,7 @@ void DX12_Hook::Create() if (hook == nullptr) { hook = new DX12_Hook; + hook->start_hook(); // Register the hook to the Hook Manager Hook_Manager::Inst().AddHook(hook); } diff --git a/overlay_experimental/DX12_Hook.h b/overlay_experimental/DX12_Hook.h index cbc7cb0..555826f 100644 --- a/overlay_experimental/DX12_Hook.h +++ b/overlay_experimental/DX12_Hook.h @@ -38,9 +38,9 @@ private: decltype(&IDXGISwapChain::ResizeTarget) ResizeTarget; // Hook functions so we know we use DX11 - static decltype(D3D12CreateDevice) MyD3D12CreateDevice; + //static decltype(D3D12CreateDevice) MyD3D12CreateDevice; - decltype(D3D12CreateDevice)* D3D12CreateDevice; + //decltype(D3D12CreateDevice)* D3D12CreateDevice; public: static void Create(); // Initialize DX11 Hook. diff --git a/overlay_experimental/DX9_Hook.cpp b/overlay_experimental/DX9_Hook.cpp index 82be136..9fbad2b 100644 --- a/overlay_experimental/DX9_Hook.cpp +++ b/overlay_experimental/DX9_Hook.cpp @@ -23,10 +23,10 @@ void DX9_Hook::start_hook() if (!_hooked) { Hook_Manager::Inst().FoundRenderer(this); - Hook_Manager::Inst().FoundHook(this); IDirect3D9Ex* pD3D; IDirect3DDevice9Ex* pDeviceEx; + decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(_dll, "Direct3DCreate9Ex"); Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D); @@ -118,25 +118,25 @@ void DX9_Hook::prepareForOverlay(IDirect3DDevice9 *pDevice) ///////////////////////////////////////////////////////////////////////////////////// // DirectX 9 Initialization functions -IDirect3D9* DX9_Hook::MyDirect3DCreate9(UINT SDKVersion) -{ - auto res = hook->Direct3DCreate9(SDKVersion); - - if( res != nullptr ) - hook->hook_dx9(SDKVersion); - - return res; -} - -HRESULT DX9_Hook::MyDirect3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppDevice) -{ - auto res = hook->Direct3DCreate9Ex(SDKVersion, ppDevice); - - if (SUCCEEDED(res)) - hook->hook_dx9(SDKVersion); - - return res; -} +//IDirect3D9* DX9_Hook::MyDirect3DCreate9(UINT SDKVersion) +//{ +// auto res = hook->Direct3DCreate9(SDKVersion); +// +// if( res != nullptr ) +// hook->hook_dx9(SDKVersion); +// +// return res; +//} +// +//HRESULT DX9_Hook::MyDirect3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppDevice) +//{ +// auto res = hook->Direct3DCreate9Ex(SDKVersion, ppDevice); +// +// if (SUCCEEDED(res)) +// hook->hook_dx9(SDKVersion); +// +// return res; +//} ///////////////////////////////////////////////////////////////////////////////////// HRESULT STDMETHODCALLTYPE DX9_Hook::MyReset(IDirect3DDevice9* _this, D3DPRESENT_PARAMETERS* pPresentationParameters) @@ -177,15 +177,15 @@ DX9_Hook::DX9_Hook(): _dll = GetModuleHandle(DLL_NAME); // Hook to Direct3DCreate9 and Direct3DCreate9Ex so we know when it gets called. // If its called, then DX9 will be used to render the overlay. - Direct3DCreate9 = (decltype(Direct3DCreate9))GetProcAddress(_dll, "Direct3DCreate9"); - Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(_dll, "Direct3DCreate9Ex"); - - BeginHook(); - HookFuncs( - std::make_pair(&(PVOID&)Direct3DCreate9, &DX9_Hook::MyDirect3DCreate9), - std::make_pair(&(PVOID&)Direct3DCreate9Ex, &DX9_Hook::MyDirect3DCreate9Ex) - ); - EndHook(); + //Direct3DCreate9 = (decltype(Direct3DCreate9))GetProcAddress(_dll, "Direct3DCreate9"); + //Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(_dll, "Direct3DCreate9Ex"); + // + //BeginHook(); + //HookFuncs( + // std::make_pair(&(PVOID&)Direct3DCreate9, &DX9_Hook::MyDirect3DCreate9), + // std::make_pair(&(PVOID&)Direct3DCreate9Ex, &DX9_Hook::MyDirect3DCreate9Ex) + //); + //EndHook(); } DX9_Hook::~DX9_Hook() @@ -209,6 +209,7 @@ void DX9_Hook::Create() if( hook == nullptr ) { hook = new DX9_Hook; + hook->start_hook(); // Register the hook to the Hook Manager Hook_Manager::Inst().AddHook(hook); } diff --git a/overlay_experimental/DX9_Hook.h b/overlay_experimental/DX9_Hook.h index 310ce6d..e20913a 100644 --- a/overlay_experimental/DX9_Hook.h +++ b/overlay_experimental/DX9_Hook.h @@ -37,11 +37,11 @@ private: static HRESULT STDMETHODCALLTYPE MyPresentEx(IDirect3DDevice9Ex* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags); // Hook functions so we know we use DX9 - static decltype(Direct3DCreate9) MyDirect3DCreate9; - static decltype(Direct3DCreate9Ex) MyDirect3DCreate9Ex; + //static decltype(Direct3DCreate9) MyDirect3DCreate9; + //static decltype(Direct3DCreate9Ex) MyDirect3DCreate9Ex; - decltype(Direct3DCreate9)* Direct3DCreate9; - decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex; + //decltype(Direct3DCreate9)* Direct3DCreate9; + //decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex; public: static void Create(); // Initialize DX9 Hook. diff --git a/overlay_experimental/Hook_Manager.cpp b/overlay_experimental/Hook_Manager.cpp index 16f2d01..7d8871a 100644 --- a/overlay_experimental/Hook_Manager.cpp +++ b/overlay_experimental/Hook_Manager.cpp @@ -5,78 +5,368 @@ #include "../detours/detours.h" +#ifdef STEAM_WIN32 #include "DX12_Hook.h" #include "DX11_Hook.h" #include "DX10_Hook.h" #include "DX9_Hook.h" +#endif + #include "OpenGL_Hook.h" #include +#ifdef STEAM_WIN32 decltype(LoadLibraryA )* _LoadLibraryA = LoadLibraryA; decltype(LoadLibraryW )* _LoadLibraryW = LoadLibraryW; decltype(LoadLibraryExA )* _LoadLibraryExA = LoadLibraryExA; decltype(LoadLibraryExW )* _LoadLibraryExW = LoadLibraryExW; -void create_hookA(const char* libname) +decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present; +decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present; +decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx; +decltype(wglMakeCurrent)* _wglMakeCurrent; + +HRESULT STDMETHODCALLTYPE Hook_Manager::MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags) +{ + IUnknown *pDevice; + _this->GetDevice(__uuidof(ID3D10Device), (void**)&pDevice); + if (pDevice) + { + Hook_Manager::Inst().UnHookAllRendererDetector(); + DX10_Hook::Create(); + } + else + { + _this->GetDevice(__uuidof(ID3D11Device), (void**)& pDevice); + if (pDevice) + { + Hook_Manager::Inst().UnHookAllRendererDetector(); + DX11_Hook::Create(); + } + else + { + _this->GetDevice(__uuidof(ID3D12Device), (void**)& pDevice); + if (pDevice) + { + Hook_Manager::Inst().UnHookAllRendererDetector(); + DX12_Hook::Create(); + } + } + } + if (pDevice) pDevice->Release(); + + return (_this->*_IDXGISwapChain_Present)(SyncInterval, Flags); +} + +HRESULT STDMETHODCALLTYPE Hook_Manager::MyPresent(IDirect3DDevice9* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) +{ + Hook_Manager::Inst().UnHookAllRendererDetector(); + DX9_Hook::Create(); + return (_this->*_IDirect3DDevice9_Present)(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); +} + +HRESULT STDMETHODCALLTYPE Hook_Manager::MyPresentEx(IDirect3DDevice9Ex* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) +{ + Hook_Manager::Inst().UnHookAllRendererDetector(); + DX9_Hook::Create(); + return (_this->*_IDirect3DDevice9Ex_PresentEx)(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags); +} + +BOOL WINAPI Hook_Manager::MywglMakeCurrent(HDC hDC, HGLRC hGLRC) +{ + Hook_Manager::Inst().UnHookAllRendererDetector(); + OpenGL_Hook::Create(); + return _wglMakeCurrent(hDC, hGLRC);; +} + +void Hook_Manager::HookDXGIPresent() +{ + if (!_dxgi_hooked) + { + rendererdetect_hook->BeginHook(); + + rendererdetect_hook->HookFuncs( + std::pair((PVOID*)& _IDXGISwapChain_Present, &Hook_Manager::MyIDXGISwapChain_Present) + ); + + rendererdetect_hook->EndHook(); + } +} + +void Hook_Manager::HookDX9Present() +{ + if (!_dx9_hooked) + { + rendererdetect_hook->BeginHook(); + + rendererdetect_hook->HookFuncs( + std::pair((PVOID*)& _IDirect3DDevice9_Present, &Hook_Manager::MyPresent), + std::pair((PVOID*)& _IDirect3DDevice9Ex_PresentEx, &Hook_Manager::MyPresentEx) + ); + + rendererdetect_hook->EndHook(); + } +} + +void Hook_Manager::HookwglMakeCurrent() +{ + if (!_ogl_hooked) + { + rendererdetect_hook->BeginHook(); + + rendererdetect_hook->HookFuncs( + std::pair((PVOID*)& _wglMakeCurrent, &Hook_Manager::MywglMakeCurrent) + ); + + rendererdetect_hook->EndHook(); + } +} + +void Hook_Manager::hook_dx9() +{ + if (!_dx9_hooked && !_renderer_found) + { + IDirect3D9Ex* pD3D; + IDirect3DDevice9Ex* pDeviceEx; + decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(GetModuleHandle(DX9_Hook::DLL_NAME), "Direct3DCreate9Ex"); + + Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D); + + D3DPRESENT_PARAMETERS params = {}; + params.BackBufferWidth = 1; + params.BackBufferHeight = 1; + params.hDeviceWindow = GetForegroundWindow(); + + pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, &pDeviceEx); + + if (pDeviceEx) + { + PRINT_DEBUG("Hooked D3D9::Present to detect DX Version\n"); + (void*&)_IDirect3DDevice9_Present = (*reinterpret_cast(pDeviceEx))[(int)IDirect3DDevice9VTable::Present]; + (void*&)_IDirect3DDevice9Ex_PresentEx = (*reinterpret_cast(pDeviceEx))[(int)IDirect3DDevice9VTable::PresentEx]; + HookDX9Present(); + } + else + { + PRINT_DEBUG("Failed to hook D3D9::Present to detect DX Version\n"); + } + + if (pDeviceEx)pDeviceEx->Release(); + if (pD3D)pD3D->Release(); + } +} + +void Hook_Manager::hook_dx10() +{ + if (!_dxgi_hooked && !_renderer_found) + { + IDXGISwapChain* pSwapChain; + ID3D10Device* pDevice; + DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; + decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain = + (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(GetModuleHandle(DX10_Hook::DLL_NAME), "D3D10CreateDeviceAndSwapChain"); + SwapChainDesc.BufferCount = 1; + SwapChainDesc.BufferDesc.Width = 1; + SwapChainDesc.BufferDesc.Height = 1; + SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; + SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + SwapChainDesc.OutputWindow = GetForegroundWindow(); + SwapChainDesc.SampleDesc.Count = 1; + SwapChainDesc.SampleDesc.Quality = 0; + SwapChainDesc.Windowed = TRUE; + + D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDevice); + + if (pDevice != nullptr && pSwapChain != nullptr) + { + PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); + (void*&)_IDXGISwapChain_Present = (*reinterpret_cast(pSwapChain))[(int)IDXGISwapChainVTable::Present]; + HookDXGIPresent(); + } + else + { + PRINT_DEBUG("Failed to Hook IDXGISwapChain::Present to detect DX Version\n"); + } + if (pDevice)pDevice->Release(); + if (pSwapChain)pSwapChain->Release(); + } +} + +void Hook_Manager::hook_dx11() +{ + if (!_dxgi_hooked && !_renderer_found) + { + IDXGISwapChain* pSwapChain; + ID3D11Device* pDevice; + DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; + decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain = + (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(GetModuleHandle(DX11_Hook::DLL_NAME), "D3D11CreateDeviceAndSwapChain"); + SwapChainDesc.BufferCount = 1; + SwapChainDesc.BufferDesc.Width = 1; + SwapChainDesc.BufferDesc.Height = 1; + SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; + SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + SwapChainDesc.OutputWindow = GetForegroundWindow(); + SwapChainDesc.SampleDesc.Count = 1; + SwapChainDesc.SampleDesc.Quality = 0; + SwapChainDesc.Windowed = TRUE; + + D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, NULL, D3D11_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDevice, NULL, NULL); + + if (pDevice != nullptr && pSwapChain != nullptr) + { + PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); + (void*&)_IDXGISwapChain_Present = (*reinterpret_cast(pSwapChain))[(int)IDXGISwapChainVTable::Present]; + HookDXGIPresent(); + } + else + { + PRINT_DEBUG("Failed to Hook IDXGISwapChain::Present to detect DX Version\n"); + } + + if (pDevice) pDevice->Release(); + if (pSwapChain) pSwapChain->Release(); + } +} + +void Hook_Manager::hook_dx12() +{ + if (!_dxgi_hooked && !_renderer_found) + { + DX12_Hook::Create(); + } +} + +void Hook_Manager::hook_opengl() +{ + if (!_ogl_hooked && !_renderer_found) + { + _wglMakeCurrent = (decltype(_wglMakeCurrent))GetProcAddress(GetModuleHandle(OpenGL_Hook::DLL_NAME), "wglMakeCurrent"); + HookwglMakeCurrent(); + } +} + +void Hook_Manager::create_hookA(const char* libname) { if (!_stricmp(libname, "d3d9.dll")) - DX9_Hook::Create(); + Hook_Manager::Inst().hook_dx9(); else if (!_stricmp(libname, "d3d10.dll")) - DX10_Hook::Create(); + Hook_Manager::Inst().hook_dx10(); else if (!_stricmp(libname, "d3d11.dll")) - DX11_Hook::Create(); + Hook_Manager::Inst().hook_dx11(); else if (!_stricmp(libname, "d3d12.dll")) - DX12_Hook::Create(); + Hook_Manager::Inst().hook_dx12(); else if (!_stricmp(libname, "opengl32.dll")) - OpenGL_Hook::Create(); + Hook_Manager::Inst().hook_opengl(); } -void create_hookW(const wchar_t *libname) +void Hook_Manager::create_hookW(const wchar_t *libname) { if (!_wcsicmp(libname, L"d3d9.dll")) - DX9_Hook::Create(); + Hook_Manager::Inst().hook_dx9(); else if (!_wcsicmp(libname, L"d3d10.dll")) - DX10_Hook::Create(); + Hook_Manager::Inst().hook_dx10(); else if (!_wcsicmp(libname, L"d3d11.dll")) - DX11_Hook::Create(); + Hook_Manager::Inst().hook_dx11(); else if (!_wcsicmp(libname, L"d3d12.dll")) - DX12_Hook::Create(); + Hook_Manager::Inst().hook_dx12(); else if (!_wcsicmp(libname, L"opengl32.dll")) - OpenGL_Hook::Create(); + Hook_Manager::Inst().hook_opengl(); } -HMODULE WINAPI mLoadLibraryA(LPCTSTR lpLibFileName) +HMODULE WINAPI Hook_Manager::MyLoadLibraryA(LPCTSTR lpLibFileName) { auto res = _LoadLibraryA(lpLibFileName); - create_hookA(lpLibFileName); + Hook_Manager::Inst().create_hookA(lpLibFileName); return res; } -HMODULE WINAPI mLoadLibraryW(LPCWSTR lpLibFileName) +HMODULE WINAPI Hook_Manager::MyLoadLibraryW(LPCWSTR lpLibFileName) { auto res = _LoadLibraryW(lpLibFileName); - create_hookW(lpLibFileName); + Hook_Manager::Inst().create_hookW(lpLibFileName); return res; } -HMODULE WINAPI mLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +HMODULE WINAPI Hook_Manager::MyLoadLibraryExA(LPCTSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) { auto res = _LoadLibraryA(lpLibFileName); - create_hookA(lpLibFileName); + Hook_Manager::Inst().create_hookA(lpLibFileName); return res; } -HMODULE WINAPI mLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +HMODULE WINAPI Hook_Manager::MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) { auto res = _LoadLibraryExW(lpLibFileName, hFile, dwFlags); - create_hookW(lpLibFileName); + Hook_Manager::Inst().create_hookW(lpLibFileName); return res; } +void Hook_Manager::HookLoadLibrary() +{ + if (!_renderer_found && !_loadlibrary_hooked) + { + _loadlibrary_hooked = true; + + rendererdetect_hook = new Base_Hook(); + AddHook(rendererdetect_hook); + + rendererdetect_hook->BeginHook(); + + 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(); + } +} + +void Hook_Manager::ChangeGameWindow(HWND hWnd) const +{ + overlay->HookReady(hWnd); +} + +void Hook_Manager::CallOverlayProc(int width, int height) const +{ + overlay->OverlayProc(width, height); +} + +#endif + +void Hook_Manager::UnHookAllRendererDetector() +{ + auto it = std::find(_hooks.begin(), _hooks.end(), rendererdetect_hook); + if (it != _hooks.end()) + { + _hooks.erase(it); + delete rendererdetect_hook; + rendererdetect_hook = nullptr; + } + _ogl_hooked = false; + +#ifdef STEAM_WIN32 + _dxgi_hooked = _dx9_hooked = false; +#endif +} + Hook_Manager::Hook_Manager(): - _isSet(false), - _LoadLibraryHooked(false) +#ifdef STEAM_WIN32 + _game_hwnd(nullptr), + _game_wndproc(nullptr), + _loadlibrary_hooked(false), + _dxgi_hooked(false), + _dx9_hooked(false), +#endif + _renderer_found(false), + _ogl_hooked(false) {} Hook_Manager::~Hook_Manager() @@ -94,6 +384,7 @@ Hook_Manager& Hook_Manager::Inst() void Hook_Manager::HookRenderer(Steam_Overlay *ovlay) { overlay = ovlay; +#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(); @@ -112,47 +403,14 @@ void Hook_Manager::HookRenderer(Steam_Overlay *ovlay) create_hookA(it->c_str()); ++it; } +#endif } -void Hook_Manager::UnHookLoadLibrary() +void Hook_Manager::FoundRenderer(Base_Hook* hook) { - _LoadLibraryHooked = false; - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - - DetourDetach((PVOID*)& _LoadLibraryA, mLoadLibraryA); - DetourDetach((PVOID*)& _LoadLibraryW, mLoadLibraryW); - DetourDetach((PVOID*)& _LoadLibraryExA, mLoadLibraryExA); - DetourDetach((PVOID*)& _LoadLibraryExW, mLoadLibraryExW); - - DetourTransactionCommit(); -} - -void Hook_Manager::HookLoadLibrary() -{ - if (!_isSet && !_LoadLibraryHooked) + if (!_renderer_found) { - _LoadLibraryHooked = true; - - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - - DetourAttach((PVOID*)& _LoadLibraryA, mLoadLibraryA); - DetourAttach((PVOID*)& _LoadLibraryW, mLoadLibraryW); - DetourAttach((PVOID*)& _LoadLibraryExA, mLoadLibraryExA); - DetourAttach((PVOID*)& _LoadLibraryExW, mLoadLibraryExW); - - DetourTransactionCommit(); - } -} - -void Hook_Manager::FoundHook(Base_Hook* hook) -{ - if (!_isSet) - { - _isSet = true; - - UnHookLoadLibrary(); + _renderer_found = true; // Remove all hooks that are unused _hooks.erase(std::remove_if(_hooks.begin(), _hooks.end(), [&hook](Base_Hook* it_hook) { @@ -163,17 +421,9 @@ void Hook_Manager::FoundHook(Base_Hook* hook) } return false; }), _hooks.end()); + + _loadlibrary_hooked = false; } } -void Hook_Manager::ChangeGameWindow(HWND hWnd) const -{ - overlay->HookReady(hWnd); -} - -void Hook_Manager::CallOverlayProc(int width, int height) const -{ - overlay->OverlayProc(width, height); -} - #endif//NO_OVERLAY \ No newline at end of file diff --git a/overlay_experimental/Hook_Manager.h b/overlay_experimental/Hook_Manager.h index 529b828..bffe287 100644 --- a/overlay_experimental/Hook_Manager.h +++ b/overlay_experimental/Hook_Manager.h @@ -5,9 +5,19 @@ #ifndef NO_OVERLAY -#include #include +#if defined(_WIN32) || defined(WIN32) +#include + +struct IDXGISwapChain; +struct IDirect3DDevice9; +struct IDirect3DDevice9Ex; +#endif + +/* + * + */ class Hook_Manager { friend class Base_Hook; @@ -16,20 +26,59 @@ public: using hookReady_t = void(*)(void*); protected: - std::vector _hooks; + // TODO: If needed, create a second vector with only the renderers hook + // Cause actually, a call to FoundRenderer will unhook everything registered except the renderer hook + // If you do that, you should consider moving the renderer hooks to its own class and keep this one generic ? + std::vector _hooks; - WNDPROC _gameWndProc; // The game main windows proc - HWND _gameHWnd; // The game main window - bool _showOverlay; // Should we render the overlay - bool _isSet; // Is the renderer hooked ? - bool _LoadLibraryHooked; // Are the LoadLibrary functions hooked ? + bool _renderer_found; // Is the renderer hooked ? + bool _ogl_hooked; // wglMakeCurrent is hooked ? (opengl) + Base_Hook* rendererdetect_hook; class Steam_Overlay* overlay; Hook_Manager(); virtual ~Hook_Manager(); + void UnHookAllRendererDetector(); + + void hook_opengl(); + void HookLoadLibrary(); - void UnHookLoadLibrary(); + +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) + WNDPROC _game_wndproc; // The game main window proc + HWND _game_hwnd; // The game main window + bool _loadlibrary_hooked; // Are the LoadLibrary functions hooked ? + bool _dx9_hooked; // DX9 Present and PresentEx Hooked ? + bool _dxgi_hooked; // DXGI Present is hooked ? (DX10, DX11, DX12) + + void HookDXGIPresent(); + void HookDX9Present(); + void HookwglMakeCurrent(); + void hook_dx9(); + void hook_dx10(); + void hook_dx11(); + void hook_dx12(); + void create_hookA(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 HRESULT STDMETHODCALLTYPE MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags); + static HRESULT STDMETHODCALLTYPE MyPresent(IDirect3DDevice9* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion); + static HRESULT STDMETHODCALLTYPE MyPresentEx(IDirect3DDevice9Ex* _this, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags); + static BOOL WINAPI MywglMakeCurrent(HDC hDC, HGLRC hGLRC); + +public: + void ChangeGameWindow(HWND hWnd) const; + +protected: + +#elif defined(__linux__) + +#endif public: static Hook_Manager& Inst(); @@ -37,10 +86,10 @@ public: void HookRenderer(Steam_Overlay *overlay); // Set the found hook and free all other hooks - void FoundHook(Base_Hook *hook); + void FoundRenderer(Base_Hook *hook); inline void AddHook(Base_Hook* hook) { _hooks.push_back(hook); } - void ChangeGameWindow(HWND hWnd) const; + void CallOverlayProc(int width, int height) const; Steam_Overlay* GetOverlay() const { return overlay; } }; diff --git a/overlay_experimental/OpenGL_Hook.cpp b/overlay_experimental/OpenGL_Hook.cpp index b960485..7211883 100644 --- a/overlay_experimental/OpenGL_Hook.cpp +++ b/overlay_experimental/OpenGL_Hook.cpp @@ -21,7 +21,6 @@ void OpenGL_Hook::start_hook() if (!_hooked) { Hook_Manager::Inst().FoundRenderer(this); - Hook_Manager::Inst().FoundHook(this); GLenum err = glewInit(); @@ -65,6 +64,9 @@ void OpenGL_Hook::prepareForOverlay(HDC hDC) GetClientRect(hWnd, &rect); + if (hWnd != Hook_Manager::Inst().GetOverlay()->GetGameHwnd()) + resetRenderState(); + if (!initialized) { ImGui::CreateContext(); @@ -94,12 +96,12 @@ void OpenGL_Hook::prepareForOverlay(HDC hDC) ///////////////////////////////////////////////////////////////////////////////////// // OpenGL Initialization functions -BOOL WINAPI OpenGL_Hook::MywglMakeCurrent(HDC hDC, HGLRC hGLRC) -{ - auto res = hook->wglMakeCurrent(hDC, hGLRC); - hook->hook_ogl(); - return res; -} +//BOOL WINAPI OpenGL_Hook::MywglMakeCurrent(HDC hDC, HGLRC hGLRC) +//{ +// auto res = hook->wglMakeCurrent(hDC, hGLRC); +// hook->hook_ogl(); +// return res; +//} ///////////////////////////////////////////////////////////////////////////////////// BOOL WINAPI OpenGL_Hook::MywglSwapBuffers(HDC hDC) @@ -115,14 +117,14 @@ OpenGL_Hook::OpenGL_Hook(): _dll = GetModuleHandle(DLL_NAME); // Hook to wglMakeCurrent so we know when it gets called. // If its called, then OpenGL will be used to render the overlay. - wglMakeCurrent = (decltype(wglMakeCurrent))GetProcAddress(_dll, "wglMakeCurrent"); - wglSwapBuffers = (decltype(wglSwapBuffers))GetProcAddress(_dll, "wglSwapBuffers"); - - BeginHook(); - HookFuncs( - std::make_pair(&(PVOID&)wglMakeCurrent, &OpenGL_Hook::MywglMakeCurrent) - ); - EndHook(); + //wglMakeCurrent = (decltype(wglMakeCurrent))GetProcAddress(_dll, "wglMakeCurrent"); + //wglSwapBuffers = (decltype(wglSwapBuffers))GetProcAddress(_dll, "wglSwapBuffers"); + // + //BeginHook(); + //HookFuncs( + // std::make_pair(&(PVOID&)wglMakeCurrent, &OpenGL_Hook::MywglMakeCurrent) + //); + //EndHook(); } OpenGL_Hook::~OpenGL_Hook() @@ -144,6 +146,7 @@ void OpenGL_Hook::Create() if (hook == nullptr) { hook = new OpenGL_Hook; + hook->start_hook(); // Register the hook to the Hook Manager Hook_Manager::Inst().AddHook(hook); } diff --git a/overlay_experimental/OpenGL_Hook.h b/overlay_experimental/OpenGL_Hook.h index df72cfc..80b94e0 100644 --- a/overlay_experimental/OpenGL_Hook.h +++ b/overlay_experimental/OpenGL_Hook.h @@ -10,7 +10,7 @@ public: static constexpr const char *DLL_NAME = "opengl32.dll"; using wglSwapBuffers_t = BOOL(WINAPI*)(HDC); - using wglMakeCurrent_t = BOOL(WINAPI*)(HDC, HGLRC); + //using wglMakeCurrent_t = BOOL(WINAPI*)(HDC, HGLRC); private: // Variables @@ -30,9 +30,9 @@ private: wglSwapBuffers_t wglSwapBuffers; // Hook functions so we know we use OGL - static BOOL WINAPI MywglMakeCurrent(HDC hDC, HGLRC hGLRC); + //static BOOL WINAPI MywglMakeCurrent(HDC hDC, HGLRC hGLRC); - wglMakeCurrent_t wglMakeCurrent; + //wglMakeCurrent_t wglMakeCurrent; public: static void Create(); // Initialize OGL Hook.