SMM Rootkit初步 - 读写SMRAM(带你迈入CPU级Rootkit之门)
好吧,我承认标题有点夸大,不介意的都进来BS我把
就像 qihoocom 大侠说的,“SMM XX早就几万年前就不是什么秘密了”,不过国内讨论这个的到是鲜见,希望这篇文章能抛砖引玉吧。
之前看到rootkit.com上 Implementing SMM PS/2 Keyboard sniffer 那个代码,狠狠震撼了一把。于是开始研究SMM,半月下来总算有些收获。这里将如何读写SMRAM的方法拿出来科普一下,希望更多人能迈入编写SMM Rootkit的大门。
文章后面提供可以在VPC和VMware两大虚拟机中运行的代码,将演示如何在WinXP(SP2)中读写SMRAM。(本文只考虑最简单的系统环境,不涉及 SMM Space Locked(D_LCK)=1 时无法读写SMRAM的情况)另外,按 Ivanov 大牛的说法,这种方法局限性很大,只能在没有执行 Intel 修补方案的主板上运用(感谢两大VM模拟的都是I440BX
)。
对硬件方面接触尚浅,文中若有疏漏之处,欢迎指正。
--------------------------------------------------------------------------------------------------------
首先放下PCI相关的诸多知识,我用最短的篇幅叙述读写SMRAM的过程。希望这篇文章能带你迈出SMM Rootkit的第一步。
首先说说什么是SMM(System Management Mode)。System Management Mode Hack中说:SMM是专门为电源管理设计的执行规则。当进入SMM后,系统的各个部件可以被关闭或者使用最低的功耗。SMM独立于其他的系统软件,也可以被用在其他目的... 该文章中文版点这里
了解SMM是什么东西就够了,这篇文章不会涉及太多SMM的东西。相反,读写SMRAM更需要的是PCI配置空间(PCI Configuration Space)方面的知识。
先讲讲两个访问PCI配置空间的I/O端口:CF8h 和 CFCh
通过向 CF8h 端口写一个特殊的地址,我们就可以在 CFCh 端口上读写指定寄存器的值。这里要读的寄存器是位于配置空间偏移为 72h 的8bit寄存器SMRAM (System Management RAM Control Register)
首先要介绍一下 CF8h 这个I/O端口。实际上 I/O CF8h 写的是CONFIG_ADDRESS寄存器,所以 CF8h又叫CONFIG_ADDRESS。其布局如下[1]:

按上图格式,31位置1(enable),假设I440BX的北桥82443BX位于Bus: 0, Device:0, Func:0(后面将教你如何确定芯片类型以及取得这几个值),这样配置空间的基址就是0x80000000。
通过I/O指令向CF8h写入0x80000000,就可以从 CFCh(CONFIG_DATA)中读出82443BX配置空间偏移为0的一个DWORD值了。而这个DWORD的高低16位分别是VendorID和DeviceID,如图:

下面在我们去读配置空间偏移为72h的SMRAM前,首先注意一个特性。不知道你注意到没有,回头看看CONFIG_ADDRESS的低2位,它们被定义为0。且不谈PCI规范上的大道理,说白了这个地方为0是为了限制你给出的地址必须为4的整数倍。了解到这一点再看那个Register Number就比较好理解了,原来这个寄存器编号和偏移是这么对应的。
好了,那么偏移为72h (01110010) 的SMRAM,最后两位置零是70h (01110000),即位于编号为1C (11100)的寄存器上。所以只要向 CF8h 里写入0x80000070这个地址,此时从 CFCh 端口读出的数据就是包含SMRAM的一个DWORD了。

假设读出来的数据为DWORD 380A0000h (00 00 0A 38),对照上面82443BX寄存器表可知:
注意:上传附件及图片大小不得大于30M。
⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。
