Gcc 拦截GNU tar的openat()系统调用

Gcc 拦截GNU tar的openat()系统调用,gcc,system-calls,libc,intercept,ld-preload,Gcc,System Calls,Libc,Intercept,Ld Preload,我试图使用一个自定义共享库拦截Linux上的openat()系统调用,我可以通过LD\u PRELOAD加载该库。示例intercept openat.c包含以下内容: #define _GNU_SOURCE #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <dlfcn.h> int (*_orig

我试图使用一个自定义共享库拦截Linux上的
openat()
系统调用,我可以通过
LD\u PRELOAD
加载该库。示例
intercept openat.c
包含以下内容:

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <dlfcn.h>

int (*_original_openat)(int dirfd, const char *pathname, int flags, mode_t mode);

void init(void) __attribute__((constructor));
int openat(int dirfd, const char *pathname, int flags, mode_t mode);

void init(void)
{
        _original_openat = (int (*)(int, const char *, int, mode_t))
                dlsym(RTLD_NEXT, "openat");
}

int openat(int dirfd, const char *pathname, int flags, mode_t mode)
{
        fprintf(stderr, "intercepting openat()...\n");
        return _original_openat(dirfd, pathname, flags, mode);
}
通过库重新写入
openat()
调用:

$ LD_PRELOAD=./intercept-openat.so ./openat 
intercepting openat()...
但是,即使GNU tar使用相同的系统调用,也不会发生同样的情况:

$ strace -e openat tar cf /tmp/t.tgz .vimrc  
openat(AT_FDCWD, ".vimrc", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC) = 4
$ LD_PRELOAD=./intercept-openat.so tar cf /tmp/t.tgz .vimrc

因此,
intercept openat中的自定义
openat()
。因此,
未被调用。为什么会这样?

它使用相同的系统调用,但显然它没有通过相同的C函数调用。或者,也可能是这样,但它是静态链接的

不管怎样,我想你已经证明了它从来不会动态链接函数名“openat”。如果您仍然希望继续使用此选项,您可能希望查看它是否与该函数的特定版本相链接,但这是一个长期目标

您仍然可以通过编写程序以使用
ptrace
来拦截系统调用。这与strace和gdb使用的接口相同。不过,它将受到更高的性能惩罚


谢谢你为我指明了正确的方向
tar
似乎从不调用库函数
openat()
。相反,它使用了
\uu openat_2()
(不管是什么)。因此,如果我添加这一行,上面的代码将适用于示例程序和GNU tar:
int\uu openat_2(int dirfd,const char*pathname,int flags,mode\u t mode)\uu属性(别名(“openat”)
使得
\uuu openat_2
openat
的别名。此外,执行此任务的正确工具似乎是
ltrace
(如库调用跟踪)。
$ strace -e openat tar cf /tmp/t.tgz .vimrc  
openat(AT_FDCWD, ".vimrc", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC) = 4
$ LD_PRELOAD=./intercept-openat.so tar cf /tmp/t.tgz .vimrc