linux-kernel模块(内核3.5)中的系统调用拦截 [英] System call interception in linux-kernel module (kernel 3.5)
本文介绍了linux-kernel模块(内核3.5)中的系统调用拦截的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我需要用自己的实现替换标准的系统调用(例如SYS_mkdir).
I need to replace a standard system call (e.g. SYS_mkdir) with my own implementation.
正如我在某些资料中所读到的,包括这个问题在Stackoverflow上,从内核版本2.6
开始,不会导出sys_call_table
符号.
As I read in some sources, including this question on Stackoverflow, the sys_call_table
is not exported symbol since kernel version 2.6
.
我尝试了以下代码:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <asm/syscall.h>
int (*orig_mkdir)(const char *path);
....
int init_module(void)
{
orig_mkdir=sys_call_table[__NR_mkdir];
sys_call_table[__NR_mkdir]=own_mkdir;
printk("sys_mkdir replaced\n");
return(0);
}
....
不幸的是,我收到编译器错误:
Unfortunately I receive compiler error:
error: assignment of read-only location ‘sys_call_table[83]’
如何替换系统调用?
编辑:有没有没有内核补丁的解决方案?
Is there any solution without kernel patching?
推荐答案
这对我有用.
请参阅 Linux内核:系统调用挂钩示例 和 https://bbs.archlinux.org/viewtopic.php?id=139406
asmlinkage long (*ref_sys_open)(const char __user *filename, int flags, umode_t mode);
asmlinkage long new_sys_open(const char __user *filename, int flags, umode_t mode)
{
return ref_sys_open(filename, flags, mode);
}
static unsigned long **aquire_sys_call_table(void)
{
unsigned long int offset = PAGE_OFFSET;
unsigned long **sct;
while (offset < ULLONG_MAX) {
sct = (unsigned long **)offset;
if (sct[__NR_close] == (unsigned long *) sys_close)
return sct;
offset += sizeof(void *);
}
print("Getting syscall table failed. :(");
return NULL;
}
// Crazy copypasted asm stuff. Could use linux function as well...
// but this works and will work in the future they say.
static void disable_page_protection(void)
{
unsigned long value;
asm volatile("mov %%cr0, %0" : "=r" (value));
if(!(value & 0x00010000))
return;
asm volatile("mov %0, %%cr0" : : "r" (value & ~0x00010000));
}
static void enable_page_protection(void)
{
unsigned long value;
asm volatile("mov %%cr0, %0" : "=r" (value));
if((value & 0x00010000))
return;
asm volatile("mov %0, %%cr0" : : "r" (value | 0x00010000));
}
static int __init rootkit_start(void)
{
//Hide me
print("loaded");
if(!(sys_call_table = aquire_sys_call_table()))
return -1;
disable_page_protection();
{
ref_sys_open = (void *)sys_call_table[__NR_open];
sys_call_table[__NR_open] = (unsigned long *)new_sys_open;
}
enable_page_protection();
return 0;
}
static void __exit rootkit_end(void)
{
print("exiting");
if(!sys_call_table) {
return;
}
disable_page_protection();
{
sys_call_table[__NR_open] = (unsigned long *)ref_sys_open;
}
enable_page_protection();
}
这篇关于linux-kernel模块(内核3.5)中的系统调用拦截的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文