赞
踩
【题目】What Your Firmware Tells You Is Not How You Should Emulate It: A Specification-Guided Approach for Firmware Emulation
【来源】2022 CCS
【笔记建立时间】2023-4-4
现有工作的普遍共识是,仿真器应该生成满足固件期望的响应,以便它不会crash或hang。
P2IM
通过观察外设访问模式自动构建外设模型,当在仿真器中运行目标固件时。Laelaps
,uEmu
,Jetset
和Fuzzware
使用符号执行去探索固件以找到满意的响应值。每个外设模型代表相应的硬件外设提供适当的响应。
同时,通过有选择地以正确的顺序执行某些相关的C-A规则来维护外围设备的状态(执行这些规则隐式地维护了相应的状态机)。uEmu
提出的无效引导仿真来快速定位缺失/错误的C-A规则。 直白地说,如果一个C-A规则丢失或者错误,仿真可能进入无效状态。如果发生这种情况,我们使用符号执行来快速识别哪个外设读操作对错误负责,并相应地修复C-A规则。(基于NLP技术从芯片手册自动提取C-A规则和无效性引导的仿真对提取的规则进行诊断和增强是互补的操作。
)基于修改编辑距离的新方法来量化仿真的保真度
(即轨迹相似性)SEmu
应用到一个新的动态分析任务,即基于规范的一致性检查
,利用手册中提取的语义信息,检查外设驱动程序的实现是否符合芯片手册中指定的逻辑。RDRF is set when the number of datawords in the receive buffer is equal to or more than the numberindicated by RWFIFO[RXW ATER].
SR1
寄存器的RDRF
字段。即当…,设置RDRF为1。在大部分单片机构建的应用产品中,基本都是以前后台方式(大循环加中断)的方式来实现功能,在主循环中处理应用,并在中断处理程序中处理外部的触发信号。
C1:通过外部硬件生成的信号
,这些信号由外部硬件事件驱动,例如从物理UART接口接收新数据,通常可以抽象为用新数据填充内部缓冲区。
C2:通过固件生成的信号
,这种类型的条件由固件的操作驱动,例如在"LBKDIF is cleared by writing a 1 to it"这句话中,写操作是一个更新LBKDIF值的信号。C3:通过内部信号
,当寄存器值由于之前任何动作的执行而被更新时,一些相关的条件可能变为真。A1:与MMIO寄存器相关
,这些动作更新寄存器字段的值。例如上面提到的"RDRF is set"。A2:与中断相关
,这些动作向中断控制器发送中断请求。A3:与DMA相关
,这些动作在DMA传输完成时生成DMA传输请求或中断请求。自动提取相关的C-A规则面临几个挑战:
status register of UART, UARTx_SR, and SR.
名词短语"RWFIFO[RXWATER]"接近"UART FIFO Receive Watermark(UARTx_RWFIFO)"
,我们知道"RWFIFO"是命名实体"UARTx_RWFIFO"的同义词。Stanford Constituency Parser
(一个流行的语言模型)来分析句子的语法结构。语法模式是将一个句子分成几个子句的一系列正则表达式。
Stanford Constituency Parser
将命名实体和相关动词连接起来。例如,“set"连接到命名实体"RDRF”。Reg[Field]
,例如RWFIFO[RXWATER]
。#D[R]
表示该缓冲区当前占用的大小。QEMU
来仿真基本的ARM ISA指令集和内核外设(例如,中断控制器NVIC)。在固件仿真过程中,我们动态地为每个外设建立模型。
选择了5本芯片手册,包括 STM32F103
, STM32F429
,STM32L152
, NXP K64F
series and Atmel SAM3X
series,它们分别属于三家MCU供应商。
值得注意的是,一本芯片手册可以涵盖共享相似外设的一系列MCU芯片。
所有实验运行在16-core Intel Xeon Silver 4110 CPU@2.10GHz服务器的Ubuntu18.04系统,该服务器配有48G DRAM。
我们使用原始的C-A规则为P2IM论文中发布的66个单元测试样本构建外设模型
。这些单元测试在三个芯片上运行,涵盖了各种外设和操作系统库。F103的RCC
(下一节介绍如何纠正不正确的规则)、K64的MCG、SAM3X的PMC的原始C-A规则不能为这些外设构建可用的模型。在修改时钟相关规则后,我们的方法达到了96.97%的通过率。我们使用F103的时钟外设RCC来解释如何在诊断工具的帮助下纠正不正确的规则
)
O * ->CFGR[SWS]:=0/1/2/3
",这表明1这是O触发器,2条件总是被满足,3动作是用0-3的随机值设置CFGR[SWS]。当我们对固件样本使用这个规则时,我们发现RCC驱动程序总是引导失败。使用诊断工具,我们能够捕获无效状态并精确定位该字段。特别是,由SEmu生成的CFGR[SWS]的具体响应导致符号执行进入无限循环。追溯起来,检测到CFGR[SWS]对应的符号值。然后,我们阅读了手册中描述CFGR[SWS]的相关句子,发现CFGR[SWS]应该遵循CFGR[SW]中的值(即相等),此外,3是一个不可能的值。因此,我们将此规则更新如下:[**] is not implemented, the registers are included for compability
"这样的句子。将执行轨迹表示为地址序列
,可以采用传统字符串距离算法(比如编辑距离),计算相似度。然而,由于固件执行的不确定性,直接使用编辑距离不能可靠测量真实相似度
。例如,对于相同的输入和固件,在在真实设备上的两次执行可能会产生不同的轨迹,但它们都能达到100%的保真度。(因为都是真实设备产生的)每个轨迹基于功能划分为三个部分
。初始化轨迹,包括初始化功能,如外设配置。主循环轨迹,包括主要的固件业务功能。中断轨迹,记录在中断上下文中执行的指令。对于轨迹的每个部分,我们使用编辑距离来衡量相似度。编辑距离被用来量化两个字符串的不同程度,具体来说,是将一个字符串转换到另一个字符串所需的最小操作(即删除、插入和替换)。删除或插入重复序列被认为不那么重要
。例如,固件通常以轮询模式运行,等待状态寄存器的某个值,它运行100个循环还是1000个循环不会有效地影响固件分析。因此,我们将重复删除或插入操作的权重分配为1,而将其他操作的权重分配为2。覆盖率的提高似乎微不足道。然而,我们注意到SEmu实现了更好的路径保真度,因此没有探索许多错误处理函数。
例如,像I2C这样的外设使用两个独立的中断来处理正常和错误信号,错误中断仅在硬件故障时发生。然而,P2IM和uEmu仍然会周期性地触发这些错误中断。SEmu成功重现了之前工作中提到的所有bugs,而且没有报告任何错误的崩溃/挂起
。事实上,现有工作中提出的许多崩溃报告是重复的或误报的。原因有二,一是现有工作随机传递中断,这导致遭遇相同崩溃的两个执行的边缘覆盖显著变化,AFL错误以为这是两个不同的崩溃。二是由于P2IM和μEmu中不准确的仿真,有许多不可行的路径被探索,导致相当多的假阳性发生。固件应该在检查另一寄存器状态后才访问某些寄存器
。这个简单的规则适用于许多I/O操作。例如,固件首先通过轮询状态寄存器中的状态来检查硬件是否就绪。只有当返回一个特定值时,它才会继续访问数据寄存器。如果固件直接访问数据寄存器,则违反R1。为了启用中断,固件不仅需要激活到外设的本地配置,而且还需要通过在全局中断管理器(即NVIC)中设置中断集启用寄存器(ISERx)来启用相应的中断源。
R1违背
:我们在SAM3X HAL驱动程序代码中观察到几处违反R1的情况。我们后来确认了根本原因是外设访问的竞争。例如SAM3X MCU的UART驱动代码在数据传输前检查TXRDY字段。但是,它还允许在TXRDY验证和数据传输之间发生UART中断,在此期间中断处理程序进行独立的数据传输。当中断返回时,之前的TXRDY验证无效,接下来的数据传输将失败。R2违背
:芯片供应商通常为开发人员提供一个HAL库,它抽象了硬件细节,并提供了一个统一的API来访问外设。但是,并不是所有的HAL都支持NVIC寄存器配置。这是因为IRQ号分配是特定于芯片的,配置NVIC成了开发者的责任。这个假设导致了R2的违背
。特别是,开发人员可能会忘记配置NVIC。例如,我们发现Robot固件调用HAL函数HAL_TIM_Base_Start_IT()来设置TIM2_DIER寄存器以启用Timer2中断。但是,它不启用NVIC寄存器中相应的中断号(28)。因此,中断永远不能被传递。actions
通常显式表示为执行几个简单的寄存器赋值。conditions
通常依赖于具有隐式语义的某些硬件信号,可以通过默认行为来建模。(例如,F103 ADC示例中默认赋值1)无法发现外设驱动程序的问题
。此外,开发人员为了性能考虑并不总是使用高级抽象库。通过观察外设访问模式
,P2IM推断寄存器类型(即CR、SR、C&SR和DR),然后使用启发式方法根据寄存器类型信息生成响应。然而,如前所述,它存在寄存器错误分类问题。此外,当启发式不可用时,P2IM在有限的搜索空间内盲目地搜索合适的响应。基于符号执行的解决方案
通过推理来自外围设备的响应如何影响固件执行来解决上述问题。这些解决方案的一个关键限制是它们依赖于启发式来决定要采取的路径。PRETENDER和Conware通过学习
硬件和固件之间的真实交互来创建外围模型。因此,它们需要依赖于硬件的记录阶段,降低了可伸缩性。在这项工作中,我们提出了第一个基于规范的固件模拟解决方案
,而不是提出另一个固件引导的仿真解决方案。这种新方法利用NLP技术将人类语言描述的外设行为(记录在芯片手册)转换为一组结构化的条件-动作规则。通过在运行时正确地执行和链接这些规则,我们可以为固件执行期间访问的每个外设动态地合成一个外设模型。在机器辅助规则诊断的帮助下,我们的评估证实,在提出的保真度度量方法下,我们的原型与真实设备相比达到了100%的仿真保真度。相比之下,现有工作所达到的保真度在73%到86%之间。有了更好的保真度,我们的解决方案提高了模糊测试的效率。在模糊测试期间没有观察到虚假的崩溃和挂起。通过更高的仿真精度,我们还设计了一个新的动态分析任务来根据规范执行驱动程序代码符合性检查。我们发现了一些不符合,我们后来确认是由竞争条件引起的错误。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。