为啥某些 Linux x86_64 系统调用需要存根?

Posted

技术标签:

【中文标题】为啥某些 Linux x86_64 系统调用需要存根?【英文标题】:Why do certain Linux x86_64 system calls require a stub?为什么某些 Linux x86_64 系统调用需要存根? 【发布时间】:2014-07-07 04:51:15 【问题描述】:

如果有人试图通过sys_call_table-hooking 来挂钩某些系统调用,例如sys_execve 这将失败,因为它们被存根间接调用。对于sys_execve,这是stub_execve(比较LXR 上的汇编代码)。

但是这些存根有什么用呢?为什么只有像execve(2)fork(2) 这样的某些系统调用需要存根,它是如何连接到x86_64 的?是否有解决方法来挂钩存根系统调用(在可加载内核模块中)?

【问题讨论】:

从这个文件的顶部开始 lxr.free-electrons.com/source/arch/x86/kernel/entry_64.S Normal syscalls and interrupts don't save a full stack frame, this is only done for syscall tracing, signals or fork/exec et.al. 。所以基本上答案是:考虑到这个函数在跟踪和调试中发挥的关键作用,我们需要在每个事件期间保存和查看尽可能多的寄存器。 courses.cms.caltech.edu/cs124/lectures/CS124Lec09.pdf 幻灯片 21 和 22 清楚地介绍了大多数操作系统中的这个存根,基本上,Allows the OS’ interrupt service routines to be more uniformOSes frequently use short stubs of assembly code to invoke their interrupt service routines (ISRs) ~ 这张幻灯片对我有很大帮助,希望对你有帮助: ) 【参考方案1】:

来自here,它说:

“某些特殊的系统调用需要保存完整的完整堆栈帧。”

我认为 execve 只是这些特殊系统调用之一。

来自stub_execve的代码,如果你想hook它,至少你可以试试:

    了解这些汇编代码的含义并自己动手,然后您可以在自己的汇编代码中调用自己的函数。 从汇编代码中间,有一个call sys_execve,你可以把sys_execve的地址替换成你自己的hook函数。

【讨论】:

第一个链接现已断开。

以上是关于为啥某些 Linux x86_64 系统调用需要存根?的主要内容,如果未能解决你的问题,请参考以下文章

x86_64 汇编 Linux 系统调用混淆

x86_64 Linux 上定义的 ioctl 系统调用的用户空间包装器在哪里?

Linux系统调用表(x86_64)

为啥 linux multiarch 使用 x86_64-linux-gnu 而不是 lib64?

LINUX系统调用

为啥我的 C++/QT 应用程序在 Linux x86_64 上的 nanosleep() 中崩溃?