1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-25 01:57:47 +01:00

#41 IAT Hooking for all game modules

This commit is contained in:
FunkyFr3sh 2020-09-19 11:23:06 +02:00
parent f58bc7117f
commit 28b4965611
7 changed files with 102 additions and 3 deletions

View File

@ -23,7 +23,8 @@ typedef LONG (WINAPI* SETWINDOWLONGAPROC)(HWND, int, LONG);
typedef BOOL (WINAPI* ENABLEWINDOWPROC)(HWND, BOOL); typedef BOOL (WINAPI* ENABLEWINDOWPROC)(HWND, BOOL);
typedef HWND (WINAPI* CREATEWINDOWEXAPROC)(DWORD, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID); typedef HWND (WINAPI* CREATEWINDOWEXAPROC)(DWORD, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
typedef BOOL (WINAPI* DESTROYWINDOWPROC)(HWND); 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 GETCURSORPOSPROC real_GetCursorPos;
extern CLIPCURSORPROC real_ClipCursor; extern CLIPCURSORPROC real_ClipCursor;
@ -46,6 +47,7 @@ extern ENABLEWINDOWPROC real_EnableWindow;
extern CREATEWINDOWEXAPROC real_CreateWindowExA; extern CREATEWINDOWEXAPROC real_CreateWindowExA;
extern DESTROYWINDOWPROC real_DestroyWindow; extern DESTROYWINDOWPROC real_DestroyWindow;
extern GETDEVICECAPSPROC real_GetDeviceCaps; extern GETDEVICECAPSPROC real_GetDeviceCaps;
extern LOADLIBRARYEXWPROC real_LoadLibraryExW;
extern int HookingMethod; extern int HookingMethod;
extern BOOL Hook_Active; extern BOOL Hook_Active;

View File

@ -37,6 +37,7 @@ extern BOOL ShowDriverWarning;
extern RECT WindowRect; extern RECT WindowRect;
extern int WindowState; extern int WindowState;
extern BOOL ChildWindowExists; extern BOOL ChildWindowExists;
extern HMODULE DDrawModule;
BOOL detect_cutscene(); BOOL detect_cutscene();
void LimitGameTicks(); void LimitGameTicks();

View File

@ -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_EnableWindow(HWND hWnd, BOOL bEnable);
BOOL WINAPI fake_DestroyWindow(HWND hWnd); BOOL WINAPI fake_DestroyWindow(HWND hWnd);
int WINAPI fake_GetDeviceCaps(HDC hdc, int index); int WINAPI fake_GetDeviceCaps(HDC hdc, int index);
HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
HWND WINAPI fake_CreateWindowExA( HWND WINAPI fake_CreateWindowExA(
DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y,
int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);

View File

@ -31,6 +31,7 @@ ENABLEWINDOWPROC real_EnableWindow = EnableWindow;
CREATEWINDOWEXAPROC real_CreateWindowExA = CreateWindowExA; CREATEWINDOWEXAPROC real_CreateWindowExA = CreateWindowExA;
DESTROYWINDOWPROC real_DestroyWindow = DestroyWindow; DESTROYWINDOWPROC real_DestroyWindow = DestroyWindow;
GETDEVICECAPSPROC real_GetDeviceCaps = GetDeviceCaps; GETDEVICECAPSPROC real_GetDeviceCaps = GetDeviceCaps;
LOADLIBRARYEXWPROC real_LoadLibraryExW = LoadLibraryExW;
void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction) 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); DetourAttach((PVOID *)function, (PVOID)newFunction);
DetourTransactionCommit(); 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 #endif
if (HookingMethod == 1) if (HookingMethod == 1)
@ -121,6 +153,41 @@ void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *f
DetourDetach((PVOID *)function, (PVOID)newFunction); DetourDetach((PVOID *)function, (PVOID)newFunction);
DetourTransactionCommit(); 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 #endif
if (HookingMethod == 1) if (HookingMethod == 1)
@ -141,8 +208,16 @@ void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *f
void Hook_Init() 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_Active = TRUE;
Hook_Create("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos); Hook_Create("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
@ -175,6 +250,14 @@ void Hook_Exit()
{ {
Hook_Active = FALSE; 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", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
Hook_Revert("user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor); Hook_Revert("user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor);
Hook_Revert("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor); Hook_Revert("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor);

View File

@ -48,6 +48,7 @@ BOOL GameHandlesClose;
BOOL ChildWindowExists; BOOL ChildWindowExists;
DWORD NvOptimusEnablement = 1; DWORD NvOptimusEnablement = 1;
DWORD AmdPowerXpressRequestHighPerformance = 1; DWORD AmdPowerXpressRequestHighPerformance = 1;
HMODULE DDrawModule;
//BOOL WINAPI DllMainCRTStartup(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved) //BOOL WINAPI DllMainCRTStartup(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) 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: case DLL_PROCESS_ATTACH:
{ {
DDrawModule = hDll;
char buf[1024]; char buf[1024];
if (GetEnvironmentVariable("__COMPAT_LAYER", buf, sizeof(buf))) if (GetEnvironmentVariable("__COMPAT_LAYER", buf, sizeof(buf)))
{ {

View File

@ -432,6 +432,15 @@ int WINAPI fake_GetDeviceCaps(HDC hdc, int index)
return real_GetDeviceCaps(hdc, 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 WINAPI fake_DestroyWindow(HWND hWnd)
{ {
BOOL result = real_DestroyWindow(hWnd); BOOL result = real_DestroyWindow(hWnd);

View File

@ -282,7 +282,7 @@ static void CreateSettingsIni()
"; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n" "; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n"
"singlecpu=true\n" "singlecpu=true\n"
"\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" "; 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" "hook=1\n"
"\n" "\n"