c - 在 4.x.x 内核的 64 位内存中查找系统调用表

标签 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 编译代码,没有出现警告或通知,这是打印的内容(在 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。

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

  2. 您可能会找到 sys_closecompat_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/

相关文章:

c - 两个进程写入共享内存

linux - 通过 ssh 传递外部 shell 脚本变量

c - 有没有办法用头文件打包C库

c - 将结构写入c中的文件

c - 正确使用 malloc()

linux - pthread_cancel 和取消点

linux - Linux中的tty和vty有什么区别

memory - WinDbg MEM_COMMIT 为 1GB,eeheap 显示为 150MB,找不到剩余内存

C : pointer and union and address

c - 将错误写入文件