在不修改内核的情况下拦截系统调用的最小开销方式 [英] Minimal overhead way of intercepting system calls without modifying the kernel

查看:18
本文介绍了在不修改内核的情况下拦截系统调用的最小开销方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  1. 使用ptrace,但这似乎有很高的开销。据我所知,像strace这样的工具也在内部使用ptrace。
  2. 使用内核模块更改系统调用表,但据我所知,这种方法在以后的Linux内核中不再可行。
  3. 使用LD_PRELOAD。但是,例如,如果您直接进行系统调用,而没有为该系统调用使用某些包装库函数,则这将不起作用。

所以您可以看到上面提到的所有方法都有缺陷。因此,我的问题是,在不修改内核的情况下以最小的开销拦截系统调用的方法是什么。

推荐答案

如果不能修改内核,则必须修改应用程序。您需要以某种方式拦截int/syscall/sysenter指令,方法是在那里设置一个断点(如果您可以在Linux中的应用程序中处理它们;您可以在Windows中使用SEH/VEH)或通过以更具侵入性的方式挂钩指令(将其更改为jmp到将获得保存系统调用号和参数的代码,执行原始int/syscall/sysenterjmpBack)。

编辑:哦,我忘了补充一句,查找这些说明可能是一项挑战。您可能无法在编译后的二进制文件中正确识别它们。您可能会遗漏一些代码(尤其是在运行时创建的代码),并且您可以使用其他一些int/syscall/sysenter的指令(如果您的代码分析不够完美)。在运行时找到它们(通过在执行/模拟它们之前分析单个指令(或它们的块))将导致性能损失。

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

这篇关于在不修改内核的情况下拦截系统调用的最小开销方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆