104 lines
2.9 KiB
C++
104 lines
2.9 KiB
C++
|
#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");
|
||
|
}
|
||
|
|
||
|
}
|