spicetools/hooks/debughook.cpp

104 lines
2.9 KiB
C++
Raw Permalink Normal View History

2024-08-28 15:10:34 +00:00
#include "debughook.h"
#include "util/utils.h"
#include "util/detour.h"
#include "util/libutils.h"
#include "avs/core.h"
#include "avs/ea3.h"
#include "avs/game.h"
namespace debughook {
// settings
bool DEBUGHOOK_LOGGING = true;
// function pointers
static decltype(OutputDebugStringA) *OutputDebugStringA_orig = nullptr;
static decltype(OutputDebugStringW) *OutputDebugStringW_orig = nullptr;
static void WINAPI OutputDebugStringA_hook(LPCTSTR str) {
// check if logging is enabled
if (!DEBUGHOOK_LOGGING) {
return;
}
// create buffer
auto len = strlen(str);
auto buf = new TCHAR[len + 1];
memset(buf, 0, len + 1);
// copy to buffer, log message on new lines
size_t buf_i = 0;
for (size_t i = 0; str[i] != 0 && i < len; i++) {
if (str[i] == '\r') {
// skip carriage return
continue;
} else if (str[i] == '\n') {
// null terminate buffer
buf[buf_i] = '\0';
// log buffer
log_info("debughook", "{}", buf);
// reset buffer
len -= buf_i;
buf_i = 0;
memset(buf, 0, len + 1);
} else {
buf[buf_i] = str[i];
buf_i++;
}
}
// log buffer if there are remaining characters
if (buf_i > 0) {
log_info("debughook", "{}", buf);
}
// delete buffer
delete[] buf;
}
static void WINAPI OutputDebugStringW_hook(const wchar_t *str) {
// check if logging is enabled
if (!DEBUGHOOK_LOGGING) {
return;
}
OutputDebugStringA_hook(ws2s(str).c_str());
}
void attach() {
log_info("debughook", "attaching...");
HMODULE kernel32 = libutils::try_module("kernel32.dll");
detour::inline_hook((void *) OutputDebugStringA_hook,
libutils::try_proc(kernel32, "OutputDebugStringA"));
detour::inline_hook((void *) OutputDebugStringW_hook,
libutils::try_proc(kernel32, "OutputDebugStringW"));
OutputDebugStringA_orig = detour::iat_try(
"OutputDebugStringA", OutputDebugStringA_hook, nullptr);
OutputDebugStringW_orig = detour::iat_try(
"OutputDebugStringW", OutputDebugStringW_hook, nullptr);
log_info("debughook", "attached");
}
void detach() {
log_info("debughook", "detaching...");
if (OutputDebugStringA_orig != nullptr) {
detour::iat_try("OutputDebugStringA", OutputDebugStringA_orig, nullptr);
}
if (OutputDebugStringW_orig != nullptr) {
detour::iat_try("OutputDebugStringW", OutputDebugStringW_orig, nullptr);
}
log_info("debughook", "detached");
}
}