1
0
mirror of https://github.com/djhackersdev/bemanitools.git synced 2024-12-05 03:17:55 +01:00

feat(procmon): Library to hook and monitor selected system calls

A general debugging tool. 3rd party applications such as
"procmon" (same name) provide these capabilites and even
more. But, they are more difficult to run with bemanitools
and don't provide a unified look at the output in combination
with the log output by bemanitools.

Provide an initial set of system call hooks that have already
supported debugging efforts. More can be added when needed
later.
This commit is contained in:
icex2 2024-02-25 09:36:53 +01:00
parent cbb3d37f11
commit 024929e13c
14 changed files with 854 additions and 0 deletions

View File

@ -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 $@ $^

View File

@ -0,0 +1,8 @@
libs += procmon-lib
libs_procmon-lib := \
util \
src_procmon-lib := \
procmon.c \

View File

@ -0,0 +1,96 @@
#define LOG_MODULE "procmon-lib"
#include <windows.h>
#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);
}

View File

@ -0,0 +1,37 @@
#ifndef PROCMON_LIB_PROCMON_H
#define PROCMON_LIB_PROCMON_H
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#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

View File

@ -0,0 +1,13 @@
dlls += procmon
libs_procmon := \
core \
hook \
util \
src_procmon := \
file.c \
module.c \
procmon.c \
thread.c \

176
src/main/procmon/file.c Normal file
View File

@ -0,0 +1,176 @@
#define LOG_MODULE "procmon-file"
#include <windows.h>
#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");
}

7
src/main/procmon/file.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef PROCMON_FILE_H
#define PROCMON_FILE_H
void procmon_file_init();
void procmon_file_fini();
#endif

289
src/main/procmon/module.c Normal file
View File

@ -0,0 +1,289 @@
#define LOG_MODULE "procmon-module"
#include <windows.h>
#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");
}

View File

@ -0,0 +1,7 @@
#ifndef PROCMON_MODULE_H
#define PROCMON_MODULE_H
void procmon_module_init();
void procmon_module_fini();
#endif

View File

@ -0,0 +1,73 @@
#define LOG_MODULE "procmon"
#include <stdbool.h>
#include <stdint.h>
#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");
}

View File

@ -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

View File

@ -0,0 +1,21 @@
#ifndef PROCMON_PROCMON_H
#define PROCMON_PROCMON_H
#include <stdbool.h>
#include <stdint.h>
#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

106
src/main/procmon/thread.c Normal file
View File

@ -0,0 +1,106 @@
#define LOG_MODULE "procmon-thread"
#include <windows.h>
#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");
}

View File

@ -0,0 +1,7 @@
#ifndef PROCMON_THREAD_H
#define PROCMON_THREAD_H
void procmon_thread_init();
void procmon_thread_fini();
#endif