资讯动态

硬件动态分析逆向FSM:从激励设计到状态机还原的工程化方法

发布时间:2026/10/18 1:01:28 来源:尧图企业网站定制
1. 从一个逆向工程难题说起硬件动态分析如何还原状态机1.1 为什么FSM逆向是个硬骨头搞硬件安全分析的人都知道从一块芯片或者一段固件里把有限状态机FSM扒出来是件既考验耐心又考验技术功底的事。FSM这东西说白了就是硬件电路的“行为剧本”——它规定了电路在什么状态下收到什么输入该跳转到什么状态、输出什么信号。你拿到的往往只是一堆波形数据、一堆网表文件或者一个黑盒子的输入输出响应要从中反推出完整的状态转移图难度不亚于只看一部电影的几帧截图就还原出整个剧本。传统做法无非两条路静态分析和动态分析。静态分析就是直接啃网表、读RTL代码理论上能拿到完整信息但实际工程中你面对的可能是经过综合优化、混淆处理甚至加密保护的网表可读性极差。动态分析则是给电路喂激励、看响应从行为反推结构。这条路更贴近实际攻击场景但挑战在于状态空间可能极大激励序列的设计直接决定你能不能覆盖到所有关键状态转移。TIFS 21上那篇关于硬件动态分析逆向FSM的工作核心贡献就在于提出了一套系统化的方法论把“喂激励-收响应-推状态机”这个流程做得更自动化、更可靠。它不是单纯炫技而是解决了一个实际痛点面对一个未知的硬件模块如何在有限的时间和激励预算内尽可能完整地还原出它的FSM。1.2 这套方法适合谁看如果你在做硬件安全评估、IP核验证、或者逆向工程相关的工作这套思路值得仔细琢磨。具体来说以下几类人会有直接收获硬件安全研究员需要评估一个第三方IP核是否存在隐藏状态或后门FSM逆向是基础能力。验证工程师想通过动态手段交叉验证RTL设计的FSM是否与规格一致发现仿真覆盖不到的角落。嵌入式逆向爱好者面对一个固件或可编程逻辑器件想理解其控制逻辑的行为模式。学术研究者关注硬件FSM逆向的形式化方法和自动化工具链。即便你之前没接触过硬件逆向只要对状态机概念有基本认知这篇文章也能帮你建立起一套可操作的思路框架。我会尽量把原理讲透把实操步骤拆细让你看完能自己动手试。1.3 核心思路一句话概括这套方法的核心思想是用精心设计的输入序列去“刺激”目标硬件观察其输出响应和内部状态的可观测信号然后通过算法自动推断出状态转移关系最终重构出FSM模型。听起来简单但魔鬼在细节里——激励怎么设计、状态怎么区分、转移怎么确认、模型怎么验证每一步都有坑。2. 方案选型背后的逻辑为什么是动态分析而不是静态2.1 静态分析的局限性静态分析硬件FSM典型做法是解析网表或RTL提取状态寄存器和组合逻辑然后构建状态转移图。这在理想情况下可行但实际中会遇到几个硬伤第一网表可读性问题。经过综合工具优化后状态编码可能被重新映射原本的二进制编码变成独热码或格雷码甚至被工具自动重编码以优化面积或功耗。你拿到的网表里状态寄存器的名字可能全是_0_、_1_这种无意义标识根本看不出哪个是状态位。第二混淆与保护。商业IP核常常带有防逆向措施比如状态机加密、虚假状态注入、逻辑锁定等。静态分析面对这些保护手段往往束手无策。第三规模爆炸。一个复杂协议控制器可能有几十个状态、上百条转移静态提取后得到的图可能庞大到难以人工理解而动态分析可以按需探索只关注实际可达的状态。2.2 动态分析的独特优势动态分析不依赖网表可读性它把硬件当成一个黑盒或灰盒通过外部接口施加激励并观察响应。优势体现在绕过混淆不管内部状态怎么编码只要行为一致动态分析就能捕捉到。按需探索可以优先探索感兴趣的状态区域不必一次性处理整个状态空间。贴近真实场景攻击者或评估者通常只有外部接口访问权限动态分析更符合实际威胁模型。可验证性推断出的FSM可以直接通过再次施加激励来验证形成闭环。当然动态分析也有代价激励序列的设计需要领域知识状态覆盖可能不完整且对深层状态的观测可能受限。TIFS 21那篇工作的价值就在于系统化地解决了这些问题把动态分析从“手艺活”变成了“工程化流程”。2.3 灰盒假设平衡可观测性与实用性纯黑盒动态分析只能看输入输出很多内部状态无法直接观测导致状态区分困难。纯白盒又回到静态分析的老路。这套方法采用的是灰盒假设假设可以通过某种方式如扫描链、调试接口、功耗侧信道等观测到部分内部信号。这个假设在实际中很合理——很多芯片都留有JTAG或类似调试接口测试模式下可以访问内部节点。灰盒假设的关键在于你不需要看到所有状态位只需要有足够的可观测信号来区分不同状态即可。比如一个8位状态寄存器你只能观测到其中3位但如果这3位在所有可达状态上的取值组合是唯一的那就能完全区分状态。这套方法会分析可观测信号与状态之间的区分度指导激励设计。3. 核心细节解析从激励设计到状态推断的完整链条3.1 激励序列设计不是随便喂几个向量就行激励设计是动态FSM逆向的第一步也是最关键的一步。目标是设计一组输入序列使得目标FSM的所有或尽可能多的状态转移都被激活并且不同状态在输出或可观测信号上表现出可区分的特征。常用的激励设计策略包括随机激励简单粗暴适合初步探索但覆盖效率低可能遗漏深层状态。基于覆盖的激励借鉴软件测试中的覆盖导向方法以状态覆盖、转移覆盖为目标迭代生成激励。基于模型的激励先根据已有知识构建一个粗略模型然后针对模型中的不确定区域设计激励。自适应激励根据上一次激励的响应动态调整下一次激励类似主动学习。这套方法采用的是自适应覆盖导向的混合策略。具体来说它维护一个“已探索状态集合”和“待探索转移集合”每次选择能最大化新覆盖的激励向量。选择依据是一个信息增益指标综合考虑了状态区分度和转移激活概率。实操心得激励设计时复位序列要固定且可靠。很多FSM的行为依赖复位后的初始状态如果复位不稳定后续所有推断都建立在流沙上。建议在正式激励前先施加多次复位并观测响应一致性。3.2 状态区分可观测信号怎么用有了激励和响应数据下一步是从中区分出不同状态。这里的关键是定义状态签名对于每个时间点把可观测信号的值组合成一个向量作为该时刻状态的“指纹”。如果可观测信号足够丰富每个状态都有唯一签名那状态区分就很简单。但实际中往往可观测信号有限可能出现多个状态共享同一签名的情况。这时需要增加观测点通过调试接口读取更多内部节点。延长观测窗口不仅看当前周期的输出还看后续几个周期的响应序列用时间维度上的模式来区分。施加区分序列设计特定的输入序列使得原本签名相同的两个状态在响应上产生差异。这套方法引入了一个区分树的概念通过一系列精心选择的输入逐步分裂状态集合直到每个叶子节点对应一个唯一状态。区分树的构建过程类似于决策树的生成每个内部节点是一个输入向量分支是可能的响应叶子是状态集合。3.3 转移推断从序列到图状态区分完成后接下来要推断状态之间的转移关系。基本思路是在已知状态A下施加输入x观测下一个状态签名如果该签名对应状态B则推断存在转移A --x-- B。但这里有个鸡生蛋蛋生鸡的问题要推断转移需要知道当前状态要知道当前状态又需要先有转移图来跟踪状态演化。解决方法是增量式推断从复位状态开始这是已知的初始状态。施加一个输入观测响应根据状态签名判断到达了哪个状态可能是已知状态也可能是新状态。记录这条转移更新状态集合和转移集合。从新状态继续探索直到所有可达状态和转移都被覆盖。这个过程类似于图遍历但难点在于状态签名可能不唯一导致“到达了哪个状态”这个判断存在歧义。方法中采用了一致性检查如果根据签名判断到达状态B但后续从B出发的响应与预期不符则说明之前的判断有误需要回溯修正。3.4 模型验证与精化推断出的FSM模型需要验证。验证方法包括重放验证用推断出的模型预测新激励序列的响应与实际硬件响应对比。如果一致说明模型在该序列覆盖的范围内正确。交叉验证用不同的激励序列探索同一区域看推断结果是否一致。形式化验证如果可观测信号足够可以用形式化方法证明模型与硬件行为等价在观测范围内。如果验证发现不一致需要精化模型可能是状态区分不够细可能是遗漏了某些转移也可能是可观测信号不足导致误判。精化过程会指导下一轮激励设计形成迭代闭环。4. 实操过程手把手复现FSM逆向流程4.1 环境准备与目标选择要复现这套方法你需要一个可观测的硬件目标。对于初学者建议从以下平台入手FPGA开发板可以自己烧录一个已知FSM的设计然后尝试逆向验证方法有效性。仿真环境用Verilog/VHDL仿真器可以完全控制可观测信号适合理解算法流程。带调试接口的MCU通过JTAG/SWD读取内部状态寄存器但需要注意不要违反相关使用规定。工具链方面你需要激励生成与响应采集脚本Python即可状态签名提取与区分树构建代码FSM模型存储与可视化工具如Graphviz注意所有操作应在合法合规的环境下进行仅针对自己拥有或获得明确授权的硬件目标。未经授权的硬件逆向可能违反法律法规。4.2 激励生成与数据采集以FPGA上的一个简单FSM为例假设它是一个序列检测器检测输入流中的“1011”模式。我们假装不知道它的内部结构只通过外部接口施加输入并观测输出。# 伪代码激励生成与响应采集 import serial # 假设通过串口与FPGA通信 def apply_stimulus(input_seq): 施加输入序列并采集响应 responses [] for inp in input_seq: send_input(inp) resp read_output() responses.append(resp) return responses # 初始随机激励 random_seq [random.choice([0,1]) for _ in range(1000)] responses apply_stimulus(random_seq)采集到的数据包括输入序列和对应的输出序列。如果可观测内部信号也一并记录。4.3 状态签名提取与区分树构建假设我们只能观测到输出信号那么状态签名就是输出序列的局部模式。比如用最近3个周期的输出作为签名def extract_signatures(responses, window3): 提取状态签名 signatures [] for i in range(len(responses) - window 1): sig tuple(responses[i:iwindow]) signatures.append(sig) return signatures然后构建区分树。初始时所有时间点都在一个集合里选择一个输入向量根据响应分裂集合递归直到每个集合内的签名一致。4.4 转移推断与模型构建有了状态集合和签名就可以推断转移了。遍历输入序列跟踪状态变化def infer_transitions(input_seq, responses, state_map): 推断状态转移 transitions [] current_state state_map[0] # 初始状态 for i, inp in enumerate(input_seq): next_sig get_signature(responses, i1) next_state state_map.get(next_sig) if next_state is None: next_state create_new_state(next_sig) transitions.append((current_state, inp, next_state)) current_state next_state return transitions最后用Graphviz画出状态转移图人工检查合理性。4.5 参数选择与计算过程几个关键参数需要根据实际情况调整签名窗口长度太短区分度不够太长则状态数爆炸。可以用信息熵来指导选择计算不同窗口长度下签名分布的熵选择熵开始饱和的窗口长度。激励序列长度取决于状态空间大小。一个经验公式是L ≈ N * log(N)其中N是估计的状态数。比如估计有16个状态激励长度至少64。区分树深度受可观测信号限制。如果深度超过一定值仍无法区分说明需要增加观测点。实操心得签名窗口长度不要一开始就设太大。我试过直接用10个周期的输出做签名结果状态数虚高到几百个后来发现很多是同一状态的不同相位。先用短窗口快速探索再逐步加长精化。5. 常见问题与排查技巧实录5.1 状态数虚高怎么办这是最常见的问题。原因通常是签名区分度过细把同一状态的不同表现当成了不同状态。排查方法检查签名窗口是否过长尝试缩短。检查是否有周期性噪声导致签名波动考虑对响应做滤波或取多数投票。检查复位是否稳定不稳定的复位会导致初始状态漂移。5.2 转移推断出现矛盾如果推断出的转移图中有矛盾比如同一状态同一输入到达不同状态可能原因状态区分有误两个不同状态被合并了。存在未观测到的内部变量影响转移。硬件存在非确定性行为如异步接口。解决方法增加观测点或引入概率模型处理非确定性。5.3 激励覆盖不全如果探索了很久仍有大量状态未覆盖可能是激励设计不够“聪明”。可以尝试增加激励的随机性避免陷入局部循环。使用基于覆盖的反馈优先选择能到达新区域的激励。如果知道部分协议知识可以手工设计针对性激励。5.4 可观测信号不足这是灰盒方法的根本限制。如果可观测信号太少状态区分和转移推断都会困难。应对策略寻找更多调试接口或测试模式。利用侧信道信息如功耗、电磁辐射作为补充观测。接受部分可观测性构建部分FSM模型标注不确定区域。问题现象可能原因排查方法解决技巧状态数虚高签名窗口过长缩短窗口重试用熵饱和点确定窗口转移矛盾状态合并错误检查签名唯一性增加观测点或区分序列覆盖不全激励设计不佳分析已覆盖区域自适应激励领域知识观测不足接口限制评估可用信号侧信道补充部分模型避坑技巧整个流程一定要有版本管理和日志记录。每次激励序列、响应数据、推断结果都存档方便回溯和对比。我踩过的最大坑就是改了一版代码后结果变差但找不到之前的数据对比白白浪费两天。6. 影响范围与延伸思考6.1 对硬件安全评估的意义这套方法把FSM逆向从依赖专家经验的手工活变成了可重复、可自动化的流程。对于硬件安全评估来说这意味着可以更高效地发现隐藏状态、异常转移和潜在后门。比如某个IP核在特定输入序列下会进入一个未文档化的状态这个状态可能泄露密钥或绕过访问控制动态FSM逆向就是发现这类问题的利器。6.2 对硬件设计的反馈价值从设计者角度这套方法也可以用于验证自己设计的FSM是否真的按预期工作有没有仿真没覆盖到的角落把逆向出的FSM与设计规格对比可以快速定位差异。这比单纯跑覆盖率工具更直接因为它是在真实硬件上验证的。6.3 局限性与未来方向当前方法仍有局限对深层状态的观测依赖调试接口对非确定性FSM的处理还不够完善激励设计的自动化程度可以进一步提高。未来可能的方向包括结合机器学习预测状态转移、利用形式化方法指导激励生成、支持多时钟域和异步FSM的逆向等。我个人在实际操作中的体会是这套方法最值钱的地方不是某个具体算法而是它把整个流程串起来了——从激励到观测到推断到验证每一步都有明确的输入输出和反馈机制。你不需要一开始就追求完美先跑通闭环再逐步精化比一上来就追求全自动要务实得多。另外领域知识永远比算法更重要如果你对目标协议或硬件功能有先验知识激励设计会事半功倍。最后再分享一个小技巧把推断出的FSM用Graphviz画出来后先别急着分析拿给不熟悉这个项目的同事看一眼如果他们能看懂状态转移逻辑说明你的模型抽象层次是对的如果他们一脸懵那大概率是状态区分或命名有问题。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑