From 28b49656113c4b7af09b8783c07b4dcb3771c562 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 19 Sep 2020 11:23:06 +0200 Subject: [PATCH] #41 IAT Hooking for all game modules --- inc/hook.h | 4 ++- inc/main.h | 1 + inc/mouse.h | 1 + src/hook.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++- src/main.c | 3 ++ src/mouse.c | 9 ++++++ src/settings.c | 2 +- 7 files changed, 102 insertions(+), 3 deletions(-) diff --git a/inc/hook.h b/inc/hook.h index d75cb22..a0762a1 100644 --- a/inc/hook.h +++ b/inc/hook.h @@ -23,7 +23,8 @@ typedef LONG (WINAPI* SETWINDOWLONGAPROC)(HWND, int, LONG); typedef BOOL (WINAPI* ENABLEWINDOWPROC)(HWND, BOOL); typedef HWND (WINAPI* CREATEWINDOWEXAPROC)(DWORD, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID); typedef BOOL (WINAPI* DESTROYWINDOWPROC)(HWND); -typedef BOOL(WINAPI* GETDEVICECAPSPROC)(HDC, int); +typedef int (WINAPI* GETDEVICECAPSPROC)(HDC, int); +typedef HMODULE (WINAPI* LOADLIBRARYEXWPROC)(LPCWSTR, HANDLE, DWORD); extern GETCURSORPOSPROC real_GetCursorPos; extern CLIPCURSORPROC real_ClipCursor; @@ -46,6 +47,7 @@ extern ENABLEWINDOWPROC real_EnableWindow; extern CREATEWINDOWEXAPROC real_CreateWindowExA; extern DESTROYWINDOWPROC real_DestroyWindow; extern GETDEVICECAPSPROC real_GetDeviceCaps; +extern LOADLIBRARYEXWPROC real_LoadLibraryExW; extern int HookingMethod; extern BOOL Hook_Active; diff --git a/inc/main.h b/inc/main.h index a758061..89d2297 100644 --- a/inc/main.h +++ b/inc/main.h @@ -37,6 +37,7 @@ extern BOOL ShowDriverWarning; extern RECT WindowRect; extern int WindowState; extern BOOL ChildWindowExists; +extern HMODULE DDrawModule; BOOL detect_cutscene(); void LimitGameTicks(); diff --git a/inc/mouse.h b/inc/mouse.h index 991e538..f4848b5 100644 --- a/inc/mouse.h +++ b/inc/mouse.h @@ -26,6 +26,7 @@ LONG WINAPI fake_SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong); BOOL WINAPI fake_EnableWindow(HWND hWnd, BOOL bEnable); BOOL WINAPI fake_DestroyWindow(HWND hWnd); int WINAPI fake_GetDeviceCaps(HDC hdc, int index); +HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); HWND WINAPI fake_CreateWindowExA( DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); diff --git a/src/hook.c b/src/hook.c index 340593e..c905852 100644 --- a/src/hook.c +++ b/src/hook.c @@ -31,6 +31,7 @@ ENABLEWINDOWPROC real_EnableWindow = EnableWindow; CREATEWINDOWEXAPROC real_CreateWindowExA = CreateWindowExA; DESTROYWINDOWPROC real_DestroyWindow = DestroyWindow; GETDEVICECAPSPROC real_GetDeviceCaps = GetDeviceCaps; +LOADLIBRARYEXWPROC real_LoadLibraryExW = LoadLibraryExW; void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction) @@ -102,6 +103,37 @@ void Hook_Create(char *moduleName, char *functionName, PROC newFunction, PROC *f DetourAttach((PVOID *)function, (PVOID)newFunction); DetourTransactionCommit(); } + + if (HookingMethod == 3) + { + char gameExePath[MAX_PATH] = { 0 }; + char gameDir[MAX_PATH] = { 0 }; + + if (GetModuleFileNameA(NULL, gameExePath, MAX_PATH)) + { + _splitpath(gameExePath, NULL, gameDir, NULL, NULL); + + char modPath[MAX_PATH] = { 0 }; + char modDir[MAX_PATH] = { 0 }; + HMODULE hMod = NULL; + + while (hMod = DetourEnumerateModules(hMod)) + { + if (hMod == DDrawModule) + continue; + + if (GetModuleFileNameA(hMod, modPath, MAX_PATH)) + { + _splitpath(modPath, NULL, modDir, NULL, NULL); + + if (_strnicmp(gameDir, modDir, strlen(gameDir)) == 0) + { + Hook_PatchIAT(hMod, moduleName, functionName, newFunction); + } + } + } + } + } #endif if (HookingMethod == 1) @@ -121,6 +153,41 @@ void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *f DetourDetach((PVOID *)function, (PVOID)newFunction); DetourTransactionCommit(); } + + if (HookingMethod == 3) + { + char gameExePath[MAX_PATH] = { 0 }; + char gameDir[MAX_PATH] = { 0 }; + + if (GetModuleFileNameA(NULL, gameExePath, MAX_PATH)) + { + _splitpath(gameExePath, NULL, gameDir, NULL, NULL); + + char modPath[MAX_PATH] = { 0 }; + char modDir[MAX_PATH] = { 0 }; + HMODULE hMod = NULL; + + while (hMod = DetourEnumerateModules(hMod)) + { + if (hMod == DDrawModule) + continue; + + if (GetModuleFileNameA(hMod, modPath, MAX_PATH)) + { + _splitpath(modPath, NULL, modDir, NULL, NULL); + + if (_strnicmp(gameDir, modDir, strlen(gameDir)) == 0) + { + Hook_PatchIAT( + hMod, + moduleName, + functionName, + GetProcAddress(GetModuleHandle(moduleName), functionName)); + } + } + } + } + } #endif if (HookingMethod == 1) @@ -141,8 +208,16 @@ void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *f void Hook_Init() { - if (!Hook_Active) + if (!Hook_Active || HookingMethod == 3) { + if (!Hook_Active && HookingMethod == 3) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach((PVOID*)&real_LoadLibraryExW, (PVOID)fake_LoadLibraryExW); + DetourTransactionCommit(); + } + Hook_Active = TRUE; Hook_Create("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos); @@ -175,6 +250,14 @@ void Hook_Exit() { Hook_Active = FALSE; + if (HookingMethod == 3) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourDetach((PVOID*)&real_LoadLibraryExW, (PVOID)fake_LoadLibraryExW); + DetourTransactionCommit(); + } + Hook_Revert("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos); Hook_Revert("user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor); Hook_Revert("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor); diff --git a/src/main.c b/src/main.c index aacbc2a..c4b3355 100644 --- a/src/main.c +++ b/src/main.c @@ -48,6 +48,7 @@ BOOL GameHandlesClose; BOOL ChildWindowExists; DWORD NvOptimusEnablement = 1; DWORD AmdPowerXpressRequestHighPerformance = 1; +HMODULE DDrawModule; //BOOL WINAPI DllMainCRTStartup(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved) BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) @@ -56,6 +57,8 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { case DLL_PROCESS_ATTACH: { + DDrawModule = hDll; + char buf[1024]; if (GetEnvironmentVariable("__COMPAT_LAYER", buf, sizeof(buf))) { diff --git a/src/mouse.c b/src/mouse.c index 74a9959..eb8e160 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -432,6 +432,15 @@ int WINAPI fake_GetDeviceCaps(HDC hdc, int index) return real_GetDeviceCaps(hdc, index); } +HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE hMod = real_LoadLibraryExW(lpLibFileName, hFile, dwFlags); + + Hook_Init(); + + return hMod; +} + BOOL WINAPI fake_DestroyWindow(HWND hWnd) { BOOL result = real_DestroyWindow(hWnd); diff --git a/src/settings.c b/src/settings.c index 4bce76f..d96fb0d 100644 --- a/src/settings.c +++ b/src/settings.c @@ -282,7 +282,7 @@ static void CreateSettingsIni() "; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n" "singlecpu=true\n" "\n" - "; Windows API Hooking, Possible values: 0 = disabled, 1 = IAT Hooking, 2 = Microsoft Detours\n" + "; Windows API Hooking, Possible values: 0 = disabled, 1 = IAT Hooking, 2 = Microsoft Detours, 3 = IAT Hooking (All Modules)\n" "; Note: Can be used to fix issues related to new features added by cnc-ddraw such as windowed mode or stretching\n" "hook=1\n" "\n"