1
0

proj: Add struct addrinfo and INTERCEPT_VERBOSE

This commit is contained in:
2025-04-19 16:43:20 +02:00
parent d988d1d28b
commit 127456d23a
6 changed files with 113 additions and 39 deletions

View File

@@ -10,6 +10,7 @@ import sys
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('-F', '--functions')
parser.add_argument('-s', '--sparse', action='store_true')
libs = parser.add_mutually_exclusive_group()
libs.add_argument('-o', '--only-own', action='store_true')
libs.add_argument('-L', '--libraries')
@@ -31,6 +32,7 @@ def main() -> None:
subprocess.run(extra, stdin=sys.stdin, env={
'LD_PRELOAD': os.getcwd() + '/intercept.so',
'INTERCEPT': intercept,
'INTERCEPT_VERBOSE': '0' if args.sparse else '1',
'INTERCEPT_FUNCTIONS': args.functions or '*',
'INTERCEPT_LIBRARIES': '*,-/lib*,-/usr/lib*' if args.only_own else args.libraries or '*',
})

View File

@@ -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) {

View File

@@ -17,7 +17,9 @@ StructSockAddr = TypedDict('StructSockAddr', {'sa_family': Constant, 'sa_data':
'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', {})
StructAddrInfo = TypedDict('StructAddrInfo', {'ai_flags': Flags, 'ai_family': Constant, 'ai_socktype': Constant, 'ai_protocol': int, 'ai_addrlen': int,
'ai_addr': PointerTo[StructSockAddr],
'ai_canonname': PointerTo[bytes], 'ai_next': Pointer})
StructMsgHdr = TypedDict('StructMsgHdr', {})
@@ -481,10 +483,10 @@ class Handler(StreamRequestHandler):
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_ptr: Pointer) -> str:
def before_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[list[StructAddrInfo]], res_ptr: Pointer) -> str:
raise NotImplementedError()
def after_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[StructAddrInfo], res_ptr: Pointer,
ret_value: int, errno: str = None, res: Pointer = None) -> None:
def after_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[list[StructAddrInfo]], res_ptr: Pointer,
ret_value: int, errno: str = None, res: PointerTo[list[StructAddrInfo]] = None) -> None:
raise NotImplementedError()
def before_freeaddrinfo(self, res: Pointer) -> str:
raise NotImplementedError()

View File

@@ -24,6 +24,7 @@ def main() -> None:
subprocess.run(extra, env={
'LD_PRELOAD': os.getcwd() + '/../../intercept/intercept.so',
'INTERCEPT': 'unix:' + socket_name,
'INTERCEPT_VERBOSE': '1',
'INTERCEPT_FUNCTIONS': '*',
'INTERCEPT_LIBRARIES': '*,-/lib*,-/usr/lib*',
})

View File

@@ -24,6 +24,7 @@ def main() -> None:
subprocess.run(extra, env={
'LD_PRELOAD': os.getcwd() + '/../../intercept/intercept.so',
'INTERCEPT': 'unix:' + socket_name,
'INTERCEPT_VERBOSE': '1',
'INTERCEPT_FUNCTIONS': ','.join(['malloc', 'calloc', 'realloc', 'reallocarray', 'free', 'getaddrinfo', 'freeaddrinfo']),
'INTERCEPT_LIBRARIES': '*,-/lib*,-/usr/lib*',
})

View File

@@ -35,6 +35,7 @@ def main() -> None:
subprocess.run(extra, stdin=stdin, env={
'LD_PRELOAD': os.getcwd() + '/../../intercept/intercept.so',
'INTERCEPT': 'unix:' + socket_name,
'INTERCEPT_VERBOSE': '1',
'INTERCEPT_FUNCTIONS': '*',
'INTERCEPT_LIBRARIES': '*,-/lib*,-/usr/lib*',
})