|
|
|
|
@@ -545,6 +545,7 @@ static char *strtostr(char *ptr, char **end_ptr, char *buf) {
|
|
|
|
|
|
|
|
|
|
static int mode = 0;
|
|
|
|
|
static int intercept = 0;
|
|
|
|
|
static int verbosity = 0;
|
|
|
|
|
static uint8_t func_flags[256];
|
|
|
|
|
static uint8_t lib_flags[0x1000];
|
|
|
|
|
|
|
|
|
|
@@ -578,7 +579,7 @@ static size_t msg_bytes(char *buf, size_t maxlen, size_t len, const char *str, i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static size_t msg_str(char *buf, size_t maxlen, const char *str, int flags) {
|
|
|
|
|
return msg_bytes(buf, maxlen, strlen(str), str, flags);
|
|
|
|
|
return msg_bytes(buf, maxlen, str == NULL ? 0 : strlen(str), str, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static size_t msg_array_str(char *buf, size_t maxlen, char *const array[], int n) {
|
|
|
|
|
@@ -597,6 +598,35 @@ static size_t msg_array_str(char *buf, size_t maxlen, char *const array[], int n
|
|
|
|
|
return offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static size_t msg_sockaddr(char *buf, const size_t size, const struct sockaddr *addr, const socklen_t len) {
|
|
|
|
|
size_t offset = 0;
|
|
|
|
|
if (addr == NULL) {
|
|
|
|
|
offset += snprintf(buf + offset, size - offset, "%p:{}", (void *)addr);
|
|
|
|
|
} else 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, size - offset, "%p:{sa_family: %i:AF_UNIX, sun_Path: ", (void *)un, AF_UNIX);
|
|
|
|
|
offset += msg_str(buf + offset, size - offset, un->sun_path, 1);
|
|
|
|
|
offset += snprintf(buf + offset, size - 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, size - 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, size - 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, size - offset, "%p:{sa_family: %i:%s, sa_data: ", (void *)addr, addr->sa_family, getdomainstr(addr->sa_family));
|
|
|
|
|
offset += msg_bytes(buf + offset, size - offset, len - sizeof(addr->sa_family), addr->sa_data, 1);
|
|
|
|
|
offset += snprintf(buf + offset, size - offset, "}");
|
|
|
|
|
}
|
|
|
|
|
return offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void msg(const char *fmt, ...) {
|
|
|
|
|
if (!intercept || mode == -1) return;
|
|
|
|
|
char buf[8192], sub_fmt[16];
|
|
|
|
|
@@ -640,11 +670,21 @@ 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 *), 0);
|
|
|
|
|
const char *str = va_arg(args, const char *);
|
|
|
|
|
if (!verbosity) {
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:\"\"", (void *)str);
|
|
|
|
|
} else {
|
|
|
|
|
offset += msg_str(buf + offset, sizeof(buf) - offset, str, 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 *), 0);
|
|
|
|
|
const char *str = va_arg(args, const char *);
|
|
|
|
|
if (!verbosity) {
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:\"\"", (void *)str);
|
|
|
|
|
} else {
|
|
|
|
|
offset += msg_bytes(buf + offset, sizeof(buf) - offset, len, str, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
state = 0;
|
|
|
|
|
} else if (state == 'q') {
|
|
|
|
|
@@ -652,42 +692,54 @@ static void msg(const char *fmt, ...) {
|
|
|
|
|
// 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);
|
|
|
|
|
if (!verbosity) {
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{}", (void *)addr);
|
|
|
|
|
} 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, "}");
|
|
|
|
|
offset += msg_sockaddr(buf + offset, sizeof(buf) - offset, addr, len);
|
|
|
|
|
}
|
|
|
|
|
} 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);
|
|
|
|
|
if (!verbosity) {
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{}", (void *)msg);
|
|
|
|
|
} else {
|
|
|
|
|
// TODO format 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);
|
|
|
|
|
if (!verbosity) {
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:{}", (void *)tv);
|
|
|
|
|
} else {
|
|
|
|
|
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);
|
|
|
|
|
if (!verbosity) {
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:[]", (void *)ai);
|
|
|
|
|
} else {
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:[", (void *)ai);
|
|
|
|
|
for (; ai != NULL; ai = ai->ai_next) {
|
|
|
|
|
char fstr[256] = "|";
|
|
|
|
|
flag_str(ai->ai_flags, AI_PASSIVE, fstr);
|
|
|
|
|
flag_str(ai->ai_flags, AI_CANONNAME, fstr);
|
|
|
|
|
flag_str(ai->ai_flags, AI_NUMERICHOST, fstr);
|
|
|
|
|
flag_str(ai->ai_flags, AI_V4MAPPED, fstr);
|
|
|
|
|
flag_str(ai->ai_flags, AI_ALL, fstr);
|
|
|
|
|
flag_str(ai->ai_flags, AI_ADDRCONFIG, fstr);
|
|
|
|
|
flag_str(ai->ai_flags, AI_CANONIDN, fstr);
|
|
|
|
|
flag_str(ai->ai_flags, AI_NUMERICSERV, fstr);
|
|
|
|
|
if (ai->ai_flags & ~(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_CANONIDN | AI_NUMERICSERV)) strcat(fstr, "?|");
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "{ai_flags: 0x%x:%s, ai_family: %i:%s, ai_socktype: %i:%s, ai_protocol: %i, ai_addrlen: %i, ai_addr: ", ai->ai_flags, fstr, ai->ai_family, getdomainstr(ai->ai_family), ai->ai_socktype, getsocktype(ai->ai_socktype), ai->ai_protocol, ai->ai_addrlen);
|
|
|
|
|
offset += msg_sockaddr(buf + offset, sizeof(buf) - offset, ai->ai_addr, ai->ai_addrlen);
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, ", ai_canonname: ");
|
|
|
|
|
offset += msg_str(buf + offset, sizeof(buf) - offset, ai->ai_canonname, 0);
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, ", ai_next: %p}%s", (void *)ai->ai_next, ai->ai_next ? ", " : "");
|
|
|
|
|
}
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "]");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
va_end(args);
|
|
|
|
|
@@ -699,7 +751,11 @@ static void msg(const char *fmt, ...) {
|
|
|
|
|
// string array
|
|
|
|
|
const int len = va_arg(args, int);
|
|
|
|
|
char *const *array = va_arg(args, char *const *);
|
|
|
|
|
offset += msg_array_str(buf + offset, sizeof(buf) - offset, array, len);
|
|
|
|
|
if (!verbosity) {
|
|
|
|
|
offset += snprintf(buf + offset, sizeof(buf) - offset, "%p:[]", (void *)array);
|
|
|
|
|
} else {
|
|
|
|
|
offset += msg_array_str(buf + offset, sizeof(buf) - offset, array, len);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
va_end(args);
|
|
|
|
|
@@ -842,6 +898,13 @@ static void init(void) {
|
|
|
|
|
fprintf(stderr, "intercept: not logging or manipulating function/system calls\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *verbose = getenv("INTERCEPT_VERBOSE");
|
|
|
|
|
if (!verbose || verbose[0] == 0 || strcmp(verbose, "0") == 0) {
|
|
|
|
|
verbosity = 0;
|
|
|
|
|
} else {
|
|
|
|
|
verbosity = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *fncts = getenv("INTERCEPT_FUNCTIONS");
|
|
|
|
|
if (!fncts) {
|
|
|
|
|
memset(func_flags, 1, sizeof(func_flags));
|
|
|
|
|
@@ -1195,7 +1258,11 @@ 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)" ret_str, sig, sigstr, act, act->sa_flags, flgstr, name, ptr, maskstr, oact, ret_data);
|
|
|
|
|
if (!verbosity) {
|
|
|
|
|
msg("sigaction(%i:%s, %p:{}, %p)" ret_str, sig, sigstr, act, oact, ret_addr);
|
|
|
|
|
} else {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
@@ -2226,9 +2293,9 @@ int sym(getaddrinfo)(const char *restrict node, const char *restrict service, co
|
|
|
|
|
}
|
|
|
|
|
const int ret = __real_getaddrinfo(node, service, hints, res);
|
|
|
|
|
if (res != NULL) {
|
|
|
|
|
msg("return %i; errno %s; res=%p", ret, strerrorname_np(errno), *res);
|
|
|
|
|
msg("return %i; errno %s; res=%qi", ret, strerrorname_np(errno), *res);
|
|
|
|
|
} else {
|
|
|
|
|
msg("return %i; errno %s", ret, strerrorname_np(errno), *res);
|
|
|
|
|
msg("return %i; errno %s", ret, strerrorname_np(errno));
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
@@ -2262,7 +2329,7 @@ ssize_t sym(send)(int sockfd, const void *buf, size_t length, int flags) {
|
|
|
|
|
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, "?|");
|
|
|
|
|
if (flags & ~(MSG_CONFIRM | MSG_DONTROUTE | MSG_DONTWAIT | MSG_EOR | MSG_MORE | MSG_NOSIGNAL | MSG_OOB | MSG_FASTOPEN)) strcat(fstr, "?|");
|
|
|
|
|
|
|
|
|
|
msg("send(%i, %eb, %i, 0x%x:%s)" ret_str, sockfd, length, buf, length, flags, fstr, ret_data);
|
|
|
|
|
if (mode >= 4) {
|
|
|
|
|
@@ -2293,7 +2360,7 @@ ssize_t sym(sendto)(int sockfd, const void *buf, size_t size, int flags, const s
|
|
|
|
|
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, "?|");
|
|
|
|
|
if (flags & ~(MSG_CONFIRM | MSG_DONTROUTE | MSG_DONTWAIT | MSG_EOR | MSG_MORE | MSG_NOSIGNAL | MSG_OOB | MSG_FASTOPEN)) strcat(fstr, "?|");
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
@@ -2324,7 +2391,7 @@ ssize_t sym(sendmsg)(int sockfd, const struct msghdr *message, int flags) {
|
|
|
|
|
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, "?|");
|
|
|
|
|
if (flags & ~(MSG_CONFIRM | MSG_DONTROUTE | MSG_DONTWAIT | MSG_EOR | MSG_MORE | MSG_NOSIGNAL | MSG_OOB | MSG_FASTOPEN)) strcat(fstr, "?|");
|
|
|
|
|
|
|
|
|
|
msg("sendmsg(%i, %qm, 0x%x:%s)" ret_str, sockfd, message, flags, fstr, ret_data);
|
|
|
|
|
if (mode >= 4) {
|
|
|
|
|
|