在4.x.x内核中找到64位内存的系统调用表内核
我试图编写一个简单的内核模块来在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位内核,并遇到一些麻烦。我的代码是在这里:在4.x.x内核中找到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的是通过运行:
[email protected]:~/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
..meaning我的代码看似得到sys_call_table的完全错误的位置。所以ffff880001a001c0而不是ffffffff81a001c0。
我不完全确定从哪里开始调试。我在这里做了明显错误的事吗?这对我自己来说是一个很好的第一步调试?我对编写内核模块相当陌生,不胜感激!
您的内核可能启用了x32 compat。
在这种内核中有两个
sys_call_table
s。对于32位为compat_sys_call_table(ia23_sys_call_table)
,对于64位为sys_call_table
。他们使用相同的sys_close
。您可能会发现
compat_sys_call_table
sys_close
,但__NR_close
是32位unistd.h
和64位unistd.h
不同。您可能正在使用64位__NR_close
,因此您无法正确获取compat_sys_call_table
和sys_call_table
。
您可以检查我的代码,ASyScallHookFrame,它在Android内核3.10上正常工作。
因为你发现了一个不是sys_call_table的地方,它也有sys_close的地址。 – immibis
所以在内存中恰好有__NR_CLOSE的正确偏移量?这似乎不太可能或我错过了@immibis?在我看来,我可能会错误地在某个地方解引用指针? – user6833363
是的。你在内存中发现了另一个恰好在__NR_close偏移处有sys_close的地方。 – immibis