【分享】把 Claude Code 的 claude.exe 拆开看:一个 235MB Bun 单文件的完整逆向笔记 —— 遥测通道、内嵌源码、系统提示词与字节码
声明:本文为纯静态分析的学习笔记,全程未修改、未传播目标程序,未绕过任何授权机制。分析对象是官方分发的 Claude Code CLI(claude.exe,v2.1.153)。文中所有结论均给出可复现的证据位置,仅供安全研究与隐私参考。
0. 写在前面:这次用的是什么工具
本次分析的主刀工具是 REA(Reverse Engineer Anything,v6.4.0)——一个把"二进制 / JS 应用 / .NET / 网页"统一接到一个 MCP 上的逆向工具箱,静态分析证据链做得非常严格(每个结论带 SHA-256、置信度和局限性声明);驱动全程的是 ZCode(智谱 GLM coding agent)——我让 agent 一边跑命令一边做字节级解析和报告整理,人工只负责定方向和验收。辅助工具:自写 Node.js 流式扫描器(对付 235MB 大文件)、js-beautify(反混淆)、Ghidra 12.1.4(原生反编译,由 REA 调度)。AI 交叉验证用的是本地 llama.cpp 加载的无审查模型(数据不出本机)。
一句话总结先行:claude.exe 没有任何加密,235MB 里藏着一份 15.4MB 的完整明文 JS 源码、约 110MB 的 JSC 字节码、以及五条默认开启的数据上传通道。
1. 目标识别:这是什么结构的 exe
文件:D:\Program Files\nodejs\node_modules\@anthropic-ai\claude-code\bin\claude.exe
大小:235,564,192 字节(225MB)
版本:2.1.153(内嵌 bundle 头部明文标注)
签名:DigiCert 代码签名(PKCS#7,SHA-256,PE Security 目录 RVA 0xe0a4400,覆盖含 .bun 段的整个文件)
用 Node 解析 PE 头,12 个段:
| 段 |
大小 |
说明 |
.text |
60.13MB |
原生代码(Bun 运行时,GCC/MinGW 编译,编译时间戳 2026-05-15) |
.rdata |
36.98MB |
只读数据(字符串常量、Rust panic 路径、vtable) |
.bun |
125.83MB |
Bun 模块图:字节码 + JS 明文源码 + 附属资产 |
| 其他(.data/.pdata/.rsrc/.reloc…) |
~2MB |
|
导入表只有 8 个系统 DLL(约 393 个函数):ntdll、KERNEL32、USER32、SHELL32、OLEAUT32、USERENV、bcryptprimitives、api-ms-win-core-synch。没有 winhttp/wininet/ws2_32——网络栈、加密(除 bcryptprimitives 外)全部静态链接进 .text。这也是为什么用常规抓 DLL 加载的方式看不到它的行为特征。
最有意思的是 .bun 段:Bun 用 bun build --compile 打包时,把应用连同 JS 源码、预编译的 JSC 字节码、资产一起作为正式 PE 段塞进去,段内布局:
.bun 段内:
[JSC 字节码 blob(含常量表、模块元数据)]
[15.4MB 明文 JS 主 bundle:"// @bun @bytecode @bun-cjs" 头 + CJS 包装]
[BUN/root/image-processor.js、audio-capture.js 资产模块]
["---- Bun! ----" 模块图 trailer + DigiCert 签名块]
明文 bundle 的尾部还带出了它的仓库路径 B:/~BUN/root/src/entrypoints/cli.js——顺便确认了 Claude Code 的源码目录结构。
2. 第一步:云端行为扫描(它往外传什么)
对 235MB 文件做了 5 遍流式扫描(主机枚举 → 遥测关键词 → 上下文提取 → 事件名 → 上传目的地),扫出 209 个 URL 主机后聚焦分析,确认 5 条真实上传通道:
| # |
端点 |
用途 |
关闭开关 |
| 1 |
api.anthropic.com/api/event_logging/v2/batch |
产品遥测批量上报(200 条/批,失败重试 8 次,指数退避至 30s;事件先落盘 ~/.claude/telemetry/ 再发) |
DISABLE_TELEMETRY / DO_NOT_TRACK |
| 2 |
http-intake.logs.us5.datadoghq.com/api/v2/logs |
日志上传到 Anthropic 的 Datadog US5 实例(内嵌公共 intake key),事件名 tengu_log_datadog_events |
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC |
| 3 |
{base}/api/oauth/file_upload |
OAuth Bearer multipart 文件上传(会话附件) |
功能门控 |
| 4 |
claude.ai/api/desktop/win32/x64/exe/latest/redirect |
桌面版更新重定向 |
DISABLE_UPDATES |
| 5 |
cdn.growthbook.io |
特性开关/A/B 配置拉取(下行) |
DISABLE_GROWTHBOOK |
值得注意的细节(源码级确证):
- 遥测端点构造逻辑是"只要
ANTHROPIC_BASE_URL 不等于 staging 就固定连 api.anthropic.com"——你把 API 地址改到企业网关,遥测照样直连 Anthropic;Datadog 通道更是硬编码,代理/审计设备无法重定向。
- 批量上报类支持
skipAuth,未登录也会上报。
- 事件负载里有会话标题,来源是用户首条提示的截断片段(
firstPrompt → 标题 → 事件),这是提示内容出网的明确通道。
- 环境变量
P4PORT(Perforce 服务器地址,常含内网拓扑)被采集进遥测。
- 正面发现:尊重
DO_NOT_TRACK;Bedrock/Vertex 等企业云模式自动关错误上报;总开关 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 覆盖面很大。
隐私敏感环境的建议配置:
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
DISABLE_TELEMETRY=1
DISABLE_ERROR_REPORTING=1
DISABLE_GROWTHBOOK=1
3. 第二步:把内嵌 JS"解密"出来
先澄清一个常见误解:这套东西没有加密。所谓混淆只是打包器 minify(变量名压成单字母)。提取方法:
- 对全文件做"可打印长游程"扫描,一条 15,456,673 字节的连续明文游程立即现形(0xcff8e40 起);
- 原样切割得到
claude-bundle.raw.js;
- js-beautify 美化 → 25.7MB / 631,337 行可读源码。
bundle 开头就很有信息量(多数用户从没见过的一段话):
// Claude Code is a Beta product per Anthropic's Commercial Terms of Service.
// By using Claude Code, you agree that all code acceptance or rejection decisions you make,
// and the associated conversations in context, constitute Feedback ...
// and may be used to improve Anthropic's products, including training models.
你对 AI 代码建议的采纳/拒绝行为,被声明为可用于训练的反馈——写在二进制里,而不是任何用户会读到的文档里。
4. 源码里有什么:全景清单
反混淆后的 63 万行代码可以系统枚举了:
- 141 个斜杠命令:除公开命令外,还有一票未公开的——计算机/浏览器控制(
computer、computer_batch、claude-in-chrome、read_network_requests、read_console_messages)、示教模式(teach_step、teach_batch、request_teach_access)、后台编排(daemon、teleport、goal、loops),以及实验性的 voice、stickers、gif_creator 等。
- *1,237 个 `tengu_
遥测事件**:内部代号"天狗",从 API 调用、工具选择到 UI 交互全埋点,另有大量tenguamber*` 实验通道。
- 465 个环境变量开关:含
ANTHROPIC_UNIX_SOCKET(Unix 套接字直连)、CLAUDE_CODE_SUBPROCESS_ENV_SCRUB(子进程环境清洗)等。
- 三份身份提示 + 一份协调者提示词:CLI 身份、Agent SDK 身份、通用 agent 身份,外加一个"orchestrates software engineering tasks across multiple workers"的多 worker 协调者系统提示词(含
coordinator_mode_start 埋点)——多智能体编排在代码里早已就绪。
最意外的发现:系统提示词是运行时拼接 + 远程 A/B 控制。 主提示词不是一整块字符串,而是函数返回的字符串数组动态 join("\n"),数组里直接嵌着 GrowthBook 开关调用:
G8("tengu_verified_vs_assumed",!1) ? ["When reporting results, be accurate about
what you verified vs. what you assumed..."] : []
也就是说,你拿到的系统提示词内容会按服务端开关动态变化——不同用户/不同时段的行为可能不同,这不是推测,是源码里的控制流。
OAuth 部分是标准 PKCE 流程(console.anthropic.com/oauth/authorize 与 claude.ai/oauth/authorize 双入口 + refresh token 轮换),没发现离线破解面。
5. 第三步:字节码本体——反编译器为什么救不了它
百余 MB 的 JSC 字节码是这次最硬的骨头。先说结论:现有公开工具链反编译不了它,我做了完整尝试:
| 尝试 |
结果 |
REA analyze / inspect-artifact 字节码 |
unsupported binary format(REA 不识别 Bun 字节码容器) |
| REA + Ghidra 12.1.4(原生反编译) |
类别不匹配——JSC 字节码不是机器码,Ghidra/IDA/Hopper 只针对 CPU 指令流,装载后只能当数据处理 |
BUN_JSC_dumpBytecode=1 让 Bun 自曝 |
invalid JSC environment variable;对照组 BUN_JSC_useJIT=0 正常生效 → release 版 Bun 把 JSC 调试开关编译掉了 |
但字节码容器本身可解析:常量表格式为 [u32 0x10][u32 0][u32 0][u32 9][u32 len][bytes],共扫出 40 万条目 / 4,062 个不同字符串(原始函数名如 sendEventsInBatches 未混淆保留);字节分布零字节占 39.3%(加密数据应 ≈0.4%)——再次证实未加密。字节码与明文 JS 语义完全等价,真正有价值的是它构成反篡改层:直接改 exe 里的明文 JS 不生效,运行时优先加载字节码副本。
(补充:模块图在 PE 里以正式 .bun 段存在,字节码 blob 与 Bun 自身 .rdata 数据相邻——这修正了我中间报告里"尾部附加数据"的初步描述。)
6. 第四步:Bun 运行时本体(60MB 原生代码)
配置好 Ghidra 12.1.4 后,用 REA 对 claude.exe 做原生分析:60MB .text 全部是 Bun 运行时的 Zig/C++/Rust 混合编译产物。纯 PE 层面能确认的特征:
- 静态链接风格(8 个导入 DLL 拉起全部能力,网络走 ntdll 原生调用),.rdata 里能扫到 Rust 标准库 panic 路径(
library\core\src\...、encoding_rs-0.8.35,甚至构建机路径 C:\Users\runneradmin\.cargo\...)——连构建环境信息都留在了发布二进制里;
- Authenticode Security 目录指向 .bun 段尾的 PKCS#7 块,签名覆盖整包(含模块图)。
工具边界实战记录(给用 REA 的朋友避坑):REA 的 Ghidra provider 对单次操作有 330 秒硬预算,60MB 代码的全量自动分析远超预算,首次 analyze 直接 provider_timeout。解法是用 REA 的 --snapshot 快照机制——快照会在多次调用间增量积累分析进度,配合循环重试即可消化大目标。函数级反编译正以该方式在后台推进,出结果后本帖追加。
7. 方法论小结:REA + ZCode 的工作流
这次分析是一次"AI agent 主导逆向"的完整实践,供参考:
- REA 负责证据:
analyze-javascript-application 做应用图(带 SHA-256 与完整性校验)、doctor/capabilities 摸清工具边界、Ghidra provider 调度原生反编译;每步结论都是结构化 Evidence JSON,可复核。
- ZCode 负责驱动:参数解析、PE 头/导入表解析、多遍流式扫描、常量表格式逆向,这些一次性脚本由 agent 现场编写执行,235MB 文件五遍扫描全程零卡顿。
- AI 交叉验证:把提取出的源码片段喂给本地 llama.cpp 无审查模型和云端模型各跑一遍结论,两方与人工判断一致才写入报告。
- 所有中间产物落盘:明文 bundle、美化源码、事件清单、环境变量清单、载荷留档,报告全部可回溯。
工具链对新手友好的一点:REA 是 MCP server,接进任意 agent 后一句"分析这个程序的联网行为"就能开跑,证据链自动生成。
8. 结语
235MB 的 claude.exe,拆开是:60MB Bun 运行时 + 150MB 字节码/明文源码 + 5 条遥测通道 + 一个被远程开关控制的系统提示词。它不加密自己的代码,反而把"训练你的反馈"写进每份 bundle 的第一行注释。对普通用户的建议只有一条:敏感环境记得设 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1——这是它自己提供的刹车,只是没几个人知道刹车在哪。
附件清单(分析产物):明文主 bundle(15.4MB)、反混淆源码(25.7MB/63 万行)、1237 个遥测事件清单、465 个环境变量清单、字节码常量表字符串清单、协调者系统提示词。如需我另发网盘请留言。
分析日期:2026-10。工具:REA 6.4.0 + ZCode(GLM agent)+ Ghidra 12.1.4 + js-beautify + llama.cpp(本地无审查模型)。