在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。

我不完全确定从哪里开始调试。我在这里做了明显错误的事吗?这对我自己来说是一个很好的第一步调试?我对编写内核模块相当陌生,不胜感激!

+0

因为你发现了一个不是sys_call_table的地方,它也有sys_close的地址。 – immibis

+0

所以在内存中恰好有__NR_CLOSE的正确偏移量?这似乎不太可能或我错过了@immibis?在我看来,我可能会错误地在某个地方解引用指针? – user6833363

+0

是的。你在内存中发现了另一个恰好在__NR_close偏移处有sys_close的地方。 – immibis

您的内核可能启用了x32 compat。

  1. 在这种内核中有两个sys_call_table s。对于32位为compat_sys_call_table(ia23_sys_call_table),对于64位为sys_call_table。他们使用相同的sys_close

  2. 您可能会发现compat_sys_call_tablesys_close,但__NR_close是32位unistd.h和64位unistd.h不同。您可能正在使用64位__NR_close,因此您无法正确获取compat_sys_call_tablesys_call_table

您可以检查我的代码,ASyScallHookFrame,它在Android内核3.10上正常工作。