From b377a2927b53cc7635908fa90b33291dc0815244 Mon Sep 17 00:00:00 2001 From: hugoc Date: Sat, 10 Feb 2024 16:19:49 +0100 Subject: [PATCH] hook read and write --- src/allocator_thread.c | 6 +++--- src/core.c | 9 +++++---- src/core.h | 4 ++++ src/debug.c | 2 +- src/libproxychains.c | 46 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/allocator_thread.c b/src/allocator_thread.c index 66cf7f6..2c3715f 100644 --- a/src/allocator_thread.c +++ b/src/allocator_thread.c @@ -174,7 +174,7 @@ static int trywrite(int fd, void* buf, size_t bytes) { ssize_t ret; unsigned char *out = buf; again: - ret = write(fd, out, bytes); + ret = true_write(fd, out, bytes); switch(ret) { case -1: if(errno == EINTR) goto again; @@ -200,7 +200,7 @@ static int tryread(int fd, void* buf, size_t bytes) { ssize_t ret; unsigned char *out = buf; again: - ret = read(fd, out, bytes); + ret = true_read(fd, out, bytes); switch(ret) { case -1: if(errno == EINTR) goto again; @@ -350,7 +350,7 @@ void at_init(void) { void at_close(void) { PFUNC(); const int msg = ATM_EXIT; - write(req_pipefd[1], &msg, sizeof(int)); + true_write(req_pipefd[1], &msg, sizeof(int)); pthread_join(allocator_thread, NULL); close(req_pipefd[0]); close(req_pipefd[1]); diff --git a/src/core.c b/src/core.c index 9ab3786..8cedc3c 100644 --- a/src/core.c +++ b/src/core.c @@ -122,7 +122,7 @@ static int write_n_bytes(int fd, char *buff, size_t size) { int i = 0; size_t wrote = 0; for(;;) { - i = write(fd, &buff[wrote], size - wrote); + i = true_write(fd, &buff[wrote], size - wrote); if(i <= 0) return i; wrote += i; @@ -141,7 +141,7 @@ static int read_n_bytes(int fd, char *buff, size_t size) { for(i = 0; i < size; i++) { pfd[0].revents = 0; ready = poll_retry(pfd, 1, tcp_read_time_out); - if(ready != 1 || !(pfd[0].revents & POLLIN) || 1 != read(fd, &buff[i], 1)) + if(ready != 1 || !(pfd[0].revents & POLLIN) || 1 != true_read(fd, &buff[i], 1)) return -1; } return (int) size; @@ -934,7 +934,8 @@ int socksify_udp_packet(void* udp_data, size_t udp_data_len, udp_relay_chain cha // Append UDP data in the remaining space of the buffer - int min = (udp_data_len>(buffer_len-tmp_buffer_len))?(buffer_len-tmp_buffer_len):udp_data_len; + size_t min = (udp_data_len>(buffer_len-tmp_buffer_len))?(buffer_len-tmp_buffer_len):udp_data_len; + PDEBUG("test, min = %lu\n", min); memcpy(buffer + tmp_buffer_len, udp_data, min); *buffer_len = tmp_buffer_len + min; @@ -1628,7 +1629,7 @@ struct hostent* proxy_gethostbyname_old(const char *name) close(pipe_fd[1]); waitpid(pid, &status, 0); buff[0] = 0; - read(pipe_fd[0],&buff,sizeof(buff)); + true_read(pipe_fd[0],&buff,sizeof(buff)); close(pipe_fd[0]); got_buff: l = strlen(buff); diff --git a/src/core.h b/src/core.h index 88211fc..9014958 100644 --- a/src/core.h +++ b/src/core.h @@ -176,6 +176,8 @@ typedef ssize_t (*sendmsg_t) (int sockfd, const struct msghdr *msg, int flags); typedef int (*sendmmsg_t) (int sockfd, struct mmsghdr* msgvec, unsigned int vlen, int flags); typedef ssize_t (*recvmsg_t) (int sockfd, struct msghdr *msg, int flags); typedef int (*getpeername_t) (int sockfd, struct sockaddr *restrict addr, socklen_t *restrict addrlen); +typedef ssize_t (*read_t)(int fd, void* buf, size_t count); +typedef ssize_t (*write_t)(int fd, const void* buf, size_t count); extern connect_t true_connect; @@ -192,6 +194,8 @@ extern sendmsg_t true_sendmsg; extern sendmmsg_t true_sendmmsg; extern recvmsg_t true_recvmsg; extern getpeername_t true_getpeername; +extern read_t true_read; +extern write_t true_write; struct gethostbyname_data { struct hostent hostent_space; diff --git a/src/debug.c b/src/debug.c index 81ed643..9b6efc5 100644 --- a/src/debug.c +++ b/src/debug.c @@ -24,7 +24,7 @@ void dump_proxy_chain(proxy_data *pchain, unsigned int count) { void dump_buffer(unsigned char * data, size_t len){ printf("buffer_dump["); - for(int i=0; i #include +#include + + + #include "core.h" #include "common.h" @@ -72,6 +76,8 @@ sendmsg_t true_sendmsg; recvmsg_t true_recvmsg; sendmmsg_t true_sendmmsg; getpeername_t true_getpeername; +read_t true_read; +write_t true_write; int tcp_read_time_out; int tcp_connect_time_out; @@ -1080,6 +1086,8 @@ HOOKFUNC(ssize_t, sendto, int sockfd, const void *buf, size_t len, int flags, PDEBUG("target: %s\n", inet_ntop(v6 ? AF_INET6 : AF_INET, v6 ? (void*)p_addr_in6 : (void*)p_addr_in, str, sizeof(str))); PDEBUG("port: %d\n", port); PDEBUG("client socket: %d\n", sockfd); + PDEBUG("trying to send %lu bytes : ", len); + DUMP_BUFFER(buf, len); // check if connect called from proxydns remote_dns_connect = !v6 && (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet); @@ -1184,7 +1192,7 @@ HOOKFUNC(ssize_t, sendto, int sockfd, const void *buf, size_t len, int flags, return -1; } - int sent = 0; + ssize_t sent = 0; sent = true_sendto(sockfd, send_buffer, send_buffer_len, flags, (struct sockaddr*)(v6?(void*)&addr6:(void*)&addr), v6?sizeof(addr6):sizeof(addr)); if(sent == -1){ @@ -2094,6 +2102,40 @@ HOOKFUNC(ssize_t, send, int sockfd, const void *buf, size_t len, int flags){ return sendto(sockfd, buf, len, flags, (struct sockaddr*)&addr, addr_len); } + +HOOKFUNC(ssize_t, read,int fd, void* buf, size_t count){ + + // If fd is a socket, call recv() with no flags as it is equivalent to read() + // WARNING: As stated in https://man7.org/linux/man-pages/man2/recv.2.html in NOTES, + //"If a zero-length datagram is pending, read(2) and recv() with a + // flags argument of zero provide different behavior. In this + // circumstance, read(2) has no effect (the datagram remains + // pending), while recv() consumes the pending datagram." + + struct stat statbuf; + fstat(fd, &statbuf); + if(S_ISSOCK(statbuf.st_mode)){ + PDEBUG("hooked read() on a socket file descriptor, calling recv() with 0 flags\n"); + return recv(fd, buf, count, 0); + } + return true_read(fd, buf, count); +} + +HOOKFUNC(ssize_t, write, int fd, const void* buf, size_t count ){ + + PDEBUG("fd : %d, count: %zu, buf: %p\n", fd, count, buf); + DUMP_BUFFER(buf, count); + + // If fd is a socket, call send() with no flags as it is equivalent to write() + struct stat statbuf; + fstat(fd, &statbuf); + if(S_ISSOCK(statbuf.st_mode)){ + PDEBUG("hooked write() on a socket file descriptor, calling send() with 0 flags\n"); + return send(fd, buf,count, 0); + } + return true_write(fd, buf, count); +} + #ifdef MONTEREY_HOOKING #define SETUP_SYM(X) do { if (! true_ ## X ) true_ ## X = &X; } while(0) #define SETUP_SYM_OPTIONAL(X) @@ -2118,6 +2160,8 @@ static void setup_hooks(void) { SETUP_SYM(freeaddrinfo); SETUP_SYM(gethostbyaddr); SETUP_SYM(getnameinfo); + SETUP_SYM(write); + SETUP_SYM(read); #ifdef IS_SOLARIS SETUP_SYM(__xnet_connect); #endif