10

我一直试图在内核级别拦截系统调用。我从这个问题中得到了基本的想法。我试图拦截的系统调用是fork()。所以我从 System.map 中找到了sys_fork()的地址,结果是 0xc1010e0c。现在我编写了如下模块。

#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;
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)
{
    printk(KERN_ALERT "Module Intercept inserted");
    sys_call_table=(void *)0xc1010e0c;
    original_call=sys_call_table[__NR_open];
    set_memory_rw((long unsigned int)sys_call_table,1);
    sys_call_table[__NR_open]=our_call;
    return 0;
}
static void __exit p_exit(void)
{
    sys_call_table[__NR_open]=original_call;
    set_memory_ro((long unsigned int)sys_call_table,1);
    printk(KERN_ALERT "Module Intercept removed");
}
module_init(p_entry);
module_exit(p_exit);

但是,在编译模块之后,当我尝试将其插入内核时,我从 dmesg 输出中得到了以下信息。 在此处输入图像描述 在此处输入图像描述

当然它没有拦截系统调用。你能帮我找出问题吗?我使用的是3.2.0-4-686版本的 Linux 内核。

4

3 回答 3

8

http://lxr.linux.no/linux+*/arch/x86/mm/pageattr.c#L874

            if (*addr & ~PAGE_MASK) {
                    *addr &= PAGE_MASK;
                    /*
                     * People should not be passing in unaligned addresses:
                     */
                    WARN_ON_ONCE(1);
            }

所以警告是因为你的sys_call_table变量不是页面对齐的。

应该说,内核维护人员正式不鼓励修补系统调用表,而且他们故意为您设置了一些障碍——您可能已经注意到您无法访问真正的sys_call_table符号,并且写入保护也是刻意的。如果您可能找到另一种方法来做您想做的事,那么您应该这样做。根据您更大的目标,您可能可以完全使用ptrace内核模块来完成它。trace_sched_process_fork钩子也可能有用。

于 2013-01-19T15:06:28.037 回答
2
original_call=sys_call_table[__NR_open];
....
sys_call_table[__NR_open]=our_call;

如果您正在拦截fork,则条目open不是您想要更改的。而不是 System.map 中 sys_fork() 的地址,您应该使用sys_call_table.

于 2013-01-19T15:01:53.277 回答
0

目前尚不清楚您是否解决了问题,但取决于您如何测试模块 glib 不再使用 sys_fork ,而是使用 sys_clone 。

于 2013-07-23T16:37:56.727 回答