网表级逆向分析:LUT级网表提取技术
网表级逆向分析,说白了就是要把FPGA的比特流或者版图信息,还原成我们能理解的逻辑网表。这步很关键,因为它是连接底层硬件和上层RTL的桥梁。我个人习惯把网表级逆向分成四个核心步骤:LUT提取、触发器识别、组合逻辑还原、再到RTL映射。每一步都有坑,咱们一个一个说。
LUT级网表提取技术
LUT(查找表)是FPGA的基本逻辑单元。一个LUT本质上就是一个小的RAM,输入地址,输出存储的值。提取LUT网表,就是要搞清楚每个LUT的输入输出关系。
提取的核心思路:
- 从比特流中解析LUT配置:FPGA的比特流里包含了每个LUT的配置数据。这些数据决定了LUT的查找表内容。我建议先找到LUT的配置帧结构,不同厂商的帧结构差异很大。
- 从版图中提取LUT连接:如果你在做版图级逆向,那就得从金属层和晶体管层提取LUT的输入输出连线。这活儿很累,但有时候比特流拿不到,只能硬啃版图。
- 建立LUT的布尔函数:拿到LUT的配置值后,就能推导出它的布尔函数。比如一个4输入LUT,配置值是0x8ACE,那它的逻辑就是特定输入组合下的输出。
重要提示:LUT提取的精度直接决定了后续分析的成败。我见过有人因为LUT配置解析错了一位,结果整个网表逻辑全乱了。所以,每一步都要做交叉验证。
触发器与寄存器识别
触发器(Flip-Flop)和寄存器(Register)是时序逻辑的核心。在网表里,它们通常表现为带有时钟和复位信号的存储单元。
识别方法:
- 结构特征匹配:触发器在网表里通常有固定的结构:一个数据输入D,一个时钟输入CLK,一个输出Q。有些还有复位RST和使能EN。我习惯先扫描所有节点,找出符合这种结构的子图。
- 时钟信号追踪:时钟信号在网表里是全局的,它会连接到很多触发器的CLK端。通过追踪时钟树,能快速定位触发器的位置。
- 复位信号分析:同步复位和异步复位的处理方式不同。异步复位在网表里通常直接连到触发器的复位端,而同步复位会先和D输入做逻辑运算。
个人经验:我曾经在一个项目里遇到过一个奇葩设计,他们把触发器的时钟信号和复位信号混在一起用了。结果我按常规方法识别,死活找不到触发器。后来才发现,他们用了一个组合逻辑把时钟和复位做了与运算。所以,识别时一定要考虑各种奇葩用法。
组合逻辑还原方法
组合逻辑还原,就是把LUT和触发器之间的那些逻辑门和连线,还原成我们熟悉的与门、或门、非门等基本逻辑单元。
还原步骤:
- 提取LUT的布尔表达式:每个LUT的配置值对应一个布尔函数。比如一个3输入LUT,配置值是0xE8,那它的布尔表达式就是 (A & B) | (!A & C)。
- 化简布尔表达式:多个LUT级联后,布尔表达式会变得很复杂。我建议用卡诺图或者Quine-McCluskey算法进行化简。化简后的表达式更容易映射到标准逻辑门。
- 构建逻辑门级网表:把化简后的布尔表达式,用与门、或门、非门等基本逻辑门表示出来。这一步要注意扇入扇出问题,有些LUT的扇入很大,直接映射会导致门级网表很乱。
避坑指南:我曾经在化简布尔表达式时,忽略了LUT的延迟特性。结果还原出来的逻辑门级网表,时序完全不对。后来我才意识到,LUT的延迟和标准逻辑门的延迟不一样,还原时一定要保留LUT的延迟信息。
网表到RTL的逆向映射
这是最后一步,也是最难的一步。把门级网表映射成RTL代码,需要理解设计者的意图。
映射策略:
- 状态机识别:网表里如果有大量的反馈回路和状态寄存器,那很可能是个状态机。我习惯先找出状态寄存器和状态转移逻辑,然后还原出状态转移图。
- 数据通路分析:对于数据通路,比如加法器、乘法器、多路选择器等,它们通常有固定的结构模式。通过模式匹配,可以快速识别出这些模块。
- 控制逻辑提取:控制逻辑通常由有限状态机和一些组合逻辑组成。把控制逻辑和数据通路分开,能大大简化RTL的还原难度。
举个例子:
// 假设我们从网表里还原出了以下逻辑
// 输入:a, b, c, clk, rst
// 输出:out
// 第一步:识别出触发器
reg q1, q2;
always @(posedge clk or negedge rst) begin
if (!rst) begin
q1 <= 0;
q2 <= 0;
end else begin
q1 <= a & b;
q2 <= q1 | c;
end
end
// 第二步:组合逻辑还原
assign out = q2 & ~q1;
// 最终RTL代码
module top (
input a, b, c, clk, rst,
output out
);
reg q1, q2;
always @(posedge clk or negedge rst) begin
if (!rst) begin
q1 <= 0;
q2 <= 0;
end else begin
q1 <= a & b;
q2 <= q1 | c;
end
end
assign out = q2 & ~q1;
endmodule
你想想看,这个例子虽然简单,但已经包含了网表到RTL映射的核心思路:先找触发器,再还原组合逻辑,最后组合成完整的模块。
知识体系结构图
下面这张图展示了网表级逆向分析的整体流程和各个步骤之间的关系:
这张图把整个网表级逆向分析的流程串起来了。从LUT提取开始,到触发器识别,再到组合逻辑还原,最后映射成RTL。每一步都有对应的技术点和挑战。我个人建议,在实际项目中,一定要按照这个流程来,不要跳步。跳步的结果往往是返工。
实用技巧:在做网表到RTL映射时,我习惯先画出数据流图,把数据通路和控制通路分开。这样能快速定位关键模块,避免在细节里迷失方向。
好了,这一章的内容就到这里。网表级逆向分析是个技术活,需要耐心和细心。多练几次,你就能找到感觉了。