编译钩子 LD_PRELOAD加载 拦截系统接口调用getaddrinfo 验证socks5和socks5h的区别
分析
感谢 Debian中文群的群友 提供信息 https://t.me/c/1039975886/766705
感谢233群的群友提供信息 https://t.me/tg233boy/1228524
我们知道了, gai.conf 控制的是 getaddrinfo 系统接口的行为
/etc/gai.conf
怎么证明某个程序调用了 getaddrinfo(被gai.conf控制) 呢?
钩子拦截系统接口调用
感谢Debian中文群的群友的灵感 https://t.me/c/1039975886/766779
gdb调试我不会, 但是我会编译啊.
我问了一下GPT, getaddrinfo的库是 libc.so.6
可以在这里面查找到 getaddrinfo 的符号, 如
nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep getaddrinfo
我本来想找到源码自己编译一份 libc.so.6 文件.
思路是不影响原有的getaddrinfo功能, 只是在命令行多打印一份日志.
这样就可以确定某个软件 是不是 调用了 getaddrinfo , 于是就受到 gai.conf 的控制 (IPv4优先 / IPv6优先).
我拿这个想法去问GPT. 回答超出我的预期.
GPT告诉我,
1. 最好不要替换系统库, 因为会影响整个系统.
2. 有办法可以针对 某个程序 挂个钩子. 在钩子 里监控 调用系统 getaddrinfo 的行为, 然后打印日志. 然后在钩子里原样 调用系统原本的 getaddrinfo, 不影响实际行为.
相关代码如下, 例如 hook_getaddrinfo.c
#define _GNU_SOURCE#include <stdio.h>#include <dlfcn.h>#include <netdb.h>int getaddrinfo(const char *node, const char *service,const struct addrinfo *hints, struct addrinfo **res) {static int (*real_getaddrinfo)(const char *, const char *,const struct addrinfo *, struct addrinfo **) = NULL;if (!real_getaddrinfo)real_getaddrinfo = dlsym(RTLD_NEXT, "getaddrinfo");fprintf(stderr, "[hook] getaddrinfo called: node=%s, service=%s\n",node ? node : "(null)", service ? service : "(null)");int ret = real_getaddrinfo(node, service, hints, res);fprintf(stderr, "[hook] getaddrinfo returned %d\n", ret);return ret;}
编译
gcc -shared -fPIC -O2 -Wall hook_getaddrinfo.c -o hook_getaddrinfo.so -ldl
使用方法
LD_PRELOAD=/root/hook_getaddrinfo.so 被钩的程序
如
LD_PRELOAD=/root/hook_getaddrinfo.so curl -x socks5://127.0.0.1:1080 api.myip.la
* 当然, 这里的/root/ 是我保存 .so 文件的位置, 你需要根据你的实际情况.
结果, 钩子在命令行打印日志, 说明curl调用了 getaddrinfo
而 socks5h 的用法
LD_PRELOAD=/root/hook_getaddrinfo.so curl -x socks5h://127.0.0.1:1080 api.myip.la
没有钩子的打印, 说明curl没有调用 getaddrinfo







评论
发表评论