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

发布于 2025-01-03 16:10:30 字数 1588 浏览 4 评论 0原文

我正在尝试使用可以通过 LD_PRELOAD 加载的自定义共享库来拦截 Linux 上的 openat() 系统调用。示例 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);
}

我通过 gcc -fPIC -Wall -shared -o拦截-openat.so拦截-openat.c -ldl 编译它。然后,当我运行这个小示例程序时:

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() 调用通过库重写:

$ 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.so 的自定义 openat() 不会被调用。这是为什么?

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);
}

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;
}

The openat() call is re-written via the library:

$ LD_PRELOAD=./intercept-openat.so ./openat 
intercepting openat()...

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

So the custom openat() from intercept-openat.so is not being called. Why is that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人海汹涌 2025-01-10 16:10:30

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

不管怎样,我认为你已经证明它永远不会动态链接函数名称“openat”。如果您仍然想使用此选项,您可能想看看它是否链接到该函数的特定版本,但这不太可能。

您仍然可以通过编写程序来使用 ptrace 来拦截系统调用。这与 strace 和 gdb 使用的接口相同。但它会带来更高的性能损失。

http://linux.die.net/man/2/ptrace

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.

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.

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.

http://linux.die.net/man/2/ptrace

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文