Enuvid/bun-unpacker

GitHub: Enuvid/bun-unpacker

一款用于从 Bun 单文件可执行程序中提取内嵌 JS bundle、原生插件和资产文件的解包工具。

Stars: 1 | Forks: 0

# bun-unpacker [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/Enuvid/bun-unpacker/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/bun-unpacker)](https://www.npmjs.com/package/bun-unpacker) 读取通过 `bun build --compile` 构建的可执行文件,并将其内部打包的 文件写出来:JavaScript bundle、原生插件、sourcemap 以及任何其他 内嵌的资产。 该包仅包含源代码。它不包含任何第三方代码,也没有 提取出的产物,并且它不会下载任何内容:你只需将它指向 你机器上已有的二进制文件,它就会逐字节地将内容复制出来。没有任何 内容会被执行、反编译或反混淆;输出的文件与打包器 存储的完全一致。 ## 快速开始 ``` $ npx bun-unpacker ./my-app --list my-app 58.4 MB (/home/you/build/my-app) ELF · x86-64 · payload 41.2 MB at 0x2c41008 · 3 modules · 52-byte entries path size kind bytecode ----------- -------- ----------------------------- -------- index.js 1.84 MB JS (bun cjs, bytecode-backed) 12.6 MB sharp.node 1.40 MB ELF x86-64 - schema.json 9.11 KB JSON - total extracted: 3.25 MB ``` 去掉 `--list` 即可将文件写入 `./out`: ``` npx bun-unpacker ./my-app # extract to ./out bunx bun-unpacker ./my-app -o dump # explicit target ``` ## 选项 | 标志 | 含义 | | :------------------ | :--------------------------------------------------------------------------------------------- | | `-o`, `--out ` | 输出目录,默认为 `./out`。通用二进制文件会为每个架构生成一个子目录。 | | `-l`, `--list` | 打印模块表且不写入任何内容。 | | `--bytecode` | 同时转储 JSC bytecode 缓存。它通常是源代码大小的几倍。 | | `--json` | 在 stdout 上以 JSON 格式打印清单(manifest)。 | | `-v`, `--version` | 此工具的版本。 | | `-h`, `--help` | 用法。 | ## 输出 提取的文件会保留打包器记录的路径,因此 `/$bunfs/root/src/index.js` 会落地在 `out/src/index.js`。路径遍历片段会被丢弃,而两个如果 落地到同一路径的模块会添加数字后缀,而不是相互 覆盖。 ``` out/ src/index.js one file per embedded module manifest.json every module, with offsets and hashes _bytecode/ only with --bytecode src/index.js.jsc ``` 通用二进制文件会为每个架构生成一个目录(`out/arm64/`, `out/x86-64/`)。`manifest.json` 描述了每个模块: ``` { "name": "/$bunfs/root/src/index.js", "path": "src/index.js", "kind": "JS (bun cjs, bytecode-backed)", "size": 1929216, "offsetInFile": 46859528, "sha256": "8f1dded3...", "bytecode": { "offset": 120, "length": 13221888, "offsetInFile": 6315136 } } ``` 清单(manifest)路径始终使用正斜杠,因此在 Windows 上写入的清单 与在任何其他地方写入的清单比较结果是一致的。 ## 支持的容器 payload 是通过其 trailer magic 找到的,因此可执行文件格式仅 对报告和遍历通用二进制文件的切片有意义。 | 格式 | 平台 | | :--------------- | :------------------------------------------------------ | | ELF | Linux, x86-64 和 arm64 | | Mach-O | macOS, arm64 和 x86-64 | | Mach-O universal | macOS, 每个切片包含一个 payload,分别进行提取 | | PE32+ | Windows, x86-64 和 arm64 | 这四种格式都经过了测试。ELF、Mach-O 和 PE 还在所有三个平台上 针对 Bun 1.4.0 生成的真实二进制文件进行了额外验证,方法是将提取的 字节与输入进行比较。 ## 库 ``` import { BinaryReader, inspectContainer, extractSlice } from 'bun-unpacker'; using reader = BinaryReader.open('/path/to/binary'); const container = inspectContainer(reader); for (const slice of container.slices) { const manifest = extractSlice(reader, container, slice, { outputDir: 'extracted', write: true, includeBytecode: false, }); console.log(manifest.modules.map((module) => module.path)); } ``` `unpackBinary` 和 `unpackTargets` 也被导出,供那些使用自己的方式 查找二进制文件来包装此 CLI 的工具使用。 [claude-code-unpacker](https://github.com/Enuvid/claude-code-unpacker) 就是这样 的一个包装器。 ## 工作原理 Bun 将其 payload 追加到可执行镜像的末尾: ``` ...native executable... payload blob bytecode cache, file contents, sourcemaps, NUL-terminated names module table moduleCount * entrySize offsets struct u64 blobSize, u32 tableOffset, u32 tableLength, ... "\n---- Bun! ----\n" ...native metadata... ELF section headers, Mach-O code signature, ... ``` 有两个细节会导致简单的读取器失败。原生元数据跟在 trailer 之后, 因此它并不位于文件的末尾。此外,Bun 自己的 runtime 将 magic 作为 字符串字面量携带,因此真实的二进制文件会包含多个副本,只有最后一个 才标志着 payload。 offsets 结构的大小和模块表的步长是探测出来的,而不是硬编码的。只有 当第一个表条目解析为打包器路径时(Linux 和 macOS 上为 `/$bunfs/root/...`,Windows 上为 `B:/~BUN/root/...`),候选项才会被 接受。这使得解析器能够在改变这些结构的 Bun 版本中继续正常工作。 ## 范围和许可 该工具采用 MIT 许可,且不包含任何第三方代码。 它提取的内容则是另一回事。从二进制文件中提取出的任何内容仍受该 二进制文件自身许可证的约束,该工具既不捆绑也不重新分发 其中的任何内容。为了研究或调试而解包你已有的副本,正是此工具的 用途。 ## 开发 需要 Node 22 或更高版本。 ``` npm install npm run build # tsc, output in dist/ npm test # compiles src and test, then runs node:test npm run test:smoke # runs dist/cli.js against a synthetic binary npm run lint # eslint with type-checked rules npm run format:check # prettier ``` 测试套件会逐字节构建合成的 Bun 可执行文件:payload blob、 模块表、offsets 结构、trailer,以及包含所有这些内容的通用包装器。 这涵盖了当前版本使用的结构大小和表步长之外的其他情况,而 没有任何真实的二进制文件会涉及这些情况。 ## 许可证 MIT
标签:Bun, CMS安全, JavaScript, MITM代理, SOC Prime, 二进制解析, 云资产清单, 可执行文件提取, 开发工具, 自动化攻击, 逆向工程