diff --git a/Module.mk b/Module.mk index 803bca7..23f9af3 100644 --- a/Module.mk +++ b/Module.mk @@ -181,6 +181,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 @@ -232,6 +234,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 $@ $^ @@ -246,6 +249,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..2375101 --- /dev/null +++ b/src/main/procmon-lib/procmon.c @@ -0,0 +1,87 @@ +#define LOG_MODULE "procmon-lib" + +#include + +#include "procmon-lib/procmon.h" + +#include "util/log.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..cbf52f0 --- /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 "util/log.h" + +typedef uint32_t (*procmon_api_version_t)(); +typedef void (*procmon_set_loggers_t)( + log_formatter_t misc, + log_formatter_t info, + log_formatter_t warning, + log_formatter_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..3ead527 --- /dev/null +++ b/src/main/procmon/Module.mk @@ -0,0 +1,12 @@ +dlls += procmon + +libs_procmon := \ + 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..2e3a14f --- /dev/null +++ b/src/main/procmon/file.c @@ -0,0 +1,120 @@ +#define LOG_MODULE "procmon-file" + +#include + +#include "hook/table.h" + +#include "util/log.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..7fdbc10 --- /dev/null +++ b/src/main/procmon/module.c @@ -0,0 +1,229 @@ +#define LOG_MODULE "procmon-module" + +#include + +#include "hook/table.h" + +#include "util/log.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..5400980 --- /dev/null +++ b/src/main/procmon/procmon.c @@ -0,0 +1,71 @@ +#define LOG_MODULE "procmon" + +#include + +#include "procmon/file.h" +#include "procmon/module.h" +#include "procmon/thread.h" + +#include "util/log.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( + log_formatter_t misc, + log_formatter_t info, + log_formatter_t warning, + log_formatter_t fatal) +{ + log_to_external(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..776fb99 --- /dev/null +++ b/src/main/procmon/procmon.h @@ -0,0 +1,21 @@ +#ifndef PROCMON_PROCMON_H +#define PROCMON_PROCMON_H + +#include +#include + +#include "util/log.h" + +uint32_t procmon_api_version(); +void procmon_set_loggers( + log_formatter_t misc, + log_formatter_t info, + log_formatter_t warning, + log_formatter_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..acf68b9 --- /dev/null +++ b/src/main/procmon/thread.c @@ -0,0 +1,59 @@ +#define LOG_MODULE "procmon-thread" + +#include + +#include "hook/table.h" + +#include "util/log.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