more hook 3/4 performance improvements

This commit is contained in:
FunkyFr3sh 2020-10-20 05:59:41 +02:00
parent 9c555c8e05
commit de02f46413
3 changed files with 81 additions and 90 deletions

View file

@ -6,7 +6,7 @@
typedef struct hook_list_data { char function_name[32]; PROC new_function; PROC* function; } hook_list_data; typedef struct hook_list_data { char function_name[32]; PROC new_function; PROC* function; } hook_list_data;
typedef struct hook_list { char module_name[32]; BOOL enabled; hook_list_data data[32]; } hook_list; typedef struct hook_list { char module_name[32]; BOOL enabled; hook_list_data data[24]; } hook_list;
typedef BOOL (WINAPI* GETCURSORPOSPROC)(LPPOINT); typedef BOOL (WINAPI* GETCURSORPOSPROC)(LPPOINT);
typedef BOOL(WINAPI* CLIPCURSORPROC)(const RECT*); typedef BOOL(WINAPI* CLIPCURSORPROC)(const RECT*);
@ -65,7 +65,8 @@ extern BOOL g_hook_active;
void hook_init(); void hook_init();
void hook_exit(); void hook_exit();
void hook_patch_iat(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction); void hook_patch_iat(HMODULE hmod, BOOL unhook, char* module_name, char* function_name, PROC new_function);
void hook_patch_iat_list(HMODULE hmod, BOOL unhook, hook_list* hooks);
void hook_create(hook_list* hooks); void hook_create(hook_list* hooks);
void hook_revert(hook_list* hooks); void hook_revert(hook_list* hooks);

View file

@ -89,14 +89,10 @@ static HRESULT WINAPI fake_DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion,
void dinput_hook() void dinput_hook()
{ {
hook_patch_iat(GetModuleHandle(NULL), "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA); hook_patch_iat(GetModuleHandle(NULL), FALSE, "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA);
} }
void dinput_unhook() void dinput_unhook()
{ {
hook_patch_iat( hook_patch_iat(GetModuleHandle(NULL), TRUE, "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA);
GetModuleHandle(NULL),
"dinput.dll",
"DirectInputCreateA",
(PROC)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA"));
} }

View file

@ -65,7 +65,7 @@ static hook_list g_hooks[] =
{ "EnableWindow", (PROC)fake_EnableWindow, (PROC*)&real_EnableWindow }, { "EnableWindow", (PROC)fake_EnableWindow, (PROC*)&real_EnableWindow },
{ "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC*)&real_CreateWindowExA }, { "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC*)&real_CreateWindowExA },
{ "DestroyWindow", (PROC)fake_DestroyWindow, (PROC*)&real_DestroyWindow }, { "DestroyWindow", (PROC)fake_DestroyWindow, (PROC*)&real_DestroyWindow },
{ "", NULL } { "", NULL, NULL }
} }
}, },
{ {
@ -73,7 +73,7 @@ static hook_list g_hooks[] =
TRUE, TRUE,
{ {
{ "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps }, { "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps },
{ "", NULL } { "", NULL, NULL }
} }
}, },
{ {
@ -84,21 +84,35 @@ static hook_list g_hooks[] =
{ "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW }, { "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW },
{ "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA }, { "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA },
{ "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW }, { "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW },
{ "", NULL } { "", NULL, NULL }
} }
}, },
{ {
"", "",
FALSE, FALSE,
{ {
{ "", NULL } { "", NULL, NULL }
} }
} }
}; };
void hook_patch_iat(HMODULE hmod, char *module_name, char *function_name, PROC new_function) void hook_patch_iat(HMODULE hmod, BOOL unhook, char* module_name, char* function_name, PROC new_function)
{ {
if (!hmod || hmod == INVALID_HANDLE_VALUE || !new_function) hook_list hooks[2];
memset(&hooks, 0, sizeof(hooks));
hooks[0].enabled = TRUE;
hooks[0].data[0].new_function = new_function;
strncpy(hooks[0].module_name, module_name, sizeof(hooks[0].module_name)-1);
strncpy(hooks[0].data[0].function_name, function_name, sizeof(hooks[0].data[0].function_name) - 1);
hook_patch_iat_list(hmod, unhook, (hook_list*)&hooks);
}
void hook_patch_iat_list(HMODULE hmod, BOOL unhook, hook_list* hooks)
{
if (!hmod || hmod == INVALID_HANDLE_VALUE || !hooks)
return; return;
#ifdef _MSC_VER #ifdef _MSC_VER
@ -121,37 +135,69 @@ void hook_patch_iat(HMODULE hmod, char *module_name, char *function_name, PROC n
while (import_desc->FirstThunk) while (import_desc->FirstThunk)
{ {
char* imp_module_name = (char*)((DWORD)dos_header + (DWORD)(import_desc->Name)); for (int i = 0; hooks[i].module_name[0]; i++)
if (_stricmp(imp_module_name, module_name) == 0)
{ {
PIMAGE_THUNK_DATA first_thunk = if (!hooks[i].enabled)
(PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->FirstThunk); continue;
PIMAGE_THUNK_DATA original_first_thunk = char* imp_module_name = (char*)((DWORD)dos_header + (DWORD)(import_desc->Name));
(PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->OriginalFirstThunk);
while (first_thunk->u1.Function && original_first_thunk->u1.AddressOfData) if (_stricmp(imp_module_name, hooks[i].module_name) == 0)
{ {
PIMAGE_IMPORT_BY_NAME import = PIMAGE_THUNK_DATA first_thunk =
(PIMAGE_IMPORT_BY_NAME)((DWORD)dos_header + original_first_thunk->u1.AddressOfData); (PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->FirstThunk);
if ((original_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0 && PIMAGE_THUNK_DATA original_first_thunk =
_stricmp((const char*)import->Name, function_name) == 0) (PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->OriginalFirstThunk);
while (first_thunk->u1.Function && original_first_thunk->u1.AddressOfData)
{ {
DWORD old_protect; PIMAGE_IMPORT_BY_NAME import =
(PIMAGE_IMPORT_BY_NAME)((DWORD)dos_header + original_first_thunk->u1.AddressOfData);
if (VirtualProtect(&first_thunk->u1.Function, sizeof(DWORD), PAGE_READWRITE, &old_protect)) if ((original_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0)
{ {
first_thunk->u1.Function = (DWORD)new_function; for (int x = 0; hooks[i].data[x].function_name[0]; x++)
VirtualProtect(&first_thunk->u1.Function, sizeof(DWORD), old_protect, &old_protect); {
if (!unhook && !hooks[i].data[x].new_function)
continue;
if (_stricmp((const char*)import->Name, hooks[i].data[x].function_name) == 0)
{
DWORD old_protect;
if (VirtualProtect(
&first_thunk->u1.Function, sizeof(DWORD), PAGE_READWRITE, &old_protect))
{
if (unhook)
{
DWORD org =
(DWORD)GetProcAddress(
GetModuleHandle(hooks[i].module_name),
hooks[i].data[x].function_name);
if (org)
{
first_thunk->u1.Function = org;
}
}
else
{
first_thunk->u1.Function = (DWORD)hooks[i].data[x].new_function;
}
VirtualProtect(
&first_thunk->u1.Function, sizeof(DWORD), old_protect, &old_protect);
}
break;
}
}
} }
break; first_thunk++;
original_first_thunk++;
} }
first_thunk++;
original_first_thunk++;
} }
} }
@ -209,20 +255,7 @@ void hook_create(hook_list* hooks)
if (_wcsnicmp(game_dir, mod_dir, wcslen(game_dir)) == 0) if (_wcsnicmp(game_dir, mod_dir, wcslen(game_dir)) == 0)
{ {
for (int i = 0; hooks[i].module_name[0]; i++) hook_patch_iat_list(hmod, FALSE, hooks);
{
if (!hooks[i].enabled)
continue;
for (int x = 0; hooks[i].data[x].function_name[0]; x++)
{
hook_patch_iat(
hmod,
hooks[i].module_name,
hooks[i].data[x].function_name,
hooks[i].data[x].new_function);
}
}
} }
} }
} }
@ -232,20 +265,7 @@ void hook_create(hook_list* hooks)
if (g_hook_method == 1) if (g_hook_method == 1)
{ {
for (int i = 0; hooks[i].module_name[0]; i++) hook_patch_iat_list(GetModuleHandle(NULL), FALSE, hooks);
{
if (!hooks[i].enabled)
continue;
for (int x = 0; hooks[i].data[x].function_name[0]; x++)
{
hook_patch_iat(
GetModuleHandle(NULL),
hooks[i].module_name,
hooks[i].data[x].function_name,
hooks[i].data[x].new_function);
}
}
} }
} }
@ -293,20 +313,7 @@ void hook_revert(hook_list* hooks)
if (_wcsnicmp(game_dir, mod_dir, wcslen(game_dir)) == 0) if (_wcsnicmp(game_dir, mod_dir, wcslen(game_dir)) == 0)
{ {
for (int i = 0; hooks[i].module_name[0]; i++) hook_patch_iat_list(hmod, TRUE, hooks);
{
if (!hooks[i].enabled)
continue;
for (int x = 0; hooks[i].data[x].function_name[0]; x++)
{
hook_patch_iat(
hmod,
hooks[i].module_name,
hooks[i].data[x].function_name,
GetProcAddress(GetModuleHandle(hooks[i].module_name), hooks[i].data[x].function_name));
}
}
} }
} }
} }
@ -316,20 +323,7 @@ void hook_revert(hook_list* hooks)
if (g_hook_method == 1) if (g_hook_method == 1)
{ {
for (int i = 0; hooks[i].module_name[0]; i++) hook_patch_iat_list(GetModuleHandle(NULL), TRUE, hooks);
{
if (!hooks[i].enabled)
continue;
for (int x = 0; hooks[i].data[x].function_name[0]; x++)
{
hook_patch_iat(
GetModuleHandle(NULL),
hooks[i].module_name,
hooks[i].data[x].function_name,
GetProcAddress(GetModuleHandle(hooks[i].module_name), hooks[i].data[x].function_name));
}
}
} }
} }