#include #include #include #include #include #include #include void crimes_startup_run(uint8_t* frame) { // we trash argv up to hack on ld.so arguments without needing malloc // this is pad space to catch that and not explode uwu volatile char _pad[(sizeof(char*) * 4)]; // XXX: assumes stack goes up // big weh size_t argc = *((size_t*) (frame + sizeof(size_t))); char** argv = ((char**) (frame + sizeof(size_t) + sizeof(char*))); char** envp = argv + argc + 1; // fake usage of _pad // also a barrier to ensure argc gets read asm volatile("" :: "rm"(_pad) : "memory"); syscall(SYS_write, STDOUT_FILENO, "[crimes] detect maps\n", 21); int fd = syscall(SYS_open, "/proc/self/maps", O_RDONLY); if (fd < 0) { syscall(SYS_write, STDOUT_FILENO, "[crimes] open failed\n", 21); syscall(SYS_exit, -1); } char buf[32]; int state = 0; while (true) { ssize_t res = syscall(SYS_read, fd, buf, sizeof(buf)); if (res == 0) { break; } else if (res < 0) { syscall(SYS_write, STDOUT_FILENO, "[crimes] read error\n", 20); syscall(SYS_exit, -1); } for (ssize_t i = 0; i < res; i++) { switch (state) { case 0: if (buf[i] == '/') { state++; } else { state = 0; } break; case 1: if (buf[i] == 'l') { state++; } else { state = 0; } break; case 2: if (buf[i] == 'd') { state++; } else { state = 0; } break; case 3: if (buf[i] == '-') { state++; } else { state = 0; } break; default: break; } if (state > 3) { break; } } if (state > 3) { break; } } if (state > 3) { syscall(SYS_write, STDOUT_FILENO, "[crimes] detected libc. going back to startup\n", 46); return; } syscall(SYS_write, STDOUT_FILENO, "[crimes] running ld.so\n", 23); // XXX: currently we hardcode the glibc parameters // detect glibc or musl at runtime and load the appropriate params char* ld = "/usr/lib/ld-2.32.so"; char* pl = "--preload"; char* ldlp = "/usr/lib/libm.so.6:/usr/lib/libpthread.so.0:/usr/lib/libdl.so.2:/usr/lib/libc.so.6"; uintptr_t args[4 + argc]; args[0] = (uintptr_t)ld; args[1] = (uintptr_t)pl; args[2] = (uintptr_t)ldlp; for (size_t i = 0; i < argc; i++) { args[3 + i] = (uintptr_t) argv[i]; } args[3 + argc] = 0; syscall(SYS_execve, ld, args, envp); syscall(SYS_write, STDOUT_FILENO, "[crimes] exec failed!\n", 22); syscall(SYS_exit, -1); }