P2IM论文笔记
简介
背景:模拟以MCU为处理器的固件设备并没有完全的模拟外设,导致fuzzing时外设需要实际物理设备,速度偏慢,且没有达到完全模拟。
主要实现了一个可以模拟在MCU下运行的固件的模拟器P2IM。通过自动化外设接口的建模来进行自动化,可扩展的模拟。
特点:对mcu架构下的寄存器进行分类识别,在qemu模拟时同时模拟这些寄存器值的操作,从而模拟出了firmware外设的一系列操作。保证了firmware在qemu上的稳定运行的同时加入了外设的模拟。
解决问题
当时对固件的模拟需要软硬件结合,导致fuzz的效率很慢,因此提出了一种模拟器对固件完全模拟的思路,通过实现对固件外设寄存器的分类并模拟以达到完全模拟的目的。
主要贡献
实现了对无硬件模拟
提出了P2IE(外设接口等效属性):为了定义怎样的仿真是好的仿真
提出了MMIO寄存器四种模型:对四种模型的行为进行了定义
探索性执行技术
尚存不足
寄存器分类可能存在错误(eg: 某些SR会错分类为DR,导致fuzz时将其作为输入,效率下降。)
代码覆盖率不够高
- 存在僵尸代码:写了但是没有使用上的代码
- 模糊器太基础:只用了最简单的AFL
- 假挂起情况:出现了两次假挂起的情况,一次是由于DR被错误分类为了CR;另一次是出现了DMA操作,P2IM不予处理
- 输入保持:作者发现不仅是输入值,输入持续的时间也会影响固件逻辑的执行
具体内容
Processor-Peripheral Interface Equivalence:
1)模拟器模拟了外设接口,而不是外设本身;2)模拟接口要与固件提供的外设行为相同,以便顺利运行
该文章模拟的寄存器为①②类,③由于不同设备差异较大不涉及。
实现步骤
- 根据专家对MCU的架构以及寄存器操作构建抽象模型,主要是总结了寄存器的类别和中断的类型。
- 模型的实例化,将抽象模型具体化为可用于特定固件模拟的模型。主要是根据固件对寄存器的操作类型以及后续的访问方式将寄存器进行分类以及设置中断。
抽象模型构建
寄存器种类
外设寄存器会被映射到固定内存区域(0x40000000-0x5fffffff)
Control Registers(CR):
- Access Pattern:RMW,大部分为先读,再修改,再写回。因为可能会有其他控制参数。所以需要先保存数据。小部分会是直接写入,模型会分类为DR(Data Registers),但是此类寄存器之后不会在被读取,因此对固件运行没有影响。
- Access Handling:模拟器将分类好的CR作为永久变量,不再改变。
Status Registers(SR):
- Access Pattern:若对寄存器访问为非条件读,且读取到的值作为了判断条件。则可以作为SR。部分情况下,可能会是直接写入,则会导致SR错判为DR,不过可以在后续再次访问时进行修改(polls)
- Access handling:SR经常变化,P2IM使用探索式执行的方式来自动推断SR值(遍历取最优),对于SR的写操作则显得没有必要,因此直接忽略SR写入。
Data Registers(DR):
- Access Pattern:若寄存器是被SR读后访问的,或者是直接写入的,那么将其作为DR
- Access Handling:理想的Fuzzing接口。
Control-Status Register(C&SR):
有些寄存器既可以做CR又可以做SR,不过由于CR是在外设配置阶段进行修改,SR为在外设运行阶段进行修改,所以只需在不同时刻将其按不同分类识别即可。
中断
直接使用基于代码块的中断方式(简单,易于复现)每执行1000个基本块后进行一次中断。
并没有对不可行输入进行判别:1)可以作为Fuzzer的改进;2)如果攻击者已经攻陷设备,则也有可能进行这些操作
自动构建具体模型
实例化过程与fuzzing过程同时进行,相互补充。首先进行fuzzer输入,如果模型由于未实例化的部分而停止,那么就停止fuzzing,根据已有的fuzzing输入信息进行实例化,如果实例化过程结束则继续进行fuzz。
模型实例化主要内容:
- 识别内存映射的寄存器类型,内存位置
- 每个寄存器的访问处理方式
- 启用的中断类型
注:同一外设的内存映射寄存器通常在内存区域地址是连续的,可以根据此特点将寄存器归为同一个外设,方便后续的优化。
Explorative Execution
前面提到了SR由于频繁变化的特性,导致每次需要调用其值时,都无法确定其正确值,因此采用了探索式执行的方式来确定SR的最优解
通过遍历SR的可能取值(32位只考虑同时只存在一个bit为1的情况),共32种情况,只需新建32个线程同时运行,查看哪个线程运行效果最好来确定结果(通过查看在跳出函数时的情况来判断)