我正在编写内核模块,我需要劫持/包装一些sys调用。我蛮力强制sys_call_table地址,我正在使用cr0来禁用/启用页面保护。到目前为止一切都很好(一旦完成,我会公开整个代码,所以如果有人想要我可以更新这个问题。)
无论如何,我注意到如果我劫持__NR_sys_read
,当我卸载内核模块时,我会得到一个内核oops,并且所有konsoles(KDE)都会崩溃。请注意,__NR_sys_open
或__NR_sys_write
不会发生这种情况。
我想知道为什么会这样。有什么想法吗?
PS:请不要采用KProbes方式,我已经了解它并且我无法使用它,因为最终产品应该可以使用,而无需重新编译整个内核。编辑 :(添加信息)
我在卸载之前恢复原始功能。另外,我创建了两个测试用例,一个仅使用_write
,另一个使用_read
。 _write
卸载正常,但_read
卸载然后崩溃内核的那个。)
编辑 :(源代码)
我目前在家,因此我现在无法发布源代码,但如果有人想要,我可以在上班后立即发布示例代码。 (~5小时)
答案 0 :(得分:5)
这可能是因为内核线程当前位于read
内 - 如果调用您的read-hook没有锁定模块,则无法安全卸载。
这可以解释" konsoles" (?)崩溃,因为他们当前正在执行read
系统调用,等待数据。当他们从实际的系统调用返回时,他们将跳到您的函数曾经的位置,从而导致问题。
卸载会很麻烦,但你需要先删除钩子,然后等待所有调用者退出钩子函数,然后卸载模块。
我最近一直在玩linux系统调用,但我绝不是一个内核专家,所以如果这是非基础,我会道歉。
PS: This technique可能比强制执行sys_call_table更可靠。我已经看到的蛮力技术如果sys_close
已被钩住,往往会引起内核恐慌。