Gcc 拦截GNU tar的openat()系统调用
我试图使用一个自定义共享库拦截Linux上的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
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