Linux内核 - 通过模块动态添加系统调用

时间:2010-03-07 03:03:28

标签: linux linux-kernel kernel kernel-module

有没有办法添加动态系统调用,比如通过模块?我已经找到了一些地方,我可以用模块覆盖现有的系统调用,只需更改sys_call_table[]数组,以便在安装我的模块时获取被覆盖的函数而不是本机,但是你可以用新的系统调用来完成还有一个模块?

3 个答案:

答案 0 :(得分:12)

不,sys_call_table具有固定大小:

const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { ... 

您可能已经发现的最好的办法是intercept现有的系统调用。

答案 1 :(得分:6)

Zach,是的,有可能:D

虽然sys_call_table的大小固定,但在某些情况下表中可能有空位

看这个链接:
lxr.free-electrons.com/source/arch/x86/kernel/syscall_32.c
lxr.free-electrons.com/source/arch/x86/kernel/syscall_64.c

  • 首先,内核使用指向sys_ni_syscall的指针填充sys_call_table的所有位置

  • 在编译时,文件 asm / syscalls_32.h asm / syscalls_64.h 是 根据以下表格生成:

lxr.free-electrons.com/source/arch/x86/syscalls/syscall_32.tbl
lxr.free-electrons.com/source/arch/x86/syscalls/syscall_64.tbl

简要回顾一下这些表格,你可以看到一些位置会继续 指向sys_ni_syscall,例如,在syscall_32.tbl中的位置17,21,32,35,... 因为它们没有实施。

因此,我们唯一的任务是识别这些位置并“注册”我们的新系统调用。

我在我的git上添加了类似的东西 https://github.com/MrN0body/rsysadd

答案 2 :(得分:0)

在某些情况下,拦截现有的系统调用(在内核中完成某些操作)并不是正确的方法。例如,如果您的用户空间驱动程序需要在内核中执行某些操作,在那里发送内容或从内核中读取内容?

通常对于驱动程序,正确的方法是使用ioctl()调用,这只是一个系统调用,但它可以调用不同的内核函数或驱动程序模块 - 通过ioctl()传递不同的参数。

以上是用户控制的内核代码执行。

对于数据传递,您可以使用procfs或sysfs驱动程序与内核通信。

PS:当你拦截通常会影响整个操作系统的系统调用时,你必须担心如何安全地解决这个问题:如果其他人正在中途调用系统调用,然后你修改/拦截怎么办?代码?