问题描述
我试图在Linux上使用自定义共享库来拦截Linux上的 openat()
系统调用,我可以通过 LD_PRELOAD
。例如 intercept-openat.c
包含以下内容:
I'm trying to intercept the openat()
system call on Linux using a custom shared library that I can load via LD_PRELOAD
. An example intercept-openat.c
has this content:
#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);
}
我通过 gcc -fPIC -Wall - shared -o intercept-openat.so intercept-openat.c -ldl
。然后,当我运行这个小例子程序:
I compile it via gcc -fPIC -Wall -shared -o intercept-openat.so intercept-openat.c -ldl
. Then, when I run this small example program:
int main(int argc, char *argv[])
{
int fd;
fd = openat(AT_FDCWD, "/home/feh/.vimrc", O_RDONLY);
if(fd == -1)
return -1;
close(fd);
return 0;
}
openat()
调用通过库重新写入:
The openat()
call is re-written via the library:
$ LD_PRELOAD=./intercept-openat.so ./openat
intercepting openat()...
然而,GNU tar也不会发生这种情况,即使它使用相同的系统调用:
However, the same does not happen with GNU tar, even though it uses the same system call:
$ 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
所以从自定义
没有被调用。为什么会这样? openat()
intercept-openat.so
So the custom openat()
from intercept-openat.so
is not being called. Why is that?
推荐答案
它使用相同的系统调用,但显然它不会通过相同的C函数调用它。或者,它可能是它的,但它是静态链接的。
It uses the same system call, but apparently it does not call that via the same C function. Alternatively, it could be that it does, but it's statically linked.
无论如何,我认为你已经证明它永远不会动态链接一个函数名称openat。如果你仍然想追求这个选择,你可能想看看它是否与该功能的特定版本相关联,但这是一个长镜头。
Either way, I think you've proved that it never dynamically links a function names "openat". If you still want to pursue this option, you might like to see if it links against a specific version of that function, but that's a long shot.
您仍然可以通过编写程序来拦截系统调用,以使用 ptrace
。这是strace和gdb使用的接口。尽管它会有更高的性能损失。
You can still intercept the system call by writing your program to use ptrace
. This is the same interface used by strace and gdb. It will have a higher performance penalty though.
这篇关于拦截GNU tar的openat()系统调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!