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

标签 c linux gcc x86-64 system-calls

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

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

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

最佳答案

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

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

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

关于c - 在不修改内核的情况下拦截系统调用的最小开销方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11291632/

相关文章:

c - 在 C 中,如何附加到文件行而不是文件末尾?

linux - 带反引号的远程 shell 命令的退出状态

gcc - gcc FLTK编译错误

c - 当计算结果为 0 的整数枚举用作指针时,gcc 是否应该发出警告?

C 程序没有打印我所期望的

c - 了解 printf 吗?

c - 尝试通过拦截文件系统调用在 linux 中使用 readlink 从 fd 获取文件名,但它不起作用

python - IPython 键盘中断 CTRL + C 不一致

linux - checkpatch.pl 标记八进制权限错误

c++ - 递归push_back不适用于自定义类