Hooking getaddrinfo to Test IPv4 Priority on Debian 13

Preface

Group members reported that IPv4 priority cannot be set on Debian 13

Analysis

Thanks to the group members of the Debian Chinese group for providing the information https://t.me/c/1039975886/766705

Thanks to the group members of the 233 group for providing the information https://t.me/tg233boy/1228524

Now we know that gai.conf controls the behavior of the getaddrinfo system interface
/etc/gai.conf

How can we prove that a certain program calls getaddrinfo (controlled by gai.conf)? 

Hooking to intercept system interface calls

Thanks to the inspiration from the group members of the Debian Chinese group https://t.me/c/1039975886/766779

I don't know how to use gdb for debugging, but I know how to compile.
I asked GPT, and the library for getaddrinfo is libc.so.6
You can find the getaddrinfo symbol here, e.g.
nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep getaddrinfo

I originally wanted to find the source code and compile a copy of libc.so.6 myself.
The idea was to not affect the original getaddrinfo functionality, but just to print an additional log on the command line.
This way, we can determine whether a certain software calls getaddrinfo, and therefore is controlled by gai.conf (IPv4 priority / IPv6 priority).

I took this idea and asked GPT. The answer exceeded my expectations.
GPT told me, 
1. It's best not to replace the system library, because it will affect the entire system.
2. There is a way to hook a specific program. In the hook, monitor the behavior of calling the system getaddrinfo, and then print the log. Then call the original system getaddrinfo in the hook as-is, without affecting the actual behavior.

The relevant code is as follows, for example, hook_getaddrinfo.c
#define _GNU_SOURCE
#include
#include
#include

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;
}
Compile
gcc -shared -fPIC -O2 -Wall hook_getaddrinfo.c -o hook_getaddrinfo.so -ldl
Usage
LD_PRELOAD=/root/hook_getaddrinfo.so hooked program
e.g.
LD_PRELOAD=/root/hook_getaddrinfo.so curl -x socks5://127.0.0.1:1080 api.myip.la
* Of course, the /root/ here is the location where I saved the .so file, you need to adjust it according to your actual situation.

As a result, the hook prints the log on the command line, indicating that curl called getaddrinfo

And the usage of socks5h
LD_PRELOAD=/root/hook_getaddrinfo.so curl -x socks5h://127.0.0.1:1080 api.myip.la
There is no hook log output, indicating that curl did not call getaddrinfo

========

Related Recommendations


Comments