- 人工智能
- 大模型
- 逆向工程
- 微调
- 代码模型
【免费下载链接】LLM4Decompile
Reverse Engineering: Decompiling Binary Code with Large Language Models
本篇技术指南围绕 SK²Decompile 在 BringUpBench 基准上 O2 优化级别(-O2)的评估报告展开,逐项解读报告中的总体统计、按基准(Benchmark)细分的三项指标(Replacement / Build / Exec),并结合 eval_infer_out.py 的源码实现说明这些数字是如何通过"函数替换—重新编译—运行测试"的闭环自动测量出来的。读完本文,你将能够读懂并复现这份报告,理解反编译模型在中等优化级别下的真实能力边界与失败模式。
报告定位:O2 级别在整体评估中的位置
本报告(O2_results.md)属于 SK²Decompile 在 BringUpBench 上四个优化级别(O0–O3)评估报告之一。BringUpBench 是包含90 个自包含 C 程序的基准套件,零外部库依赖,仅依赖内置libmin库和 4 个系统调用,因此非常适合在无头文件缺失、无库依赖干扰的条件下评估反编译质量。SK²Decompile 将所有程序在 O0–O3 四个级别上编译、反编译并执行验证,共产生505 个函数(其中经推理过滤后实际评估 1488 个函数),并与工业级规则反编译器 IDA Pro(Hex-Rays)进行了对比,详见 bringupbench README。
O2 是编译器默认开启的常见优化级别,内联、寄存器分配、常量折叠等变换会显著改变二进制形态,是检验反编译器鲁棒性的关键难度档位。下表汇总了四个级别与 IDA Pro 的对照(数据来自 bringupbench README):
| Opt Level | Functions | SK²Decompile Compilable | SK²Decompile Executable | IDA Compilable | IDA Executable |
|---|---|---|---|---|---|
| O0 | 382 | 50.26% | 49.48% | — | — |
| O1 | 379 | 40.90% | 39.05% | — | — |
| O2 | 368 | 37.77% | 34.24% | — | — |
| O3 | 359 | 31.75% | 29.53% | — | — |
| Avg | 1488 | 42.3% | 27.0% | 23.6% | 21.7% |
可以看出,随着优化级别升高(O0 → O3),可编译率与可执行率单调下降,这是符合预期的:优化越激进,原始源代码结构信息丢失越多。平均而言,SK²Decompile 在全部 1488 个函数上取得42.3% 的编译率与 27.0% 的可执行率,高于 IDA Pro 的 23.6% / 21.7%(平均行数据取自论文 Section A.6 的 Table 8,各优化级别的 IDA 基线在论文中未单独报告)。
O2 报告总体统计:一次 100% 替换的完整评估
O2 报告头部给出了本次评估的运行元信息与总体结果:
- Timestamp:20251119-170633
- Source JSONL:merged.O2.func_map.infer.jsonl
- Target:host(原生 x86-64 Linux)
- Total cases:368
- Replacement success:368(100.00%)
- Compilable:139(37.77%)
- Executable:126(34.24%)
三个指标的含义(依据 bringupbench README 的 Metrics 表与 eval_infer_out.py 源码):
| Metric | Definition |
|---|---|
| Replacement Rate | 反编译输出能够被定位并替换回原始源文件中的函数占比 |
| Compilable Rate | 替换后修改过的源文件能够成功编译(make build)的函数占比 |
| Executable Rate | 编译后的程序能够通过其测试套件(make test,输出与参考一致)的函数占比 |
值得强调的是"Replacement success: 368 (100.00%)"这一项:说明 SK²Decompile 的推理输出(pseudo.content-fix字段)对于全部 368 个案例都能被精确定位并替换到原源文件中。从源码看,这一步骤由replace_function_body()实现(eval_infer_out.py):它先对原文、参考函数与推理输出做换行符归一化(canonicalize),再尝试三种匹配形态(原始文本、去尾空白加换行、去首尾空白),一旦找到精确子串即完成替换——这要求推理输出的函数体在文本层面与源码中的原始函数严格对齐。
Benchmark Breakdown:90 个程序在 O2 下的逐项表现
报告主体是 90 个基准程序(Benchmark)在 O2 下的逐项统计表。下表完整继承自 O2_results.md:
| Benchmark | Cases | Replacement% | Build% | Exec% |
|---|---|---|---|---|
| ackermann | 2 | 100.00% | 50.00% | 50.00% |
| aes | 10 | 100.00% | 20.00% | 20.00% |
| anagram | 13 | 100.00% | 46.15% | 46.15% |
| audio-codec | 3 | 100.00% | 33.33% | 33.33% |
| avl-tree | 15 | 100.00% | 20.00% | 20.00% |
| banner | 1 | 100.00% | 0.00% | 0.00% |
| bit-kernels | 3 | 100.00% | 66.67% | 66.67% |
| blake2b | 4 | 100.00% | 0.00% | 0.00% |
| bloom-filter | 4 | 100.00% | 50.00% | 50.00% |
| boyer-moore-search | 3 | 100.00% | 0.00% | 0.00% |
| bubble-sort | 3 | 100.00% | 100.00% | 100.00% |
| c-interp | 10 | 100.00% | 50.00% | 50.00% |
| ccmac | 1 | 100.00% | 0.00% | 0.00% |
| checkers | 16 | 100.00% | 68.75% | 62.50% |
| cipher | 3 | 100.00% | 66.67% | 0.00% |
| congrad | 1 | 100.00% | 0.00% | 0.00% |
| connect4-minimax | 13 | 100.00% | 61.54% | 53.85% |
| convex-hull | 4 | 100.00% | 75.00% | 75.00% |
| dhrystone | 5 | 100.00% | 20.00% | 20.00% |
| distinctness | 2 | 100.00% | 0.00% | 0.00% |
| fft-int | 4 | 100.00% | 50.00% | 50.00% |
| flood-fill | 2 | 100.00% | 50.00% | 50.00% |
| frac-calc | 10 | 100.00% | 50.00% | 50.00% |
| fuzzy-match | 3 | 100.00% | 33.33% | 33.33% |
| fy-shuffle | 3 | 100.00% | 33.33% | 33.33% |
| gcd-list | 2 | 100.00% | 50.00% | 0.00% |
| grad-descent | 4 | 100.00% | 25.00% | 25.00% |
| graph-tests | 20 | 100.00% | 10.00% | 10.00% |
| hanoi | 1 | 100.00% | 0.00% | 0.00% |
| heapsort | 2 | 100.00% | 50.00% | 50.00% |
| heat-calc | 1 | 100.00% | 0.00% | 0.00% |
| huff-encode | 13 | 100.00% | 92.31% | 92.31% |
| idct-alg | 3 | 100.00% | 66.67% | 33.33% |
| indirect-test | 2 | 100.00% | 50.00% | 50.00% |
| k-means | 6 | 100.00% | 33.33% | 33.33% |
| kadane | 2 | 100.00% | 50.00% | 50.00% |
| kepler | 7 | 100.00% | 14.29% | 14.29% |
| knapsack | 3 | 100.00% | 33.33% | 33.33% |
| knights-tour | 3 | 100.00% | 33.33% | 33.33% |
| life | 14 | 100.00% | 21.43% | 14.29% |
| longdiv | 6 | 100.00% | 50.00% | 50.00% |
| lu-decomp | 3 | 100.00% | 33.33% | 33.33% |
| lz-compress | 2 | 100.00% | 100.00% | 100.00% |
| mandelbrot | 1 | 100.00% | 0.00% | 0.00% |
| matmult | 1 | 100.00% | 0.00% | 0.00% |
| max-subseq | 2 | 100.00% | 0.00% | 0.00% |
| mersenne | 3 | 100.00% | 0.00% | 0.00% |
| minspan | 8 | 100.00% | 25.00% | 25.00% |
| monte-carlo | 1 | 100.00% | 0.00% | 0.00% |
| murmur-hash | 2 | 100.00% | 0.00% | 0.00% |
| n-queens | 3 | 100.00% | 66.67% | 66.67% |
| natlog | 1 | 100.00% | 0.00% | 0.00% |
| nbody-sim | 1 | 100.00% | 0.00% | 0.00% |
| nr-solver | 1 | 100.00% | 100.00% | 100.00% |
| packet-filter | 4 | 100.00% | 0.00% | 0.00% |
| parrondo | 2 | 100.00% | 50.00% | 50.00% |
| pascal | 3 | 100.00% | 66.67% | 66.67% |
| pi-calc | 1 | 100.00% | 0.00% | 0.00% |
| primal-test | 3 | 100.00% | 33.33% | 33.33% |
| priority-queue | 5 | 100.00% | 80.00% | 80.00% |
| qsort-demo | 7 | 100.00% | 28.57% | 28.57% |
| qsort-test | 5 | 100.00% | 80.00% | 80.00% |
| quaternions | 4 | 100.00% | 0.00% | 0.00% |
| rabinkarp-search | 2 | 100.00% | 0.00% | 0.00% |
| rand-test | 3 | 100.00% | 0.00% | 0.00% |
| ransac | 2 | 100.00% | 50.00% | 0.00% |
| regex-parser | 7 | 100.00% | 28.57% | 14.29% |
| rho-factor | 3 | 100.00% | 66.67% | 66.67% |
| rle-compress | 2 | 100.00% | 0.00% | 0.00% |
| rsa-cipher | 4 | 100.00% | 0.00% | 0.00% |
| sat-solver | 5 | 100.00% | 60.00% | 60.00% |
| shortest-path | 3 | 100.00% | 66.67% | 66.67% |
| sieve | 1 | 100.00% | 0.00% | 0.00% |
| simple-grep | 1 | 100.00% | 0.00% | 0.00% |
| spelt2num | 1 | 100.00% | 0.00% | 0.00% |
| spirograph | 2 | 100.00% | 50.00% | 0.00% |
| sudoku-solver | 4 | 100.00% | 50.00% | 50.00% |
| tetris-sim | 12 | 100.00% | 75.00% | 58.33% |
| tiny-NN | 4 | 100.00% | 25.00% | 25.00% |
| topo-sort | 7 | 100.00% | 0.00% | 0.00% |
| totient | 2 | 100.00% | 50.00% | 50.00% |
| transcend | 1 | 100.00% | 0.00% | 0.00% |
| uniquify | 1 | 100.00% | 0.00% | 0.00% |
| vectors-3d | 8 | 100.00% | 12.50% | 0.00% |
| verlet | 1 | 100.00% | 0.00% | 0.00% |
| weekday | 2 | 100.00% | 0.00% | 0.00% |
从表格中可提炼的规律
高表现区间(≥80% Build/Exec):bubble-sort、lz-compress、nr-solver(均 100%),huff-encode(92.31%)、priority-queue与qsort-test(均 80%)。这些程序要么结构规整、要么逻辑简单直接,说明在 O2 下简单算法的函数级反编译恢复率很高。
中等区间(50%–80%):checkers(68.75% / 62.50%)、connect4-minimax(61.54% / 53.85%)、sat-solver(60.00%)、tetris-sim(75.00% / 58.33%)、sudoku-solver(50.00%)等。值得注意的是checkers、tetris-sim这类"规则密集型"程序,其 Build% 高于 Exec%,说明反编译结果语法正确但语义仍有偏差(函数能编译,但行为与测试期望不符)。
"编译成功但执行失败"的典型:cipher(Build 66.67% / Exec 0.00%)、gcd-list(50.00% / 0.00%)、ransac(50.00% / 0.00%)、spirograph(50.00% / 0.00%)、vectors-3d(12.50% / 0.00%)、regex-parser(28.57% / 14.29%)、idct-alg(66.67% / 33.33%)、life(21.43% / 14.29%)。这种"编译通过但运行结果错误"的模式在反编译评估中非常典型:类型、指针运算、边界条件等细微语义错误的函数依然能通过语法编译,但运行时行为与参考程序不一致。
完全失败(0.00%):banner、blake2b、boyer-moore-search、ccmac、congrad、distinctness、hanoi、heat-calc、mandelbrot、matmult、max-subseq、mersenne、monte-carlo、murmur-hash、natlog、nbody-sim、packet-filter、pi-calc、quaternions、rabinkarp-search、rand-test、rle-compress、rsa-cipher、sieve、simple-grep、spelt2num、topo-sort、transcend、uniquify、verlet、weekday等。这些程序在 O2 下没有任何一个函数能成功编译,往往是整体性的结构问题(例如topo-sort7 个函数全部失败,说明图数据结构的指针操作在 O2 优化后极难恢复)。
失败明细:Compilation Failures 与 Execution Failures 的判读
报告末尾以源文件::函数名@函数地址格式列出了两类失败。函数地址(如@0x1100、@0x18c0)对应二进制中的虚拟地址,可用于与 merged.O2.func_map.jsonl 中的pseudo.address字段精确对应。
Compilation Failures(229 条,略举代表性条目)
ackermann/ackermann.c::main@0x1100aes/aes.c::aes_decrypt@0x18c0、aes/aes.c::aes_encrypt@0x1780、aes/aes.c::inv_mix_columns@0x1640、aes/aes.c::key_expansion@0x16d0、aes/aes.c::mix_columns@0x1580、aes/aes.c::shift_rows@0x1480、aes/aes.c::inv_shift_rows@0x14f0、aes/aes.c::main@0x1100avl-tree/avlcore.c::Insert@0x1f30、avl-tree/avlcore.c::DeleteByElement@0x2860、avl-tree/avlcore.c::DeleteByElementRecursive@0x26d0、avl-tree/avlcore.c::DeleteLeftMost@0x2610、avl-tree/avlcore.c::DoubleLeftRotation@0x1c00、avl-tree/avlcore.c::DoubleRightRotation@0x1bd0、avl-tree/avlcore.c::FindByElement@0x1b00、avl-tree/avlcore.c::MakeEmpty@0x1f80、avl-tree/avlcore.c::CheckTreeNodeRotation@0x1c30c-interp/c-interp.c::eval@0x3e90、c-interp/c-interp.c::function_body@0x37f0、c-interp/c-interp.c::function_declaration@0x3a10、c-interp/c-interp.c::next@0x1580connect4-minimax/connect4-minimax.c::minimax@0x1840、connect4-minimax/connect4-minimax.c::play_game@0x1c90、connect4-minimax/connect4-minimax.c::score_position@0x1620、connect4-minimax/connect4-minimax.c::init_board@0x1230graph-tests/graph-tests.c::main@0x1120、graph-tests/graph-tests.c::bfs@0x1540、graph-tests/graph-tests.c::depthFirstSearch@0x1b20等 20 个案例life/life.c::main@0x1100、life/life.c::process@0x1550、life/life.c::getNumNeigbors@0x1390等 14 个案例regex-parser/regex-parser.c::matchpattern@0x2670等 7 个案例
编译失败占比约 62%(229/368),是 O2 级别的"主要瓶颈"。从失败清单的分布可以推断:指针密集、结构体嵌套深、递归/回溯算法(avl-tree、graph-tests、c-interp、regex-parser)在 O2 优化后反编译结果的类型与语法恢复难度显著上升。
Execution Failures(13 条,完整列出)
checkers/functions.c::all_possible_moves@0x1a60cipher/cipher.c::decipher@0x1360cipher/cipher.c::encipher@0x12f0connect4-minimax/connect4-minimax.c::terminal_score@0x1800gcd-list/gcd-list.c::gcd@0x1310idct-alg/idct-alg.c::idct_2d@0x12f0life/life.c::init@0x1220ransac/ransac.c::ransac_line_fitting@0x1410regex-parser/regex-parser.c::matchpattern@0x2670spirograph/spirograph.c::test@0x1390tetris-sim/tetris-sim.c::clear_lines@0x1480tetris-sim/tetris-sim.c::simulate_board@0x17c0vectors-3d/vectors-3d.c::get_angle@0x17d0
执行失败的含义是:该函数反编译结果成功替换并编译通过,但运行make test时输出与参考不一致。观察这些案例可以发现语义错误的集中模式:gcd(辗转相除的循环边界)、idct_2d(浮点/查表变换)、clear_lines/simulate_board(游戏状态更新逻辑)、get_angle(向量夹角计算)、matchpattern(正则匹配)。这类案例是反编译"最后一公里"问题——语法正确但语义漂移,也正是 verl/SK2DECOMPILE 中基于编译器反馈的强化学习(GRPO)奖励函数所针对优化的对象。
这些数字是如何测出来的:评估脚本源码解析
报告中的每个数字都由 eval_infer_out.py 自动生成,其处理逻辑清晰地解释了指标口径:
- 逐案例处理(
process_case):从 JSONL 中读取每个案例,用replace_function_body()把源文件中的原始函数文本替换为反编译结果(pseudo.content-fix); - 隔离工作区(
prepare_workspace):为避免案例间相互污染,每个案例复制Makefile、common/、target/及对应基准目录到独立临时工作区(eval_infer_out.py),默认--jobs 96并行处理; - 依次执行
make TARGET=host clean→make TARGET=host build→make TARGET=host test,每步默认 20 秒超时(--command-timeout 20);build 通过记为 Compilable,build 且 test 均通过记为 Executable; - 聚合汇总(
compute_summary/write_summary):按基准目录分组统计 Replacement / Build / Exec 三项比率,并输出 Compilation Failures(build failed)与 Execution Failures(build 成功但 test 失败)清单,最终生成 JSON 与 Markdown 两类报告。
复现报告只需预置数据 + BringUpBench 源码仓库:
# 1. 克隆 Bringup-Bench(上游基准套件) git clone https://github.com/toddmaustin/bringup-bench.git # 2. 配置路径(BENCH_REPO_ROOT 指向 bringup-bench 根目录) cd sk2decompile/evaluation/bringupbench vim config.env # 设置 BENCH_REPO_ROOT=/path/to/bringup-bench # 3. 运行 O2 评估 python3 scripts/eval_infer_out.py data/infer_results/merged.O2.func_map.infer.jsonl \ --jobs 16 \ --command-timeout 20 # 4. 查看结果 cat reports/O2_results.md常用参数(默认值来自 eval_infer_out.py 的参数解析):
| 参数 | 默认值 | 说明 |
|---|---|---|
--jobs N | 96 | 并行处理案例数(ThreadPoolExecutor并发) |
--command-timeout S | 20 | 每条 make 命令的超时秒数,0 表示不设超时 |
--limit N | None | 只处理前 N 个案例(调试用) |
--keep-workspaces | False | 保留临时构建工作区(默认处理完删除) |
--target | host | 传给 make 的 TARGET 变量(默认原生 x86-64 Linux) |
--bench-root | config.env | Bringup-Bench 仓库根目录,优先级 CLI > 环境变量 > config.env |
配置文件的优先级同样体现在 config.env:BENCH_REPO_ROOT、IDA_BIN(Step 2 用)、DEFAULT_TARGET=host,均可被同名环境变量或 CLI 参数覆盖。
从报告到流水线:O2 数据在整个评估体系中的位置
报告对应的推理数据文件 merged.O2.func_map.infer.jsonl(368 个案例)源自上游 merged.O2.func_map.jsonl(441 个函数)。两者数量差(441 → 368)源于推理阶段的过滤——例如超过 token 上限的函数会被剔除(见 bringupbench README 的 Notes)。
整个 BringUpBench 评估采用五步流水线:编译(O0–O3)→ IDA Pro 伪代码基线 → 函数级真值映射 → SK²Decompile 两阶段推理 → 替换/编译/执行验证。其中 SK²Decompile 的两阶段推理由 sk2decompile_inf.py 完成:Phase 1(Skeleton,sk2decompile-struct-6.7b)将规范化伪代码恢复为结构中间表示,Phase 2(Skin,sk2decompile-ident-6.7)再恢复可读标识符,最终输出写入 JSONL 的pseudo.content-fix字段供 Step 5 验证使用。
如需在 O2 数据上完整复现反编译推理步骤:
cd sk2decompile/evaluation/ python3 sk2decompile_inf.py \ --dataset_path bringupbench/data/func_maps/merged.O2.func_map.jsonl \ --model_path LLM4Binary/sk2decompile-struct-6.7b \ --recover_model_path LLM4Binary/sk2decompile-ident-6.7b需要说明的适用前提:SK²Decompile 的训练面向 C 语言 Linux-x64 代码(IDA 伪代码输入),其他语言或架构上的效果可能衰减;BringUpBench 程序自包含、零外部依赖,这保证了评估不受缺失头文件或库函数的干扰(见 sk2decompile README)。
结论与阅读建议
O2 报告给出了 SK²Decompile 在中等优化级别下的清晰画像:100% 的替换成功率保证了评估覆盖完整性;37.77% 的编译率与 34.24% 的可执行率表明近六成函数仍无法通过编译验证,且编译失败远多于执行失败,说明 O2 下反编译的"结构级恢复"仍是主要挑战;而cipher、vectors-3d等"编译通过但执行失败"的案例则指向语义精度问题。
若要继续深入研究,建议按以下顺序阅读仓库中的关联材料:
- O0_results.md / O1_results.md / O3_results.md——对比不同优化级别下的能力衰减曲线;
- bringupbench README——完整五步复现流水线与数据格式(
func_map.jsonl、func_map.infer.jsonl字段说明); - eval_infer_out.py——评估脚本的完整实现;
- sk2decompile_inf.py——两阶段推理管线的实现与参数。
- 人工智能
- 大模型
- 逆向工程
- 微调
- 代码模型
【免费下载链接】LLM4Decompile
Reverse Engineering: Decompiling Binary Code with Large Language Models
相关推荐
filebrowser config init 完全指南:初始化 File Browser 数据库与全局配置
filebrowser config init 完全指南:初始化 File Browser 数据库与全局配置 导读 filebrowser config ini
人工智能大模型逆向工程微调代码模型大麦抢票自动化系统:告别抢票焦虑,轻松锁定心仪演出
大麦抢票自动化系统:告别抢票焦虑,轻松锁定心仪演出 还在为抢不到演唱会门票而烦恼吗?想象一下,当别人还在紧张地刷新页面时,你已经通过自动化系统完成了从登录到下单
GUI 自动化RPALighthouse编译优化:代码编译和执行效率
Lighthouse编译优化:代码编译和执行效率 引言 在Web开发中,性能优化是至关重要的一环。Lighthouse作为一款自动化的网页质量评估工具,其自身的
开发工具测试性能测试前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考