关于 Every App Is Open Source
Every App Is Open Source(EAOS)是借助 Ghidra 让 Agent 检查编译程序的 MCP 服务,面向 Apple Silicon Mac 上的原生逆向分析。工具以简短结果呈现发现,并提供可追溯、经哈希校验的证据,同时区分事实、计算结果和猜测。
主要功能
- 01基于 Ghidra 的原生程序分析
- 02搜索和检查函数
- 03静态调用者与被调用者遍历
- 04经哈希校验的保存证据
- 05应用清单与 JavaScript 检查
适用场景
- 01检查编译程序中的函数
- 02追踪有界静态调用关系
- 03依据证据核验 Agent 的结论
- 04盘点应用组件以供检查
MCP 相关
MCP 服务提供程序分析工具,例如搜索、检查、读取内存和检索证据。可用工具随会话类型变化:原生文件会话提供八种工具,应用目录会话提供十一种。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Every App Is Open Source
给你的 AI Agent 一个编译后的程序,它就能弄清楚程序是如何构建的。Ghidra 负责反编译。这是 Agent 这边的部分:一小组 MCP 工具,默认提供简短回答,并附上可追溯到二进制文件的证据。
这个名字是一种挑衅,并非许可证。了解应用的工作原理,并不意味着你有权复制它。请阅读免责声明。
效果一览
一个只连接到 EAOS 的 Agent 获得了一个小型编译程序,并被问到 quote(6) 会返回什么。以下是它实际调用的工具:
| 工具调用 | 返回内容 |
|---|---|
search {"kind":"functions","pattern":"quote"} | 位于 0x100000460 的 _quote |
inspect {"addresses":["100000460"],"mode":"all"} | 汇编和反编译后的代码,保存为证据 fe8589bb… |
read_evidence {"id":"fe8589bb…"} | 已保存的证据,且已通过哈希校验 |
它的回答是:45。函数在小于 4 时返回 19,否则返回 7*n + 3,并引用了地址和证据 ID。
这是一个基于版本 0.1.1、使用已完成分析的缓存记录的会话,并非基准测试。完整记录包含每次调用及其局限。
横向比较
我在三个经过修改的程序上,将它与 REA 和 GhidraMCP 进行了比较,每种工具使用相同的模型和问题。结果取决于目标,EAOS 并非每次都占优:
| 目标 | EAOS 版本 | 与 GhidraMCP 相比 | 与 REA 相比 |
|---|---|---|---|
| 修改版 Doom | 0.1.0 | 成本低 16%,速度快 17%;18/18 全部正确 | 成本低 36%,速度快 27%;18/18 全部正确 |
| 修改版 Ollama | 0.1.4 | 成本高 28%,速度慢 23%;GhidraMCP 漏掉了 195 个案例中的 3 个 | 成本低 14%,速度快 17%;两者均为 195/195 |
| 修改版 Ollama,第 2 轮 | 0.1.5 | 成本低 6%,耗时相近 | 成本低 25%,耗时相近 |
成本是按 API 价格折算的模型费用;耗时不包括初始分析。每行数据都是每种工具运行 3 次的结果,因此这些数据仅作描述,并非普遍排名。第 2 轮中,其他工具漏掉的案例主要涉及标头顺序和不完整的错误文本,而非行为错误。修改后的程序和答案密钥均为私有,因此测试无法被提前泄露。这意味着你可以查看每次运行的摘要、评分审查和协议,但无法自行重现这些确切的对比结果。所有数字、失分项和局限都列在 BENCHMARKS.md 中。
获取第一个结果
这些说明适用于 0.2.0。发布前,请使用经过审核的本地 wheel 路径替代软件包要求。
你需要一台 Apple Silicon Mac、uv 和 Apple 的命令行工具(xcode-select --install)。目前尚不支持 Windows、Linux 和 Intel Mac。
1. 安装。 这会下载带校验和固定的 Java 和 Ghidra(约 770 MB),并构建 Ghidra 的 Apple Silicon 反编译器;官方下载安装包不包含该反编译器:
uvx --python 3.13 --from every-app-is-open-source==0.2.0 eaos setup
所有文件都会放入 ~/Library/Application Support/Every App Is Open Source/。它不会修改你的 shell 配置文件、系统 Java 或 Agent 设置。版本、大小、故障排除和卸载说明见 SETUP.md。
2. 构建一个小型测试程序并分析它:
mkdir -p /tmp/eaos-example
cat > /tmp/eaos-example/example.c <<'C'
#include <stdio.h>
__attribute__((noinline)) int quote(int n) { return n < 4 ? 19 : n * 7 + 3; }
int main(int argc, char **argv) { puts("eaos fixture anchor"); return quote(argc); }
C
clang -O0 /tmp/eaos-example/example.c -o /tmp/eaos-example/example
uvx --python 3.13 --from every-app-is-open-source==0.2.0 eaos call /tmp/eaos-example/example open_program
你应该会看到 classification: computed、ARM64 语言、SHA-256 和证据 ID。
3. 连接你的 Agent。 对于 Claude Code:
claude mcp add --transport stdio --scope local eaos -- uvx --python 3.13 --from every-app-is-open-source==0.2.0 eaos mcp /tmp/eaos-example/example
Codex 和其他 MCP 客户端的配置说明见 CLIENTS.md。
4. 提问:
找到 quote 函数。quote(6) 会返回什么?解释两个分支,并引用函数地址和已保存的证据。
正确答案是 45。这可以检查你的配置是否正常,但不能证明 Agent 能理解任何应用。地址取决于编译器,因此你的地址会与上方示例不同。
对于独立程序,使用相同的 eaos mcp /absolute/path/to/program 命令。对于应用目录,请通过显式指定外部工作区来选择其根目录:
uvx --python 3.13 --from every-app-is-open-source==0.2.0 eaos mcp /Applications/Example.app --workspace /absolute/path/outside-bundles/eaos-workspace
让 Agent 清点根目录,根据返回的 ID 选择一个原生组件,然后检查该组件。完整原生分析仍是默认模式;快速模式需要主动启用。仍然会拒绝处理软件包内单个可执行文件的路径;如需独立分析,请将可执行文件复制出来。对于大型独立程序,可在连接 Agent 之前先在终端完成预分析。
工具
最初,我根据 Agent 在此前 24 次测试运行中的调用设计了七个工具。原生文件会话现在提供 八个工具,包括有界静态调用遍历。应用程序目录会话提供 十一个工具,新增清单、显式组件选择和有界 JavaScript 检查。
| 工具 | 功能 |
|---|---|
open_program | 了解程序:架构、内存布局、分析状态 |
search | 查找程序中的文本及其使用位置,或查找函数 |
inspect | 反编译代码、原始指令、调用方和被调用方 |
read_memory | 读取静态内存或 Go 字符串表,并提供来源信息 |
calculate | 安全地执行算术运算和字节解码,避免 Agent 在脑中计算 |
decode_swift_string | 还原 Apple 平台上隐藏在 Swift 代码中的文本 |
read_evidence | 调取任何回复背后完整的已保存证据,并校验哈希 |
trace_calls | 跟踪有界的静态调用方/被调用方关系,保留间接边和作为未解决项的截断情况 |
应用程序目录会话还提供:
| 工具 | 功能 |
|---|---|
inventory_application | 清点选定根目录和受支持的 ASAR 成员,并明确列出缺口和预算 |
select_component | 在原始捆绑包之外捕获并选择一个已清点的原生组件 |
inspect_javascript | 检查捕获的 JavaScript 源码;开发配置文件还支持针对性地检查 preload/模块,以及有界证据关系 |
0.2.0 在 0.1.9 的基础上扩展了最初的 JavaScript/ASAR 检查功能;该版本的源码检查上限为 1 MiB。
0.2.0 的源码配置文件支持捕获连贯、最大 8 MiB 的 JavaScript,并提供明确的有界语法索引续查和固定大小的结果页。聚焦于一个已观察到的 preload API,检查一个选定模块或其周边加载器骨架,然后将选定的已保存证据组合成紧凑的源码关系包。每个候选项都会保留其组件、源码、表和证据标识;未知绑定会明确标出。Python 解析器依赖随软件包提供;不会执行 JavaScript 或应用程序。
在官方 Electron Fiddle 0.39.0 上,记录的开发检查分析了其大型捆绑包,生成了 60 个选定源码节点、六个条件式模块查找候选项和三个保留的精简 preload 关系。该检查没有确立完整的主进程 IPC 边:动态工厂替换、加载器/互操作身份、继承的分发机制和进程上下文仍未解决。这些是本地静态检查,并非对比基准测试,也不代表 Agent 能可靠作答。另一次有界 Ghostty 跟踪仍未确立完整的 Swift/C/Zig 重新加载链。完整的 Electron 支持、重构后的应用程序和 REA 同等能力均未确立。
原生遍历也会保留未准备的快速模式候选项的可用名称。但这并不会准备这些候选项的指令体,也不能确立缺失的关系。完整原生分析仍是默认模式。
每个工具的确切输入、输出和限制都列在工具契约中。
每个工具结果都会说明自身性质
每个工具结果都标有以下标签:
- 事实:直接读取捕获的二进制文件或源码所得
- 计算结果:根据这些内容推导而来,例如反编译代码或解码字符串
- 猜测:尚未验证的推断
反编译代码属于计算结果,而非原始源码。成功的分析结果包含已保存的证据,可通过 read_evidence 调取。状态响应和错误不包含证据 ID;工具失败不代表作出了任何分析结论。
这些标签描述的是工具结果,而不是 Agent 的最终回答。Agent 仍可能误读标记正确的证据。这些标签和证据 ID 可让你核查结论,但不能为结论背书。
分析一次,重复使用
Ghidra 的分析速度较慢,因此每个独立程序都会在其旁边获得一个专属的 eaos-analysis/<sha256>/ 文件夹,其中包含分析项目和证据。重新打开兼容的当前版本配置文件时,会重复使用这些内容;不同的引擎、架构或分析配置文件可能需要重新分析。应用程序目录捕获和原生缓存会存放在明确指定的外部工作区中。0.1.7 之前创建的项目会保留,但不会重复使用:0.1.7 会以新的缓存格式重新分析程序。
每个会话都会使用其计算哈希值时对应的精确字节的只读副本,因此更改原始文件不会影响已打开的会话。如果缓存项目与程序的哈希值不符,程序会停止,而不是猜测,并且绝不会删除旧证据。
Ghidra 有个小问题:它不会在名称以点开头的文件夹(例如 .cache)中创建项目。请不要将要分析的程序放在这类文件夹中。
分析选项
默认使用完整分析。CLI 和 MCP 服务支持 --analysis-mode quick,用于准备部分元数据和请求的函数;也支持 --architecture arm64,用于明确指定 Mach-O 切片。快速函数搜索提供明确的、有界索引续查,与受视图限制的结果分页分开。快速模式仅适用于 64 位 ARM/x86 Mach-O;它无法恢复所有 Swift 名称,也无法证明缺失的引用不存在。近期没有进行新的速度或准确度对比。
在 Apple Silicon 上,兼容的通用输入会自动选择 ARM64。每个已捕获的整文件哈希值都会在 profiles/ 下保留单独的架构/配置文件/引擎缓存,并共享不可变证据。旧版项目会保留;新缓存格式不会重复使用这些项目。原生操作期间仍可查看状态,并支持配置截止时间和取消操作。使用这些选项前,请参阅设置和工具契约。
基准测试的运行方式
摘要见上文;详细信息位于 BENCHMARKS.md,每个目标占一行,并分别链接到其运行摘要和评分。
每次都遵循相同的规则:
- 使用相同的模型,每个工具开启全新会话并运行三次。
- 问题和答案密钥在首次运行前冻结。 如果模型可能记得答案,我会暗中修改答案并先重新构建程序。
- 起点相同。 每个工具开始计时前,程序都已完成分析。
- REA 按照人们实际安装的方式运行, 使用其捆绑的技能和完整工具目录。
- 所有内容都会保留, 包括我输掉的轮次。
由于目标和答案密钥不公开,你无法重现我进行的确切对比。你可以使用基准测试指南,在自己的目标上采用相同的方法。
接下来要做什么
目前,它可以在 Apple Silicon Mac 上分析原生程序,并提供选定根目录的清单以及初步的 JavaScript/ASAR 检查。我希望它能检查更多类型的软件,但目前没有固定顺序或时间表:新增支持需基于已证实的需求和可复现的测试,而且在做出任何声明前,每项支持都会有自己的基准测试。
安全
这些工具会暴露所选程序,或明确选定的应用根目录和组件,以及它们生成的证据。这里没有通用的文件读取或 shell 工具。不过,Python 和 Java 进程并未受到操作系统沙箱的隔离:它们以你的用户权限运行,而且从二进制文件中提取的文本并不可信。在分析任何你不信任的内容之前,请阅读安全模型。
发现漏洞?请私下报告,不要在公开的议题中报告。
开发
uv build
PYTHONPATH=src uv run --no-project --python 3.13 python -m unittest discover -s tests -v
python3 scripts/check_distribution.py dist
各项测试的运行位置:
| 检查项 | 运行位置 |
|---|---|
| 单元测试、失败场景测试和打包测试 | CI 在 Ubuntu 上运行,每次推送时执行 |
| 已安装 wheel 的 CLI 冒烟测试 | CI 在 Ubuntu 上运行,每次推送时执行 |
| 使用真实 Ghidra 的原生检查(12 项测试) | 每次发布前在已配置的 Mac 上本地运行;CI 中跳过 |
绿色的 CI 徽章仅涵盖前两行。运行 eaos setup 或 ./install.sh 后,要运行原生检查:
EAOS_NATIVE_TESTS=1 uv run python -m unittest discover -s tests -v
如果要从代码检出目录而不是 PyPI 开始,./install.sh 会在本地完成所有设置,然后运行 ./eaos mcp /absolute/path/to/program 来启动服务。
贡献
这是我的项目,由我自己开发。非常欢迎通过议题提交错误报告和想法。我不接受外部代码贡献。如果你想把它发展到其他方向,可以创建分支;这正是许可证的意义所在。更多信息请参阅 CONTRIBUTING.md。
许可证和致谢
Apache-2.0。如果你基于它进行开发,请保留 NOTICE 文件。每个版本的变更记录见更新日志。
Ghidra 和 PyGhidra 承担了主要工作;它们是各自贡献者的成果。对比基准采用 LaurieWired 的 GhidraMCP。我用于基准测试的程序及其许可证列于 BENCHMARKS.md。
由 thomasisalwayslate 制作。我制作应用、游戏和小工具,通常是自己也想用的东西。更多内容请访问我的网站,其中包括基准测试背后的分析文章。
如果这帮你省下了一些摸索时间,点个 ⭐ 就能帮助其他人发现它。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。