Page 22 - 《软件学报》2026年第6期
P. 22

李玉璋 等: BinDec: 面向  RISC-V  的  LLM  与符号执行协同反编译方法                                 2341


                 法构建的数据集基础上, 选取了          2 000  个样本, 构造了一个专门用于验证等价性检查准确性的数据集. 该数据集的
                 构建过程如下: 首先随机选取         1 000  个由不同源代码编译生成的样本作为参考代码; 随后, 对每一个参考代码, 随
                 机选取来自同一源代码但在不同编译优化级别下生成的样本, 作为语义一致的正样本; 最后, 对每一个参考代码,
                 再随机选取来自不同源代码且在任意编译优化级别下生成的样本, 作为语义不一致的负样本. 我们在二进制代码
                 与中间代码两个层面上, 依据本文所采用的等价性检查流程, 分别在该数据集上进行了测试, 并使用二分类评估指
                 标  (精确率、召回率与      F1  分数) 对实验结果进行评估, 具体结果如表          7  所示. 实验表明, 基于符号执行的代码等价
                 性检查方法在两类代码上均取得了较高的召回率                 (二进制代码为 99.71%, 中间代码为 98.56%), 说明该方法能够有
                 效识别语义不一致的代码对. 然而, 其精确率相对较低                (二进制代码为     86.10%, 中间代码为 91.38%), 表明存在一定
                 比例的将语义一致代码误判为不一致的情况. 进一步对比二进制代码与中间代码上的检查效果, 可发现基于符号
                 执行的方法在二进制代码上表现更为严格, 但也产生了更多误报. 我们认为这一现象与两个阶段代码的检查方式
                 差异有关. 对于中间代码, BinDec 方法构建了统一的符号模型, 并通过约束求解完成一致性判断; 而在二进制代码
                 层面, 该方法则基于符号执行生成测试用例, 并在实际程序环境中执行这些用例. 由于真实执行环境对运行条件的
                 要求更为严苛, 容易出现运行异常或失败, 从而导致检查过程更为严格, 误报率相应升高.

                                              表 7 代码等价性检查准确性结果 (%)

                                          检查对象        精确率        召回率         F1
                                         二进制代码         86.10      99.71     92.41
                                          中间代码         91.38      98.56     94.83

                    针对问题    3  的总结: 本文所提出的基于符号执行的方法可以实现低漏报的代码等价性检查, 因此其可以作为
                 保证  LLM  生成代码质量的可靠工具.

                  4.4   问题  4: 与传统反编译器相比, BinDec 方法的失败模式有何异同?
                    为深入探究本文所提出的          BinDec 方法与传统反编译器      Ghidra 在失败模式上的异同, 我们对两者在实验测试
                 集上产生的失败案例进行了系统的归纳与对比分析. 首先, 我们依据错误发生的阶段和外在表现, 构建了一个双层
                 分类框架: 第   1  层级将失败划分为编译错误         (即反编译代码无法通过编译) 与执行错误             (即程序可编译但运行结果
                 异常). 在第  2  层级中, 我们进一步根据编译器报错信息           (如语法错误、类型不匹配、未定义符号等) 对编译错误进
                 行细分; 对于执行错误, 则根据其异常行为的本质, 划分为与程序稳定性有关的内存错误                           (如段错误、内存泄漏)
                 和与语义等价有关的逻辑错误           (如输出不符、无限循环). 基于此框架, 我们对所有失败案例进行了人工复核与归
                 类, 其统计结果如表      8  所示. 该分类结果表明两种方法在错误类型分布上的总体差异, 即                   BinDec 方法克服了传统
                 反编译器    Ghidra 中的典型错误, 并且未引入新的错误类型. 而           BinDec 方法中仍然存在的错误        (例如未定义变量)
                 相较其他错误更容易手工解决, 这表明            BinDec 方法生成的反编译代码具有更高的重用价值.


                                              表 8 反编译代码的典型错误归纳 (%)

                                      错误分类           子类别           BinDec      Ghidra
                                                   未定义变量            90          60
                                                   未定义类型             0          13
                                                   未定义函数             0           6
                                      编译错误
                                                  不兼容的类型             0           3
                                                    语法错误             5          10
                                                      其他             5           8
                                                    内存错误            100         90
                                      执行错误
                                                    逻辑错误             0          10

                    针对问题    4  的总结: 本文提出的    BinDec 方法在失败模式上实现了对传统反编译器中复杂错误的规避, 其失败
                 案例呈现出更高的可修正性, 这为其在软件逆向工程中的实用价值提供了实证支持.
   17   18   19   20   21   22   23   24   25   26   27