Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Notable changes in each release.
- Add support for Crysis MP Beta ([#77](https://github.com/ccomrade/c1-launcher/pull/77) by
[illusion0001](https://github.com/illusion0001)).
- Disable DPI awareness for editor ([#83](https://github.com/ccomrade/c1-launcher/pull/83)).
- Fix crash logger not working with [MWLL](https://mechlivinglegends.net/)
([#85](https://github.com/ccomrade/c1-launcher/pull/85)).
- Fix editor crash in `oleacc.AccessibleObjectFromWindow` ([#79](https://github.com/ccomrade/c1-launcher/pull/79)).
- Fix loading mods via in-game Mods menu ([#69](https://github.com/ccomrade/c1-launcher/pull/69)).
- Revert sys_crashtest improvements ([#71](https://github.com/ccomrade/c1-launcher/pull/71)).
Expand Down
80 changes: 77 additions & 3 deletions Code/Library/CrashLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
#define CRASH_LOGGER_INVALID_PARAM 0xE0C1C102
#define CRASH_LOGGER_ENGINE_ERROR 0xE0C1C103

static CrashLogger::LogFileProvider g_logFileProvider;
static const char* g_banner;
static LPTOP_LEVEL_EXCEPTION_FILTER g_userExceptionFilter = NULL;
static CrashLogger::LogFileProvider g_logFileProvider = NULL;
static const char* g_banner = NULL;
static int g_crashed = 0;

static void* ByteOffset(void* base, std::size_t offset)
{
Expand Down Expand Up @@ -410,7 +412,12 @@ static void WriteCrashDump(std::FILE* file, EXCEPTION_POINTERS* exception)
static LONG __stdcall CrashHandler(EXCEPTION_POINTERS* exception)
{
// avoid recursive calls
SetUnhandledExceptionFilter(NULL);
if (g_crashed)
{
return EXCEPTION_CONTINUE_SEARCH;
}

g_crashed = 1;

if (g_logFileProvider)
{
Expand All @@ -422,9 +429,75 @@ static LONG __stdcall CrashHandler(EXCEPTION_POINTERS* exception)
}
}

if (g_userExceptionFilter)
{
return g_userExceptionFilter(exception);
}

return EXCEPTION_CONTINUE_SEARCH;
}

static LPTOP_LEVEL_EXCEPTION_FILTER __stdcall SetUnhandledExceptionFilter_Hook(LPTOP_LEVEL_EXCEPTION_FILTER filter)
{
LPTOP_LEVEL_EXCEPTION_FILTER previous = g_userExceptionFilter;
g_userExceptionFilter = filter;
return previous;
}

static void HookWithJump(void* address, void* newFunc)
{
if (!address)
{
return;
}

#ifdef BUILD_64BIT
unsigned char code[] = {
0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax, 0x0
0xFF, 0xE0 // jmp rax
};

memcpy(&code[2], &newFunc, 8);
#else
unsigned char code[] = {
0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, 0x0
0xFF, 0xE0 // jmp eax
};

memcpy(&code[1], &newFunc, 4);
#endif

DWORD oldProtection;
if (!VirtualProtect(address, sizeof(code), PAGE_EXECUTE_READWRITE, &oldProtection))
{
return;
}

memcpy(address, &code, sizeof(code));

if (!VirtualProtect(address, sizeof(code), oldProtection, &oldProtection))
{
return;
}
}

static void Hook_SetUnhandledExceptionFilter()
{
HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
if (!kernel32)
{
return;
}

void* pSetUnhandledExceptionFilter = GetProcAddress(kernel32, "SetUnhandledExceptionFilter");
if (!pSetUnhandledExceptionFilter)
{
return;
}

HookWithJump(pSetUnhandledExceptionFilter, &SetUnhandledExceptionFilter_Hook);
}

static void AbortHandler(int)
{
RaiseException(CRASH_LOGGER_ABORT, EXCEPTION_NONCONTINUABLE, 0, NULL);
Expand Down Expand Up @@ -463,6 +536,7 @@ void CrashLogger::Enable(LogFileProvider logFileProvider, const char* banner)
g_banner = banner;

SetUnhandledExceptionFilter(&CrashHandler);
Hook_SetUnhandledExceptionFilter(); // prevent the engine and mods from disabling us

signal(SIGABRT, &AbortHandler);
_set_abort_behavior(0, _WRITE_ABORT_MSG); // suppress abort message (console) and dialog (GUI)
Expand Down