c - 拦截系统调用时无法处理 X 处的内核分页请求

标签 c linux kernel-module kernel

<分区>

Possible Duplicate:
Linux Kernel: System call hooking example

我一直在尝试在内核级别 Hook 系统调用。我从这个 question 得到了基本的想法.我试图拦截的系统调用是fork()。所以我从System.map中找到了sys_call_table的地址,结果是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:unable to handle kernel paging request at c12c9e98 这是详细的 dmesg 输出把

enter image description here enter image description here

作为找出问题的实验,我简单地注释掉了这一行

 sys_call_table[__NR_fork]=our_call;

之后我重复了编译和插入,并没有出现任何错误。所以我得出结论,上面指定的将新函数分配给 sys_call_table 的行是问题所在。但我不知道是什么原因造成的,也不知道如何解决。谁能帮我解决一下?

最佳答案

我希望你对 set_memory_rw 的调用不会生效,因为你没有使用 flush_tlb,所以当你写入时,CPU 的 TLB 仍然处于事件状态syscall_table 生效。您需要刷新 TLB。您或许可以使用 local_flush_tlb()

关于c - 拦截系统调用时无法处理 X 处的内核分页请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14425410/

相关文章:

linux-kernel - 如何在 Linux 内核模块中获取电池电量?

c - 为什么我的 hello world 驱动程序模块不打印任何内容?

使用 fork() 创建进程树,然后对它们进行编号并将其显示在数组中

c - 是否可以让 Gyp 生成预(或后)构建步骤?

conio.h 的 C 处理器错误

c - 缓冲区及其与函数的交互?

c - 与 gcc 链接时 Solaris 和 GNU/Linux 之间的 lpthread 库差异

PHP - 限制套接字连接时间

linux - 使用 dd 转储映射缓冲区

c - 为什么 X 在此代码中未定义?