感谢你下载我的 Ghidra + LLM 流水线。
这是我的第一份 README。ASL(美国手语)是我的第一语言,所以我的英语并不完美。我已尽了最大努力。
我热爱一款从小就玩的旧 PC 模拟游戏,我想在底层对它进行改进。
研究 OpenRA 和 OpenTTD 这类开源游戏让我明白了一点:爱好者的重实现并不是要拿到原始源代码。而是要构建一个全新的开源版本,能够加载原版的资源。这样任何人都可以扩展它或为它做贡献。
为了完成这项工作,我把两种 AI 结合使用:
每个函数都会得到一个标签。这能节省大量时间,因为我不会把精力浪费在大量操作系统和运行时垃圾上。
|-----------|------------------------------------------------------------------------------------------------------------------
| 标签 | 含义 |
|---|---|
| KEEP | 游戏自身的逻辑(例如飞行模型、伤害模型、TrackIR) |
| WRAP | 面向 Java 的胶水代码,调用操作系统或输入 API:保留签名,编写新的函数体。 |
| (IL-2 1946 是一个有趣的引擎:C++ 和 Java 结合在一起。) | |
| REPLACE | 旧的 C 运行时、分配器、thunk:由编译器或操作系统提供,因此新的 64 位版本不需要它们 |
| UNKNOWN | 不明确:手动查看 |
| ----------- | ------------------------------------------------------------------------------------------------------------------ |
在我的测试程序中,大约 44% 的函数是 REPLACE,因此它们从来不需要被转换。
一开始我信任 C 伪代码能给出所有答案。那太天真了。它是 Ghidra 对汇编的解读, 而且它会猜测(变量类型、丢失的参数)。
汇编才是原始真相。它没有变量类型,但它保留了每个函数的精确行为。 因此脚本读取汇编,并将其转换为 C 风格形式的蓝图。Ghidra 的 C 仅作为提示保留。
我早期的测试使用本地 LLM(Qwen 2.5 Coder、DeepSeek Coder V2 Lite、Mellum 2)直接读取汇编。 它从未可靠地工作过。它们会产生幻觉,因为它们被设计用来编写代码,而不是读取原始机器码。
在多次失败的实验之后,我拆分了工作:
注意:Python 如何检查答案
文本检查:函数名、蓝图中的每个调用、全局变量和字符串、 循环、步长、比较的常量、返回值,以及没有遗留寄存器名或臆造的名称。
gcc 编译检查:代码用 gcc 编译(仅做语法检查,不运行任何内容)。 这帮助很大。在早期的一次运行中,文本检查通过了 Mellum 2 的答案, 但它们全都没能编译通过,原因是一段写在注释之外的头部注释。 gcc 能捕捉到文本检查看不到的问题:未声明或重复声明的变量、 错误的类型,以及损坏的花括号或分号。只有当文本检查和编译 都通过时,函数才算 PASS。gcc 并不能证明逻辑正确,所以我仍然 会对照蓝图阅读代码。
如果某项检查失败,LLM 会收到失败项列表,并再尝试一次。
Python 会自行修复小疏漏,无需 LLM 介入:它为每个变量声明一次, 将零散的头部行包裹进注释,让最后一个 return 返回正确的结果, 并补上 include 和声明。
这份检查清单是在我看到 LLM 在超长函数上失败之后才加入的。它的运作方式就像飞行员在 起飞和降落前使用的检查清单。Python 根据函数生成清单,并对照清单检查答案。在我的测试中, 长函数开始通过,运行速度也变快了。
|-------------------|---------------------------------------|---------------------------------------------
| 文件夹 | 功能 | 阅读 |
|---|---|---|
ghidra_pipeline | 转储、分组、分类、角色 | ghidra_pipeline/INSTRUCTION.txt |
llm_pipeline | 蓝图与 LLM 运行器(v3) | llm_pipeline/INSTRUCTION_BLUEPRINT_LLM.txt |
| ------------------- | --------------------------------------- | --------------------------------------------- |
从 ghidra_pipeline 开始,当你准备好使用本地 LLM 时,再转到 llm_pipeline。
首先,在 PyGhidra 中分析你的程序,并运行 PyGhidra Scripts/decompile_full_dump.py。
两个 INSTRUCTION 文件说明了文件夹的设置方式。然后:
首先,在 PyGhidra 中分析你的程序,并运行 PyGhidra Scripts/decompile_full_dump.py。
两个 INSTRUCTION 文件说明了文件夹的设置方式。然后:
python .\make_full_lite_v2.py --in . --out .\OUT
python .\triage_evidence_v2.py --lite .\OUT\LITE_AC
python .\build_roles_v2.py --triage .\OUT\TRIAGE
python .\blueprint_v3.py --group ".\SOURCE\LITE_AC\<GroupName>" --out ".\G_<GroupName>\BLUEPRINT_v3"
python .\run_blueprint_llm_v3.py --bp ".\G_<GroupName>\BLUEPRINT_v3" --out ".\G_<GroupName>\RUN1_v3_<model>" --model <model name>
你需要带有 PyGhidra 的 Ghidra、Python 3、LM Studio(已加载一个模型)以及 gcc(推荐,用作编译检查)。
本仓库仅包含脚本和文档。不含游戏文件、代码或数据。请仅在你拥有的程序上使用它, 并遵守适用于这些程序的规则。
在另一个游戏上试用它,并告诉我哪些有效、哪些无效。欢迎提出想法和 改进建议。
你可以自由地取用这些脚本并进一步改进它们。Apache 2.0 许可证 允许你使用、修改和分享它们,所以请 fork 它、制作你自己的版本,并分享 你学到的东西。
我最喜欢的词是去中心化。对我来说,它意味着基于社区的分享和 支持,我们共同改进已有的东西。我希望这能为 爱好者重实现(逆向工程)和 LLM 开发带来新的想法。
Apache License 2.0。参见 LICENSE 和 NOTICE。
Copyright 2026 Ryu116(又名 HappyTotoro116)