diff --git a/Module.mk b/Module.mk index eb28f82..bc1d3a4 100644 --- a/Module.mk +++ b/Module.mk @@ -182,6 +182,8 @@ include src/main/p4ioemu/Module.mk include src/main/popnhook-util/Module.mk include src/main/popnhook1/Module.mk include src/main/popnio/Module.mk +include src/main/procmon/Module.mk +include src/main/procmon-lib/Module.mk include src/main/pcbidgen/Module.mk include src/main/sdvxhook/Module.mk include src/main/sdvxhook2-cn/Module.mk @@ -233,6 +235,7 @@ $(zipdir)/tools.zip: \ build/bin/indep-32/ezusb2-dbg-hook.dll \ build/bin/indep-32/ezusb2-tool.exe \ build/bin/indep-32/ezusb-tool.exe \ + build/bin/indep-32/procmon.dll \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -247,6 +250,7 @@ $(zipdir)/tools-x64.zip: \ build/bin/indep-64/iidx-ezusb2-exit-hook.dll \ build/bin/indep-64/jbiotest.exe \ build/bin/indep-64/mempatch-hook.dll \ + build/bin/indep-64/procmon.dll \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ diff --git a/src/main/procmon-lib/Module.mk b/src/main/procmon-lib/Module.mk new file mode 100644 index 0000000..994dd69 --- /dev/null +++ b/src/main/procmon-lib/Module.mk @@ -0,0 +1,8 @@ +libs += procmon-lib + +libs_procmon-lib := \ + util \ + +src_procmon-lib := \ + procmon.c \ + diff --git a/src/main/procmon-lib/procmon.c b/src/main/procmon-lib/procmon.c new file mode 100644 index 0000000..787aa2e --- /dev/null +++ b/src/main/procmon-lib/procmon.c @@ -0,0 +1,96 @@ +#define LOG_MODULE "procmon-lib" + +#include + +#include "core/log.h" + +#include "procmon-lib/procmon.h" + +#define PROCMON_LIB "procmon.dll" +#define CONCAT(x, y) x##y +#define LOAD_FUNC(lib_func, module, path, func_name) \ + lib_func = (CONCAT(func_name, _t)) GetProcAddress(module, #func_name); \ + if (lib_func == NULL) { \ + log_fatal("Failed to load function '%s' from '%s'", #func_name, path); \ + } + +bool procmon_available() +{ + HMODULE module; + + module = LoadLibraryExA(PROCMON_LIB, NULL, DONT_RESOLVE_DLL_REFERENCES); + + if (module == NULL) { + return false; + } else { + FreeLibrary(module); + return true; + } +} + +void procmon_init(struct procmon *procmon) +{ + log_assert(procmon); + + memset(procmon, 0, sizeof(*procmon)); +} + +void procmon_load(struct procmon *procmon) +{ + HMODULE module; + uint32_t api_version; + + log_assert(procmon); + + module = LoadLibraryA(PROCMON_LIB); + + if (module == NULL) { + LPSTR buffer; + + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &buffer, + 0, + NULL); + + log_fatal("Failed to load library %s: %s", PROCMON_LIB, buffer); + + LocalFree(buffer); + } + + procmon->module = module; + + LOAD_FUNC(procmon->api_version, module, PROCMON_LIB, procmon_api_version); + + api_version = procmon->api_version(); + + if (api_version != 0) { + log_fatal("Unsupported API version %d of %s", api_version, PROCMON_LIB); + } + + LOAD_FUNC(procmon->set_loggers, module, PROCMON_LIB, procmon_set_loggers); + LOAD_FUNC(procmon->init, module, PROCMON_LIB, procmon_init); + LOAD_FUNC( + procmon->file_mon_enable, module, PROCMON_LIB, procmon_file_mon_enable); + LOAD_FUNC( + procmon->module_mon_enable, + module, + PROCMON_LIB, + procmon_module_mon_enable); + LOAD_FUNC( + procmon->thread_mon_enable, + module, + PROCMON_LIB, + procmon_thread_mon_enable); +} + +void procmon_free(struct procmon *procmon) +{ + log_assert(procmon); + + FreeLibrary(procmon->module); +} \ No newline at end of file diff --git a/src/main/procmon-lib/procmon.h b/src/main/procmon-lib/procmon.h new file mode 100644 index 0000000..135a4b8 --- /dev/null +++ b/src/main/procmon-lib/procmon.h @@ -0,0 +1,37 @@ +#ifndef PROCMON_LIB_PROCMON_H +#define PROCMON_LIB_PROCMON_H + +#include + +#include +#include + +#include "core/log.h" + +typedef uint32_t (*procmon_api_version_t)(); +typedef void (*procmon_set_loggers_t)( + core_log_message_t misc, + core_log_message_t info, + core_log_message_t warning, + core_log_message_t fatal); +typedef void (*procmon_file_mon_enable_t)(); +typedef void (*procmon_module_mon_enable_t)(); +typedef void (*procmon_thread_mon_enable_t)(); +typedef void (*procmon_init_t)(); + +struct procmon { + HMODULE module; + procmon_api_version_t api_version; + procmon_set_loggers_t set_loggers; + procmon_file_mon_enable_t file_mon_enable; + procmon_module_mon_enable_t module_mon_enable; + procmon_thread_mon_enable_t thread_mon_enable; + procmon_init_t init; +}; + +void procmon_init(struct procmon *procmon); +bool procmon_available(); +void procmon_load(struct procmon *procmon); +void procmon_free(struct procmon *procmon); + +#endif \ No newline at end of file diff --git a/src/main/procmon/Module.mk b/src/main/procmon/Module.mk new file mode 100644 index 0000000..f1e355d --- /dev/null +++ b/src/main/procmon/Module.mk @@ -0,0 +1,13 @@ +dlls += procmon + +libs_procmon := \ + core \ + hook \ + util \ + +src_procmon := \ + file.c \ + module.c \ + procmon.c \ + thread.c \ + diff --git a/src/main/procmon/file.c b/src/main/procmon/file.c new file mode 100644 index 0000000..229455d --- /dev/null +++ b/src/main/procmon/file.c @@ -0,0 +1,176 @@ +#define LOG_MODULE "procmon-file" + +#include + +#include "core/log.h" + +#include "hook/table.h" + +#include "util/str.h" + +static HANDLE(STDCALL *real_CreateFileW)( + const wchar_t *lpFileName, + uint32_t dwDesiredAccess, + uint32_t dwShareMode, + SECURITY_ATTRIBUTES *lpSecurityAttributes, + uint32_t dwCreationDisposition, + uint32_t dwFlagsAndAttributes, + HANDLE hTemplateFile); +static HANDLE(STDCALL *real_CreateFileA)( + const char *lpFileName, + uint32_t dwDesiredAccess, + uint32_t dwShareMode, + SECURITY_ATTRIBUTES *lpSecurityAttributes, + uint32_t dwCreationDisposition, + uint32_t dwFlagsAndAttributes, + HANDLE hTemplateFile); + +static HANDLE STDCALL my_CreateFileW( + const wchar_t *lpFileName, + uint32_t dwDesiredAccess, + uint32_t dwShareMode, + SECURITY_ATTRIBUTES *lpSecurityAttributes, + uint32_t dwCreationDisposition, + uint32_t dwFlagsAndAttributes, + HANDLE hTemplateFile); + +static HANDLE STDCALL my_CreateFileA( + const char *lpFileName, + uint32_t dwDesiredAccess, + uint32_t dwShareMode, + SECURITY_ATTRIBUTES *lpSecurityAttributes, + uint32_t dwCreationDisposition, + uint32_t dwFlagsAndAttributes, + HANDLE hTemplateFile); + +static const struct hook_symbol _procmon_file_hook_syms[] = { + { + .name = "CreateFileW", + .patch = my_CreateFileW, + .link = (void **) &real_CreateFileW, + }, + { + .name = "CreateFileA", + .patch = my_CreateFileA, + .link = (void **) &real_CreateFileA, + }, +}; + +static HANDLE STDCALL my_CreateFileW( + const wchar_t *lpFileName, + uint32_t dwDesiredAccess, + uint32_t dwShareMode, + SECURITY_ATTRIBUTES *lpSecurityAttributes, + uint32_t dwCreationDisposition, + uint32_t dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + HANDLE result; + char *tmp; + + wstr_narrow(lpFileName, &tmp); + + log_misc( + "CreateFileW(lpFileName %s, dwDesiredAccess 0x%X, dwShareMode 0x%X, " + "dwCreationDisposition 0x%X, dwFlagsAndAttributes 0x%X, hTemplateFile " + "%p)", + tmp, + dwDesiredAccess, + dwShareMode, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + + result = real_CreateFileW( + lpFileName, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + + log_misc( + "CreateFileW(lpFileName %s, dwDesiredAccess 0x%X, dwShareMode 0x%X, " + "dwCreationDisposition 0x%X, dwFlagsAndAttributes 0x%X, hTemplateFile " + "%p) = %p", + tmp, + dwDesiredAccess, + dwShareMode, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile, + result); + + free(tmp); + + return result; +} + +static HANDLE STDCALL my_CreateFileA( + const char *lpFileName, + uint32_t dwDesiredAccess, + uint32_t dwShareMode, + SECURITY_ATTRIBUTES *lpSecurityAttributes, + uint32_t dwCreationDisposition, + uint32_t dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + HANDLE result; + + log_misc( + "CreateFileA(lpFileName %s, dwDesiredAccess 0x%X, dwShareMode 0x%X, " + "dwCreationDisposition 0x%X, dwFlagsAndAttributes 0x%X, hTemplateFile " + "%p)", + lpFileName, + dwDesiredAccess, + dwShareMode, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + + result = real_CreateFileA( + lpFileName, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + + log_misc( + "CreateFileA(lpFileName %s, dwDesiredAccess 0x%X, dwShareMode 0x%X, " + "dwCreationDisposition 0x%X, dwFlagsAndAttributes 0x%X, hTemplateFile " + "%p) = %p", + lpFileName, + dwDesiredAccess, + dwShareMode, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile, + result); + + return result; +} + +void procmon_file_init() +{ + hook_table_apply( + NULL, + "kernel32.dll", + _procmon_file_hook_syms, + lengthof(_procmon_file_hook_syms)); + + log_misc("init"); +} + +void procmon_file_fini() +{ + hook_table_revert( + NULL, + "kernel32.dll", + _procmon_file_hook_syms, + lengthof(_procmon_file_hook_syms)); + + log_misc("fini"); +} \ No newline at end of file diff --git a/src/main/procmon/file.h b/src/main/procmon/file.h new file mode 100644 index 0000000..6b9d751 --- /dev/null +++ b/src/main/procmon/file.h @@ -0,0 +1,7 @@ +#ifndef PROCMON_FILE_H +#define PROCMON_FILE_H + +void procmon_file_init(); +void procmon_file_fini(); + +#endif \ No newline at end of file diff --git a/src/main/procmon/module.c b/src/main/procmon/module.c new file mode 100644 index 0000000..3a130ac --- /dev/null +++ b/src/main/procmon/module.c @@ -0,0 +1,289 @@ +#define LOG_MODULE "procmon-module" + +#include + +#include "core/log.h" + +#include "hook/table.h" + +#include "util/str.h" + +static HMODULE(STDCALL *real_GetModuleHandleA)(LPCSTR lpModuleName); +static BOOL(STDCALL *real_GetModuleHandleExA)( + DWORD dwFlags, LPCSTR lpModuleName, HMODULE *phModule); +static BOOL(STDCALL *real_GetModuleHandleExW)( + DWORD dwFlags, LPCWSTR lpModuleName, HMODULE *phModule); +static HMODULE(STDCALL *real_GetModuleHandleW)(LPCWSTR lpModuleName); +static HMODULE(STDCALL *real_LoadLibraryA)(LPCSTR lpLibFileName); +static HMODULE(STDCALL *real_LoadLibraryW)(LPCWSTR lpLibFileName); +static HMODULE(STDCALL *real_LoadLibraryExA)( + LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +static HMODULE(STDCALL *real_LoadLibraryExW)( + LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +static FARPROC(STDCALL *real_GetProcAddress)( + HMODULE hModule, LPCSTR lpProcName); + +static HMODULE STDCALL my_GetModuleHandleA(LPCSTR lpModuleName); +static BOOL STDCALL +my_GetModuleHandleExA(DWORD dwFlags, LPCSTR lpModuleName, HMODULE *phModule); +static BOOL STDCALL +my_GetModuleHandleExW(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE *phModule); +static HMODULE STDCALL my_GetModuleHandleW(LPCWSTR lpModuleName); +static HMODULE STDCALL my_LoadLibraryA(LPCSTR lpLibFileName); +static HMODULE STDCALL my_LoadLibraryW(LPCWSTR lpLibFileName); +static HMODULE STDCALL +my_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +static HMODULE STDCALL +my_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +static FARPROC STDCALL my_GetProcAddress(HMODULE hModule, LPCSTR lpProcName); + +static const struct hook_symbol _procmon_module_hook_syms[] = { + { + .name = "GetModuleHandleA", + .patch = my_GetModuleHandleA, + .link = (void **) &real_GetModuleHandleA, + }, + { + .name = "GetModuleHandleExA", + .patch = my_GetModuleHandleExA, + .link = (void **) &real_GetModuleHandleExA, + }, + { + .name = "GetModuleHandleExW", + .patch = my_GetModuleHandleExW, + .link = (void **) &real_GetModuleHandleExW, + }, + { + .name = "GetModuleHandleW", + .patch = my_GetModuleHandleW, + .link = (void **) &real_GetModuleHandleW, + }, + { + .name = "LoadLibraryA", + .patch = my_LoadLibraryA, + .link = (void **) &real_LoadLibraryA, + }, + { + .name = "LoadLibraryW", + .patch = my_LoadLibraryW, + .link = (void **) &real_LoadLibraryW, + }, + { + .name = "LoadLibraryExA", + .patch = my_LoadLibraryExA, + .link = (void **) &real_LoadLibraryExA, + }, + { + .name = "LoadLibraryExW", + .patch = my_LoadLibraryExW, + .link = (void **) &real_LoadLibraryExW, + }, + { + .name = "GetProcAddress", + .patch = my_GetProcAddress, + .link = (void **) &real_GetProcAddress, + }, +}; + +static HMODULE STDCALL my_GetModuleHandleA(LPCSTR lpModuleName) +{ + HMODULE result; + + log_misc("GetModuleHandleA(lpModuleName %s)", lpModuleName); + + result = real_GetModuleHandleA(lpModuleName); + + log_misc("GetModuleHandleA(lpModuleName %s) = %p", lpModuleName, result); + + return result; +} + +static BOOL STDCALL +my_GetModuleHandleExA(DWORD dwFlags, LPCSTR lpModuleName, HMODULE *phModule) +{ + BOOL result; + + log_misc( + "GetModuleHandleExA(dwFlags %lu, lpModuleName %s, phModule %p)", + dwFlags, + lpModuleName, + phModule); + + result = real_GetModuleHandleExA(dwFlags, lpModuleName, phModule); + + log_misc( + "GetModuleHandleExA(dwFlags %lu, lpModuleName %s, phModule %p) = %d", + dwFlags, + lpModuleName, + phModule, + result); + + return result; +} + +static BOOL STDCALL +my_GetModuleHandleExW(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE *phModule) +{ + BOOL result; + char *tmp; + + wstr_narrow(lpModuleName, &tmp); + + log_misc( + "GetModuleHandleExW(dwFlags %lu, lpModuleName %s, phModule %p)", + dwFlags, + tmp, + phModule); + + result = real_GetModuleHandleExW(dwFlags, lpModuleName, phModule); + + log_misc( + "GetModuleHandleExW(dwFlags %lu, lpModuleName %s, phModule %p) = %d", + dwFlags, + tmp, + phModule, + result); + + free(tmp); + + return result; +} + +static HMODULE STDCALL my_GetModuleHandleW(LPCWSTR lpModuleName) +{ + HMODULE result; + char *tmp; + + wstr_narrow(lpModuleName, &tmp); + + log_misc("GetModuleHandleW(lpModuleName %s)", tmp); + + result = real_GetModuleHandleW(lpModuleName); + + log_misc("GetModuleHandleW(lpModuleName %s) = %p", tmp, result); + + free(tmp); + + return result; +} + +static HMODULE STDCALL my_LoadLibraryA(LPCSTR lpLibFileName) +{ + HMODULE result; + + log_misc("LoadLibraryA(lpLibFileName %s)", lpLibFileName); + + result = real_LoadLibraryA(lpLibFileName); + + log_misc("LoadLibraryA(lpLibFileName %s) = %p", lpLibFileName, result); + + return result; +} + +static HMODULE STDCALL my_LoadLibraryW(LPCWSTR lpLibFileName) +{ + HMODULE result; + char *tmp; + + wstr_narrow(lpLibFileName, &tmp); + + log_misc("LoadLibraryW(lpLibFileName %s)", tmp); + + result = real_LoadLibraryW(lpLibFileName); + + log_misc("LoadLibraryW(lpLibFileName %s) = %p", tmp, result); + + free(tmp); + + return result; +} + +static HMODULE STDCALL +my_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE result; + + log_misc( + "LoadLibraryExA(lpLibFileName %s, hFile %p, dwFlags %lu)", + lpLibFileName, + hFile, + dwFlags); + + result = real_LoadLibraryExA(lpLibFileName, hFile, dwFlags); + + log_misc( + "LoadLibraryExA(lpLibFileName %s, hFile %p, dwFlags %lu) = %p", + lpLibFileName, + hFile, + dwFlags, + result); + + return result; +} + +static HMODULE STDCALL +my_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE result; + char *tmp; + + wstr_narrow(lpLibFileName, &tmp); + + log_misc( + "LoadLibraryExA(lpLibFileName %s, hFile %p, dwFlags %lu)", + tmp, + hFile, + dwFlags); + + result = real_LoadLibraryExW(lpLibFileName, hFile, dwFlags); + + log_misc( + "LoadLibraryExA(lpLibFileName %s, hFile %p, dwFlags %lu) = %p", + tmp, + hFile, + dwFlags, + result); + + free(tmp); + + return result; +} + +static FARPROC STDCALL my_GetProcAddress(HMODULE hModule, LPCSTR lpProcName) +{ + FARPROC result; + + log_misc("GetProcAddress(hModule %p, lpProcName %s)", hModule, lpProcName); + + result = real_GetProcAddress(hModule, lpProcName); + + log_misc( + "GetProcAddress(hModule %p, lpProcName %s = %p", + hModule, + lpProcName, + result); + + return result; +} + +void procmon_module_init() +{ + hook_table_apply( + NULL, + "kernel32.dll", + _procmon_module_hook_syms, + lengthof(_procmon_module_hook_syms)); + + log_misc("init"); +} + +void procmon_module_fini() +{ + hook_table_revert( + NULL, + "kernel32.dll", + _procmon_module_hook_syms, + lengthof(_procmon_module_hook_syms)); + + log_misc("fini"); +} \ No newline at end of file diff --git a/src/main/procmon/module.h b/src/main/procmon/module.h new file mode 100644 index 0000000..8cb8912 --- /dev/null +++ b/src/main/procmon/module.h @@ -0,0 +1,7 @@ +#ifndef PROCMON_MODULE_H +#define PROCMON_MODULE_H + +void procmon_module_init(); +void procmon_module_fini(); + +#endif \ No newline at end of file diff --git a/src/main/procmon/procmon.c b/src/main/procmon/procmon.c new file mode 100644 index 0000000..6120ae9 --- /dev/null +++ b/src/main/procmon/procmon.c @@ -0,0 +1,73 @@ +#define LOG_MODULE "procmon" + +#include +#include + +#include "core/log.h" + +#include "procmon/file.h" +#include "procmon/module.h" +#include "procmon/procmon.h" +#include "procmon/thread.h" + +static bool _procmon_file_mon_enabled; +static bool _procmon_module_mon_enabled; +static bool _procmon_thread_mon_enabled; + +uint32_t procmon_api_version() +{ + return 0; +} + +void procmon_set_loggers( + core_log_message_t misc, + core_log_message_t info, + core_log_message_t warning, + core_log_message_t fatal) +{ + core_log_impl_set(misc, info, warning, fatal); +} + +void procmon_init() +{ + _procmon_file_mon_enabled = false; + _procmon_module_mon_enabled = false; + _procmon_thread_mon_enabled = false; + + log_info("init"); +} + +void procmon_file_mon_enable() +{ + procmon_file_init(); + _procmon_file_mon_enabled = true; +} + +void procmon_module_mon_enable() +{ + procmon_module_init(); + _procmon_module_mon_enabled = true; +} + +void procmon_thread_mon_enable() +{ + procmon_thread_init(); + _procmon_thread_mon_enabled = true; +} + +void procmon_fini() +{ + if (_procmon_file_mon_enabled) { + procmon_file_fini(); + } + + if (_procmon_module_mon_enabled) { + procmon_module_fini(); + } + + if (_procmon_thread_mon_enabled) { + procmon_thread_fini(); + } + + log_info("fini"); +} \ No newline at end of file diff --git a/src/main/procmon/procmon.def b/src/main/procmon/procmon.def new file mode 100644 index 0000000..1dfb0d3 --- /dev/null +++ b/src/main/procmon/procmon.def @@ -0,0 +1,10 @@ +LIBRARY procmon + +EXPORTS + procmon_api_version + procmon_set_loggers + procmon_init + procmon_file_mon_enable + procmon_module_mon_enable + procmon_thread_mon_enable + procmon_fini diff --git a/src/main/procmon/procmon.h b/src/main/procmon/procmon.h new file mode 100644 index 0000000..0d485fb --- /dev/null +++ b/src/main/procmon/procmon.h @@ -0,0 +1,21 @@ +#ifndef PROCMON_PROCMON_H +#define PROCMON_PROCMON_H + +#include +#include + +#include "core/log.h" + +uint32_t procmon_api_version(); +void procmon_set_loggers( + core_log_message_t misc, + core_log_message_t info, + core_log_message_t warning, + core_log_message_t fatal); +void procmon_init(); +void procmon_file_mon_enable(); +void procmon_module_mon_enable(); +void procmon_thread_mon_enable(); +void procmon_fini(); + +#endif \ No newline at end of file diff --git a/src/main/procmon/thread.c b/src/main/procmon/thread.c new file mode 100644 index 0000000..790925f --- /dev/null +++ b/src/main/procmon/thread.c @@ -0,0 +1,106 @@ +#define LOG_MODULE "procmon-thread" + +#include + +#include "core/log.h" + +#include "hook/table.h" + +#ifdef _WIN64 +#define SIZE_T_FORMAT_SPECIFIER "llu" +#else +#define SIZE_T_FORMAT_SPECIFIER "lu" +#endif + +static HANDLE(STDCALL *real_CreateThread)( + LPSECURITY_ATTRIBUTES lpThreadAttributes, + SIZE_T dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId); + +static HANDLE STDCALL my_CreateThread( + LPSECURITY_ATTRIBUTES lpThreadAttributes, + SIZE_T dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId); + +static const struct hook_symbol _procmon_thread_hook_syms[] = { + { + .name = "CreateThread", + .patch = my_CreateThread, + .link = (void **) &real_CreateThread, + }, +}; + +static HANDLE STDCALL my_CreateThread( + LPSECURITY_ATTRIBUTES lpThreadAttributes, + SIZE_T dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId) +{ + HANDLE result; + + log_misc( + "CreateThread(lpThreadAttributes %p, dwStackSize " + "%" SIZE_T_FORMAT_SPECIFIER + ", lpStartAddress %p, lpParameter %p, dwCreationFlags %lu, lpThreadId " + "%p)", + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId); + + result = real_CreateThread( + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId); + + log_misc( + "CreateThread(lpThreadAttributes %p, dwStackSize " + "%" SIZE_T_FORMAT_SPECIFIER + ", lpStartAddress %p, lpParameter %p, dwCreationFlags %lu, lpThreadId " + "%p) = %p, tid %lu", + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId, + result, + lpThreadId ? *lpThreadId : -1); + + return result; +} + +void procmon_thread_init() +{ + hook_table_apply( + NULL, + "kernel32.dll", + _procmon_thread_hook_syms, + lengthof(_procmon_thread_hook_syms)); + + log_misc("init"); +} + +void procmon_thread_fini() +{ + hook_table_revert( + NULL, + "kernel32.dll", + _procmon_thread_hook_syms, + lengthof(_procmon_thread_hook_syms)); + + log_misc("fini"); +} \ No newline at end of file diff --git a/src/main/procmon/thread.h b/src/main/procmon/thread.h new file mode 100644 index 0000000..c90e89c --- /dev/null +++ b/src/main/procmon/thread.h @@ -0,0 +1,7 @@ +#ifndef PROCMON_THREAD_H +#define PROCMON_THREAD_H + +void procmon_thread_init(); +void procmon_thread_fini(); + +#endif \ No newline at end of file