我一直在尝试在内核级别挂钩系统调用。我从这个问题中得到了基本的想法。我试图拦截的系统调用是fork()
. 所以我找到了sys_call_table
from的地址,System.map
原来是0xc12c9e90。现在我编写了如下模块。
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/unistd.h>
#include<linux/semaphore.h>
#include<asm/cacheflush.h>
MODULE_LICENSE("GPL");
void **sys_call_table;
unsigned long addr;
asmlinkage int (*original_call)(struct pt_regs);
asmlinkage int our_call(struct pt_regs regs)
{
printk("Intercepted sys_fork");
return original_call(regs);
}
static int __init p_entry(void)
{
struct page *pg;
printk(KERN_ALERT "Module Intercept inserted");
sys_call_table=(void *)0xc12c9e90;
pg=virt_to_page(sys_call_table);
addr=(unsigned long)page_address(pg);
set_memory_rw(addr,1);
original_call=sys_call_table[__NR_fork];
sys_call_table[__NR_fork]=our_call;
set_memory_ro(addr,1);
return 0;
}
static void __exit p_exit(void)
{
sys_call_table[__NR_fork]=original_call;
set_memory_ro(addr,1);
printk(KERN_ALERT "Module Intercept removed");
}
module_init(p_entry);
module_exit(p_exit);
我编译了模块并尝试将其插入内核。不幸的是,dmesg 输出给了我如下消息BUG:无法在 c12c9e98 处理内核分页请求,这是 ellaborate dmesg 输出
作为找出问题的实验,我只是将这一行注释掉了
sys_call_table[__NR_fork]=our_call;
之后我重复编译,然后插入。它没有显示任何错误。所以我得出结论,上面指定的将新函数分配给 sys_call_table 的行是问题所在。但我不知道是什么原因造成的以及如何解决它。任何人都可以帮我解决它吗?