213 lines
7.1 KiB
C
213 lines
7.1 KiB
C
#include "log.h"
|
|
|
|
BOOL HAS_COLOUR = FALSE;
|
|
|
|
char _log_prelude[32];
|
|
char* log_prelude() {
|
|
time_t rawtime;
|
|
struct tm* timeinfo;
|
|
|
|
time(&rawtime);
|
|
timeinfo = localtime(&rawtime);
|
|
|
|
strftime(_log_prelude, 32, "[%Y/%m/%d %H:%M:%S] ", timeinfo);
|
|
return _log_prelude;
|
|
}
|
|
|
|
HANDLE LOG_FILE = NULL;
|
|
VOID trace_hook(char* output);
|
|
CRITICAL_SECTION logger_lock;
|
|
|
|
int _do_log(const char* caller, const char* level, const char* format, va_list args, bool toStdout) {
|
|
EnterCriticalSection(&logger_lock);
|
|
|
|
int len = snprintf(NULL, 0, "%s%s:%s:", log_prelude(), level, caller) + vsnprintf(NULL, 0, format, args);
|
|
char* buf = (char*)malloc(len + 2);
|
|
if (!buf) {
|
|
LeaveCriticalSection(&logger_lock);
|
|
return 0;
|
|
}
|
|
|
|
int wrote_a = snprintf(buf, len, "%s%s:%s:", log_prelude(), level, caller);
|
|
int wrote_b = vsnprintf(buf + wrote_a, len - wrote_a + 1, format, args);
|
|
buf[len] = '\n';
|
|
buf[len + 1] = '\0';
|
|
|
|
// No +1 here to not get the \n
|
|
if (toStdout) WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, len, NULL, NULL);
|
|
#ifdef LOG_TO_FILE
|
|
if (LOG_FILE && LOG_FILE != INVALID_HANDLE_VALUE) WriteFile(LOG_FILE, buf, len + 1, NULL, NULL);
|
|
#endif
|
|
|
|
free(buf);
|
|
|
|
LeaveCriticalSection(&logger_lock);
|
|
return wrote_b;
|
|
}
|
|
int vlog_misc(const char* caller, const char* format, va_list args) {
|
|
#ifdef LOG_MISC
|
|
if (HAS_COLOUR) WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\033[90m", 5, NULL, NULL);
|
|
int ret = _do_log(caller, "M", format, args, true);
|
|
puts(HAS_COLOUR ? "\033[0m" : "");
|
|
return ret;
|
|
#else
|
|
return _do_log(caller, "M", format, args, false);
|
|
#endif
|
|
}
|
|
int log_misc(const char* caller, const char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
int ret = vlog_misc(caller, format, args);
|
|
va_end(args);
|
|
return ret;
|
|
}
|
|
int vlog_info(const char* caller, const char* format, va_list args) {
|
|
#ifdef LOG_INFO
|
|
if (HAS_COLOUR) WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\033[97m", 5, NULL, NULL);
|
|
int ret = _do_log(caller, "I", format, args, true);
|
|
puts(HAS_COLOUR ? "\033[0m" : "");
|
|
return ret;
|
|
#else
|
|
return _do_log(caller, "I", format, args, false);
|
|
#endif
|
|
}
|
|
int log_info(const char* caller, const char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
int ret = vlog_info(caller, format, args);
|
|
va_end(args);
|
|
return ret;
|
|
}
|
|
int vlog_warning(const char* caller, const char* format, va_list args) {
|
|
#ifdef LOG_WARNING
|
|
if (HAS_COLOUR) WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\033[33m", 5, NULL, NULL);
|
|
int ret = _do_log(caller, "W", format, args, true);
|
|
puts(HAS_COLOUR ? "\033[0m" : "");
|
|
return ret;
|
|
#else
|
|
return _do_log(caller, "W", format, args, false);
|
|
#endif
|
|
}
|
|
int log_warning(const char* caller, const char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
int ret = vlog_warning(caller, format, args);
|
|
va_end(args);
|
|
return ret;
|
|
}
|
|
int vlog_error(const char* caller, const char* format, va_list args) {
|
|
#ifdef LOG_ERROR
|
|
if (HAS_COLOUR) WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\033[91m", 5, NULL, NULL);
|
|
int ret = _do_log(caller, "E", format, args, true);
|
|
puts(HAS_COLOUR ? "\033[0m" : "");
|
|
return ret;
|
|
#else
|
|
return _do_log(caller, "E", format, args, false);
|
|
#endif
|
|
}
|
|
int log_error(const char* caller, const char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
int ret = vlog_error(caller, format, args);
|
|
va_end(args);
|
|
return ret;
|
|
}
|
|
|
|
// char format_buf[1024]; // Will do. We guard against overflow in
|
|
// Fake[f]printf int WINAPIV Fakeprintf(const char* _Format, ...) { int
|
|
// flen = strlen(_Format); if (flen == strcspn(_Format, "\n") + 1 && flen
|
|
// < (sizeof format_buf)) { strcpy_s(format_buf, flen, _Format);
|
|
// format_buf[flen - 1] = 0; _Format = format_buf;
|
|
// }
|
|
// va_list args;
|
|
// va_start(args, _Format);
|
|
// int ret = vlog_info("printf", _Format, args);
|
|
// va_end(args);
|
|
// return ret;
|
|
// };
|
|
// int WINAPIV Fakefprintf(FILE* _File, const char* _Format, ...) {
|
|
// int flen = strlen(_Format);
|
|
// if (flen == strcspn(_Format, "\n") + 1 && flen < (sizeof format_buf))
|
|
// { strcpy_s(format_buf, flen, _Format); format_buf[flen
|
|
// - 1] = 0; _Format = format_buf;
|
|
// }
|
|
// va_list args;
|
|
// va_start(args, _Format);
|
|
// int ret = vlog_error("fprintf", _Format, args);
|
|
// va_end(args);
|
|
// return ret;
|
|
// };
|
|
|
|
// int WINAPIV Fakefprintf_s(FILE* _Stream, const char* _Format, ...) {
|
|
// va_list args;
|
|
// va_start(args, _Format);
|
|
// int ret = vlog_error("fprintf_s", _Format, args);
|
|
// va_end(args);
|
|
// return ret;
|
|
// };
|
|
|
|
char* trim_string(char* string) {
|
|
size_t len = strlen(string) - 1;
|
|
|
|
DWORD oldProt;
|
|
while (len > 0 && (string[len] == '\n' || string[len] == '\r')) {
|
|
// TODO: Reassess this. Suspect it may be causing issues.
|
|
// Make sure we can write! This is a terrible hack, but it does work.
|
|
VirtualProtect(string + len, 1, PAGE_EXECUTE_READWRITE, &oldProt);
|
|
string[len--] = '\0';
|
|
VirtualProtect(string + len + 1, 1, oldProt, &oldProt);
|
|
}
|
|
return string;
|
|
}
|
|
|
|
HANDLE WINAPI FakeRegisterEventSourceA(LPCSTR lpUNCServerName, LPCSTR lpSourceName) { return (HANDLE)0xDEADBEEF; }
|
|
|
|
BOOL WINAPI FakeReportEventA(HANDLE hEventLog, WORD wType, WORD wCategory, DWORD dwEventID, PSID lpUserSid,
|
|
WORD wNumStrings, DWORD dwDataSize, LPCSTR* lpStrings, LPVOID lpRawData) {
|
|
switch (wType) {
|
|
case EVENTLOG_SUCCESS:
|
|
case EVENTLOG_AUDIT_SUCCESS:
|
|
for (int i = 0; i < wNumStrings; i++) log_misc("evtlog", trim_string((char*)lpStrings[i]));
|
|
break;
|
|
case EVENTLOG_AUDIT_FAILURE:
|
|
case EVENTLOG_ERROR_TYPE:
|
|
for (int i = 0; i < wNumStrings; i++) log_error("evtlog", trim_string((char*)lpStrings[i]));
|
|
break;
|
|
case EVENTLOG_WARNING_TYPE:
|
|
for (int i = 0; i < wNumStrings; i++) log_warning("evtlog", trim_string((char*)lpStrings[i]));
|
|
break;
|
|
case EVENTLOG_INFORMATION_TYPE:
|
|
default:
|
|
for (int i = 0; i < wNumStrings; i++) log_info("evtlog", trim_string((char*)lpStrings[i]));
|
|
break;
|
|
}
|
|
return TRUE;
|
|
};
|
|
|
|
BOOL WINAPI FakeDeregisterEventSource(HANDLE hEventLog) { return TRUE; }
|
|
|
|
static VOID(WINAPI* TrueOutputDebugStringA)(LPCSTR lpOutputString);
|
|
VOID WINAPI FakeOutputDebugStringA(LPCSTR lpOutputString) { log_info("debug", "%s", lpOutputString); }
|
|
|
|
VOID trace_hook(char* output) {
|
|
output[strcspn(output, "\n")] = 0;
|
|
log_error("trace", output);
|
|
}
|
|
|
|
void setup_logging() {
|
|
// Enable colour in CMD
|
|
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
DWORD dwMode = 0;
|
|
if (GetConsoleMode(hConsole, &dwMode))
|
|
HAS_COLOUR = SetConsoleMode(hConsole, dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
|
|
|
InitializeCriticalSection(&logger_lock);
|
|
|
|
if (LOG_FILE == NULL)
|
|
LOG_FILE = CreateFileA("log.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
|
|
|
|
hook("Advapi32.dll", "RegisterEventSourceA", FakeRegisterEventSourceA, &TrueRegisterEventSourceA);
|
|
hook("Advapi32.dll", "ReportEventA", FakeReportEventA, &TrueReportEventA);
|
|
hook("Advapi32.dll", "DeregisterEventSource", FakeDeregisterEventSource, &TrueDeregisterEventSource);
|
|
}
|