From a738e3ee2b72e1a4b4aab2664ad71d7b944e55a8 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 14 Apr 2025 15:03:08 +0200 Subject: [PATCH] proj: Implement socket --- proj/intercept/Makefile | 4 +- proj/intercept/src/intercept.c | 945 ++++++++++++++++++++------ proj/server/src/intercept/__init__.py | 76 ++- 3 files changed, 816 insertions(+), 209 deletions(-) diff --git a/proj/intercept/Makefile b/proj/intercept/Makefile index 73fa0ca..6a1245c 100644 --- a/proj/intercept/Makefile +++ b/proj/intercept/Makefile @@ -24,7 +24,9 @@ main_intercept: bin/main.o src/intercept.c --wrap=sem_init,--wrap=sem_open,--wrap=sem_post,--wrap=sem_wait,--wrap=sem_trywait,--wrap=sem_timedwait,--wrap=sem_getvalue,--wrap=sem_close,--wrap=sem_unlink,--wrap=sem_destroy,\ --wrap=shm_open,--wrap=shm_unlink,--wrap=mmap,--wrap=munmap,\ --wrap=ftruncate,--wrap=fork,--wrap=wait,--wrap=waitpid,--wrap=pipe,--wrap=dup,--wrap=dup2,--wrap=dup3,\ ---wrap=execl,--wrap=execlp,--wrap=execle,--wrap=execv,--wrap=execvp,--wrap=execvpe,--wrap=execve,--wrap=fexecve +--wrap=execl,--wrap=execlp,--wrap=execle,--wrap=execv,--wrap=execvp,--wrap=execvpe,--wrap=execve,--wrap=fexecve,\ +--wrap=socket,--wrap=bind,--wrap=listen,--wrap=accept,--wrap=connect,--wrap=getaddrinfo,--wrap=freeaddrinfo,\ +--wrap=send,--wrap=sendto,--wrap=sendmsg,--wrap=recv,--wrap=recvfrom,--wrap=recvmsg clean: rm -rf main_intercept bin/* *.so *.ko *.o diff --git a/proj/intercept/src/intercept.c b/proj/intercept/src/intercept.c index 0d7b91e..1855c6c 100644 --- a/proj/intercept/src/intercept.c +++ b/proj/intercept/src/intercept.c @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include #define BUFFER_SIZE 256 @@ -28,96 +31,188 @@ return; \ } #define sym(name) name -static void *(*__real_malloc)(size_t); -static void *(*__real_calloc)(size_t, size_t); -static void *(*__real_realloc)(void *, size_t); -static void *(*__real_reallocarray)(void *, size_t, size_t); -static void (*__real_free)(void *); -static int (*__real_getopt)(int, char *const [], const char *); -static void (*__real_exit)(int); -static ssize_t (*__real_read)(int, void *, size_t); -static ssize_t (*__real_pread)(int, void *, size_t, off_t); -static ssize_t (*__real_write)(int, const void *, size_t); -static ssize_t (*__real_pwrite)(int, const void *, size_t, off_t); -static int (*__real_close)(int); -static int (*__real_sigaction)(int, const struct sigaction *, struct sigaction *); -static int (*__real_sem_init)(sem_t *, int, unsigned int); -static sem_t *(*__real_sem_open)(const char *, int, ...); -static int (*__real_sem_post)(sem_t *); -static int (*__real_sem_wait)(sem_t *); -static int (*__real_sem_trywait)(sem_t *); -static int (*__real_sem_timedwait)(sem_t *restrict, const struct timespec *restrict); -static int (*__real_sem_getvalue)(sem_t *restrict, int *restrict); -static int (*__real_sem_close)(sem_t *); -static int (*__real_sem_unlink)(const char *); -static int (*__real_sem_destroy)(sem_t *); -static int (*__real_shm_open)(const char *, int, mode_t); -static int (*__real_shm_unlink)(const char *); -static void *(*__real_mmap)(void *, size_t, int, int, int, off_t); -static int (*__real_munmap)(void *, size_t); -static int (*__real_ftruncate)(int, off_t); -static pid_t (*__real_fork)(void); -static pid_t (*__real_wait)(int *); -static pid_t (*__real_waitpid)(pid_t, int *, int); -static int (*__real_execl)(const char *, const char *, ...); -static int (*__real_execlp)(const char *, const char *, ...); -static int (*__real_execle)(const char *, const char *, ...); -static int (*__real_execv)(const char *, char *const[]); -static int (*__real_execvp)(const char *, char *const[]); -static int (*__real_execvpe)(const char *, char *const[], char *const[]); -static int (*__real_execve)(const char *, char *const[], char *const[]); -static int (*__real_fexecve)(int, char *const[], char *const[]); -static int (*__real_pipe)(int[2]); -static int (*__real_dup)(int); -static int (*__real_dup2)(int, int); -static int (*__real_dup3)(int, int, int); +#define func_def(ret, name) static ret (*__real_ ## name) #else #define sym(name) __wrap_ ## name -extern void *__real_malloc(size_t); -extern void *__real_calloc(size_t, size_t); -extern void *__real_realloc(void *, size_t); -extern void *__real_reallocarray(void *, size_t, size_t); -extern void __real_free(void *); -extern int __real_getopt(int, char *const [], const char *); -extern void __real_exit(int); -extern ssize_t __real_read(int, void *, size_t); -extern ssize_t __real_pread(int, void *, size_t, off_t); -extern ssize_t __real_write(int, const void *, size_t); -extern ssize_t __real_pwrite(int, const void *, size_t, off_t); -extern int __real_close(int); -extern int __real_sigaction(int, const struct sigaction *, struct sigaction *); -extern int __real_sem_init(sem_t *, int, unsigned int); -extern sem_t *__real_sem_open(const char *, int, ...); -extern int __real_sem_post(sem_t *); -extern int __real_sem_wait(sem_t *); -extern int __real_sem_trywait(sem_t *); -extern int __real_sem_timedwait(sem_t *restrict, const struct timespec *restrict); -extern int __real_sem_getvalue(sem_t *restrict, int *restrict); -extern int __real_sem_close(sem_t *); -extern int __real_sem_unlink(const char *); -extern int __real_sem_destroy(sem_t *); -extern int __real_shm_open(const char *, int, mode_t); -extern int __real_shm_unlink(const char *); -extern void *__real_mmap(void *, size_t, int, int, int, off_t); -extern int __real_munmap(void *, size_t); -extern int __real_ftruncate(int, off_t); -extern pid_t __real_fork(void); -extern pid_t __real_wait(int *); -extern pid_t __real_waitpid(pid_t, int *, int); -extern int __real_execl(const char *, const char *, ...); -extern int __real_execlp(const char *, const char *, ...); -extern int __real_execle(const char *, const char *, ...); -extern int __real_execv(const char *, char *const[]); -extern int __real_execvp(const char *, char *const[]); -extern int __real_execvpe(const char *, char *const[], char *const[]); -extern int __real_execve(const char *, char *const[], char *const[]); -extern int __real_fexecve(int, char *const[], char *const[]); -extern int __real_pipe(int[2]); -extern int __real_dup(int); -extern int __real_dup2(int, int); -extern int __real_dup3(int, int, int); +#define func_def(ret, name) extern ret __real_ ## name #endif +func_def(void *, malloc)(size_t); +func_def(void *, calloc)(size_t, size_t); +func_def(void *, realloc)(void *, size_t); +func_def(void *, reallocarray)(void *, size_t, size_t); +func_def(void, free)(void *); +func_def(int, getopt)(int, char *const [], const char *); +func_def(void, exit)(int); +func_def(ssize_t, read)(int, void *, size_t); +func_def(ssize_t, pread)(int, void *, size_t, off_t); +func_def(ssize_t, write)(int, const void *, size_t); +func_def(ssize_t, pwrite)(int, const void *, size_t, off_t); +func_def(int, close)(int); +func_def(int, sigaction)(int, const struct sigaction *, struct sigaction *); +func_def(int, sem_init)(sem_t *, int, unsigned int); +func_def(sem_t *, sem_open)(const char *, int, ...); +func_def(int, sem_post)(sem_t *); +func_def(int, sem_wait)(sem_t *); +func_def(int, sem_trywait)(sem_t *); +func_def(int, sem_timedwait)(sem_t *restrict, const struct timespec *restrict); +func_def(int, sem_getvalue)(sem_t *restrict, int *restrict); +func_def(int, sem_close)(sem_t *); +func_def(int, sem_unlink)(const char *); +func_def(int, sem_destroy)(sem_t *); +func_def(int, shm_open)(const char *, int, mode_t); +func_def(int, shm_unlink)(const char *); +func_def(void *, mmap)(void *, size_t, int, int, int, off_t); +func_def(int, munmap)(void *, size_t); +func_def(int, ftruncate)(int, off_t); +func_def(pid_t, fork)(void); +func_def(pid_t, wait)(int *); +func_def(pid_t, waitpid)(pid_t, int *, int); +func_def(int, execl)(const char *, const char *, ...); +func_def(int, execlp)(const char *, const char *, ...); +func_def(int, execle)(const char *, const char *, ...); +func_def(int, execv)(const char *, char *const[]); +func_def(int, execvp)(const char *, char *const[]); +func_def(int, execvpe)(const char *, char *const[], char *const[]); +func_def(int, execve)(const char *, char *const[], char *const[]); +func_def(int, fexecve)(int, char *const[], char *const[]); +func_def(int, pipe)(int[2]); +func_def(int, dup)(int); +func_def(int, dup2)(int, int); +func_def(int, dup3)(int, int, int); +func_def(int, socket)(int, int, int); +func_def(int, bind)(int, const struct sockaddr *, socklen_t); +func_def(int, listen)(int, int); +func_def(int, accept)(int, struct sockaddr *, socklen_t *); +func_def(int, connect)(int, const struct sockaddr *, socklen_t); +func_def(int, getaddrinfo)(const char *, const char *, const struct addrinfo *, struct addrinfo **); +func_def(void, freeaddrinfo)(struct addrinfo *); +func_def(ssize_t, send)(int, const void *, size_t, int); +func_def(ssize_t, sendto)(int, const void *, size_t, int, const struct sockaddr *, socklen_t); +func_def(ssize_t, sendmsg)(int, const struct msghdr *, int); +func_def(ssize_t, recv)(int, void *, size_t, int); +func_def(ssize_t, recvfrom)(int, void *, size_t, int, struct sockaddr *, socklen_t *); +func_def(ssize_t, recvmsg)(int, struct msghdr *, int); + +#define func_idx_malloc 0 +#define func_idx_calloc 1 +#define func_idx_realloc 2 +#define func_idx_reallocarray 3 +#define func_idx_free 4 +#define func_idx_getopt 5 +#define func_idx_exit 6 +#define func_idx_read 7 +#define func_idx_pread 8 +#define func_idx_write 9 +#define func_idx_pwrite 10 +#define func_idx_close 11 +#define func_idx_sigaction 12 +#define func_idx_sem_init 13 +#define func_idx_sem_open 14 +#define func_idx_sem_post 15 +#define func_idx_sem_wait 16 +#define func_idx_sem_trywait 17 +#define func_idx_sem_timedwait 18 +#define func_idx_sem_getvalue 19 +#define func_idx_sem_close 20 +#define func_idx_sem_unlink 21 +#define func_idx_sem_destroy 22 +#define func_idx_shm_open 23 +#define func_idx_shm_unlink 24 +#define func_idx_mmap 25 +#define func_idx_munmap 26 +#define func_idx_ftruncate 27 +#define func_idx_fork 28 +#define func_idx_wait 29 +#define func_idx_waitpid 30 +#define func_idx_execl 31 +#define func_idx_execlp 32 +#define func_idx_execle 33 +#define func_idx_execv 34 +#define func_idx_execvp 35 +#define func_idx_execvpe 36 +#define func_idx_execve 37 +#define func_idx_fexecve 38 +#define func_idx_pipe 39 +#define func_idx_dup 40 +#define func_idx_dup2 41 +#define func_idx_dup3 42 +#define func_idx_socket 43 +#define func_idx_bind 44 +#define func_idx_listen 45 +#define func_idx_accept 46 +#define func_idx_connect 47 +#define func_idx_getaddrinfo 48 +#define func_idx_freeaddrinfo 49 +#define func_idx_send 50 +#define func_idx_sendto 51 +#define func_idx_sendmsg 52 +#define func_idx_recv 53 +#define func_idx_recvfrom 54 +#define func_idx_recvmsg 55 + +#define FUNCTIONS \ + X(malloc) \ + X(calloc) \ + X(realloc) \ + X(reallocarray) \ + X(free) \ + X(getopt) \ + X(exit) \ + X(read) \ + X(pread) \ + X(write) \ + X(pwrite) \ + X(close) \ + X(sigaction) \ + X(sem_init) \ + X(sem_open) \ + X(sem_post) \ + X(sem_wait) \ + X(sem_trywait) \ + X(sem_timedwait) \ + X(sem_getvalue) \ + X(sem_close) \ + X(sem_unlink) \ + X(sem_destroy) \ + X(shm_open) \ + X(shm_unlink) \ + X(mmap) \ + X(munmap) \ + X(ftruncate) \ + X(fork) \ + X(wait) \ + X(waitpid) \ + X(execl) \ + X(execlp) \ + X(execle) \ + X(execv) \ + X(execvp) \ + X(execvpe) \ + X(execve) \ + X(fexecve) \ + X(pipe) \ + X(dup) \ + X(dup2) \ + X(dup3) \ + X(socket) \ + X(bind) \ + X(listen) \ + X(accept) \ + X(connect) \ + X(getaddrinfo) \ + X(freeaddrinfo) \ + X(send) \ + X(sendto) \ + X(sendmsg) \ + X(recv) \ + X(recvfrom) \ + X(recvmsg) + +#define case_const(name) case name: return #name + +#define flag_str(flags, name, buf) if (flags & name) strcat(buf, #name "|") + #define ret_addr __builtin_return_address(0) #define if_fail if (strncmp(msg_buf, "fail ", 5) == 0) @@ -217,7 +312,7 @@ extern int __real_dup3(int, int, int); #define if_error(err) if (strcmp(msg_buf + 5, #err) == 0) { errno = err; } -static long set_errno(const char *name, const char *msg_buf) { +static void set_errno(const char *name, const char *msg_buf) { char *end_ptr = NULL; long val = strtol(msg_buf + 5, &end_ptr, 0); if (end_ptr != NULL && end_ptr[0] == 0 && end_ptr != msg_buf + 5) { @@ -360,6 +455,29 @@ static long set_errno(const char *name, const char *msg_buf) { } } +static const char *getdomainstr(int domain) { + switch (domain) { + case_const(AF_UNSPEC); + case_const(AF_UNIX); + case_const(AF_INET); + case_const(AF_INET6); + default: return "?"; + } +} + +static const char *getsocktype(int type) { + switch (type) { + case_const(SOCK_STREAM); + case_const(SOCK_DGRAM); + case_const(SOCK_RAW); + case_const(SOCK_RDM); + case_const(SOCK_SEQPACKET); + case_const(SOCK_DCCP); + case_const(SOCK_PACKET); + default: return "?"; + } +} + static char *strtostr(char *ptr, char **end_ptr, char *buf) { if (ptr[0] != '"') return NULL; int i = 0, esc = 0, hex = 0; @@ -423,9 +541,10 @@ static char *strtostr(char *ptr, char **end_ptr, char *buf) { static int mode = 0; static int intercept = 0; +static uint8_t func_flags[256]; -static size_t msg_bytes(char *buf, size_t maxlen, size_t len, const char *str) { - size_t offset = snprintf(buf, maxlen, "%p:\"", str); +static size_t msg_bytes(char *buf, size_t maxlen, size_t len, const char *str, int flags) { + size_t offset = flags & 1 ? snprintf(buf, maxlen, "\"") : snprintf(buf, maxlen, "%p:\"", str); for (int i = 0; i < len && offset <= maxlen - 2; i++) { char ch = str[i]; if (ch == '\\' || ch == '"') { @@ -453,8 +572,8 @@ static size_t msg_bytes(char *buf, size_t maxlen, size_t len, const char *str) { return offset; } -static size_t msg_str(char *buf, size_t maxlen, const char *str) { - return msg_bytes(buf, maxlen, strlen(str), str); +static size_t msg_str(char *buf, size_t maxlen, const char *str, int flags) { + return msg_bytes(buf, maxlen, strlen(str), str, flags); } static size_t msg_array_str(char *buf, size_t maxlen, char *const array[], int n) { @@ -464,7 +583,7 @@ static size_t msg_array_str(char *buf, size_t maxlen, char *const array[], int n buf[offset++] = ','; buf[offset++] = ' '; } - offset += msg_str(buf + offset, maxlen - offset, array[i]); + offset += msg_str(buf + offset, maxlen - offset, array[i], 0); } if (offset <= maxlen - 2) { buf[offset++] = ']'; @@ -475,7 +594,7 @@ static size_t msg_array_str(char *buf, size_t maxlen, char *const array[], int n static void msg(const char *fmt, ...) { if (!intercept || mode == -1) return; - char buf[1024], sub_fmt[16]; + char buf[8192], sub_fmt[16]; int sub_fmt_p = 0; va_list args; @@ -493,6 +612,9 @@ static void msg(const char *fmt, ...) { } else if (ch == 'e') { state = 'e'; continue; + } else if (ch == 'q') { + state = 'q'; + continue; } else if (ch == 'a') { state = 'a'; continue; @@ -513,11 +635,54 @@ static void msg(const char *fmt, ...) { } else if (state == 'e') { if (ch == 's') { // escaped string - offset += msg_str(buf + offset, sizeof(buf) - offset, va_arg(args, const char *)); + offset += msg_str(buf + offset, sizeof(buf) - offset, va_arg(args, const char *), 0); } else if (ch == 'b') { // escaped byte sequence const int len = va_arg(args, int); - offset += msg_bytes(buf + offset, sizeof(buf) - offset, len, va_arg(args, const char *)); + offset += msg_bytes(buf + offset, sizeof(buf) - offset, len, va_arg(args, const char *), 0); + } + state = 0; + } else if (state == 'q') { + if (ch == 'a') { + // address, struct sockaddr + const int len = va_arg(args, int); + const struct sockaddr *addr = va_arg(args, struct sockaddr *); + if (addr->sa_family == AF_UNIX) { + // 0x0:{sa_family: 1:AF_UNIX, sun_path: "/path/"} + const struct sockaddr_un *un = (const struct sockaddr_un *)addr; + offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{sa_family: %i:AF_UNIX, sun_Path: ", (void *)un, AF_UNIX); + offset += msg_str(buf + offset, sizeof(buf) - offset, un->sun_path, 1); + offset += snprintf(buf + offset, sizeof(buf) - offset, "}"); + } else if (addr->sa_family == AF_INET && len == sizeof(struct sockaddr_in)) { + // 0x0:{sa_family: 2:AF_INET, sin_addr: "192.168.0.1", sin_port: 80} + const struct sockaddr_in *in = (const struct sockaddr_in *)addr; + char addr_buf[INET_ADDRSTRLEN]; + offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{sa_family: %i:AF_INET, sin_addr: \"%s\", sin_port: %i}", (void *)in, AF_INET, inet_ntop(AF_INET, &in->sin_addr, addr_buf, sizeof(addr_buf)), ntohs(in->sin_port)); + } else if (addr->sa_family == AF_INET6 && len == sizeof(struct sockaddr_in6)) { + // 0x0:{sa_family: 10:AF_INET6, sin6_addr: "::1", sin6_port: 80, sin6_scope_id: 0} + const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)addr; + char addr_buf[INET6_ADDRSTRLEN]; + offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{sa_family: %i:AF_INET6, sin6_addr: \"%s\", sin6_port: %i, sin6_scope_id: %i}", (void *)in6, AF_INET6, inet_ntop(AF_INET6, &in6->sin6_addr, addr_buf, sizeof(addr_buf)), ntohs(in6->sin6_port), in6->sin6_scope_id); + } else { + // 0x0:{sa_family: 7:?, sa_data: "\x01\x02\x03\x04"} + offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{sa_family: %i:%s, sa_data: ", (void *)addr, addr->sa_family, getdomainstr(addr->sa_family)); + offset += msg_bytes(buf + offset, sizeof(buf) - offset, len - sizeof(addr->sa_family), addr->sa_data, 1); + offset += snprintf(buf + offset, sizeof(buf) - offset, "}"); + } + } else if (ch == 'm') { + // struct msghdr + // TODO format struct msghdr + const struct msghdr *msg = va_arg(args, struct msghdr *); + offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{}", (void *)msg); + } else if (ch == 't') { + // struct timespec + const struct timespec *tv = va_arg(args, struct timespec *); + offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{tv_sec: %li, tv_nsec: %li}", (void *)tv, tv->tv_sec, tv->tv_nsec); + } else if (ch == 'i') { + // struct addrinfo + // TODO format struct addrinfo + const struct addrinfo *ai = va_arg(args, struct addrinfo *); + offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{}", (void *)ai); } else { // error va_end(args); @@ -591,49 +756,12 @@ static void init(void) { if (mode) return; mode = -1; #ifdef INTERCEPT_PRELOAD - load(malloc); - load(calloc); - load(realloc); - load(reallocarray); - load(free); - load(getopt); - load(exit); - load(read); - load(pread); - load(write); - load(pwrite); - load(close); - load(sigaction); - load(sem_init); - load(sem_open); - load(sem_post); - load(sem_wait); - load(sem_trywait); - load(sem_timedwait); - load(sem_getvalue); - load(sem_close); - load(sem_unlink); - load(sem_destroy); - load(shm_open); - load(shm_unlink); - load(mmap); - load(munmap); - load(ftruncate); - load(fork); - load(wait); - load(waitpid); - load(execl); - load(execlp); - load(execle); - load(execv); - load(execvp); - load(execvpe); - load(execve); - load(fexecve); - load(pipe); - load(dup); - load(dup2); - load(dup3) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#define X(name) load(name); + FUNCTIONS +#undef X +#pragma GCC diagnostic pop #endif atexit(fin); const char *val = getenv("INTERCEPT"); @@ -655,7 +783,7 @@ static void init(void) { fprintf(stderr, "intercept: intercepting function/system calls and logging to file\n"); mode = 3; } else if (val && strncmp(val, "unix:", 5) == 0) { - if ((intercept = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + if ((intercept = __real_socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "intercept: unable to open unix socket '%s': %s\n" "intercept: not logging or manipulating function/system calls\n", val + 5, strerror(errno)); errno = 0; mode = -1; @@ -663,9 +791,9 @@ static void init(void) { } struct sockaddr_un addr = {.sun_family = AF_UNIX}; strncpy(addr.sun_path, val + 5, sizeof(addr.sun_path)); - if (connect(intercept, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + if (__real_connect(intercept, (struct sockaddr *)&addr, sizeof(addr)) == -1) { fprintf(stderr, "intercept: unable to connect to unix socket '%s': %s\n" "intercept: not logging or manipulating function/system calls\n", val + 5, strerror(errno)); - close(intercept); + __real_close(intercept); errno = 0; mode = -1; return; @@ -681,10 +809,40 @@ static void init(void) { } else { fprintf(stderr, "intercept: not logging or manipulating function/system calls\n"); } + char *fncts = getenv("INTERCEPT_FUNCTIONS"); + if (fncts) { + memset(func_flags, 0, sizeof(func_flags)); + const char *func_names_ordered[] = { + #define X(name) #name, + FUNCTIONS + #undef X + }; + char *func_names[256] = {fncts, NULL}; + const size_t len = strlen(fncts); + for (int i = 0, p = 0; i < len; i++) { + const char ch = fncts[i]; + if (ch == ',' || ch == ';' || ch == ':' || ch == 0) { + fncts[i] = 0; + func_names[++p] = fncts + i + 1; + } + } + for (int i = 0; func_names[i] != NULL; i++) { + const char *name1 = func_names[i]; + const int wildcard = name1[strlen(name1) - 1] == '*'; + for (int j = 0; j < sizeof(func_names_ordered) / sizeof(char *); j++) { + const char *name2 = func_names_ordered[j]; + if (strcmp(name1, name2) == 0 || (wildcard && strncmp(name1, name2, strlen(name1) - 1) == 0)) + func_flags[j] |= 1; + } + } + } else { + memset(func_flags, 1, sizeof(func_flags)); + } } void *sym(malloc)(size_t size) { init(); + if (!func_flags[func_idx_malloc]) return __real_malloc(size); msg("malloc(%li): %p", size, ret_addr); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -701,6 +859,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -717,6 +876,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -733,6 +893,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -749,6 +910,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -763,6 +925,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -781,6 +944,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -793,6 +957,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -815,6 +980,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -837,7 +1003,8 @@ 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(); - msg("write(%i, %eb, %i): %p", fildes, buf, nbyte, buf, nbyte, ret_addr); + if (!func_flags[func_idx_write]) return __real_write(fildes, buf, nbyte); + msg("write(%i, %eb, %i): %p", fildes, nbyte, buf, nbyte, ret_addr); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -855,7 +1022,8 @@ 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(); - msg("pwrite(%i, %eb, %i, %i): %p", fildes, buf, nbyte, buf, nbyte, offset, ret_addr); + 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -873,6 +1041,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -888,54 +1057,60 @@ int sym(close)(int fildes) { } static const char *getsigstr(int sig) { - if (sig == SIGINT) return "SIGINT"; - if (sig == SIGILL) return "SIGILL"; - if (sig == SIGABRT) return "SIGABRT"; - if (sig == SIGFPE) return "SIGFPE"; - if (sig == SIGSEGV) return "SIGSEGV"; - if (sig == SIGTERM) return "SIGTERM"; - if (sig == SIGHUP) return "SIGHUP"; - if (sig == SIGQUIT) return "SIGQUIT"; - if (sig == SIGTRAP) return "SIGTRAP"; - if (sig == SIGKILL) return "SIGKILL"; - if (sig == SIGPIPE) return "SIGPIPE"; - if (sig == SIGALRM) return "SIGALRM"; - if (sig == SIGSTKFLT) return "SIGSTKFLT"; - if (sig == SIGPWR) return "SIGPWR"; - if (sig == SIGBUS) return "SIGBUS"; - if (sig == SIGSYS) return "SIGSYS"; - if (sig == SIGURG) return "SIGURG"; - if (sig == SIGSTOP) return "SIGSTOP"; - if (sig == SIGTSTP) return "SIGTSTP"; - if (sig == SIGCONT) return "SIGCONT"; - if (sig == SIGCHLD) return "SIGCHLD"; - if (sig == SIGTTIN) return "SIGTTIN"; - if (sig == SIGTTOU) return "SIGTTOU"; - if (sig == SIGPOLL) return "SIGPOLL"; - if (sig == SIGXFSZ) return "SIGXFSZ"; - if (sig == SIGXCPU) return "SIGXCPU"; - if (sig == SIGVTALRM) return "SIGVTALRM"; - if (sig == SIGPROF) return "SIGPROF"; - if (sig == SIGUSR1) return "SIGUSR1"; - if (sig == SIGUSR2) return "SIGUSR2"; - if (sig == SIGWINCH) return "SIGWINCH"; - return "?"; + switch (sig) { + case_const(SIGINT); + case_const(SIGILL); + case_const(SIGABRT); + case_const(SIGFPE); + case_const(SIGSEGV); + case_const(SIGTERM); + case_const(SIGHUP); + case_const(SIGQUIT); + case_const(SIGTRAP); + case_const(SIGKILL); + case_const(SIGPIPE); + case_const(SIGALRM); + case_const(SIGSTKFLT); + case_const(SIGPWR); + case_const(SIGBUS); + case_const(SIGSYS); + case_const(SIGURG); + case_const(SIGSTOP); + case_const(SIGTSTP); + case_const(SIGCONT); + case_const(SIGCHLD); + case_const(SIGTTIN); + case_const(SIGTTOU); + case_const(SIGPOLL); + case_const(SIGXFSZ); + case_const(SIGXCPU); + case_const(SIGVTALRM); + case_const(SIGPROF); + case_const(SIGUSR1); + case_const(SIGUSR2); + case_const(SIGWINCH); + default: return "?"; + } } 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); const char *sigstr = getsigstr(sig); if (act != NULL) { char *name = "sa_handler"; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" void *ptr = (void *)act->sa_handler; if (act->sa_flags & SA_SIGINFO) { name = "sa_sigaction"; ptr = (void *)act->sa_sigaction; } +#pragma GCC diagnostic pop char flgstr[64] = "|"; - if (act->sa_flags & SA_NOCLDSTOP) strcat(flgstr, "SA_NOCLDSTOP|"); - if (act->sa_flags & SA_NOCLDWAIT) strcat(flgstr, "SA_NOCLDWAIT|"); - if (act->sa_flags & SA_SIGINFO) strcat(flgstr, "SA_SIGINFO|"); + flag_str(act->sa_flags, SA_NOCLDSTOP, flgstr); + flag_str(act->sa_flags, SA_NOCLDWAIT, flgstr); + flag_str(act->sa_flags, SA_SIGINFO, flgstr); if (act->sa_flags & ~(SA_NOCLDSTOP | SA_NOCLDWAIT | SA_SIGINFO)) strcat(flgstr, "?|"); char maskstr[512] = ""; for (int i = 0; i < 64; i++) { @@ -963,15 +1138,18 @@ int sym(sigaction)(int sig, const struct sigaction *restrict act, struct sigacti const int ret = __real_sigaction(sig, act, oact); if (oact != NULL) { char *name = "sa_handler"; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" void *ptr = (void *)oact->sa_handler; if (oact->sa_flags & SA_SIGINFO) { name = "sa_sigaction"; ptr = (void *)oact->sa_sigaction; } +#pragma GCC diagnostic pop char flgstr[64] = "|"; - if (oact->sa_flags & SA_NOCLDSTOP) strcat(flgstr, "SA_NOCLDSTOP|"); - if (oact->sa_flags & SA_NOCLDWAIT) strcat(flgstr, "SA_NOCLDWAIT|"); - if (oact->sa_flags & SA_SIGINFO) strcat(flgstr, "SA_SIGINFO|"); + flag_str(oact->sa_flags, SA_NOCLDSTOP, flgstr); + flag_str(oact->sa_flags, SA_NOCLDWAIT, flgstr); + flag_str(oact->sa_flags, SA_SIGINFO, flgstr); if (oact->sa_flags & ~(SA_NOCLDSTOP | SA_NOCLDWAIT | SA_SIGINFO)) strcat(flgstr, "?|"); char maskstr[512] = ""; for (int i = 0; i < 64; i++) { @@ -989,6 +1167,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1006,8 +1185,8 @@ int sym(sem_init)(sem_t *sem, int pshared, unsigned int value) { sem_t *sym(sem_open)(const char *name, int oflag, ...) { init(); char ostr[32] = "|"; - if (oflag & O_CREAT) strcat(ostr, "O_CREAT|"); - if (oflag & O_EXCL) strcat(ostr, "O_EXCL|"); + flag_str(oflag, O_CREAT, ostr); + flag_str(oflag, O_EXCL, ostr); if (oflag & ~(O_CREAT | O_EXCL)) strcat(ostr, "?|"); mode_t mode_arg = 0; @@ -1018,8 +1197,10 @@ 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); } 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); } @@ -1090,6 +1271,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1106,6 +1288,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1122,6 +1305,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1138,7 +1322,8 @@ int sym(sem_trywait)(sem_t *sem) { int sym(sem_timedwait)(sem_t *restrict sem, const struct timespec *restrict abs_timeout) { init(); - msg("sem_timedwait(%p, %p:{tv_sec: %li, tv_nsec: %li}): %p", sem, abs_timeout, abs_timeout->tv_sec, abs_timeout->tv_nsec, ret_addr); + 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); struct timespec overwrite; if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1183,6 +1368,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1203,6 +1389,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1219,6 +1406,7 @@ 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); char overwrite[BUFFER_SIZE]; if (mode >= 4) { @@ -1250,6 +1438,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1266,12 +1455,13 @@ 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); char ostr[64] = "|"; - if (oflag & O_RDONLY) strcat(ostr, "O_RDONLY|"); - if (oflag & O_RDWR) strcat(ostr, "O_RDWR|"); - if (oflag & O_CREAT) strcat(ostr, "O_CREAT|"); - if (oflag & O_EXCL) strcat(ostr, "O_EXCL|"); - if (oflag & O_TRUNC) strcat(ostr, "O_TRUNC|"); + flag_str(oflag, O_RDONLY, ostr); + flag_str(oflag, O_RDWR, ostr); + flag_str(oflag, O_CREAT, ostr); + flag_str(oflag, O_EXCL, ostr); + 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); @@ -1342,6 +1532,7 @@ 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); char overwrite[BUFFER_SIZE]; if (mode >= 4) { @@ -1373,17 +1564,18 @@ 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); char pstr[64] = "|"; if (prot == PROT_NONE) strcat(pstr, "PROT_NONE|"); - if (prot & PROT_READ) strcat(pstr, "PROT_READ|"); - if (prot & PROT_WRITE) strcat(pstr, "PROT_WRITE|"); - if (prot & PROT_EXEC) strcat(pstr, "PROT_EXEC|"); + flag_str(prot, PROT_READ, pstr); + flag_str(prot, PROT_WRITE, pstr); + flag_str(prot, PROT_EXEC, pstr); if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) strcat(pstr, "?|"); char fstr[64] = "|"; - if (prot & MAP_SHARED) strcat(fstr, "MAP_SHARED|"); - if (prot & MAP_PRIVATE) strcat(fstr, "MAP_PRIVATE|"); - if (prot & MAP_FIXED) strcat(fstr, "MAP_FIXED|"); - if (prot & MAP_ANONYMOUS) strcat(fstr, "MAP_ANONYMOUS|"); + flag_str(prot, MAP_SHARED, fstr); + flag_str(prot, MAP_PRIVATE, fstr); + flag_str(prot, MAP_FIXED, fstr); + 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); @@ -1406,6 +1598,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1422,6 +1615,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1438,6 +1632,7 @@ int sym(ftruncate)(int fildes, off_t length) { pid_t sym(fork)(void) { init(); + if (!func_flags[func_idx_fork]) return __real_fork(); msg("fork(): %p", ret_addr); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1453,6 +1648,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1473,10 +1669,11 @@ 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); char ostr[64] = "|"; - if (options & WCONTINUED) strcat(ostr, "WCONTINUED|"); - if (options & WNOHANG) strcat(ostr, "WNOHANG|"); - if (options & WUNTRACED) strcat(ostr, "WUNTRACED|"); + 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); @@ -1508,6 +1705,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); char arg_buf[4096] = "", *arg_buf_ptr = arg_buf; for (int i = 1; i < 64; i++) { arg_buf_ptr[0] = ','; @@ -1518,7 +1716,7 @@ int sym(execl)(const char *pathname, const char *arg, ...) { strcat(arg_buf_ptr, "NULL"); break; } - arg_buf_ptr += msg_str(arg_buf, sizeof(arg_buf) - (arg_buf_ptr - arg_buf), arg_vec[i]); + 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); @@ -1547,6 +1745,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); char arg_buf[4096] = "", *arg_buf_ptr = arg_buf; for (int i = 1; i < 64; i++) { arg_buf_ptr[0] = ','; @@ -1557,7 +1756,7 @@ int sym(execlp)(const char *file, const char *arg, ...) { strcat(arg_buf_ptr, "NULL"); break; } - arg_buf_ptr += msg_str(arg_buf, sizeof(arg_buf) - (arg_buf_ptr - arg_buf), arg_vec[i]); + 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); @@ -1591,6 +1790,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); char arg_buf[4096] = "", *arg_buf_ptr = arg_buf; for (int i = 1; i < 64; i++) { arg_buf_ptr[0] = ','; @@ -1601,7 +1801,7 @@ int sym(execle)(const char *pathname, const char *arg, ...) { strcat(arg_buf_ptr, "NULL"); break; } - arg_buf_ptr += msg_str(arg_buf, sizeof(arg_buf) - (arg_buf_ptr - arg_buf), arg_vec[i]); + arg_buf_ptr += msg_str(arg_buf, sizeof(arg_buf) - (arg_buf_ptr - arg_buf), arg_vec[i], 0); } int len = 0; for (len = 0; envp[len] != NULL; len++) {} @@ -1623,6 +1823,7 @@ 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); int len = 0; for (len = 0; argv[len] != NULL; len++) {} msg("execv(%es, %as): %p", pathname, len, argv, ret_addr); if (mode >= 4) { @@ -1642,6 +1843,7 @@ 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); int len = 0; for (len = 0; argv[len] != NULL; len++) {} msg("execvp(%es, %as): %p", file, len, argv, ret_addr); if (mode >= 4) { @@ -1661,6 +1863,7 @@ 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); 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); @@ -1681,6 +1884,7 @@ 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); 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); @@ -1701,6 +1905,7 @@ 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); 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); @@ -1721,7 +1926,8 @@ int sym(fexecve)(int fd, char *const argv[], char *const envp[]) { int sym(pipe)(int fildes[2]) { init(); - msg("pipe(%p:[%i,%i]): %p", fildes, fildes[0], fildes[1], ret_addr); + if (!func_flags[func_idx_pipe]) return __real_pipe(fildes); + msg("pipe(%p): %p", fildes, ret_addr); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; rcv(msg_buf, sizeof(msg_buf)); @@ -1733,12 +1939,13 @@ int sym(pipe)(int fildes[2]) { else if_invalid(pipe) } const int ret = __real_pipe(fildes); - msg("return %i; errno %s", ret, strerrorname_np(errno)); + msg("return %i; errno %s; fildes=[%i,%i]", ret, strerrorname_np(errno), fildes[0], fildes[1]); return ret; } int sym(dup)(int oldfd) { init(); + if (!func_flags[func_idx_dup]) return __real_dup(oldfd); msg("dup(%i): %p", oldfd, ret_addr); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1755,6 +1962,7 @@ 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); if (mode >= 4) { char msg_buf[BUFFER_SIZE]; @@ -1771,8 +1979,9 @@ 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); char fstr[16] = "|"; - if (flags & O_CLOEXEC) strcat(fstr, "O_CLOEXEC|"); + 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); if (mode >= 4) { @@ -1787,3 +1996,329 @@ int sym(dup3)(int oldfd, int newfd, int flags) { msg("return %i; errno %s", ret, strerrorname_np(errno)); return ret; } + +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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO socket modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "socket"); + } else if_return_int_errno(socket) + else if_fail_int_errno(socket) + else if_invalid(socket) + } + const int ret = __real_socket(domain, type, protocol); + msg("return %i; errno %s", ret, strerrorname_np(errno)); + return ret; +} + +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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO bind modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "bind"); + } else if_return_int_errno(bind) + else if_fail_int_errno(bind) + else if_invalid(bind) + } + const int ret = __real_bind(sockfd, address, address_len); + msg("return %i; errno %s", ret, strerrorname_np(errno)); + return ret; +} + +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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if_modify_int_int(listen, int, sockfd, int, backlog) + else if_return_int_errno(listen) + else if_fail_int_errno(listen) + else if_invalid(listen) + } + const int ret = __real_listen(sockfd, backlog); + msg("return %i; errno %s", ret, strerrorname_np(errno)); + return ret; +} + +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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO accept modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "accept"); + } else if_return_int_errno(accept) + else if_fail_int_errno(accept) + else if_invalid(accept) + } + const int ret = __real_accept(sockfd, address, address_len); + if (ret >= 0) { + if (address != NULL && address_len != NULL) { + msg("return %i; errno %s; address=%qa; address_len=%i", ret, strerrorname_np(errno), *address_len, address, *address_len); + } else { + msg("return %i; errno %s", ret, strerrorname_np(errno)); + } + } else { + msg("return %i; errno %s", ret, strerrorname_np(errno)); + } + return ret; +} + +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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO connect modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "connect"); + } else if_return_int_errno(connect) + else if_fail_int_errno(connect) + else if_invalid(connect) + } + const int ret = __real_connect(sockfd, address, address_len); + msg("return %i; errno %s", ret, strerrorname_np(errno)); + return ret; +} + +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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO getaddrinfo modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "getaddrinfo"); + } else if_return_int_errno(getaddrinfo) + else if_fail_int_errno(getaddrinfo) + else if_invalid(getaddrinfo) + } + const int ret = __real_getaddrinfo(node, service, hints, res); + msg("return %i; errno %s", ret, strerrorname_np(errno)); + return ret; +} + +void sym(freeaddrinfo)(struct addrinfo *res) { + init(); + if (!func_flags[func_idx_freeaddrinfo]) { __real_freeaddrinfo(res); return; } + msg("freeaddrinfo(%p): %p", res, ret_addr); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if_modify_int(freeaddrinfo, struct addrinfo *, res) + else if_return + else if_invalid(freeaddrinfo) + } + __real_freeaddrinfo(res); + msg("return"); +} + +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); + char fstr[256] = "|"; + flag_str(flags, MSG_CONFIRM, fstr); + flag_str(flags, MSG_DONTROUTE, fstr); + flag_str(flags, MSG_DONTWAIT, fstr); + flag_str(flags, MSG_EOR, fstr); + flag_str(flags, MSG_MORE, fstr); + flag_str(flags, MSG_NOSIGNAL, fstr); + flag_str(flags, MSG_OOB, fstr); + 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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO send modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "send"); + } else if_return_int_errno(send) + else if_fail_int_errno(send) + else if_invalid(send) + } + const ssize_t ret = __real_send(sockfd, buf, length, flags); + msg("return %i; errno %s", ret, strerrorname_np(errno)); + return ret; +} + +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); + char fstr[256] = "|"; + flag_str(flags, MSG_CONFIRM, fstr); + flag_str(flags, MSG_DONTROUTE, fstr); + flag_str(flags, MSG_DONTWAIT, fstr); + flag_str(flags, MSG_EOR, fstr); + flag_str(flags, MSG_MORE, fstr); + flag_str(flags, MSG_NOSIGNAL, fstr); + flag_str(flags, MSG_OOB, fstr); + 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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO sendto modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "sendto"); + } else if_return_int_errno(sendto) + else if_fail_int_errno(sendto) + else if_invalid(sendto) + } + const ssize_t ret = __real_sendto(sockfd, buf, size, flags, dest_addr, addrlen); + msg("return %i; errno %s", ret, strerrorname_np(errno)); + return ret; +} + +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); + char fstr[256] = "|"; + flag_str(flags, MSG_CONFIRM, fstr); + flag_str(flags, MSG_DONTROUTE, fstr); + flag_str(flags, MSG_DONTWAIT, fstr); + flag_str(flags, MSG_EOR, fstr); + flag_str(flags, MSG_MORE, fstr); + flag_str(flags, MSG_NOSIGNAL, fstr); + flag_str(flags, MSG_OOB, fstr); + 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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO sendmsg modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "sendmsg"); + } else if_return_int_errno(sendmsg) + else if_fail_int_errno(sendmsg) + else if_invalid(sendmsg) + } + const ssize_t ret = __real_sendmsg(sockfd, message, flags); + msg("return %i; errno %s", ret, strerrorname_np(errno)); + return ret; +} + +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); + char fstr[256] = "|"; + flag_str(flags, MSG_DONTWAIT, fstr); + flag_str(flags, MSG_ERRQUEUE, fstr); + flag_str(flags, MSG_OOB, fstr); + flag_str(flags, MSG_PEEK, fstr); + flag_str(flags, MSG_TRUNC, fstr); + 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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO recv modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "recv"); + } else if_return_int_errno(recv) + else if_fail_int_errno(recv) + else if_invalid(recv) + } + const ssize_t ret = __real_recv(sockfd, buf, size, flags); + if (ret >= 0) { + msg("return %i; errno %s; buf=%eb", ret, strerrorname_np(errno), ret, buf); + } else { + msg("return %i; errno %s", ret, strerrorname_np(errno)); + } + return ret; +} + +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); + char fstr[256] = "|"; + flag_str(flags, MSG_DONTWAIT, fstr); + flag_str(flags, MSG_ERRQUEUE, fstr); + flag_str(flags, MSG_OOB, fstr); + flag_str(flags, MSG_PEEK, fstr); + flag_str(flags, MSG_TRUNC, fstr); + 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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO recvfrom modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "recvfrom"); + } else if_return_int_errno(recvfrom) + else if_fail_int_errno(recvfrom) + else if_invalid(recvfrom) + } + const ssize_t ret = __real_recvfrom(sockfd, buf, size, flags, src_addr, addrlen); + if (ret >= 0) { + if (src_addr != NULL && addrlen != NULL) { + msg("return %i; errno %s; buf=%eb; src_addr=%qa; addrlen=%i", ret, strerrorname_np(errno), ret, buf, *addrlen, src_addr, *addrlen); + } else { + msg("return %i; errno %s; buf=%eb", ret, strerrorname_np(errno), ret, buf); + } + } else { + msg("return %i; errno %s", ret, strerrorname_np(errno)); + } + return ret; +} + +ssize_t sym(recvmsg)(int sockfd, struct msghdr *message, int flags) { + init(); + if (!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); + flag_str(flags, MSG_ERRQUEUE, fstr); + flag_str(flags, MSG_OOB, fstr); + flag_str(flags, MSG_PEEK, fstr); + flag_str(flags, MSG_TRUNC, fstr); + 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); + if (mode >= 4) { + char msg_buf[BUFFER_SIZE]; + rcv(msg_buf, sizeof(msg_buf)); + if (strncmp(msg_buf, "modify ", 7) == 0) { + // TODO recvmsg modify + fprintf(stderr, "intercept: %s: modify command not implemented\n", "recvmsg"); + } else if_return_int_errno(recvmsg) + else if_fail_int_errno(recvmsg) + else if_invalid(recvmsg) + } + const ssize_t ret = __real_recvmsg(sockfd, message, flags); + if (ret >= 0) { + msg("return %i; errno %s; message=%eb", ret, strerrorname_np(errno), sizeof(*message), message); + } else { + msg("return %i; errno %s", ret, strerrorname_np(errno)); + } + return ret; +} diff --git a/proj/server/src/intercept/__init__.py b/proj/server/src/intercept/__init__.py index 0806150..87ce36e 100644 --- a/proj/server/src/intercept/__init__.py +++ b/proj/server/src/intercept/__init__.py @@ -13,6 +13,12 @@ type Constant = tuple[int, str] type Flags = tuple[int, list[str]] StructTimeSpec = TypedDict('StructTimeSpec', {'tv_sec': int, 'tv_nsec': int}) StructSigAction = TypedDict('StructSigAction', {'sa_flags': Flags, 'sa_handler': NotRequired[Pointer], 'sa_sigaction': NotRequired[Pointer], 'sa_mask': list[str]}) +StructSockAddr = TypedDict('StructSockAddr', {'sa_family': Constant, 'sa_data': NotRequired[bytes], + 'sun_path': NotRequired[bytes], + 'sin_addr': NotRequired[bytes], 'sin_port': NotRequired[int], + 'sin6_addr': NotRequired[bytes], 'sin6_port': NotRequired[int], 'sin6_scope_id': NotRequired[int]}) +StructAddrInfo = TypedDict('StructAddrInfo', {}) +StructMsgHdr = TypedDict('StructMsgHdr', {}) class ThreadedUnixStreamServer(ThreadingMixIn, UnixStreamServer): @@ -396,10 +402,10 @@ class Handler(StreamRequestHandler): def after_fexecve(self, fd: int, argv: PointerTo[list[PointerTo[bytes]]], envp: PointerTo[list[PointerTo[bytes]]], ret_value: int, errno: str = None) -> None: raise NotImplementedError() - def before_pipe(self, fildes: PointerTo[list[int]]) -> str: + def before_pipe(self, fildes_ptr: Pointer) -> str: raise NotImplementedError() - def after_pipe(self, fildes: PointerTo[list[int]], - ret_value: int, errno: str = None) -> None: + def after_pipe(self, fildes_ptr: Pointer, + ret_value: int, errno: str = None, fildes: list[int] = None) -> None: raise NotImplementedError() def before_dup(self, oldfd: int) -> str: raise NotImplementedError() @@ -416,6 +422,70 @@ class Handler(StreamRequestHandler): def after_dup3(self, oldfd: int, newfd: int, flags: Flags, ret_value: int, errno: str = None) -> None: raise NotImplementedError() + def before_socket(self, domain: Constant, socktype: Constant, protocol: int) -> str: + raise NotImplementedError() + def after_socket(self, domain: Constant, socktype: Constant, protocol: int, + ret_value: int, errno: str = None) -> None: + raise NotImplementedError() + def before_bind(self, sockfd: int, address: PointerTo[StructSockAddr], address_len: int) -> str: + raise NotImplementedError() + def after_bind(self, sockfd: int, address: PointerTo[StructSockAddr], address_len: int, + ret_value: int, errno: str = None) -> None: + raise NotImplementedError() + def before_listen(self, sockfd: int, backlog: int) -> str: + raise NotImplementedError() + def after_listen(self, sockfd: int, backlog: int, + ret_value: int, errno: str = None) -> None: + raise NotImplementedError() + def before_accept(self, sockfd: int, address_ptr: Pointer, address_len_ptr: Pointer) -> str: + raise NotImplementedError() + def after_accept(self, sockfd: int, address_ptr: Pointer, address_len_ptr: Pointer, + ret_value: int, errno: str = None, address: PointerTo[StructSockAddr] = None, address_len: PointerTo[StructSockAddr] = None) -> None: + raise NotImplementedError() + def before_connect(self, sockfd: int, address: PointerTo[StructSockAddr], address_len: int) -> str: + raise NotImplementedError() + def after_connect(self, sockfd: int, address: PointerTo[StructSockAddr], address_len: int, + ret_value: int, errno: str = None) -> None: + raise NotImplementedError() + def before_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[StructAddrInfo], res: Pointer) -> str: + raise NotImplementedError() + def after_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[StructAddrInfo], res: Pointer, + ret_value: int, errno: str = None) -> None: + raise NotImplementedError() + def before_freeaddrinfo(self, res: Pointer) -> str: + raise NotImplementedError() + def after_freeaddrinfo(self, res: Pointer) -> None: + raise NotImplementedError() + def before_send(self, sockfd: int, buf: PointerTo[bytes], length: int, flags: Flags) -> str: + raise NotImplementedError() + def after_send(self, sockfd: int, buf: PointerTo[bytes], length: int, flags: Flags, + ret_value: int, errno: str = None) -> None: + raise NotImplementedError() + def before_sendto(self, sockfd: int, buf: PointerTo[bytes], length: int, flags: Flags, dest_addr: PointerTo[StructSockAddr], addrlen: int) -> str: + raise NotImplementedError() + def after_sendto(self, sockfd: int, buf: PointerTo[bytes], length: int, flags: Flags, dest_addr: PointerTo[StructSockAddr], addrlen: int, + ret_value: int, errno: str = None) -> None: + raise NotImplementedError() + def before_sendmsg(self, sockfd: int, message: StructMsgHdr, flags: Flags) -> str: + raise NotImplementedError() + def after_sendmsg(self, sockfd: int, message: StructMsgHdr, flags: Flags, + ret_value: int, errno: str = None) -> None: + raise NotImplementedError() + def before_recv(self, sockfd: int, buf_ptr: Pointer, size: int, flags: Flags) -> str: + raise NotImplementedError() + def after_recv(self, sockfd: int, buf_ptr: Pointer, size: int, flags: Flags, + ret_value: int, errno: str = None, buf: PointerTo[bytes] = None) -> None: + raise NotImplementedError() + def before_recvfrom(self, sockfd: int, buf_ptr: Pointer, size: int, flags: Flags, src_addr_ptr: Pointer, addrlen_ptr: Pointer) -> str: + raise NotImplementedError() + def after_recvfrom(self, sockfd: int, buf_ptr: Pointer, size: int, flags: Flags, src_addr_ptr: Pointer, addrlen_ptr: Pointer, + ret_value: int, errno: str = None, buf: PointerTo[bytes] = None, src_addr: PointerTo[StructSockAddr] = None, addrlen: int = None) -> None: + raise NotImplementedError() + def before_recvmsg(self, sockfd: int, message_ptr: Pointer, flags: Flags) -> str: + raise NotImplementedError() + def after_recvmsg(self, sockfd: int, message_ptr: Pointer, flags: Flags, + ret_value: int, errno: str = None, message: PointerTo[StructMsgHdr] = None) -> None: + raise NotImplementedError() def intercept(socket: str, handler: type[Handler]) -> None: