我试图编写一个简单的内核模块来在Linux中找到sys_call_table并且遇到了一些麻烦。我在这里找到了32位Linux的基本指南:https://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/。我试图将它改编为现代的64位内核并且遇到了一些麻烦。我的代码在这里:
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/errno.h>
#include<linux/types.h>
#include<linux/unistd.h>
#include<asm/current.h>
#include<linux/sched.h>
#include<linux/syscalls.h>
#include<linux/utsname.h>
//#include<asm/system.h>
#include<linux/slab.h>
MODULE_LICENSE("GPL");
#define START_MEM PAGE_OFFSET
#define END_MEM ULLONG_MAX
unsigned long long *syscall_table;
unsigned long long **find(void) {
unsigned long long **sctable;
unsigned long long int i = START_MEM;
while ( i < END_MEM) {
sctable = (unsigned long long **)i;
if ( sctable[__NR_close] == (unsigned long long *) sys_close) {
printk(KERN_WARNING "------%p---------\n", (unsigned long long *) sys_close);
return &sctable[0];
}
i += sizeof(void *);
}
return NULL;
}
static int __init init_load(void) {
syscall_table = (unsigned long long *) find();
if (syscall_table != NULL) {
printk(KERN_WARNING "syscall table found at %p\n", syscall_table);
}
else {
printk(KERN_WARNING "syscall table not found!");
}
return 0;
}
static void __exit exit_unload(void) {
return;
}
module_init(init_load);
module_exit(exit_unload);
我使用简单的makefile编译代码,没有警告或通知出现,这里是打印的内容(在修改后):
$ dmesg
<snip>
[39592.352209] ------ffffffff8120a2a0---------
[39592.352214] syscall table found at ffff880001a001c0
</snip>
所以一切似乎都合适吗?但是我通过运行来检查sys_call_table的位置:
punk@punk-vbox:~/dev/m-dev/rootkit-examples$ sudo cat /boot/System.map-4.4.0-36-generic | grep sys_call_table
ffffffff81a001c0 R sys_call_table
ffffffff81a01500 R ia32_sys_call_table
..意味着我的代码似乎完全错误地获取了sys_call_table的位置。所以ffff880001a001c0而不是ffffffff81a001c0。
我不完全确定从哪里开始调试。我在做一些明显不对的事吗?什么是我自己调试这个好的第一步?我是编写内核模块的新手,我们将不胜感激!
答案 0 :(得分:1)
您的内核可能已启用x32 compat。
这种内核中有两个sys_call_table
。 compat_sys_call_table(ia23_sys_call_table)
表示32位,sys_call_table
表示64位。他们使用相同的sys_close
。
您可能会在sys_close
中找到compat_sys_call_table
,但__NR_close
在32位unistd.h
和64位unistd.h
之间有所不同。您可能正在使用64位__NR_close
,因此无法正确获取compat_sys_call_table
或sys_call_table
。
您可以检查我的代码ASyScallHookFrame,它在Android内核3.10上运行正常。