如何截获linux sys调用?

时间:2020-03-05 18:55:16  来源:igfitidea点击:

除了LD_PRELOAD技巧和用我们提供的系统调用替换了某个系统调用的Linux内核模块外,是否有可能拦截一个系统调用(例如打开),以便它在实际打开之前首先通过函数?

解决方案

回答

我们为什么/不想使用LD_PRELOAD技巧?

此处的示例代码:

/*
 * File: soft_atimes.c
 * Author: D.J. Capelis
 *
 * Compile:
 * gcc -fPIC -c -o soft_atimes.o soft_atimes.c
 * gcc -shared -o soft_atimes.so soft_atimes.o -ldl
 *
 * Use:
 * LD_PRELOAD="./soft_atimes.so" command
 *
 * Copyright 2007 Regents of the University of California
 */

#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>

extern int errorno;

int (*_open)(const char * pathname, int flags, ...);
int (*_open64)(const char * pathname, int flags, ...);

int open(const char * pathname, int flags, mode_t mode)
{
    _open = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
    if(flags & O_CREAT)
        return _open(pathname, flags | O_NOATIME, mode);
    else
        return _open(pathname, flags | O_NOATIME, 0);
}

int open64(const char * pathname, int flags, mode_t mode)
{
    _open64 = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
    if(flags & O_CREAT)
        return _open64(pathname, flags | O_NOATIME, mode);
    else
        return _open64(pathname, flags | O_NOATIME, 0);
}

据我了解...这几乎是LD_PRELOAD技巧或者内核模块。除非我们想在一个模拟器中运行它,否则它不会有很多中间立场,因为它可以捕获到函数中,或者对实际的二进制代码进行代码重写以捕获到函数中。

假设我们不能修改程序并且不能(或者不想)修改内核,则LD_PRELOAD方法是最好的方法,假设应用程序是相当标准的,并且实际上并不是恶意地试图超越拦截。 (在这种情况下,我们将需要其他技术之一。)

回答

如果我们确实需要解决方案,则可能对完成此任务的DR rootkit感兴趣,请访问http://www.immunityinc.com/downloads/linux_rootkit_source.tbz2,有关该文章的文章位于http://www.theregister.co。 uk / 2008/09/04 / linux_rootkit_released /

回答

我没有语法可以通过LKM轻松地做到这一点,但是本文提供了我们需要做的很好的概述:http://www.linuxjournal.com/article/4378

我们也可以只修补sys_open函数。从linux-2.6.26开始,它从file / open.c的第1084行开始。

我们可能还会看到,如果不需要构建新系统,是否可以使用inotify,systemtap或者SELinux为我们完成所有这些日志记录。

回答

Valgrind可用于拦截任何函数调用。如果我们需要在最终产品中拦截系统调用,则将无济于事。但是,如果我们尝试在开发过程中进行拦截,那么它可能会非常有用。我经常使用这种技术来拦截哈希函数,以便可以控制返回的哈希值以进行测试。

如果我们不知道,Valgrind主要用于查找内存泄漏和其他与内存相关的错误。但是底层技术基本上是x86仿真器。它模拟程序并拦截对malloc / free等的调用。好处是,我们无需重新编译即可使用它。

Valgrind具有一个称为功能包装的功能,该功能用于控制功能的拦截。有关详细信息,请参见Valgrind手册的3.2节。我们可以为任何喜欢的功能设置功能包装。呼叫被拦截后,便会调用我们提供的替代功能。

回答

如果只想查看打开的内容,则需要查看ptrace()函数或者命令行strace实用程序的源代码。如果我们实际上想拦截该调用,也许想使其执行其他操作,那么我认为我们列出的LD_PRELOAD或者内核模块选项是我们唯一的选择。

回答

如果仅出于调试目的而做,请查看strace,它位于ptrace(2)系统调用的顶部,可让我们在完成系统调用后挂接代码。请参见手册页的PTRACE_SYSCALL部分。

回答

某些应用程序可以欺骗strace / ptrace不运行,因此我唯一真正的选择是使用systemtap

如果需要,由于其通配符匹配,Systemtap可以拦截大量系统调用。 Systemtap不是C,而是一种独立的语言。在基本模式下,systemtap应该可以防止我们做愚蠢的事情,但是它也可以在"专家模式"下运行,如果需要,它可以退回到允许开发人员使用C的位置。

它不需要修补内核(至少不需要修补),并且一旦编译了模块,就可以从测试/开发盒中复制它,并将其插入(通过insmod)在生产系统上。

我还没有找到一个Linux应用程序,该应用程序已经找到解决/避免被systemtap捕获的方法。