我正在尝试编写一个简单的内核模块来查找 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 编译代码,没有出现警告或通知,这是打印的内容(在 insmod-ing 之后):
$ 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。
我不完全确定从哪里开始调试它。我在这里做错了什么吗?我自己调试这个的第一步是什么?我是编写内核模块的新手,如有任何帮助,我将不胜感激!
最佳答案
您的内核可能启用了 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 上运行良好。
关于c - 在 4.x.x 内核的 64 位内存中查找系统调用表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39502198/