Page 15 - 《软件学报》2026年第6期
P. 15
2334 软件学报 2026 年第 37 卷第 6 期
场景: 符号执行通常适用于中间代码层面的分析. 在二进制代码提升阶段, 因需对比提升后的 IR 代码与原始二进
制代码, 必须在二进制层面进行等价性检查; 而在本阶段, 由于比较双方均为中间代码, 因此可以借助全面的符号
化验证实现更为严格的等价性检查. 具体而言, BinDec 首先将反编译得到的 C 代码重新编译为 IR 代码, 随后借鉴
差分符号执行 [30] 的思路, 在同一个符号化程序中对两个版本的 IR 代码进行等价性约束求解. 该过程主要包括以
下步骤: 首先, 基于两个 IR 代码版本构建一个统一的产品程序 (如图 4 所示). 该程序结构与此前阶段类似, 包含外
部函数调用定义和 main 函数两部分, 区别在于本阶段将同一组符号化函数参数同时传入两个目标函数中, 并插入
对二者返回值的等价性断言. 接着, 将该产品程序编译为 IR 代码形式, 并将待比较的两个 IR 模块整合至该主程序
中以进行符号执行. 最后, 通过 SMT 求解器在符号模型上对目标函数返回值的等价性断言进行求解, 据此判断两
个版本是否语义一致. 若断言失败, 则认为语义不一致, 此时丢弃当前反编译结果并重新调用 LLM 生成新的 C 代
码. 该过程循环执行, 直至获得通过语义验证的 C 代码或达到最大尝试次数.
图 4 用于等价性约束求解的产品程序示例
2.4 LLM 提示工程
在二进制代码提升与中间代码反编译阶段, LLM 承担着代码生成的关键角色. 为有效引导 LLM 正确执行代
码理解与逆向生成任务, 提示词的设计至关重要. 本节将介绍本文所采用的提示词构建过程.
总体而言, BinDec 在使用 LLM 时采用迭代反馈机制. 该方法首先由 LLM 生成初始结果, 再借助外部工具对
生成结果进行分析与反馈, 进而指导 LLM 对输出进行修正. 若经多轮修正后, LLM 的输出仍无法通过外部工具验
证, 则放弃当前结果, 并利用 LLM 输出的随机性重新生成.
在具体每个阶段的 LLM 任务中, 本文采用了一种 LLM 辅助的提示词设计流程. 首先, 通过预实验选取若干
典型代码样本, 并请求 LLM 生成面向特定任务的提示词. 例如, 提供若干汇编代码与 IR 代码的对应样本, 要求
LLM 为二进制代码提升任务生成相应提示词. 随后, 使用该提示词执行相应任务, 并基于人工检查与外部工具验
证的结果, 总结生成内容中存在的问题, 反馈给 LLM 以指导其优化提示词. 通过多次交互迭代, 直至 LLM 所生成
的提示词在预实验样本上的任务完成率趋于稳定.
针对本文中的代码生成与修复任务, 最终采用的提示词具有以下 3 项共同特征. 其一, 提出语法规范要求, 以
引导 LLM 生成语法正确且可编译的代码. 其二, 强调语义保真约束, 要求特定函数在生成或修复后与原始输入的
语义保持一致, 从而提高语义检查的通过率. 其三, 规范输出格式, 限制 LLM 仅输出代码及必要注释, 避免冗余解
释, 在增强代码可读性的同时便于后续对生成代码的解析与提取. 前述 LLM 任务所采用的提示词如表 2 所示.
表 2 BinDec 各阶段任务使用的 LLM 提示词
LLM任务 提示词模板
作为资深软件逆向工程专家, 需将{asm_type}汇编代码转换为功能等价的 LLVM IR 代码, 确保:
1) 版本合规性: 严格遵循LLVM 13.0.1工具链规范, 禁用LLVM 14+新增语法 (如 opaque ptr), 禁用以llvm.*为前缀的
二进制代 优化伪指令
码提升 2) 语义保真度: `{func_name}`函数的功能与原始汇编代码完全一致, 包含必要的外部函数和全局变量的声明
3) 生成质量: 使用最合适的IR指令, 最小化冗余指令并保持合理的可读性
4) 输出格式: 仅输出提升后的LLVM IR代码, 允许注释但不要包含解释或其他额外文本

