Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 拦截系统调用_C_Linux_Linux Kernel_Kernel Module_Kernel - Fatal编程技术网

C 拦截系统调用

C 拦截系统调用,c,linux,linux-kernel,kernel-module,kernel,C,Linux,Linux Kernel,Kernel Module,Kernel,我一直试图在内核级别拦截系统调用。我从中得到了基本的想法。我试图拦截的系统调用是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&

我一直试图在内核级别拦截系统调用。我从中得到了基本的想法。我试图拦截的系统调用是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);
#包括
#包括
#包括
#包括
#包括
模块许可证(“GPL”);
作废**系统调用表;
ASMINT(*原始调用)(结构参数寄存器);
ASMINT our_调用(struct pt_regs regs)
{
printk(“截获的系统分叉”);
返回原始通话(regs);
} 
静态int\u初始p\u条目(void)
{
printk(插入模块拦截的内核警报);
系统调用表=(void*)0xc1010e0c;
原始调用=系统调用表[\uuuu NR\u open];
set_memory_rw((长无符号整数)sys_call_table,1);
系统调用表[\uuuu NR\u open]=我们的调用;
返回0;
}
静态无效uu退出p_退出(无效)
{
系统调用表[\uuuuu NR\u open]=原始调用;
设置内存表((长无符号整数)系统调用表,1);
printk(内核警报“模块拦截已删除”);
}
模块初始化(p_条目);
模块_出口(p_出口);
然而,在编译模块之后,当我试图将其插入内核时,我从dmesg输出中得到了以下信息。

当然不是拦截系统调用。你能帮我解决问题吗?我使用的是3.2.0-4-686版本的Linux内核

original_call=sys_call_table[__NR_open];
....
sys_call_table[__NR_open]=our_call;
如果您正在拦截
fork
,则
open
的条目不是您想要更改的内容。 您应该使用
sys\u call\u table
的地址,而不是System.map中sys\u fork()的地址

因此,警告是因为
sys\u call\u table
变量未对齐页面


应该说,内核维护人员官方不鼓励修补系统调用表,他们故意给您设置了一些障碍——您可能已经注意到,您无法访问真正的
sys\u call\u table
符号,写保护也是故意的。如果你能找到另一种方法去做你想做的事,那么你应该这样做。根据您更大的目标,您可能可以使用而不使用任何内核模块来完成它。
trace\u sched\u process\u fork
钩子也可能有用。

不清楚您是否解决了问题,但取决于您测试模块的方式,glib不再使用sys\u fork,而是使用sys\u clone。

是的。但是(刚刚编辑了答案)您应该使用sys_call_table的地址来初始化sys_call_table指针,而不是sys_fork的原始地址。当然,我犯了一个错误,使用了u NR_open而不是u NR_fork。但问题似乎并没有就此结束。现在我不确定将set_memeory_rw()应用于sys_call_表的有效性。这需要进一步调查。有什么意见吗?
            if (*addr & ~PAGE_MASK) {
                    *addr &= PAGE_MASK;
                    /*
                     * People should not be passing in unaligned addresses:
                     */
                    WARN_ON_ONCE(1);
            }