Skip to content

Instantly share code, notes, and snippets.

@dlevi309
Last active January 1, 2024 09:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dlevi309/ebde046d73788b25d5066fa5e485120a to your computer and use it in GitHub Desktop.
Save dlevi309/ebde046d73788b25d5066fa5e485120a to your computer and use it in GitHub Desktop.
Interpose-able code to catch crashes, print, and exit cleanly. Check near line 106 https://opensource.apple.com/source/libclosure/libclosure-67/objectTests/test.pl
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
// from dyld-interposing.h
#define DYLD_INTERPOSE(_replacement,_replacee) __attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee };
static void catchcrash(int sig)
{
const char *msg;
switch (sig) {
case SIGILL: msg = "CRASHED: SIGILL"; break;
case SIGBUS: msg = "CRASHED: SIGBUS"; break;
case SIGSYS: msg = "CRASHED: SIGSYS"; break;
case SIGSEGV: msg = "CRASHED: SIGSEGV"; break;
case SIGTRAP: msg = "CRASHED: SIGTRAP"; break;
case SIGABRT: msg = "CRASHED: SIGABRT"; break;
default: msg = "unknown signal"; break;
}
fprintf(stderr, "%s\n", msg);
void *array[10];
size_t size;
size = backtrace(array, 10);
fprintf(stderr, "Stack trace:\n");
backtrace_symbols_fd(array, size, STDERR_FILENO);
_exit(1);
}
static void setupcrash(void) __attribute__((constructor));
static void setupcrash(void)
{
signal(SIGILL, &catchcrash);
signal(SIGBUS, &catchcrash);
signal(SIGSYS, &catchcrash);
signal(SIGSEGV, &catchcrash);
signal(SIGTRAP, &catchcrash);
signal(SIGABRT, &catchcrash);
}
static int hacked = 0;
ssize_t hacked_write(int fildes, const void *buf, size_t nbyte)
{
if (!hacked) {
setupcrash();
hacked = 1;
}
return write(fildes, buf, nbyte);
}
DYLD_INTERPOSE(hacked_write, write);
@dlevi309
Copy link
Author

either compile as an individual library or an object

$ cc jbat.c crashcatch.c -o jbat -framework IOKit -framework CoreFoundation

an example of what to expect:

$ ./jbat

jbat(51312,0x100c48580) malloc: *** error for object 0x100908010: pointer being freed was not allocated
jbat(51312,0x100c48580) malloc: *** set a breakpoint in malloc_error_break to debug
CRASHED: SIGABRT
Stack trace:
0   jbat                                0x0000000100903c90 catchcrash + 232
1   libsystem_platform.dylib            0x0000000186dc04e4 _sigtramp + 56
2   libsystem_pthread.dylib             0x0000000186da8eb0 pthread_kill + 288
3   libsystem_c.dylib                   0x0000000186ce6314 abort + 164
4   libsystem_malloc.dylib              0x0000000186bcba1c has_default_zone0 + 0
5   libsystem_malloc.dylib              0x0000000186bcf060 malloc_report + 64
6   libsystem_malloc.dylib              0x0000000186bbdfa8 free + 500
7   jbat                                0x0000000100903b30 main + 84
8   dyld                                0x0000000100bd50f4 start + 520

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment