有没有办法添加动态系统调用,比如通过模块?我已经找到了一些地方,我可以用模块覆盖现有的系统调用,只需更改sys_call_table[]
数组,以便在安装我的模块时获取被覆盖的函数而不是本机,但是你可以用新的系统调用来完成还有一个模块?
答案 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:当你拦截通常会影响整个操作系统的系统调用时,你必须担心如何安全地解决这个问题:如果其他人正在中途调用系统调用,然后你修改/拦截怎么办?代码?