本文介绍了拦截GNU tar的openat()系统调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在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()系统调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 05:39