在4.x.x内核中查找64位内存中的sys调用表

时间:2016-09-15 02:09:45

标签: c linux memory linux-kernel

我试图编写一个简单的内核模块来在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。

我不完全确定从哪里开始调试。我在做一些明显不对的事吗?什么是我自己调试这个好的第一步?我是编写内核模块的新手,我们将不胜感激!

1 个答案:

答案 0 :(得分:1)

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

  1. 这种内核中有两个sys_call_tablecompat_sys_call_table(ia23_sys_call_table)表示32位,sys_call_table表示64位。他们使用相同的sys_close

  2. 您可能会在sys_close中找到compat_sys_call_table,但__NR_close在32位unistd.h和64位unistd.h之间有所不同。您可能正在使用64位__NR_close,因此无法正确获取compat_sys_call_tablesys_call_table

  3. 您可以检查我的代码ASyScallHookFrame,它在Android内核3.10上运行正常。