问题描述
作为我的项目的一部分,我需要读取内核以获取系统调用表的内存地址和系统调用地址.或者实际上,我需要提取系统调用表和所有系统调用的内容.
As part of my project I need to read the kernel to get the memory address of system call table and system call address. Or in effect i need to extract the contents of the system call table and all the system calls.
到目前为止,我将GDB用于此目的.有什么办法可以让我使用内核模块做到这一点.我是内核模块编程的新手.在这里寻求专家的建议.
Till now I use GDB for this purpose. Is there any way so that I could do it using a kernel module. I am new the kernel module programming. Looking for advice from experts here.
推荐答案
首先让我说读取任意内核内存是一件棘手的事情!这样做的方法很多,但复杂程度和灵活性各不相同.
Let me first start by saying reading arbitrary kernel memory is tricky business! And there are many ways to do it, which vary in their degree of complexity and flexability.
在内核版本的System.map文件中搜索它:
Search for it in your kernel version's System.map file:
# grep sys_call_table /boot/System.map-2.6.18-238.12.1.el5
c06254e0 R sys_call_table
以此,对地址进行硬编码:
With this, hard-code the address:
unsigned long *syscall_table = (unsigned long *)0xc06254e0;
然后,假设您为#include <linux/syscalls.h>
,则可以使用__NR_syscall
定义在代码内获取这些系统调用的地址:
Then, assuming you #include <linux/syscalls.h>
, you can use the __NR_syscall
definitions to grab the addresses of those syscalls within the code:
syscall_table[__NR_close]
这是最简单的方法,但到目前为止最不灵活.该模块只能在该内核上运行.如果将其插入其他内核,则有可能获得内核OOP.
This is the easiest method, but by far the least flexible. This module will only work on that exact kernel. If you insmod it into a different kernel, you're liable to get a kernel OOPs.
看看这个:
他使用一种暴力破解内核内存地址范围的方法来找到sys_call_stable.照原样,它只能在32位(64位内核的内存地址范围不同)上工作.
He uses a method to brute force the kernel memory address range to find the sys_call_stable. As-is, it only works on 32bit (64bit has a different memory address range for the kernel).
该方法有些灵活,但是随着内核语义的变化,可能会打破常规.
This method is somewhat flexible, but may break down the road as the kernel semantics change.
加载模块时,您可以读取内核的System.map文件.我在编写的 tpe-lkm 模块中对此进行了演示.该项目托管在github上.
You can read your kernel's System.map file when you load the module. I demonstrate this in the tpe-lkm module I wrote. The project is hosted on github.
查看此文件中的find_symbol_address_from_file():
Have a look at the find_symbol_address_from_file() from this file:
https://github.com/cormander/tpe-lkm/blob/master/symbols .c
非常灵活,可以找到所需的任何符号,但是从内核空间读取文件是一个很大的不".不要问我为什么,但是人们总是在告诉我.您还冒着风险,即它所查看的System.map无效,并且可能导致内核OOP.而且,代码是...很乱.
Very flexible, as you can find any symbol you want, but reading files from kernel space is a big 'no no'. Don't ask me why, but people are always telling me that. You also run the risk that the System.map it looks at is invalid, and could cause a kernel OOPs. Also, the code is... messy.
从2.6.30内核版本开始,内核导出kallsyms_on_each_symbol().我们要感谢ksplice的人们.有了这个,您找不到sys_call_table(由于某种原因它不在那儿),但是您可以找到大多数其他符号.
As of around kernel version 2.6.30, the kernel exports kallsyms_on_each_symbol(). We can thank the ksplice folks for that. With this you can't find the sys_call_table (it isn't in there for some reason), but you can find most other symbols.
一种非常灵活,非常稳定的查找符号地址的方法,但理解起来有些复杂;)
Very flexible, very stable method of finding addresses of symbols, but somewhat complicated to understand ;)
我在我的 tpe-lkm 项目中对此进行了演示.看一下此文件中的find_symbol_callback()和find_symbol_address()函数:
I demonstrate this in my tpe-lkm project. Have a look at the find_symbol_callback() and find_symbol_address() function in this file:
https://github.com/cormander/tpe-lkm/blob/master/symbols .c
这篇关于使用模块读取内核内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!