From aaeed259951eb95d10a4334e8bef55a3e6ea9c91 Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Sun, 10 Dec 2023 18:41:10 -0500 Subject: [PATCH] impl procaddr hook --- hooklib/meson.build | 2 + hooklib/procaddr.c | 124 ++++++++++++++++++++++++++++++++++++++++++++ hooklib/procaddr.h | 20 +++++++ 3 files changed, 146 insertions(+) create mode 100644 hooklib/procaddr.c create mode 100644 hooklib/procaddr.h diff --git a/hooklib/meson.build b/hooklib/meson.build index e6e62ae..2557d48 100644 --- a/hooklib/meson.build +++ b/hooklib/meson.build @@ -3,6 +3,8 @@ hooklib_lib = static_library( include_directories : inc, c_pch : '../precompiled.h', sources : [ + 'procaddr.c', + 'procaddr.h', 'serial.c', 'serial.h', 'uart.c', diff --git a/hooklib/procaddr.c b/hooklib/procaddr.c new file mode 100644 index 0000000..752f586 --- /dev/null +++ b/hooklib/procaddr.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include + +#include "hooklib/procaddr.h" + +#include "hook/table.h" + +static struct proc_addr_table *proc_addr_hook_list; +static size_t proc_addr_hook_count; +static CRITICAL_SECTION proc_addr_hook_lock; +static bool proc_addr_hook_initted; + +static FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name); +static FARPROC (WINAPI *next_GetProcAddress)(HMODULE hModule, const char *name); +static void proc_addr_hook_init(); + +static const struct hook_symbol win32_hooks[] = { + { + .name = "GetProcAddress", + .patch = my_GetProcAddress, + .link = (void **) &next_GetProcAddress + } +}; + +HRESULT proc_addr_table_push( + HMODULE loader_mod, + const char *target, + struct hook_symbol *syms, + size_t nsyms +) +{ + HRESULT hr; + struct proc_addr_table *new_item; + struct proc_addr_table *new_mem; + + proc_addr_hook_init(); + + proc_addr_insert_hooks(loader_mod); + + EnterCriticalSection(&proc_addr_hook_lock); + + new_mem = realloc( + proc_addr_hook_list, + (proc_addr_hook_count + 1) * sizeof(struct proc_addr_table)); + + if (new_mem == NULL) { + hr = E_OUTOFMEMORY; + + LeaveCriticalSection(&proc_addr_hook_lock); + return hr; + } + + new_item = &new_mem[proc_addr_hook_count]; + new_item->name = target; + new_item->nsyms = nsyms; + new_item->syms = syms; + + proc_addr_hook_list = new_mem; + proc_addr_hook_count++; + hr = S_OK; + + LeaveCriticalSection(&proc_addr_hook_lock); + + return hr; +} + +void proc_addr_insert_hooks(HMODULE target) +{ + hook_table_apply( + target, + "kernel32.dll", + win32_hooks, + _countof(win32_hooks)); +} + +static void proc_addr_hook_init(void) +{ + if (proc_addr_hook_initted) { + return; + } + + proc_addr_hook_initted = true; + + InitializeCriticalSection(&proc_addr_hook_lock); +} + +FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name) +{ + uintptr_t ordinal = (uintptr_t) name; + char mod_path[PATH_MAX]; + char *mod_name; + const struct hook_symbol *sym; + FARPROC result = next_GetProcAddress(hModule, name); + + GetModuleFileNameA(hModule, mod_path, PATH_MAX); + mod_name = basename(mod_path); + + for (int i = 0; i < proc_addr_hook_count; i++) { + + if (strcmp(proc_addr_hook_list[i].name, mod_name) == 0) { + + for (int j = 0; j < proc_addr_hook_list[i].nsyms; j++) { + sym = &proc_addr_hook_list[i].syms[j]; + + if (ordinal > 0xFFFF) { + + if (strcmp(sym->name, name) == 0) { + result = (FARPROC) sym->patch; + } + } + + else { + if (sym->ordinal == ordinal) { + result = (FARPROC) sym->patch; + } + } + } + } + } + + return result; +} \ No newline at end of file diff --git a/hooklib/procaddr.h b/hooklib/procaddr.h new file mode 100644 index 0000000..4ec3967 --- /dev/null +++ b/hooklib/procaddr.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include + +#include "hook/table.h" + +struct proc_addr_table { + const char *name; + size_t nsyms; + struct hook_symbol *syms; +}; + +HRESULT proc_addr_table_push( + HMODULE loader_mod, + const char *target, + struct hook_symbol *syms, + size_t nsyms +); +void proc_addr_insert_hooks(HMODULE target); \ No newline at end of file