在不修改内核的情况下拦截系统调用的最小开销方式

我知道拦截系统调用的方法如下。

  • 使用ptrace,但这似乎有很高的开销。 据我所知,像strace这样的工具在内部也使用ptrace。
  • 使用内核模块来更改系统调用表,但据我所知,这种方法在以后的Linux内核中不再可能。
  • 使用LD_PRELOAD。 但是,如果您直接进行系统调用而不使用该系统调用的某些包装库函数,则这将不起作用。
  • 所以你看到上面提到的所有方法都有缺陷。 所以我的问题是如何在不修改内核的情况下拦截系统调用,并且开销最小。


    如果你不能修改内核,你必须修改应用程序。 你需要以某种方式拦截int / syscall / sysenter指令,或者通过在那里设置一个断点(如果你可以在Linux的应用程序中处理它们,你可以在Windows中通过使用SEH / VEH),或者通过在更多(将其更改为jmp以获取保存系统调用编号和参数的代码,执行原始的int / syscall / sysenterjmp )。

    编辑 :哦,我忘了补充说,发现这些说明可以是一个挑战。 您可能无法在编译的二进制文件中正确识别它们。 你可能会错过一些(尤其是那些在运行时创建的),你可以为int / syscall / sysenter (如果你的代码分析不完美)采取一些其他的指令。 OTOH在运行时发现它们(通过在执行/仿真它们之前分析单独的指令(或它们的块))将会导致性能下降。

    在任何情况下,性能问题很可能与正在进行的系统调用次数以及记录/跟踪信息的数量直接相关。 如果你减少它(即只选择感兴趣的系统调用和参数)和/或仅收集关于最近10000次系统调用的信息,并将数据保存在内存中并将其仅保存到文件一次(最后的应用程序),你会有更好的表现。


    查看使用动态检测框架,例如DTrace或SystemTap。 一个或两个应该可用于您的平台。


    Pintool也可能有所帮助; 它也适用于Linux。

    链接地址: http://www.djcxy.com/p/66367.html

    上一篇: Minimal overhead way of intercepting system calls without modifying the kernel

    下一篇: Perl file processing on SHIFT