当前位置:  开发笔记 > 运维 > 正文

我怎么能拦截linux sys调用?

如何解决《我怎么能拦截linuxsys调用?》经验,为你挑选了3个好方法。

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



1> DJ Capelis..:

为什么不能/不想使用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 
#define _FCNTL_H
#include 
#include 
#include 

extern int errorno;

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

int open(const char * pathname, int flags, mode_t mode)
{
    if (NULL == _open) {
        _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)
{
    if (NULL == _open64) {
        _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方法是最好的方法,假设你的应用程序是相当标准的,并且实际上并不是那个恶意试图过去的方法你的拦截.(在这种情况下,您将需要其他技术之一.)


程序承认LD_PRELOAD完全是可选的.并非每个程序都与libc链接.
@ acib708我的意思是程序可以在不使用libc的情况下进行系统调用.然后正在加载的库实际上并不重要,因为没有调用它的符号.相反,设置寄存器和创建中断的一小段组件可以进行调用.

2> 小智..:

Valgrind可用于拦截任何函数调用.如果您需要拦截成品中的系统调用,那么这将是没有用的.但是,如果您在开发期间尝试拦截,那么它可能非常有用.我经常使用这种技术来拦截散列函数,以便我可以控制返回的散列以进行测试.

如果您不知道,Valgrind主要用于查找内存泄漏和其他与内存相关的错误.但底层技术基本上是一个x86模拟器.它模拟你的程序并拦截对malloc/free等的调用.好的是,你不需要重新编译就可以使用它.

Valgrind有一个功能,他们称之为功能包装,用于控制功能的拦截.有关详细信息,请参见Valgrind手册的第3.2节.您可以为任何您喜欢的功能设置功能包装.拦截调用后,将调用您提供的替代函数.



3> 小智..:

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

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

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

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

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有