diff --git a/doc/README.md b/doc/README.md index 497e2e1..fc503f4 100644 --- a/doc/README.md +++ b/doc/README.md @@ -9,7 +9,7 @@ From the [ENVIRONMENT section in the Linux manual page ld.so(8)](https://www.man > **`LD_PRELOAD`** > -> A list of additional, user-specified, ELF shared objects to be loaded before all others. +> A list of additional, user-specified, ELF shared objects to be loaded before all others. > This feature can be used to selectively override functions in other shared objects. > [...] diff --git a/doc/call-ident.md b/doc/call-ident.md new file mode 100644 index 0000000..b5775bd --- /dev/null +++ b/doc/call-ident.md @@ -0,0 +1,11 @@ + +# Call Identification + +## For the same program execution + +* Return address (ASLR!) + +## For different executions + +* Sequence of calls (?) +* Return address -> * `dladdr()` diff --git a/proj/intercept/src/intercept.c b/proj/intercept/src/intercept.c index efb77b8..8bafb44 100644 --- a/proj/intercept/src/intercept.c +++ b/proj/intercept/src/intercept.c @@ -214,6 +214,8 @@ func_def(ssize_t, recvmsg)(int, struct msghdr *, int); #define flag_str(flags, name, buf) if (flags & name) strcat(buf, #name "|") #define ret_addr __builtin_return_address(0) +#define ret_str ": %p (%s+%p%s%s)" +#define ret_data ret_addr, info.dli_fname, (long)ret_addr - (long)info.dli_fbase, info.dli_sname ? ", " : "", info.dli_sname ? info.dli_sname : "" #define if_fail if (strncmp(msg_buf, "fail ", 5) == 0) @@ -852,8 +854,9 @@ static void init(void) { void *sym(malloc)(size_t size) { init(); - if (!func_flags[func_idx_malloc]) return __real_malloc(size); - msg("malloc(%li): %p", size, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_malloc]) return __real_malloc(size); + msg("malloc(%li)" ret_str, size, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -869,8 +872,9 @@ void *sym(malloc)(size_t size) { void *sym(calloc)(size_t nmemb, size_t size) { init(); - if (!func_flags[func_idx_calloc]) return __real_calloc(nmemb, size); - msg("calloc(%li, %li): %p", nmemb, size, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_calloc]) return __real_calloc(nmemb, size); + msg("calloc(%li, %li)" ret_str, nmemb, size, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -886,8 +890,9 @@ void *sym(calloc)(size_t nmemb, size_t size) { void *sym(realloc)(void *ptr, size_t size) { init(); - if (!func_flags[func_idx_realloc]) return __real_realloc(ptr, size); - msg("realloc(%p, %li): %p", ptr, size, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_realloc]) return __real_realloc(ptr, size); + msg("realloc(%p, %li)" ret_str, ptr, size, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -903,8 +908,9 @@ void *sym(realloc)(void *ptr, size_t size) { void *sym(reallocarray)(void *ptr, size_t nmemb, size_t size) { init(); - if (!func_flags[func_idx_reallocarray]) return __real_reallocarray(ptr, nmemb, size); - msg("reallocarray(%p, %li): %p", ptr, size, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_reallocarray]) return __real_reallocarray(ptr, nmemb, size); + msg("reallocarray(%p, %li)" ret_str, ptr, size, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -920,8 +926,9 @@ void *sym(reallocarray)(void *ptr, size_t nmemb, size_t size) { void sym(free)(void *ptr) { init(); - if (!func_flags[func_idx_free]) { __real_free(ptr); return; } - msg("free(%p): %p", ptr, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_free]) { __real_free(ptr); return; } + msg("free(%p)" ret_str, ptr, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -935,8 +942,9 @@ void sym(free)(void *ptr) { int sym(getopt)(const int argc, char *const argv[], const char *shortopts) { init(); - if (!func_flags[func_idx_getopt]) return __real_getopt(argc, argv, shortopts); - msg("getopt(%i, %as, %es): %p", argc, argc, argv, shortopts, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_getopt]) return __real_getopt(argc, argv, shortopts); + msg("getopt(%i, %as, %es)" ret_str, argc, argc, argv, shortopts, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -954,8 +962,9 @@ int sym(getopt)(const int argc, char *const argv[], const char *shortopts) { void sym(exit)(int status) { init(); - if (!func_flags[func_idx_exit]) __real_exit(status); - msg("exit(%i): %p", status, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_exit]) __real_exit(status); + msg("exit(%i)" ret_str, status, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -967,8 +976,9 @@ void sym(exit)(int status) { ssize_t sym(read)(int fildes, void *buf, size_t nbyte) { init(); - if (!func_flags[func_idx_read]) return __real_read(fildes, buf, nbyte); - msg("read(%i, %p, %i): %p", fildes, buf, nbyte, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_read]) return __real_read(fildes, buf, nbyte); + msg("read(%i, %p, %i)" ret_str, fildes, buf, nbyte, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -990,8 +1000,9 @@ ssize_t sym(read)(int fildes, void *buf, size_t nbyte) { ssize_t sym(pread)(int fildes, void *buf, size_t nbyte, off_t offset) { init(); - if (!func_flags[func_idx_pread]) return __real_pread(fildes, buf, nbyte, offset); - msg("pread(%i, %p, %i, %i): %p", fildes, buf, nbyte, offset, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_pread]) return __real_pread(fildes, buf, nbyte, offset); + msg("pread(%i, %p, %i, %i)" ret_str, fildes, buf, nbyte, offset, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1013,8 +1024,9 @@ ssize_t sym(pread)(int fildes, void *buf, size_t nbyte, off_t offset) { ssize_t sym(write)(int fildes, const void *buf, size_t nbyte) { init(); - if (!func_flags[func_idx_write]) return __real_write(fildes, buf, nbyte); - msg("write(%i, %eb, %i): %p", fildes, nbyte, buf, nbyte, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_write]) return __real_write(fildes, buf, nbyte); + msg("write(%i, %eb, %i)" ret_str, fildes, nbyte, buf, nbyte, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1032,8 +1044,9 @@ ssize_t sym(write)(int fildes, const void *buf, size_t nbyte) { ssize_t sym(pwrite)(int fildes, const void *buf, size_t nbyte, off_t offset) { init(); - if (!func_flags[func_idx_pwrite]) return __real_pwrite(fildes, buf, nbyte, offset); - msg("pwrite(%i, %eb, %i, %i): %p", fildes, nbyte, buf, nbyte, offset, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_pwrite]) return __real_pwrite(fildes, buf, nbyte, offset); + msg("pwrite(%i, %eb, %i, %i)" ret_str, fildes, nbyte, buf, nbyte, offset, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1051,8 +1064,9 @@ ssize_t sym(pwrite)(int fildes, const void *buf, size_t nbyte, off_t offset) { int sym(close)(int fildes) { init(); - if (!func_flags[func_idx_close]) return __real_close(fildes); - msg("close(%i): %p", fildes, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_close]) return __real_close(fildes); + msg("close(%i)" ret_str, fildes, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1105,7 +1119,8 @@ static const char *getsigstr(int sig) { int sym(sigaction)(int sig, const struct sigaction *restrict act, struct sigaction *restrict oact) { init(); - if (!func_flags[func_idx_sigaction]) return __real_sigaction(sig, act, oact); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sigaction]) return __real_sigaction(sig, act, oact); const char *sigstr = getsigstr(sig); if (act != NULL) { char *name = "sa_handler"; @@ -1129,7 +1144,7 @@ int sym(sigaction)(int sig, const struct sigaction *restrict act, struct sigacti if (maskstr[0] != 0) strcat(maskstr, ","); strcat(maskstr, getsigstr(i)); } - msg("sigaction(%i:%s, %p:{sa_flags: 0x%x:%s, %s: %p, sa_mask: [%s]}, %p): %p", sig, sigstr, act, act->sa_flags, flgstr, name, ptr, maskstr, oact, ret_addr); + msg("sigaction(%i:%s, %p:{sa_flags: 0x%x:%s, %s: %p, sa_mask: [%s]}, %p)" ret_str, sig, sigstr, act, act->sa_flags, flgstr, name, ptr, maskstr, oact, ret_data); } else { msg("sigaction(%i:%s, %p:{}, %p): %p", sig, sigstr, act, oact, ret_addr); } @@ -1177,8 +1192,9 @@ int sym(sigaction)(int sig, const struct sigaction *restrict act, struct sigacti int sym(sem_init)(sem_t *sem, int pshared, unsigned int value) { init(); - if (!func_flags[func_idx_sem_init]) return __real_sem_init(sem, pshared, value); - msg("sem_init(%p, %i, %u): %p", sem, pshared, value, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_init]) return __real_sem_init(sem, pshared, value); + msg("sem_init(%p, %i, %u)" ret_str, sem, pshared, value, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1194,6 +1210,7 @@ int sym(sem_init)(sem_t *sem, int pshared, unsigned int value) { sem_t *sym(sem_open)(const char *name, int oflag, ...) { init(); + Dl_info info; char ostr[32] = "|"; flag_str(oflag, O_CREAT, ostr); flag_str(oflag, O_EXCL, ostr); @@ -1207,11 +1224,11 @@ sem_t *sym(sem_open)(const char *name, int oflag, ...) { mode_arg = va_arg(args, mode_t); value = va_arg(args, unsigned int); va_end(args); - if (!func_flags[func_idx_sem_open]) return __real_sem_open(name, oflag, mode_arg, value); - msg("sem_open(%es, 0%o:%s, 0%03o, %u): %p", name, oflag, ostr, mode_arg, value, ret_addr); + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_open]) return __real_sem_open(name, oflag, mode_arg, value); + msg("sem_open(%es, 0%o:%s, 0%03o, %u)" ret_str, name, oflag, ostr, mode_arg, value, ret_data); } else { - if (!func_flags[func_idx_sem_open]) return __real_sem_open(name, oflag); - msg("sem_open(%es, 0%o:|%s): %p", name, oflag, ostr, ret_addr); + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_open]) return __real_sem_open(name, oflag); + msg("sem_open(%es, 0%o:|%s)" ret_str, name, oflag, ostr, ret_data); } char overwrite[BUFFER_SIZE]; @@ -1281,8 +1298,9 @@ sem_t *sym(sem_open)(const char *name, int oflag, ...) { int sym(sem_post)(sem_t *sem) { init(); - if (!func_flags[func_idx_sem_post]) return __real_sem_post(sem); - msg("sem_post(%p): %p", sem, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_post]) return __real_sem_post(sem); + msg("sem_post(%p)" ret_str, sem, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1298,8 +1316,9 @@ int sym(sem_post)(sem_t *sem) { int sym(sem_wait)(sem_t *sem) { init(); - if (!func_flags[func_idx_sem_wait]) return __real_sem_wait(sem); - msg("sem_wait(%p): %p", sem, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_wait]) return __real_sem_wait(sem); + msg("sem_wait(%p)" ret_str, sem, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1315,8 +1334,9 @@ int sym(sem_wait)(sem_t *sem) { int sym(sem_trywait)(sem_t *sem) { init(); - if (!func_flags[func_idx_sem_trywait]) return __real_sem_trywait(sem); - msg("sem_trywait(%p): %p", sem, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_trywait]) return __real_sem_trywait(sem); + msg("sem_trywait(%p)" ret_str, sem, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1332,8 +1352,9 @@ int sym(sem_trywait)(sem_t *sem) { int sym(sem_timedwait)(sem_t *restrict sem, const struct timespec *restrict abs_timeout) { init(); - if (!func_flags[func_idx_sem_timedwait]) return __real_sem_timedwait(sem, abs_timeout); - msg("sem_timedwait(%p, %qt): %p", sem, abs_timeout, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_timedwait]) return __real_sem_timedwait(sem, abs_timeout); + msg("sem_timedwait(%p, %qt)" ret_str, sem, abs_timeout, ret_data); struct timespec overwrite; if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1378,8 +1399,9 @@ int sym(sem_timedwait)(sem_t *restrict sem, const struct timespec *restrict abs_ int sym(sem_getvalue)(sem_t *restrict sem, int *restrict value) { init(); - if (!func_flags[func_idx_sem_getvalue]) return __real_sem_getvalue(sem, value); - msg("sem_getvalue(%p, %p): %p", sem, value, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_getvalue]) return __real_sem_getvalue(sem, value); + msg("sem_getvalue(%p, %p)" ret_str, sem, value, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1399,8 +1421,9 @@ int sym(sem_getvalue)(sem_t *restrict sem, int *restrict value) { int sym(sem_close)(sem_t *sem) { init(); - if (!func_flags[func_idx_sem_close]) return __real_sem_close(sem); - msg("sem_close(%p): %p", sem, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_close]) return __real_sem_close(sem); + msg("sem_close(%p)" ret_str, sem, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1416,8 +1439,9 @@ int sym(sem_close)(sem_t *sem) { int sym(sem_unlink)(const char *name) { init(); - if (!func_flags[func_idx_sem_unlink]) return __real_sem_unlink(name); - msg("sem_unlink(%es): %p", name, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_unlink]) return __real_sem_unlink(name); + msg("sem_unlink(%es)" ret_str, name, ret_data); char overwrite[BUFFER_SIZE]; if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1448,8 +1472,9 @@ int sym(sem_unlink)(const char *name) { int sym(sem_destroy)(sem_t *sem) { init(); - if (!func_flags[func_idx_sem_destroy]) return __real_sem_destroy(sem); - msg("sem_destroy(%p): %p", sem, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sem_destroy]) return __real_sem_destroy(sem); + msg("sem_destroy(%p)" ret_str, sem, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1465,7 +1490,8 @@ int sym(sem_destroy)(sem_t *sem) { int sym(shm_open)(const char *name, int oflag, mode_t mode_arg) { init(); - if (!func_flags[func_idx_shm_open]) return __real_shm_open(name, oflag, mode); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_shm_open]) return __real_shm_open(name, oflag, mode); char ostr[64] = "|"; flag_str(oflag, O_RDONLY, ostr); flag_str(oflag, O_RDWR, ostr); @@ -1474,7 +1500,7 @@ int sym(shm_open)(const char *name, int oflag, mode_t mode_arg) { flag_str(oflag, O_TRUNC, ostr); if (oflag & ~(O_RDONLY | O_RDWR | O_CREAT | O_EXCL | O_TRUNC)) strcat(ostr, "?|"); - msg("shm_open(%es, 0%o:%s, 0%03o): %p", name, oflag, ostr, mode_arg, ret_addr); + msg("shm_open(%es, 0%o:%s, 0%03o)" ret_str, name, oflag, ostr, mode_arg, ret_data); char overwrite[BUFFER_SIZE]; if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1542,8 +1568,9 @@ int sym(shm_open)(const char *name, int oflag, mode_t mode_arg) { int sym(shm_unlink)(const char *name) { init(); - if (!func_flags[func_idx_shm_unlink]) return __real_shm_unlink(name); - msg("shm_unlink(%es): %p", name, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_shm_unlink]) return __real_shm_unlink(name); + msg("shm_unlink(%es)" ret_str, name, ret_data); char overwrite[BUFFER_SIZE]; if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1574,7 +1601,8 @@ int sym(shm_unlink)(const char *name) { void *sym(mmap)(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { init(); - if (!func_flags[func_idx_mmap]) return __real_mmap(addr, len, prot, flags, fildes, off); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_mmap]) return __real_mmap(addr, len, prot, flags, fildes, off); char pstr[64] = "|"; if (prot == PROT_NONE) strcat(pstr, "PROT_NONE|"); flag_str(prot, PROT_READ, pstr); @@ -1588,7 +1616,7 @@ void *sym(mmap)(void *addr, size_t len, int prot, int flags, int fildes, off_t o flag_str(prot, MAP_ANONYMOUS, fstr); if (prot & ~(MAP_SHARED | MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS)) strcat(fstr, "?|"); - msg("mmap(%p, %i, 0x%x:%s, %0x%x:%s, %i, %i): %p", addr, len, prot, pstr, flags, fstr, fildes, off, ret_addr); + msg("mmap(%p, %i, 0x%x:%s, %0x%x:%s, %i, %i)" ret_str, addr, len, prot, pstr, flags, fstr, fildes, off, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1608,8 +1636,9 @@ void *sym(mmap)(void *addr, size_t len, int prot, int flags, int fildes, off_t o int sym(munmap)(void *addr, size_t len) { init(); - if (!func_flags[func_idx_munmap]) return __real_munmap(addr, len); - msg("munmap(%p, %i): %p", addr, len, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_munmap]) return __real_munmap(addr, len); + msg("munmap(%p, %i)" ret_str, addr, len, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1625,8 +1654,9 @@ int sym(munmap)(void *addr, size_t len) { int sym(ftruncate)(int fildes, off_t length) { init(); - if (!func_flags[func_idx_ftruncate]) return __real_ftruncate(fildes, length); - msg("ftruncate(%i, %i): %p", fildes, length, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_ftruncate]) return __real_ftruncate(fildes, length); + msg("ftruncate(%i, %i)" ret_str, fildes, length, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1642,7 +1672,8 @@ int sym(ftruncate)(int fildes, off_t length) { pid_t sym(fork)(void) { init(); - if (!func_flags[func_idx_fork]) return __real_fork(); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_fork]) return __real_fork(); msg("fork(): %p", ret_addr); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1658,8 +1689,9 @@ pid_t sym(fork)(void) { pid_t sym(wait)(int *stat_loc) { init(); - if (!func_flags[func_idx_wait]) return __real_wait(stat_loc); - msg("wait(%p): %p", stat_loc, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_wait]) return __real_wait(stat_loc); + msg("wait(%p)" ret_str, stat_loc, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1679,14 +1711,15 @@ pid_t sym(wait)(int *stat_loc) { pid_t sym(waitpid)(pid_t pid, int *stat_loc, int options) { init(); - if (!func_flags[func_idx_waitpid]) return __real_waitpid(pid, stat_loc, options); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_waitpid]) return __real_waitpid(pid, stat_loc, options); char ostr[64] = "|"; flag_str(options, WCONTINUED, ostr); flag_str(options, WNOHANG, ostr); flag_str(options, WUNTRACED, ostr); if (options & ~(WCONTINUED | WNOHANG | WUNTRACED)) strcat(ostr, "?|"); - msg("waitpid(%i, %p, 0x%x:%s): %p", pid, stat_loc, options, ostr, ret_addr); + msg("waitpid(%i, %p, 0x%x:%s)" ret_str, pid, stat_loc, options, ostr, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1707,6 +1740,7 @@ pid_t sym(waitpid)(pid_t pid, int *stat_loc, int options) { int sym(execl)(const char *pathname, const char *arg, ...) { init(); + Dl_info info; va_list args; va_start(args, arg); const char *arg_vec[64]; @@ -1715,7 +1749,7 @@ int sym(execl)(const char *pathname, const char *arg, ...) { arg_vec[i] = va_arg(args, const char *); } va_end(args); - if (!func_flags[func_idx_execl]) return __real_execv(pathname, (char *const *)arg_vec); + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_execl]) return __real_execv(pathname, (char *const *)arg_vec); char arg_buf[4096] = "", *arg_buf_ptr = arg_buf; for (int i = 1; i < 64; i++) { arg_buf_ptr[0] = ','; @@ -1729,7 +1763,7 @@ int sym(execl)(const char *pathname, const char *arg, ...) { arg_buf_ptr += msg_str(arg_buf, sizeof(arg_buf) - (arg_buf_ptr - arg_buf), arg_vec[i], 0); } - msg("execl(%es, %es%s): %p", pathname, arg, arg_buf, ret_addr); + msg("execl(%es, %es%s)" ret_str, pathname, arg, arg_buf, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1747,6 +1781,7 @@ int sym(execl)(const char *pathname, const char *arg, ...) { int sym(execlp)(const char *file, const char *arg, ...) { init(); + Dl_info info; va_list args; va_start(args, arg); const char *arg_vec[64]; @@ -1755,7 +1790,7 @@ int sym(execlp)(const char *file, const char *arg, ...) { arg_vec[i] = va_arg(args, const char *); } va_end(args); - if (!func_flags[func_idx_execlp]) return __real_execvp(file, (char *const *)arg_vec); + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_execlp]) return __real_execvp(file, (char *const *)arg_vec); char arg_buf[4096] = "", *arg_buf_ptr = arg_buf; for (int i = 1; i < 64; i++) { arg_buf_ptr[0] = ','; @@ -1769,7 +1804,7 @@ int sym(execlp)(const char *file, const char *arg, ...) { arg_buf_ptr += msg_str(arg_buf, sizeof(arg_buf) - (arg_buf_ptr - arg_buf), arg_vec[i], 0); } - msg("execlp(%es, %es%s): %p", file, arg, arg_buf, ret_addr); + msg("execlp(%es, %es%s)" ret_str, file, arg, arg_buf, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1787,6 +1822,7 @@ int sym(execlp)(const char *file, const char *arg, ...) { int sym(execle)(const char *pathname, const char *arg, ...) { init(); + Dl_info info; va_list args; va_start(args, arg); const char *arg_vec[64]; @@ -1800,7 +1836,7 @@ int sym(execle)(const char *pathname, const char *arg, ...) { } } va_end(args); - if (!func_flags[func_idx_execle]) return __real_execvpe(pathname, (char *const *)arg_vec, envp); + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_execle]) return __real_execvpe(pathname, (char *const *)arg_vec, envp); char arg_buf[4096] = "", *arg_buf_ptr = arg_buf; for (int i = 1; i < 64; i++) { arg_buf_ptr[0] = ','; @@ -1815,7 +1851,7 @@ int sym(execle)(const char *pathname, const char *arg, ...) { } int len = 0; for (len = 0; envp[len] != NULL; len++) {} - msg("execle(%es, %es%s, %as): %p", pathname, arg, arg_buf, len, envp, ret_addr); + msg("execle(%es, %es%s, %as)" ret_str, pathname, arg, arg_buf, len, envp, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1833,9 +1869,10 @@ int sym(execle)(const char *pathname, const char *arg, ...) { int sym(execv)(const char *pathname, char *const argv[]) { init(); - if (!func_flags[func_idx_execv]) return __real_execv(pathname, argv); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_execv]) return __real_execv(pathname, argv); int len = 0; for (len = 0; argv[len] != NULL; len++) {} - msg("execv(%es, %as): %p", pathname, len, argv, ret_addr); + msg("execv(%es, %as)" ret_str, pathname, len, argv, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1853,9 +1890,10 @@ int sym(execv)(const char *pathname, char *const argv[]) { int sym(execvp)(const char *file, char *const argv[]) { init(); - if (!func_flags[func_idx_execvp]) return __real_execvp(file, argv); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_execvp]) return __real_execvp(file, argv); int len = 0; for (len = 0; argv[len] != NULL; len++) {} - msg("execvp(%es, %as): %p", file, len, argv, ret_addr); + msg("execvp(%es, %as)" ret_str, file, len, argv, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1873,10 +1911,11 @@ int sym(execvp)(const char *file, char *const argv[]) { int sym(execvpe)(const char *file, char *const argv[], char *const envp[]) { init(); - if (!func_flags[func_idx_execvpe]) return __real_execvpe(file, argv, envp); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_execvpe]) return __real_execvpe(file, argv, envp); int len1 = 0; for (len1 = 0; argv[len1] != NULL; len1++) {} int len2 = 0; for (len2 = 0; envp[len2] != NULL; len2++) {} - msg("execvpe(%es, %as, %as): %p", file, len1, argv, len2, envp, ret_addr); + msg("execvpe(%es, %as, %as)" ret_str, file, len1, argv, len2, envp, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1894,10 +1933,11 @@ int sym(execvpe)(const char *file, char *const argv[], char *const envp[]) { int sym(execve)(const char *pathname, char *const argv[], char *const envp[]) { init(); - if (!func_flags[func_idx_execve]) return __real_execve(pathname, argv, envp); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_execve]) return __real_execve(pathname, argv, envp); int len1 = 0; for (len1 = 0; argv[len1] != NULL; len1++) {} int len2 = 0; for (len2 = 0; envp[len2] != NULL; len2++) {} - msg("execve(%es, %as, %as): %p", pathname, len1, argv, len2, envp, ret_addr); + msg("execve(%es, %as, %as)" ret_str, pathname, len1, argv, len2, envp, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1915,10 +1955,11 @@ int sym(execve)(const char *pathname, char *const argv[], char *const envp[]) { int sym(fexecve)(int fd, char *const argv[], char *const envp[]) { init(); - if (!func_flags[func_idx_fexecve]) return __real_fexecve(fd, argv, envp); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_fexecve]) return __real_fexecve(fd, argv, envp); int len1 = 0; for (len1 = 0; argv[len1] != NULL; len1++) {} int len2 = 0; for (len2 = 0; envp[len2] != NULL; len2++) {} - msg("fexecve(%i, %as, %as): %p", fd, len1, argv, len2, envp, ret_addr); + msg("fexecve(%i, %as, %as)" ret_str, fd, len1, argv, len2, envp, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1936,8 +1977,9 @@ int sym(fexecve)(int fd, char *const argv[], char *const envp[]) { int sym(pipe)(int fildes[2]) { init(); - if (!func_flags[func_idx_pipe]) return __real_pipe(fildes); - msg("pipe(%p): %p", fildes, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_pipe]) return __real_pipe(fildes); + msg("pipe(%p)" ret_str, fildes, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1955,8 +1997,9 @@ int sym(pipe)(int fildes[2]) { int sym(dup)(int oldfd) { init(); - if (!func_flags[func_idx_dup]) return __real_dup(oldfd); - msg("dup(%i): %p", oldfd, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_dup]) return __real_dup(oldfd); + msg("dup(%i)" ret_str, oldfd, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1972,8 +2015,9 @@ int sym(dup)(int oldfd) { int sym(dup2)(int oldfd, int newfd) { init(); - if (!func_flags[func_idx_dup2]) return __real_dup2(oldfd, newfd); - msg("dup2(%i, %i): %p", oldfd, newfd, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_dup2]) return __real_dup2(oldfd, newfd); + msg("dup2(%i, %i)" ret_str, oldfd, newfd, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1989,11 +2033,12 @@ int sym(dup2)(int oldfd, int newfd) { int sym(dup3)(int oldfd, int newfd, int flags) { init(); - if (!func_flags[func_idx_dup3]) return __real_dup3(oldfd, newfd, flags); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_dup3]) return __real_dup3(oldfd, newfd, flags); char fstr[16] = "|"; flag_str(flags, O_CLOEXEC, fstr); if (flags & ~(O_CLOEXEC)) strcat(fstr, "?|"); - msg("dup3(%i, %i, 0%o:%s): %p", oldfd, newfd, flags, fstr, ret_addr); + msg("dup3(%i, %i, 0%o:%s)" ret_str, oldfd, newfd, flags, fstr, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2009,8 +2054,9 @@ int sym(dup3)(int oldfd, int newfd, int flags) { int sym(socket)(int domain, int type, int protocol) { init(); - if (!func_flags[func_idx_socket]) return __real_socket(domain, type, protocol); - msg("socket(%i:%s, %i:%s, %i): %p", domain, getdomainstr(domain), type, getsocktype(type), protocol, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_socket]) return __real_socket(domain, type, protocol); + msg("socket(%i:%s, %i:%s, %i)" ret_str, domain, getdomainstr(domain), type, getsocktype(type), protocol, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2028,8 +2074,9 @@ int sym(socket)(int domain, int type, int protocol) { int sym(bind)(int sockfd, const struct sockaddr *address, socklen_t address_len) { init(); - if (!func_flags[func_idx_bind]) return __real_bind(sockfd, address, address_len); - msg("socket(%i, %qa, %i): %p", sockfd, address_len, address, address_len, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_bind]) return __real_bind(sockfd, address, address_len); + msg("socket(%i, %qa, %i)" ret_str, sockfd, address_len, address, address_len, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2047,8 +2094,9 @@ int sym(bind)(int sockfd, const struct sockaddr *address, socklen_t address_len) int sym(listen)(int sockfd, int backlog) { init(); - if (!func_flags[func_idx_listen]) return __real_listen(sockfd, backlog); - msg("listen(%i, %i): %p", sockfd, backlog, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_listen]) return __real_listen(sockfd, backlog); + msg("listen(%i, %i)" ret_str, sockfd, backlog, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2064,8 +2112,9 @@ int sym(listen)(int sockfd, int backlog) { int sym(accept)(int sockfd, struct sockaddr *restrict address, socklen_t *restrict address_len) { init(); - if (!func_flags[func_idx_accept]) return __real_accept(sockfd, address, address_len); - msg("accept(%i, %p, %p): %p", sockfd, address, address_len, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_accept]) return __real_accept(sockfd, address, address_len); + msg("accept(%i, %p, %p)" ret_str, sockfd, address, address_len, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2091,8 +2140,9 @@ int sym(accept)(int sockfd, struct sockaddr *restrict address, socklen_t *restri int sym(connect)(int sockfd, const struct sockaddr *address, socklen_t address_len) { init(); - if (!func_flags[func_idx_connect]) return __real_connect(sockfd, address, address_len); - msg("connect(%i, %qa, %i): %p", sockfd, address_len, address, address_len, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_connect]) return __real_connect(sockfd, address, address_len); + msg("connect(%i, %qa, %i)" ret_str, sockfd, address_len, address, address_len, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2110,8 +2160,9 @@ int sym(connect)(int sockfd, const struct sockaddr *address, socklen_t address_l int sym(getaddrinfo)(const char *restrict node, const char *restrict service, const struct addrinfo *restrict hints, struct addrinfo **restrict res) { init(); - if (!func_flags[func_idx_getaddrinfo]) return __real_getaddrinfo(node, service, hints, res); - msg("getaddrinfo(%es, %es, %qi, %p): %p", node, service, hints, res, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_getaddrinfo]) return __real_getaddrinfo(node, service, hints, res); + msg("getaddrinfo(%es, %es, %qi, %p)" ret_str, node, service, hints, res, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2129,8 +2180,9 @@ int sym(getaddrinfo)(const char *restrict node, const char *restrict service, co void sym(freeaddrinfo)(struct addrinfo *res) { init(); - if (!func_flags[func_idx_freeaddrinfo]) { __real_freeaddrinfo(res); return; } - msg("freeaddrinfo(%p): %p", res, ret_addr); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_freeaddrinfo]) { __real_freeaddrinfo(res); return; } + msg("freeaddrinfo(%p)" ret_str, res, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2144,7 +2196,8 @@ void sym(freeaddrinfo)(struct addrinfo *res) { ssize_t sym(send)(int sockfd, const void *buf, size_t length, int flags) { init(); - if (!func_flags[func_idx_send]) return __real_send(sockfd, buf, length, flags); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_send]) return __real_send(sockfd, buf, length, flags); char fstr[256] = "|"; flag_str(flags, MSG_CONFIRM, fstr); flag_str(flags, MSG_DONTROUTE, fstr); @@ -2156,7 +2209,7 @@ ssize_t sym(send)(int sockfd, const void *buf, size_t length, int flags) { flag_str(flags, MSG_FASTOPEN, fstr); if (flags & ~(MSG_CONFIRM | MSG_DONTROUTE | MSG_EOR | MSG_MORE | MSG_NOSIGNAL | MSG_OOB | MSG_FASTOPEN)) strcat(fstr, "?|"); - msg("send(%i, %eb, %i, 0x%x:%s): %p", sockfd, length, buf, length, flags, fstr, ret_addr); + msg("send(%i, %eb, %i, 0x%x:%s)" ret_str, sockfd, length, buf, length, flags, fstr, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2174,7 +2227,8 @@ ssize_t sym(send)(int sockfd, const void *buf, size_t length, int flags) { ssize_t sym(sendto)(int sockfd, const void *buf, size_t size, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { init(); - if (!func_flags[func_idx_sendto]) return __real_sendto(sockfd, buf, size, flags, dest_addr, addrlen); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sendto]) return __real_sendto(sockfd, buf, size, flags, dest_addr, addrlen); char fstr[256] = "|"; flag_str(flags, MSG_CONFIRM, fstr); flag_str(flags, MSG_DONTROUTE, fstr); @@ -2186,7 +2240,7 @@ ssize_t sym(sendto)(int sockfd, const void *buf, size_t size, int flags, const s flag_str(flags, MSG_FASTOPEN, fstr); if (flags & ~(MSG_CONFIRM | MSG_DONTROUTE | MSG_EOR | MSG_MORE | MSG_NOSIGNAL | MSG_OOB | MSG_FASTOPEN)) strcat(fstr, "?|"); - msg("sendto(%i, %eb, %i, 0x%x:%s, %qa, %i): %p", sockfd, size, buf, size, flags, fstr, addrlen, dest_addr, addrlen, ret_addr); + msg("sendto(%i, %eb, %i, 0x%x:%s, %qa, %i)" ret_str, sockfd, size, buf, size, flags, fstr, addrlen, dest_addr, addrlen, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2204,7 +2258,8 @@ ssize_t sym(sendto)(int sockfd, const void *buf, size_t size, int flags, const s ssize_t sym(sendmsg)(int sockfd, const struct msghdr *message, int flags) { init(); - if (!func_flags[func_idx_sendmsg]) return __real_sendmsg(sockfd, message, flags); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_sendmsg]) return __real_sendmsg(sockfd, message, flags); char fstr[256] = "|"; flag_str(flags, MSG_CONFIRM, fstr); flag_str(flags, MSG_DONTROUTE, fstr); @@ -2216,7 +2271,7 @@ ssize_t sym(sendmsg)(int sockfd, const struct msghdr *message, int flags) { flag_str(flags, MSG_FASTOPEN, fstr); if (flags & ~(MSG_CONFIRM | MSG_DONTROUTE | MSG_EOR | MSG_MORE | MSG_NOSIGNAL | MSG_OOB | MSG_FASTOPEN)) strcat(fstr, "?|"); - msg("sendmsg(%i, %qm, 0x%x:%s): %p", sockfd, message, flags, fstr, ret_addr); + msg("sendmsg(%i, %qm, 0x%x:%s)" ret_str, sockfd, message, flags, fstr, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2234,7 +2289,8 @@ ssize_t sym(sendmsg)(int sockfd, const struct msghdr *message, int flags) { ssize_t sym(recv)(int sockfd, void *buf, size_t size, int flags) { init(); - if (!func_flags[func_idx_recv]) return __real_recv(sockfd, buf, size, flags); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_recv]) return __real_recv(sockfd, buf, size, flags); char fstr[256] = "|"; flag_str(flags, MSG_DONTWAIT, fstr); flag_str(flags, MSG_ERRQUEUE, fstr); @@ -2244,7 +2300,7 @@ ssize_t sym(recv)(int sockfd, void *buf, size_t size, int flags) { flag_str(flags, MSG_WAITALL, fstr); if (flags & ~(MSG_DONTWAIT | MSG_ERRQUEUE | MSG_OOB | MSG_PEEK | MSG_TRUNC | MSG_WAITALL)) strcat(fstr, "?|"); - msg("recv(%i, %p, %i, 0x%x:%s): %p", sockfd, buf, size, flags, fstr, ret_addr); + msg("recv(%i, %p, %i, 0x%x:%s)" ret_str, sockfd, buf, size, flags, fstr, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2266,7 +2322,8 @@ ssize_t sym(recv)(int sockfd, void *buf, size_t size, int flags) { ssize_t sym(recvfrom)(int sockfd, void *restrict buf, size_t size, int flags, struct sockaddr *restrict src_addr, socklen_t *restrict addrlen) { init(); - if (!func_flags[func_idx_recvfrom]) return __real_recvfrom(sockfd, buf, size, flags, src_addr, addrlen); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_recvfrom]) return __real_recvfrom(sockfd, buf, size, flags, src_addr, addrlen); char fstr[256] = "|"; flag_str(flags, MSG_DONTWAIT, fstr); flag_str(flags, MSG_ERRQUEUE, fstr); @@ -2276,7 +2333,7 @@ ssize_t sym(recvfrom)(int sockfd, void *restrict buf, size_t size, int flags, st flag_str(flags, MSG_WAITALL, fstr); if (flags & ~(MSG_DONTWAIT | MSG_ERRQUEUE | MSG_OOB | MSG_PEEK | MSG_TRUNC | MSG_WAITALL)) strcat(fstr, "?|"); - msg("recvfrom(%i, %p, %i, 0x%x:%s, %p, %p): %p", sockfd, buf, size, flags, fstr, addrlen, src_addr, addrlen, ret_addr); + msg("recvfrom(%i, %p, %i, 0x%x:%s, %p, %p)" ret_str, sockfd, buf, size, flags, fstr, addrlen, src_addr, addrlen, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -2302,7 +2359,8 @@ ssize_t sym(recvfrom)(int sockfd, void *restrict buf, size_t size, int flags, st ssize_t sym(recvmsg)(int sockfd, struct msghdr *message, int flags) { init(); - if (!func_flags[func_idx_recvmsg]) return __real_recvmsg(sockfd, message, flags); + Dl_info info; + if (!dladdr(ret_addr, &info) || !func_flags[func_idx_recvmsg]) return __real_recvmsg(sockfd, message, flags); char fstr[256] = "|"; flag_str(flags, MSG_CMSG_CLOEXEC, fstr); flag_str(flags, MSG_DONTWAIT, fstr); @@ -2313,7 +2371,7 @@ ssize_t sym(recvmsg)(int sockfd, struct msghdr *message, int flags) { flag_str(flags, MSG_WAITALL, fstr); if (flags & ~(MSG_CMSG_CLOEXEC | MSG_DONTWAIT | MSG_ERRQUEUE | MSG_OOB | MSG_PEEK | MSG_TRUNC | MSG_WAITALL)) strcat(fstr, "?|"); - msg("recvmsg(%i, %qm, 0x%x:%s): %p", sockfd, msg, flags, fstr, ret_addr); + msg("recvmsg(%i, %qm, 0x%x:%s)" ret_str, sockfd, msg, flags, fstr, ret_data); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); diff --git a/proj/server/src/intercept/__init__.py b/proj/server/src/intercept/__init__.py index c8fab8c..f41672e 100644 --- a/proj/server/src/intercept/__init__.py +++ b/proj/server/src/intercept/__init__.py @@ -21,15 +21,22 @@ StructAddrInfo = TypedDict('StructAddrInfo', {}) StructMsgHdr = TypedDict('StructMsgHdr', {}) +RET_ADDR_RE = re.compile(r': *((0x)?[0-9a-fA-Fx]+) *\((.+?)\+(.+?)(, *(.+?))?\)$') + + class ThreadedUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass class Handler(StreamRequestHandler): pid: Optional[int] + tid: Optional[int] path: Optional[str] - stack: list[tuple[int, str, tuple]] + stack: list[tuple[int, str, int, Optional[str], str, tuple]] ret_addr: int + dli_file_name: str + rel_ret_addr: int + dli_sym_name: Optional[str] def before(self) -> None: pass def after(self) -> None: pass @@ -164,13 +171,20 @@ class Handler(StreamRequestHandler): def handle_msg(self, msg: bytes): timestamp, pid, tid, data = msg.rstrip(b'\n').split(b' ', 3) + self.pid, self.tid = int(pid), int(tid) if not data.startswith(b'return ') and not data == b'return': call = data.decode('utf-8') - print(f'[{self.pid}] {call}') + print(f'[{self.pid}][{self.tid}] {call}') func_name = call[:call.find('(')] - self.ret_addr = int(call[call.rfind(':') + 1:], 0) + ret = call[call.rfind(':'):] + m = RET_ADDR_RE.match(ret) + g_ret, _, g_fname, g_rel, _, g_sym = m.groups() + self.ret_addr = int(g_ret, 0) + self.dli_file_name = g_fname + self.rel_ret_addr = int(g_ret, 0) + self.dli_sym_name = g_sym args, _ = Handler.parse_args(call[call.find('(') + 1:call.rfind(':') - 1]) - self.stack.append((self.ret_addr, func_name, args)) + self.stack.append((self.ret_addr, self.dli_file_name, self.rel_ret_addr, self.dli_sym_name, func_name, args)) try: func = getattr(self, f'before_{func_name}') if not callable(func): @@ -183,12 +197,12 @@ class Handler(StreamRequestHandler): command = func(*args) or self.before_fallback(func_name, *args) or 'ok' except NotImplementedError: command = self.before_fallback(func_name, *args) or 'ok' - print(f'[{self.pid}] -> {command}') + print(f'[{self.pid}][{self.tid}] -> {command}') self.wfile.write(command.encode('utf-8') + b'\n') else: ret = data.decode('utf-8') ret_value, _ = Handler.parse_arg(ret[7:].split(';')[0]) - self.ret_addr, func_name, args = self.stack.pop() + (self.ret_addr, self.dli_file_name, self.rel_ret_addr, self.dli_sym_name, func_name, args) = self.stack.pop() try: func = getattr(self, f'after_{func_name}') if not callable(func): @@ -207,7 +221,7 @@ class Handler(StreamRequestHandler): self.after_fallback(func_name, *args) else: self.after_fallback(func_name, *args, ret_value) - print(f'[{self.pid}] -> {ret}') + print(f'[{self.pid}][{self.tid}] -> {ret}') def before_malloc(self, size: int) -> str: raise NotImplementedError()