劫持sys调用

时间:2013-04-08 11:37:21

标签: c linux kernel kernel-module system-calls

我正在编写内核模块,我需要劫持/包装一些sys调用。我蛮力强制sys_call_table地址,我正在使用cr0来禁用/启用页面保护。到目前为止一切都很好(一旦完成,我会公开整个代码,所以如果有人想要我可以更新这个问题。)

无论如何,我注意到如果我劫持__NR_sys_read,当我卸载内核模块时,我会得到一个内核oops,并且所有konsoles(KDE)都会崩溃。请注意,__NR_sys_open__NR_sys_write不会发生这种情况。

我想知道为什么会这样。有什么想法吗?

PS:请不要采用KProbes方式,我已经了解它并且我无法使用它,因为最终产品应该可以使用,而无需重新编译整个内核。

编辑 :(添加信息)

我在卸载之前恢复原始功能。另外,我创建了两个测试用例,一个仅使用_write,另一个使用_read_write卸载正常,但_read卸载然后崩溃内核的那个。)

编辑 :(源代码)

我目前在家,因此我现在无法发布源代码,但如果有人想要,我可以在上班后立即发布示例代码。 (~5小时)

1 个答案:

答案 0 :(得分:5)

这可能是因为内核线程当前位于read内 - 如果调用您的read-hook没有锁定模块,则无法安全卸载。

这可以解释" konsoles" (?)崩溃,因为他们当前正在执行read系统调用,等待数据。当他们从实际的系统调用返回时,他们将跳到您的函数曾经的位置,从而导致问题。

卸载会很麻烦,但你需要先删除钩子,然后等待所有调用者退出钩子函数,然后卸载模块。

我最近一直在玩linux系统调用,但我绝不是一个内核专家,所以如果这是非基础,我会道歉。

PS: This technique可能比强制执行sys_call_table更可靠。我已经看到的蛮力技术如果sys_close已被钩住,往往会引起内核恐慌。