MCPcopy Create free account
hub / github.com/DiscordMessenger/dm / SetupCrashDebugging

Function SetupCrashDebugging

src/windows/CrashDebugger.cpp:441–593  ·  view source on GitHub ↗

Hijacks the Abort function from MSVCRT.DLL or UCRTBASE.DLL, gets information on loaded modules, and sets up an unhandled exception filter.

Source from the content-addressed store, hash-verified

439// gets information on loaded modules, and sets up an unhandled
440// exception filter.
441void SetupCrashDebugging()
442{
443#ifdef ALLOW_ABORT_HIJACKING
444#ifdef FILE_DEBUG_HIJACKER
445 FILE* something = fopen("something.txt", "w");
446#endif
447
448 // Step 1. Hijack abort()
449 if (sizeof(uintptr_t) > 4)
450 {
451 HijackDbgPrint("Abort hijack disabled. The target is 64-bit.");
452 return;
453 }
454
455 void* patchAt = (void*) &abort;
456
457 // We need to find the actual address of abort() from within the loaded libraries.
458 // This means that just "&abort" does not do as it links to our thunk which jumps
459 // indirectly to the actual loaded abort().
460 //
461 // Now, import thunks are typically encoded in FF 25 XX XX XX XX. So, check for
462 // those bytes' presence.
463 uint8_t* abortPtr = (uint8_t*) &abort;
464 if (abortPtr[0] != 0xFF || abortPtr[1] != 0x25)
465 {
466 // Wow! It looks like this ain't an import thunk of a known kind.
467 auto x = abortPtr;
468 HijackDbgPrint("Abort hijack may be ineffective. The import thunk looks weird. Here is a dump:");
469 HijackDbgPrint("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
470 x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7],
471 x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]);
472 }
473 else
474 {
475 // It is. This means that the address we're looking for is after the FF 25 bytes.
476 void*** ptr = (void***)(abortPtr + 2);
477
478 // ptr - The address of the offset of the FF 25 XX XX XX XX instruction
479 // *ptr - The address where the JMP loads the address to jump to
480 // **ptr = The address to jump to
481
482 HijackDbgPrint("Found import thunk at %p, jumping to indirection via %p", ptr, *ptr);
483 HijackDbgPrint("The indirection leads to %p", **ptr);
484
485 patchAt = **ptr;
486 }
487
488 uintptr_t Patch[2];
489 Patch[0] = 0x25FF9090; // NOP; NOP; JMP [modrm]
490 Patch[1] = (uintptr_t) &HijackedAbortPtr; // [absolute indirect 32-bit address]
491
492 if (!PatchMemory((void*) patchAt, Patch, sizeof Patch))
493 {
494 HijackDbgPrint("Abort hijack disabled. Could not write 8 bytes to %p.", &abort);
495 return;
496 }
497
498 HijackDbgPrint("Abort hijack engaged. abort() = %p, patched at %p, hijacked to %p", &abort, patchAt, &HijackedAbort);

Callers 1

WinMainFunction · 0.85

Calls 4

PatchMemoryFunction · 0.85
AddFoundModuleFunction · 0.85
TrimPathComponentsFunction · 0.85

Tested by

no test coverage detected