加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – 使用模块读取内核内存

发布时间:2020-12-14 01:25:15 所属栏目:Linux 来源:网络整理
导读:作为我项目的一部分,我需要读取内核以获取系统调用表和系统调用地址的内存地址.或者实际上我需要提取系统调用表的内容和所有系统调用. 直到现在我才将GDB用于此目的.有没有办法让我可以使用内核模块.我是新的内核模块编程.在这里寻求专家的建议. 解决方法 首
作为我项目的一部分,我需要读取内核以获取系统调用表和系统调用地址的内存地址.或者实际上我需要提取系统调用表的内容和所有系统调用.

直到现在我才将GDB用于此目的.有没有办法让我可以使用内核模块.我是新的内核模块编程.在这里寻求专家的建议.

解决方法

首先让我先说读任意内核内存是一件棘手的事!并且有很多方法可以做到这一点,它们的复杂程度和灵活性各不相同.

1)硬编码地址.

在内核版本的System.map文件中搜索它:

# grep sys_call_table /boot/System.map-2.6.18-238.12.1.el5
c06254e0 R sys_call_table

有了这个,硬编码地址:

unsigned long *syscall_table = (unsigned long *)0xc06254e0;

然后,假设您#include< linux / syscalls.h>,您可以使用__NR_syscall定义来获取代码中这些系统调用的地址:

syscall_table[__NR_close]

这是最简单的方法,但到目前为止灵活性最低.该模块仅适用于该确切的内核.如果你将它发送到另一个内核,你就有可能得到一个内核OOP.

2)对表格进行强力扫描

看看这个:

http://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/

他使用一种方法来强制内核内存地址范围来查找sys_call_stable.原样,它只适用于32位(64位具有不同的内核内存地址范围).

这种方法有点灵活,但随着内核语义的改变可能会破坏道路.

3)动态搜索System.map加载时间

加载模块时,可以读取内核的System.map文件.我在我写的tpe-lkm模块中演示了这一点.该项目托管在github上.

看看这个文件中的find_symbol_address_from_file():

https://github.com/cormander/tpe-lkm/blob/master/symbols.c

非常灵活,因为你可以找到你想要的任何符号,但是从内核空间读取文件是一个很大的“不可以”.不要问我为什么,但人们总是告诉我.您还冒着它看到的System.map无效的风险,并可能导致内核OOP.此外,代码是……凌乱.

4)使用kallsyms_on_each_symbol()

从内核版本2.6.30开始,内核导出kallsyms_on_each_symbol().我们可以感谢ksplice人员.有了这个,你找不到sys_call_table(由于某些原因它不在那里),但你可以找到大多数其他符号.

非常灵活,非常稳定的查找符号地址的方法,但理解起来有些复杂;)

我在tpe-lkm项目中证明了这一点.看看这个文件中的find_symbol_callback()和find_symbol_address()函数:

https://github.com/cormander/tpe-lkm/blob/master/symbols.c

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读