在 Ubuntu 和 CentOS 上通过 LD_PRELOAD 挂钩库函数时的行为差异

在 Ubuntu 和 CentOS 上通过 LD_PRELOAD 挂钩库函数时的行为差异

有一个钩子函数socketHook.c拦截插座()呼叫:

#include <stdio.h>
int socket(int domain, int type, int protocol)
{
    printf("socket() has been intercepted!\n");
    return 0;
}
gcc -c -fPIC socketHook.c
gcc -shared -o socketHook.so socketHook.o

和一个简单的程序获取pwuid.c(1) 仅仅调用获取pwuid()功能:

#include <pwd.h>

int main()
{
    getpwuid(0);
    return 0;
}
gcc getpwuid.c -o getpwuid

获取pwuid()内部做了一个插座()称呼。在 CentOS 上:

$ strace -e trace=socket ./getpwuid
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
socket(AF_UNIX, SOCK_STREAM, 0)         = 4

在Ubuntu上:

$ strace -e trace=socket ./getpwuid
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5

当运行(1)时,插座()在 CentOS 上被拦截,但在 Ubuntu 上则不会。

CentOS。 打印()socketHook.c存在:

$ uname -a
Linux centos-stream 4.18.0-301.1.el8.x86_64 #1 SMP Tue Apr 13 16:24:22 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

$ LD_PRELOAD=$(pwd)/socketHook.so ./getpwuid
socket() has been intercepted!

乌班图(Xubuntu 20.04)。打印()socketHook.c不存在:

$ uname -a
Linux ibse-VirtualBox 5.8.0-50-generic #56~20.04.1-Ubuntu SMP Mon Apr 12 21:46:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

$ LD_PRELOAD=$(pwd)/socketHook.so ./getpwuid
$

所以我的问题是:

  1. 它取决于什么?我认为这受到以下事实的影响插座()不是直接从可执行文件调用,而是从 getpwuid() 调用,如果我理解正确的话,它又从 libc.so 调用
  2. 如何在 CentOS 中实现与 Ubuntu 中相同的行为?我不想拦截来自 libc 的间接调用

相关内容