我编写了一个系统调用函数并使用内核模块对其进行了测试。
这是我的程序:
sudo insmod mod.ko
首先,我发现数字 336 可用于系统调用,因此我使用 336 作为偏移量,将我的函数挂钩到 sys_call_table 中:
static int __init init_addsyscall(void)
{
printk("My syscall is starting...\n");
sys_call_table = (unsigned long *)0xffffffffaae002c0;
printk("sys_call_table: 0x%p\n", sys_call_table);
anything_saved = (int(*)(void))(sys_call_table[__NR_syscall]); /* save original one */
orig_cr0 = clear_and_return_cr0(); /* make cr0 writable */
sys_call_table[__NR_syscall] = (unsigned long)&sys_mycall; /* change function pointer */
setback_cr0(orig_cr0); /* recover cr0 */
return 0;
}
我的系统调用是:
asmlinkage long sys_mycall(unsigned long long num)
{
printk("my call, num = %llu", num);
if (num % 2 == 0)
return num % 1000000;
else
return num % 100000;
}
我的测试c文件:
// t.c
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("%d\n",syscall(336, 19030123456));
return 0;
}
预计 t.c
会打印 123456
,但它会打印一个随机数。我曾多次尝试运行此测试函数,但每次都得到不同的返回值。我使用sudo dmesg
查看日志,可以确定我的系统调用被调用了,并且系统调用的参数也不是我的输入。参数更有可能是一个随机数...
[ 9444.176815] My syscall is starting...
[ 9444.176825] sys_call_table: 0x000000002dac30a7
[ 9448.550544] my call, num: 18446667112225996632
[ 9449.256182] my call, num: 18446667112224440152
[ 9449.966801] my call, num: 18446667112225046360
[ 9453.252192] my call, num: 18446667112225177432
[ 9455.373322] my call, num: 18446667112225308504
我是初学者,我不确定这里发生了什么,但可以确定哪些信息是分析所必需的。如果您需要更多详细信息,请告诉我。