1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-20 16:09:12 +01:00
cnc-ddraw/src/hook.c

704 lines
27 KiB
C
Raw Normal View History

2019-03-19 06:57:49 +01:00
#include <windows.h>
#include <stdio.h>
2021-05-11 21:45:38 +02:00
#include "directinput.h"
2020-10-13 09:20:52 +02:00
#include "dd.h"
#include "winapi_hooks.h"
2019-03-19 06:57:49 +01:00
#include "hook.h"
2021-01-23 14:55:22 +01:00
#include "debug.h"
2020-10-13 09:20:52 +02:00
#include "dllmain.h"
2023-07-28 13:53:57 +02:00
#include "config.h"
2023-10-20 10:42:15 +02:00
#include "utils.h"
#include "patch.h"
2024-06-01 22:59:12 +02:00
#include "versionhelpers.h"
2019-03-19 06:57:49 +01:00
2019-08-07 12:45:40 +02:00
#ifdef _MSC_VER
#include "detours.h"
#endif
2020-10-13 09:20:52 +02:00
BOOL g_hook_active;
2019-03-19 06:57:49 +01:00
GETCURSORPOSPROC real_GetCursorPos = GetCursorPos;
CLIPCURSORPROC real_ClipCursor = ClipCursor;
SHOWCURSORPROC real_ShowCursor = ShowCursor;
SETCURSORPROC real_SetCursor = SetCursor;
GETWINDOWRECTPROC real_GetWindowRect = GetWindowRect;
GETCLIENTRECTPROC real_GetClientRect = GetClientRect;
CLIENTTOSCREENPROC real_ClientToScreen = ClientToScreen;
SCREENTOCLIENTPROC real_ScreenToClient = ScreenToClient;
SETCURSORPOSPROC real_SetCursorPos = SetCursorPos;
WINDOWFROMPOINTPROC real_WindowFromPoint = WindowFromPoint;
GETCLIPCURSORPROC real_GetClipCursor = GetClipCursor;
GETCURSORINFOPROC real_GetCursorInfo = GetCursorInfo;
GETSYSTEMMETRICSPROC real_GetSystemMetrics = GetSystemMetrics;
SETWINDOWPOSPROC real_SetWindowPos = SetWindowPos;
MOVEWINDOWPROC real_MoveWindow = MoveWindow;
SENDMESSAGEAPROC real_SendMessageA = SendMessageA;
SETWINDOWLONGAPROC real_SetWindowLongA = SetWindowLongA;
GETWINDOWLONGAPROC real_GetWindowLongA = GetWindowLongA;
2019-08-06 04:37:06 +02:00
ENABLEWINDOWPROC real_EnableWindow = EnableWindow;
CREATEWINDOWEXAPROC real_CreateWindowExA = CreateWindowExA;
DESTROYWINDOWPROC real_DestroyWindow = DestroyWindow;
2021-05-29 21:40:21 +02:00
MAPWINDOWPOINTSPROC real_MapWindowPoints = MapWindowPoints;
2021-08-04 15:24:16 +02:00
SHOWWINDOWPROC real_ShowWindow = ShowWindow;
2022-10-18 22:21:42 +02:00
GETTOPWINDOWPROC real_GetTopWindow = GetTopWindow;
2022-10-19 05:08:22 +02:00
GETFOREGROUNDWINDOWPROC real_GetForegroundWindow = GetForegroundWindow;
2022-10-02 18:41:06 +02:00
STRETCHBLTPROC real_StretchBlt = StretchBlt;
2024-05-25 07:29:30 +02:00
BITBLTPROC real_BitBlt = BitBlt;
2022-10-03 12:19:15 +02:00
SETDIBITSTODEVICEPROC real_SetDIBitsToDevice = SetDIBitsToDevice;
2022-10-05 22:33:53 +02:00
STRETCHDIBITSPROC real_StretchDIBits = StretchDIBits;
SETFOREGROUNDWINDOWPROC real_SetForegroundWindow = SetForegroundWindow;
2021-06-06 19:03:38 +02:00
SETWINDOWSHOOKEXAPROC real_SetWindowsHookExA = SetWindowsHookExA;
2023-02-27 18:25:28 +01:00
PEEKMESSAGEAPROC real_PeekMessageA = PeekMessageA;
GETMESSAGEAPROC real_GetMessageA = GetMessageA;
2024-05-30 03:00:23 +02:00
GETWINDOWPLACEMENTPROC real_GetWindowPlacement = GetWindowPlacement;
2024-06-10 00:02:39 +02:00
ENUMDISPLAYSETTINGSAPROC real_EnumDisplaySettingsA = EnumDisplaySettingsA;
GETKEYSTATEPROC real_GetKeyState = GetKeyState;
GETASYNCKEYSTATEPROC real_GetAsyncKeyState = GetAsyncKeyState;
GETDEVICECAPSPROC real_GetDeviceCaps = GetDeviceCaps;
2023-08-16 14:21:26 +02:00
CREATEFONTINDIRECTAPROC real_CreateFontIndirectA = CreateFontIndirectA;
CREATEFONTAPROC real_CreateFontA = CreateFontA;
LOADLIBRARYAPROC real_LoadLibraryA = LoadLibraryA;
LOADLIBRARYWPROC real_LoadLibraryW = LoadLibraryW;
LOADLIBRARYEXAPROC real_LoadLibraryExA = LoadLibraryExA;
2020-09-19 11:23:06 +02:00
LOADLIBRARYEXWPROC real_LoadLibraryExW = LoadLibraryExW;
GETPROCADDRESSPROC real_GetProcAddress = GetProcAddress;
2022-10-15 18:28:23 +02:00
GETDISKFREESPACEAPROC real_GetDiskFreeSpaceA = GetDiskFreeSpaceA;
GETVERSIONPROC real_GetVersion = GetVersion;
GETVERSIONEXAPROC real_GetVersionExA = GetVersionExA;
COCREATEINSTANCEPROC real_CoCreateInstance = CoCreateInstance;
2024-06-01 23:04:06 +02:00
MCISENDCOMMANDAPROC real_mciSendCommandA = mciSendCommandA;
SETUNHANDLEDEXCEPTIONFILTERPROC real_SetUnhandledExceptionFilter = SetUnhandledExceptionFilter;
2019-08-06 04:37:06 +02:00
HOOKLIST g_hook_hooklist[] =
2020-10-19 16:37:12 +02:00
{
{
"user32.dll",
{
2021-08-06 02:07:50 +02:00
{ "GetCursorPos", (PROC)fake_GetCursorPos, (PROC*)&real_GetCursorPos, 0 },
{ "ClipCursor", (PROC)fake_ClipCursor, (PROC*)&real_ClipCursor, 0 },
{ "ShowCursor", (PROC)fake_ShowCursor, (PROC*)&real_ShowCursor, 0 },
{ "SetCursor", (PROC)fake_SetCursor, (PROC*)&real_SetCursor, 0 },
{ "GetWindowRect", (PROC)fake_GetWindowRect, (PROC*)&real_GetWindowRect, 0 },
{ "GetClientRect", (PROC)fake_GetClientRect, (PROC*)&real_GetClientRect, 0 },
2021-08-06 02:07:50 +02:00
{ "ClientToScreen", (PROC)fake_ClientToScreen, (PROC*)&real_ClientToScreen, 0 },
{ "ScreenToClient", (PROC)fake_ScreenToClient, (PROC*)&real_ScreenToClient, 0 },
{ "SetCursorPos", (PROC)fake_SetCursorPos, (PROC*)&real_SetCursorPos, 0 },
{ "GetClipCursor", (PROC)fake_GetClipCursor, (PROC*)&real_GetClipCursor, 0 },
{ "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC*)&real_WindowFromPoint, 0 },
{ "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC*)&real_GetCursorInfo, 0 },
{ "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC*)&real_GetSystemMetrics, 0 },
{ "SetWindowPos", (PROC)fake_SetWindowPos, (PROC*)&real_SetWindowPos, 0 },
{ "MoveWindow", (PROC)fake_MoveWindow, (PROC*)&real_MoveWindow, 0 },
{ "SendMessageA", (PROC)fake_SendMessageA, (PROC*)&real_SendMessageA, 0 },
{ "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC*)&real_SetWindowLongA, 0 },
{ "GetWindowLongA", (PROC)fake_GetWindowLongA, (PROC*)&real_GetWindowLongA, 0 },
{ "EnableWindow", (PROC)fake_EnableWindow, (PROC*)&real_EnableWindow, 0 },
{ "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC*)&real_CreateWindowExA, 0 },
{ "DestroyWindow", (PROC)fake_DestroyWindow, (PROC*)&real_DestroyWindow, 0 },
{ "MapWindowPoints", (PROC)fake_MapWindowPoints, (PROC*)&real_MapWindowPoints, 0 },
{ "ShowWindow", (PROC)fake_ShowWindow, (PROC*)&real_ShowWindow, 0 },
2022-10-18 22:21:42 +02:00
{ "GetTopWindow", (PROC)fake_GetTopWindow, (PROC*)&real_GetTopWindow, 0 },
2022-10-19 05:08:22 +02:00
{ "GetForegroundWindow", (PROC)fake_GetForegroundWindow, (PROC*)&real_GetForegroundWindow, 0 },
2023-02-27 18:25:28 +01:00
{ "PeekMessageA", (PROC)fake_PeekMessageA, (PROC*)&real_PeekMessageA, 0 },
{ "GetMessageA", (PROC)fake_GetMessageA, (PROC*)&real_GetMessageA, 0 },
2024-05-30 03:00:23 +02:00
{ "GetWindowPlacement", (PROC)fake_GetWindowPlacement, (PROC*)&real_GetWindowPlacement, 0 },
2024-06-10 00:02:39 +02:00
{ "EnumDisplaySettingsA", (PROC)fake_EnumDisplaySettingsA, (PROC*)&real_EnumDisplaySettingsA, 0 },
{ "GetKeyState", (PROC)fake_GetKeyState, (PROC*)&real_GetKeyState, 0 },
{ "GetAsyncKeyState", (PROC)fake_GetAsyncKeyState, (PROC*)&real_GetAsyncKeyState, 0 },
{ "SetForegroundWindow", (PROC)fake_SetForegroundWindow, (PROC*)&real_SetForegroundWindow, 0 },
2023-08-02 15:15:44 +02:00
{ "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA, (PROC*)&real_SetWindowsHookExA, 0 },
{ "", NULL, NULL, 0 }
}
},
{
"ole32.dll",
{
2023-09-26 10:41:20 +02:00
{ "CoCreateInstance", (PROC)fake_CoCreateInstance, (PROC*)&real_CoCreateInstance, HOOK_SKIP_2 },
2023-08-02 15:15:44 +02:00
{ "", NULL, NULL, 0 }
}
},
2024-06-01 23:04:06 +02:00
{
"winmm.dll",
{
{ "mciSendCommandA", (PROC)fake_mciSendCommandA, (PROC*)&real_mciSendCommandA, HOOK_SKIP_2 },
{ "", NULL, NULL, 0 }
}
},
2023-08-02 15:15:44 +02:00
{
"dinput.dll",
{
2023-09-26 10:41:20 +02:00
{ "DirectInputCreateA", (PROC)fake_DirectInputCreateA, (PROC*)&real_DirectInputCreateA, HOOK_SKIP_2 },
//{ "DirectInputCreateW", (PROC)fake_DirectInputCreateW, (PROC*)&real_DirectInputCreateW, HOOK_SKIP_2 },
{ "DirectInputCreateEx", (PROC)fake_DirectInputCreateEx, (PROC*)&real_DirectInputCreateEx, HOOK_SKIP_2 },
2023-08-02 15:15:44 +02:00
{ "", NULL, NULL, 0 }
}
},
{
"dinput8.dll",
{
2023-09-26 10:41:20 +02:00
{ "DirectInput8Create", (PROC)fake_DirectInput8Create, (PROC*)&real_DirectInput8Create, HOOK_SKIP_2 },
2021-08-06 02:07:50 +02:00
{ "", NULL, NULL, 0 }
2020-10-19 16:37:12 +02:00
}
},
{
"gdi32.dll",
{
2024-05-25 07:29:30 +02:00
{ "BitBlt", (PROC)fake_BitBlt, (PROC*)&real_BitBlt, HOOK_SKIP_2 },
2023-09-26 10:41:20 +02:00
{ "StretchBlt", (PROC)fake_StretchBlt, (PROC*)&real_StretchBlt, HOOK_SKIP_2 },
{ "SetDIBitsToDevice", (PROC)fake_SetDIBitsToDevice, (PROC*)&real_SetDIBitsToDevice, HOOK_SKIP_2 },
{ "StretchDIBits", (PROC)fake_StretchDIBits, (PROC*)&real_StretchDIBits, HOOK_SKIP_2 },
{ "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps, HOOK_LOCAL_ONLY },
2023-08-16 14:21:26 +02:00
{ "CreateFontA", (PROC)fake_CreateFontA, (PROC*)&real_CreateFontA, 0 },
{ "CreateFontIndirectA", (PROC)fake_CreateFontIndirectA, (PROC*)&real_CreateFontIndirectA, 0 },
2021-08-06 02:07:50 +02:00
{ "", NULL, NULL, 0 }
2020-10-19 16:37:12 +02:00
}
},
2024-05-27 01:15:30 +02:00
{
"WING32.DLL",
{
2024-09-10 17:15:02 +02:00
{ "WinGBitBlt", (PROC)fake_WinGBitBlt, NULL, 0 },
{ "WinGStretchBlt", (PROC)fake_WinGStretchBlt, NULL, 0 },
2024-05-27 01:15:30 +02:00
{ "", NULL, NULL, 0 }
}
},
2020-10-19 16:37:12 +02:00
{
"kernel32.dll",
{
2023-09-26 10:41:20 +02:00
{ "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA, HOOK_SKIP_2 },
{ "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW, HOOK_SKIP_2 },
{ "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA, HOOK_SKIP_2 },
{ "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW, HOOK_SKIP_2 },
{ "GetProcAddress", (PROC)fake_GetProcAddress, (PROC*)&real_GetProcAddress, HOOK_SKIP_2 },
2024-09-10 17:15:02 +02:00
{ "GetDiskFreeSpaceA", (PROC)fake_GetDiskFreeSpaceA, (PROC*)&real_GetDiskFreeSpaceA, 0 },
{ "GetVersion", (PROC)fake_GetVersion, (PROC*)&real_GetVersion, 0 },
{ "GetVersionExA", (PROC)fake_GetVersionExA, (PROC*)&real_GetVersionExA, 0 },
#if defined(_DEBUG) && defined(__GNUC__)
{ "SetUnhandledExceptionFilter", (PROC)fake_SetUnhandledExceptionFilter, (PROC*)&real_SetUnhandledExceptionFilter, 0 },
#endif
2021-08-06 02:07:50 +02:00
{ "", NULL, NULL, 0 }
2020-10-19 16:37:12 +02:00
}
},
{
"",
{
2021-08-06 02:07:50 +02:00
{ "", NULL, NULL, 0 }
2020-10-19 16:37:12 +02:00
}
}
};
2019-03-19 06:57:49 +01:00
2020-10-20 05:59:41 +02:00
void hook_patch_iat(HMODULE hmod, BOOL unhook, char* module_name, char* function_name, PROC new_function)
2019-03-19 06:57:49 +01:00
{
2021-06-11 20:30:43 +02:00
HOOKLIST hooks[2];
2020-10-20 05:59:41 +02:00
memset(&hooks, 0, sizeof(hooks));
hooks[0].data[0].new_function = new_function;
2021-06-11 20:30:43 +02:00
strncpy(hooks[0].module_name, module_name, sizeof(hooks[0].module_name) - 1);
2020-10-20 05:59:41 +02:00
strncpy(hooks[0].data[0].function_name, function_name, sizeof(hooks[0].data[0].function_name) - 1);
2023-09-26 10:41:20 +02:00
hook_patch_iat_list(hmod, unhook, (HOOKLIST*)&hooks, FALSE);
2020-10-20 05:59:41 +02:00
}
2023-09-26 10:41:20 +02:00
void hook_patch_obfuscated_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, BOOL is_local)
2021-09-04 06:24:43 +02:00
{
if (!hmod || hmod == INVALID_HANDLE_VALUE || !hooks)
return;
__try
{
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)hmod;
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
return;
PIMAGE_NT_HEADERS nt_headers = (PIMAGE_NT_HEADERS)((DWORD)dos_header + (DWORD)dos_header->e_lfanew);
if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
return;
2023-11-01 12:16:22 +01:00
DWORD import_desc_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
DWORD import_desc_size = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
2021-09-04 06:24:43 +02:00
2023-11-01 12:16:22 +01:00
if (import_desc_rva == 0 || import_desc_size == 0)
2021-09-04 06:24:43 +02:00
return;
2023-11-01 12:16:22 +01:00
PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header + import_desc_rva);
2021-09-04 06:24:43 +02:00
while (import_desc->FirstThunk)
{
if (!import_desc->Name)
{
import_desc++;
continue;
}
2021-09-04 06:24:43 +02:00
for (int i = 0; hooks[i].module_name[0]; i++)
{
2023-10-20 10:42:15 +02:00
char* imp_module_name = (char*)((DWORD)dos_header + import_desc->Name);
2021-09-04 06:24:43 +02:00
if (_stricmp(imp_module_name, hooks[i].module_name) == 0)
{
HMODULE cur_mod = GetModuleHandleA(hooks[i].module_name);
2021-09-06 01:13:17 +02:00
2023-10-20 10:42:15 +02:00
PIMAGE_THUNK_DATA first_thunk = (void*)((DWORD)dos_header + import_desc->FirstThunk);
2021-09-04 06:24:43 +02:00
while (first_thunk->u1.Function)
{
for (int x = 0; hooks[i].data[x].function_name[0]; x++)
{
2023-10-23 12:16:44 +02:00
/* GetProcAddress is slow, save the pointer and reuse it for better performance */
DWORD org_function = (DWORD)InterlockedExchangeAdd((LONG*)&hooks[i].data[x].org_function, 0);
if (!org_function || cur_mod != hooks[i].data[x].mod)
{
hooks[i].data[x].mod = cur_mod;
org_function = (DWORD)real_GetProcAddress(cur_mod, hooks[i].data[x].function_name);
InterlockedExchange((LONG*)&hooks[i].data[x].org_function, (LONG)org_function);
}
2021-09-04 06:24:43 +02:00
2021-09-04 19:34:31 +02:00
if (!hooks[i].data[x].new_function || !org_function)
2021-09-04 06:24:43 +02:00
continue;
2023-09-26 10:41:20 +02:00
if (!is_local && (hooks[i].data[x].flags & HOOK_LOCAL_ONLY))
continue;
2021-09-04 06:24:43 +02:00
if (unhook)
{
if (first_thunk->u1.Function == (DWORD)hooks[i].data[x].new_function)
{
DWORD op;
if (VirtualProtect(
&first_thunk->u1.Function,
sizeof(DWORD),
PAGE_READWRITE,
&op))
{
first_thunk->u1.Function = org_function;
VirtualProtect(&first_thunk->u1.Function, sizeof(DWORD), op, &op);
}
break;
}
}
else
{
if (first_thunk->u1.Function == org_function)
{
DWORD op;
if (VirtualProtect(
&first_thunk->u1.Function,
sizeof(DWORD),
PAGE_READWRITE,
&op))
{
first_thunk->u1.Function = (DWORD)hooks[i].data[x].new_function;
VirtualProtect(&first_thunk->u1.Function, sizeof(DWORD), op, &op);
}
break;
}
}
}
first_thunk++;
}
2023-10-20 10:42:15 +02:00
break;
2021-09-04 06:24:43 +02:00
}
}
import_desc++;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
}
2023-09-26 10:41:20 +02:00
void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, BOOL is_local)
2020-10-20 05:59:41 +02:00
{
2023-09-26 10:41:20 +02:00
hook_patch_obfuscated_iat_list(hmod, unhook, hooks, is_local);
2021-09-04 06:24:43 +02:00
2020-10-20 05:59:41 +02:00
if (!hmod || hmod == INVALID_HANDLE_VALUE || !hooks)
2019-03-19 06:57:49 +01:00
return;
2020-09-22 14:04:49 +02:00
__try
{
2020-10-13 09:20:52 +02:00
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)hmod;
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
2020-09-22 14:04:49 +02:00
return;
2019-03-19 06:57:49 +01:00
2020-10-13 09:20:52 +02:00
PIMAGE_NT_HEADERS nt_headers = (PIMAGE_NT_HEADERS)((DWORD)dos_header + (DWORD)dos_header->e_lfanew);
if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
2020-09-22 14:04:49 +02:00
return;
2019-03-19 06:57:49 +01:00
2023-11-01 12:16:22 +01:00
DWORD import_desc_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
DWORD import_desc_size = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
2019-03-19 06:57:49 +01:00
2023-11-01 12:16:22 +01:00
if (import_desc_rva == 0 || import_desc_size == 0)
2020-09-22 14:04:49 +02:00
return;
2019-03-19 06:57:49 +01:00
2023-11-01 12:16:22 +01:00
PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header + import_desc_rva);
2020-10-13 09:20:52 +02:00
while (import_desc->FirstThunk)
2019-03-19 06:57:49 +01:00
{
if (!import_desc->OriginalFirstThunk || !import_desc->Name)
{
import_desc++;
continue;
}
2020-10-20 05:59:41 +02:00
for (int i = 0; hooks[i].module_name[0]; i++)
2019-03-19 06:57:49 +01:00
{
2023-10-20 10:42:15 +02:00
char* imp_module_name = (char*)((DWORD)dos_header + import_desc->Name);
2020-09-22 14:04:49 +02:00
2020-10-20 05:59:41 +02:00
if (_stricmp(imp_module_name, hooks[i].module_name) == 0)
2019-03-19 06:57:49 +01:00
{
2023-10-20 10:42:15 +02:00
PIMAGE_THUNK_DATA first_thunk = (void*)((DWORD)dos_header + import_desc->FirstThunk);
PIMAGE_THUNK_DATA o_first_thunk = (void*)((DWORD)dos_header + import_desc->OriginalFirstThunk);
2019-03-19 06:57:49 +01:00
2023-10-20 10:42:15 +02:00
while (first_thunk->u1.Function)
2019-03-19 06:57:49 +01:00
{
2023-10-20 10:42:15 +02:00
if (!o_first_thunk->u1.AddressOfData)
{
first_thunk++;
o_first_thunk++;
continue;
}
PIMAGE_IMPORT_BY_NAME import = (void*)((DWORD)dos_header + o_first_thunk->u1.AddressOfData);
2020-09-22 14:04:49 +02:00
2023-10-20 10:42:15 +02:00
if ((o_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0)
2020-09-22 14:04:49 +02:00
{
2020-10-20 05:59:41 +02:00
for (int x = 0; hooks[i].data[x].function_name[0]; x++)
{
if (!unhook && !hooks[i].data[x].new_function)
continue;
2023-09-26 10:41:20 +02:00
if (!is_local && (hooks[i].data[x].flags & HOOK_LOCAL_ONLY))
continue;
2023-10-20 11:05:11 +02:00
#if defined(__GNUC__)
if (util_is_bad_read_ptr((void*)import->Name))
continue;
2023-10-20 11:05:11 +02:00
#endif
2023-10-20 10:42:15 +02:00
if (strcmp((const char*)import->Name, hooks[i].data[x].function_name) == 0)
2020-10-20 05:59:41 +02:00
{
2021-09-04 06:24:43 +02:00
DWORD op;
2020-10-20 05:59:41 +02:00
if (VirtualProtect(
2021-09-04 06:24:43 +02:00
&first_thunk->u1.Function,
sizeof(DWORD),
PAGE_READWRITE,
&op))
2020-10-20 05:59:41 +02:00
{
if (unhook)
{
2021-06-11 20:30:43 +02:00
DWORD org =
2023-08-06 09:25:34 +02:00
(DWORD)real_GetProcAddress(
2023-10-23 12:16:44 +02:00
GetModuleHandleA(hooks[i].module_name),
2020-10-20 05:59:41 +02:00
hooks[i].data[x].function_name);
2021-09-06 01:13:17 +02:00
if (org && first_thunk->u1.Function != org)
2020-10-20 05:59:41 +02:00
{
first_thunk->u1.Function = org;
}
}
else
{
2021-09-06 01:13:17 +02:00
if (first_thunk->u1.Function != (DWORD)hooks[i].data[x].new_function)
first_thunk->u1.Function = (DWORD)hooks[i].data[x].new_function;
2020-10-20 05:59:41 +02:00
}
2021-09-04 06:24:43 +02:00
VirtualProtect(&first_thunk->u1.Function, sizeof(DWORD), op, &op);
2020-10-20 05:59:41 +02:00
}
break;
}
}
2020-09-22 14:04:49 +02:00
}
2020-10-20 05:59:41 +02:00
first_thunk++;
2023-10-20 10:42:15 +02:00
o_first_thunk++;
2019-03-19 06:57:49 +01:00
}
2023-10-20 10:42:15 +02:00
break;
2019-03-19 06:57:49 +01:00
}
}
2020-10-13 09:20:52 +02:00
import_desc++;
2020-09-22 14:04:49 +02:00
}
}
2021-06-11 20:30:43 +02:00
__except (EXCEPTION_EXECUTE_HANDLER)
2020-09-22 14:04:49 +02:00
{
2019-03-19 06:57:49 +01:00
}
}
BOOL hook_got_ddraw_import(HMODULE mod, BOOL check_imported_dlls)
2023-08-13 20:31:26 +02:00
{
if (!mod)
return FALSE;
2023-08-13 20:31:26 +02:00
__try
{
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)mod;
2023-08-13 20:31:26 +02:00
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
PIMAGE_NT_HEADERS nt_headers = (PIMAGE_NT_HEADERS)((DWORD)dos_header + (DWORD)dos_header->e_lfanew);
if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
return FALSE;
2023-11-01 12:16:22 +01:00
DWORD import_desc_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
DWORD import_desc_size = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
2023-08-13 20:31:26 +02:00
2023-11-01 12:16:22 +01:00
if (import_desc_rva == 0 || import_desc_size == 0)
2023-08-13 20:31:26 +02:00
return FALSE;
2023-11-01 12:16:22 +01:00
PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header + import_desc_rva);
2023-08-13 20:31:26 +02:00
while (import_desc->FirstThunk)
{
2023-11-01 12:16:22 +01:00
if (import_desc->Name)
2023-10-20 10:42:15 +02:00
{
2023-11-01 12:16:22 +01:00
char* imp_module_name = (char*)((DWORD)dos_header + import_desc->Name);
2023-08-13 20:31:26 +02:00
2023-11-01 12:16:22 +01:00
if (_stricmp(imp_module_name, "ddraw.dll") == 0)
{
PIMAGE_THUNK_DATA first_thunk = (void*)((DWORD)dos_header + import_desc->FirstThunk);
if (first_thunk->u1.Function)
return TRUE;
2023-11-01 12:16:22 +01:00
}
else if (check_imported_dlls)
{
if (hook_got_ddraw_import(GetModuleHandleA(imp_module_name), FALSE))
return TRUE;
}
2023-08-13 20:31:26 +02:00
}
import_desc++;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
return FALSE;
}
2021-08-06 02:07:50 +02:00
void hook_create(HOOKLIST* hooks, BOOL initial_hook)
2019-03-19 06:57:49 +01:00
{
2019-08-07 12:45:40 +02:00
#ifdef _MSC_VER
2023-09-22 00:38:42 +02:00
if ((g_config.hook == 2) && initial_hook)
2019-03-20 05:07:28 +01:00
{
2020-10-19 16:37:12 +02:00
for (int i = 0; hooks[i].module_name[0]; i++)
{
for (int x = 0; hooks[i].data[x].function_name[0]; x++)
{
2023-09-26 10:41:20 +02:00
if ((hooks[i].data[x].flags & HOOK_SKIP_2))
2021-08-06 02:07:50 +02:00
continue;
2020-10-19 16:37:12 +02:00
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)hooks[i].data[x].function, (PVOID)hooks[i].data[x].new_function);
DetourTransactionCommit();
}
}
2019-03-20 05:07:28 +01:00
}
2021-05-10 01:00:55 +02:00
#endif
2020-09-19 11:23:06 +02:00
2023-09-22 00:38:42 +02:00
if (g_config.hook == 3 || g_config.hook == 4)
2020-09-19 11:23:06 +02:00
{
2021-01-23 14:55:22 +01:00
char game_exe_path[MAX_PATH] = { 0 };
char game_dir[MAX_PATH] = { 0 };
2020-09-19 11:23:06 +02:00
2021-01-23 14:55:22 +01:00
if (GetModuleFileNameA(NULL, game_exe_path, MAX_PATH))
2020-09-19 11:23:06 +02:00
{
2021-01-23 14:55:22 +01:00
_splitpath(game_exe_path, NULL, game_dir, NULL, NULL);
2020-09-19 11:23:06 +02:00
2021-01-23 14:55:22 +01:00
char mod_path[MAX_PATH] = { 0 };
char mod_dir[MAX_PATH] = { 0 };
2021-01-30 16:45:27 +01:00
char mod_filename[MAX_PATH] = { 0 };
2020-10-13 09:20:52 +02:00
HMODULE hmod = NULL;
while ((hmod = util_enumerate_modules(hmod)))
2020-09-19 11:23:06 +02:00
{
2020-10-13 09:20:52 +02:00
if (hmod == g_ddraw_module)
2020-09-19 11:23:06 +02:00
continue;
2021-01-23 14:55:22 +01:00
if (GetModuleFileNameA(hmod, mod_path, MAX_PATH))
2020-09-19 11:23:06 +02:00
{
2023-08-02 15:15:44 +02:00
if (initial_hook)
{
2023-08-04 08:40:52 +02:00
TRACE("Module %s = %p\n", mod_path, hmod);
2023-08-02 15:15:44 +02:00
}
2020-09-19 11:23:06 +02:00
2021-01-30 16:45:27 +01:00
_splitpath(mod_path, NULL, mod_dir, mod_filename, NULL);
/* Don't hook reshade/swiftshader/mesa3d */
2021-06-11 20:30:43 +02:00
if (_strcmpi(mod_filename, "opengl32") == 0 ||
2024-05-16 21:08:47 +02:00
_strcmpi(mod_filename, "libgallium_wgl") == 0 ||
_strcmpi(mod_filename, "libglapi") == 0 ||
2021-06-11 20:30:43 +02:00
_strcmpi(mod_filename, "d3d9") == 0 ||
_strcmpi(mod_filename, "mdraw") == 0 ||
2024-09-08 08:53:11 +02:00
_strcmpi(mod_filename, "SH33W32") == 0 ||
2021-05-26 19:34:45 +02:00
_strcmpi(mod_filename, "Shw32") == 0)
2021-01-30 16:45:27 +01:00
continue;
2021-01-23 14:55:22 +01:00
2023-09-26 10:41:20 +02:00
BOOL is_local = _strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0;
2024-06-01 22:59:12 +02:00
BOOL wine_hook = IsWine() && _strcmpi(mod_filename, "mciavi32") == 0;
2023-09-26 10:41:20 +02:00
if (is_local ||
2024-06-01 22:59:12 +02:00
wine_hook ||
2024-05-31 23:54:33 +02:00
_strcmpi(mod_filename, "QuickTime") == 0 ||
2022-10-02 18:41:06 +02:00
_strcmpi(mod_filename, "MSVFW32") == 0 ||
2021-08-11 01:36:12 +02:00
_strcmpi(mod_filename, "quartz") == 0 ||
_strcmpi(mod_filename, "winmm") == 0)
2020-09-19 11:23:06 +02:00
{
2023-09-26 10:41:20 +02:00
hook_patch_iat_list(hmod, FALSE, hooks, is_local);
2020-09-19 11:23:06 +02:00
}
}
}
}
}
2019-03-20 05:07:28 +01:00
2023-09-22 00:38:42 +02:00
if (g_config.hook == 1)
2019-08-07 12:59:23 +02:00
{
2023-09-26 10:41:20 +02:00
hook_patch_iat_list(GetModuleHandle(NULL), FALSE, hooks, TRUE);
2019-08-07 12:59:23 +02:00
}
2019-03-19 06:57:49 +01:00
}
2021-06-11 20:30:43 +02:00
void hook_revert(HOOKLIST* hooks)
2019-03-19 06:57:49 +01:00
{
2019-08-07 12:45:40 +02:00
#ifdef _MSC_VER
2023-09-22 00:38:42 +02:00
if (g_config.hook == 2)
2019-03-19 06:57:49 +01:00
{
2020-10-19 16:37:12 +02:00
for (int i = 0; hooks[i].module_name[0]; i++)
{
for (int x = 0; hooks[i].data[x].function_name[0]; x++)
{
2023-09-26 10:41:20 +02:00
if ((hooks[i].data[x].flags & HOOK_SKIP_2))
2021-08-06 02:07:50 +02:00
continue;
2020-10-19 16:37:12 +02:00
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((PVOID*)hooks[i].data[x].function, (PVOID)hooks[i].data[x].new_function);
DetourTransactionCommit();
}
}
2019-03-19 09:43:47 +01:00
}
2021-05-10 01:00:55 +02:00
#endif
2020-09-19 11:23:06 +02:00
2023-09-22 00:38:42 +02:00
if (g_config.hook == 3 || g_config.hook == 4)
2020-09-19 11:23:06 +02:00
{
2021-01-23 14:55:22 +01:00
char game_exe_path[MAX_PATH] = { 0 };
char game_dir[MAX_PATH] = { 0 };
2020-09-19 11:23:06 +02:00
2021-01-23 14:55:22 +01:00
if (GetModuleFileNameA(NULL, game_exe_path, MAX_PATH))
2020-09-19 11:23:06 +02:00
{
2021-01-23 14:55:22 +01:00
_splitpath(game_exe_path, NULL, game_dir, NULL, NULL);
2020-09-19 11:23:06 +02:00
2021-01-23 14:55:22 +01:00
char mod_path[MAX_PATH] = { 0 };
char mod_dir[MAX_PATH] = { 0 };
2021-08-11 01:36:12 +02:00
char mod_filename[MAX_PATH] = { 0 };
2020-10-13 09:20:52 +02:00
HMODULE hmod = NULL;
while ((hmod = util_enumerate_modules(hmod)))
2020-09-19 11:23:06 +02:00
{
2020-10-13 09:20:52 +02:00
if (hmod == g_ddraw_module)
2020-09-19 11:23:06 +02:00
continue;
2021-01-23 14:55:22 +01:00
if (GetModuleFileNameA(hmod, mod_path, MAX_PATH))
2020-09-19 11:23:06 +02:00
{
2021-08-11 01:36:12 +02:00
_splitpath(mod_path, NULL, mod_dir, mod_filename, NULL);
2020-09-19 11:23:06 +02:00
2023-09-26 10:41:20 +02:00
BOOL is_local = _strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0;
2024-06-01 22:59:12 +02:00
BOOL wine_hook = IsWine() && _strcmpi(mod_filename, "mciavi32") == 0;
2023-09-26 10:41:20 +02:00
if (is_local ||
2024-06-01 22:59:12 +02:00
wine_hook ||
2024-05-31 23:54:33 +02:00
_strcmpi(mod_filename, "QuickTime") == 0 ||
2022-10-02 18:41:06 +02:00
_strcmpi(mod_filename, "MSVFW32") == 0 ||
2021-08-11 01:36:12 +02:00
_strcmpi(mod_filename, "quartz") == 0 ||
_strcmpi(mod_filename, "winmm") == 0)
2020-09-19 11:23:06 +02:00
{
2023-09-26 10:41:20 +02:00
hook_patch_iat_list(hmod, TRUE, hooks, is_local);
2020-09-19 11:23:06 +02:00
}
}
}
}
}
2019-08-06 04:37:06 +02:00
2023-09-22 00:38:42 +02:00
if (g_config.hook == 1)
2019-08-07 12:45:40 +02:00
{
2023-09-26 10:41:20 +02:00
hook_patch_iat_list(GetModuleHandle(NULL), TRUE, hooks, TRUE);
2019-03-19 06:57:49 +01:00
}
}
2024-06-02 22:17:26 +02:00
void hook_init()
2019-03-19 06:57:49 +01:00
{
2024-06-02 22:17:26 +02:00
if (!g_hook_active)
2023-08-13 20:31:26 +02:00
{
if (g_config.hook == 4 && hook_got_ddraw_import(GetModuleHandleA(NULL), TRUE))
2023-08-13 20:31:26 +02:00
{
/* Switch to 3 if we can be sure that ddraw.dll will not be unloaded from the process */
2023-09-22 00:38:42 +02:00
g_config.hook = 3;
2023-08-13 20:31:26 +02:00
}
}
2023-09-22 00:38:42 +02:00
if (!g_hook_active || g_config.hook == 3 || g_config.hook == 4)
2019-03-19 06:57:49 +01:00
{
2023-07-07 01:23:41 +02:00
#if defined(_DEBUG) && defined(_MSC_VER)
2024-06-02 22:17:26 +02:00
if (!g_hook_active)
2023-08-02 15:15:44 +02:00
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)&real_SetUnhandledExceptionFilter, (PVOID)fake_SetUnhandledExceptionFilter);
DetourTransactionCommit();
if (!IsDebuggerPresent())
{
2024-08-31 08:09:51 +02:00
patch_ljmp((void*)_invoke_watson, (void*)dbg_invoke_watson);
}
2023-08-02 15:15:44 +02:00
}
#endif
2024-06-02 22:17:26 +02:00
if (!g_hook_active)
2023-08-02 15:15:44 +02:00
{
hook_patch_iat(GetModuleHandle("AcGenral"), FALSE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
}
2023-07-28 13:53:57 +02:00
2024-06-02 22:17:26 +02:00
hook_create((HOOKLIST*)&g_hook_hooklist, !g_hook_active);
2023-08-02 17:09:01 +02:00
g_hook_active = TRUE;
2023-07-28 13:53:57 +02:00
}
2021-05-14 01:24:46 +02:00
}
2020-10-13 09:20:52 +02:00
void hook_exit()
2019-08-07 12:45:40 +02:00
{
2020-10-13 09:20:52 +02:00
if (g_hook_active)
2019-08-07 12:45:40 +02:00
{
2020-10-13 09:20:52 +02:00
g_hook_active = FALSE;
2019-08-07 12:45:40 +02:00
hook_revert((HOOKLIST*)&g_hook_hooklist);
2021-05-14 01:24:46 +02:00
2024-04-26 01:41:38 +02:00
#if defined(_DEBUG)
#if defined(_MSC_VER)
2023-08-04 08:41:14 +02:00
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((PVOID*)&real_SetUnhandledExceptionFilter, (PVOID)fake_SetUnhandledExceptionFilter);
DetourTransactionCommit();
2024-04-26 01:41:38 +02:00
#endif
2023-08-04 08:41:14 +02:00
real_SetUnhandledExceptionFilter(g_dbg_exception_filter);
#endif
2023-08-04 08:41:14 +02:00
hook_patch_iat(GetModuleHandle("AcGenral"), TRUE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
}
2019-03-19 06:57:49 +01:00
}