在4.x.x内核的64位内存中查找sys调用表 [英] Finding the sys call table in memory 64-bit on 4.x.x Kernel

查看:112
本文介绍了在4.x.x内核的64位内存中查找sys调用表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个简单的内核模块以在Linux中找到sys_call_table,并且遇到了一些麻烦.我在这里找到了32位Linux的基本指南:

I'm trying to write a simple kernel module to find the sys_call_table in Linux and am having some trouble. I found a basic guide for 32-bit Linux here: https://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/. I tried to adapt it to a modern 64-bit kernel and am having some trouble. My code is here:

#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之后):

I compile the code using a simple makefile, no warnings or notices come up and here is what is printed (after insmod-ing):

$ dmesg
<snip>
[39592.352209] ------ffffffff8120a2a0---------
[39592.352214] syscall table found at ffff880001a001c0
</snip>

所以一切似乎都正确吗?但是然后我通过运行以下命令来检查sys_call_table的位置:

So all seems well right? But then I check out where the sys_call_table is by running:

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.

..meaning that my code seemingly gets the location of the sys_call_table totally wrong. So ffff880001a001c0 instead of ffffffff81a001c0.

我不确定从哪里开始调试.我在这里做错了什么吗?自行调试此方法的第一步是什么?我对编写内核模块还很陌生,任何帮助将不胜感激!

I'm not entirely sure where to start debugging this. Am I doing something obviously wrong here? What would be a good first step to debugging this on my own? I'm fairly new to writing kernel modules and any help would be appreciated!

推荐答案

您的内核可能已启用x32兼容.

Your kernel may have enabled x32 compat.

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

  1. There are two sys_call_tables in this kind of kernel. compat_sys_call_table(ia23_sys_call_table) for 32-bit and sys_call_table for 64-bit. And they use the same sys_close.

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

You may find sys_close in compat_sys_call_table, but __NR_close is different between 32-bit unistd.h and 64-bit unistd.h. You may be using 64-bit __NR_close, so you cannot get compat_sys_call_table nor sys_call_table correctly.

您可以检查我的代码 ASyScallHookFrame ,它在Android内核3.10上运行良好.

You can check my code, ASyScallHookFrame, it works fine on Android kernel 3.10.

这篇关于在4.x.x内核的64位内存中查找sys调用表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆