Skip to content

Instantly share code, notes, and snippets.

@rushkii
Last active February 13, 2026 17:48
Show Gist options
  • Select an option

  • Save rushkii/573b75e00da7368fd1ffa6b308d6f691 to your computer and use it in GitHub Desktop.

Select an option

Save rushkii/573b75e00da7368fd1ffa6b308d6f691 to your computer and use it in GitHub Desktop.
simple connect() syscall(42) interceptor for logger.
/*
* how to build:
* gcc -shared -Os -fpic -fPIC connect_logger.c -o connect_logger.so
* ---
* how to run:
* LOG_PATH=./kizu_log_connect.txt LD_PRELOAD=./connect_logger.so curl nhentai.net && cat kizu_log_connect.txt
*/
// script ref: https://gist.github.com/ammarfaizi2/1e1424f987cfbe3e3c3b571b6e590923
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <errno.h>
static FILE *log_file = NULL;
static void log_init(void) {
const char *log_path;
if (log_file) return;
log_path = getenv("LOG_PATH");
if (!log_path) log_path = "/dev/null";
log_file = fopen(log_path, "a");
assert(log_file);
}
static void log_write(const char *fmt, ...) {
va_list args; // list of args (...)
va_start(args, fmt);
vfprintf(log_file, fmt, args);
va_end(args);
}
void strtime(char *tb, size_t len) {
// struct tm for reentrant,
// this avoids race condition.
struct tm tm;
time_t now = time(NULL);
localtime_r(&now, &tm);
strftime(tb, len, "%Y-%m-%d %H:%M:%S", &tm);
}
int connect(int sockfd, const struct sockaddr *addr, unsigned int addrlen) {
long rax = 42; // connect() syscall
__asm__ volatile (
"syscall"
: "+a" (rax) // connect() syscall + write return to rax
: "D" (sockfd), // rdi
"S" (addr), // rsi
"d" (addrlen) // rdx
: "memory", "rcx", "r11"
);
log_init();
char timebuf[64];
strtime(timebuf, sizeof(timebuf));
char str[INET6_ADDRSTRLEN];
if (addr->sa_family == AF_INET) {
// cast address to its specific address family struct.
const struct sockaddr_in *in = (const struct sockaddr_in *)addr;
// write formatted ip address based on address family.
const char *address = inet_ntop(addr->sa_family, in, str, INET6_ADDRSTRLEN);
// convert network port to host port (byte order, BE to LE).
// in BE system, ntohs will do noop (no operation).
uint16_t port = ntohs(in->sin_port);
// write log string to log_file ptr.
log_write("[%s] Family-IPv4: %s:%u ret=%ld port=%d\n",
timebuf, address, port, rax, port);
} else if (addr->sa_family == AF_INET6) {
// cast address to its specific address family struct.
const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)addr;
// write formatted ip address based on address family.
const char *address = inet_ntop(addr->sa_family, in6, str, INET6_ADDRSTRLEN);
// convert network port to host port (byte order, BE to LE).
// in BE system, ntohs will do noop (no operation).
uint16_t port = ntohs(in6->sin6_port);
// write log string to log_file ptr.
log_write("[%s] Family-IPv6: %s:%u ret=%ld port=%d\n",
timebuf, address, port, rax, port);
} else if (addr->sa_family == AF_UNIX) {
// cast address to its specific address family struct.
const struct sockaddr_un *un = (const struct sockaddr_un *)addr;
// write log string to log_file ptr.
log_write("[%s] Family-UNIX:%s ret=%ld\n", timebuf, un->sun_path, rax);
} else {
// write log string to log_file ptr.
log_write("[%s] Family-unknown=%u ret=%ld\n", timebuf, addr->sa_family, rax);
}
// flush the written log to the log_file.
fflush(log_file);
if (rax < 0) {
// if returned connect() syscall error
// set errno = -rax and return -1
errno = -rax;
return -1;
}
// success
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment