HelgeSverre/sony-vp-extract
GitHub: HelgeSverre/sony-vp-extract
用于解密并提取 Sony WH-1000XM4 加密语音包中 MP3 提示音的逆向工程工具。
Stars: 22 | Forks: 2
# Sony WH-1000XM4 语音包提取器



[](https://ampcode.com/@helgesverre)

解密并从 Sony WH-1000XM4 加密的固件文件中提取语音提示 MP3 文件。
AES-128-CBC 密钥是通过低功耗蓝牙使用 [RACE protocol](https://airoha.com) dump 耳机的 Airoha MT2811 固件,然后反汇编 ARM Cortex-M4 FOTA 解密例程提取出来的。完整的技术分析:**[docs/WRITEUP.md](docs/WRITEUP.md)**
## 快速开始
```
# 安装 Bun(如果尚未安装)
curl -fsSL https://bun.sh/install | bash
git clone https://github.com/HelgeSverre/sony-vp-extract.git
cd sony-vp-extract
bun install
# 自动从 Sony CDN 下载,然后解压
bun run cli/extract.ts --all
```
## 用法
```
# 全部解压 — 如果 voice-packs/ 为空,则自动从 Sony CDN 下载
bun run cli/extract.ts --all [input-dir] [output-dir]
# 解压单个语音包
bun run cli/extract.ts voice-packs/VP_english_UPG_03.bin extracted/
# 显示语音包信息
bun run cli/extract.ts --info voice-packs/VP_english_UPG_03.bin
# 仅下载(不解压)
bun run cli/extract.ts --download [output-dir]
```
### Python 替代方案
```
uv run extract_all.py
```
从 Sony CDN 下载 + 解密 + 提取——一条命令全搞定。依赖项以内联方式声明([PEP 723](https://peps.python.org/pep-0723/))—— `uv run` 会自动处理一切。
## 可用语言
| 语言 | 文件 | 提示音数量 | CDN |
| ------------- | -------------------------- | ------- | ------------------------------------------------------------------------------------------------- |
| 🇬🇧 英语 | `VP_english_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0401/contents/0002/VP_english_UPG_03.bin) |
| 🇫🇷 法语 | `VP_french_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0402/contents/0002/VP_french_UPG_03.bin) |
| 🇩🇪 德语 | `VP_german_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0403/contents/0002/VP_german_UPG_03.bin) |
| 🇪🇸 西班牙语 | `VP_spanish_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0404/contents/0002/VP_spanish_UPG_03.bin) |
| 🇮🇹 意大利语 | `VP_italian_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0405/contents/0002/VP_italian_UPG_03.bin) |
| 🇵🇹 葡萄牙语 | `VP_portuguese_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0406/contents/0002/VP_portuguese_UPG_03.bin) |
| 🇳🇱 荷兰语 | `VP_dutch_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0407/contents/0002/VP_dutch_UPG_03.bin) |
| 🇸🇪 瑞典语 | `VP_swedish_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0408/contents/0002/VP_swedish_UPG_03.bin) |
| 🇫🇮 芬兰语 | `VP_finnish_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0409/contents/0002/VP_finnish_UPG_03.bin) |
| 🇹🇷 土耳其语 | `VP_turkish_UPG_03.bin` | 54 | [下载](https://info.update.sony.net/HP002/VGIDLPB0410/contents/0002/VP_turkish_UPG_03.bin) |
## 语音包格式
```
┌───────────────────────────────────────┐
│ Header (4096 bytes) │
│ ├── 0x000 Random nonce (32 bytes) │
│ └── 0x100 TLV metadata │
│ ├── compression_type = 2 │
│ ├── body_size │
│ ├── decompressed_size (1 MB) │
│ └── SHA-256 of decompressed │
├───────────────────────────────────────┤
│ Body (offset 0x1000+) │
│ AES-128-CBC encrypted │
│ └── LZMA1 compressed │
│ └── Voice guidance image (1MB) │
│ ├── Header (version+count) │
│ ├── Entry table (54 × 8B) │
│ │ (size, abs_offset) │
│ └── MP3 files (48kHz mono) │
└───────────────────────────────────────┘
```
## 密钥
```
AES-128-CBC Key: eibohjeCh6uegahf
AES-128-CBC IV: miefeinuShu9eilo
```
在 MT2811 CM4 固件的 `.rodata` 段中,以 ASCII 字符串的形式硬编码于 flash 偏移量 `0xD53A`(密钥)和 `0xD529`(IV)处找到。所有 WH-1000XM4 设备和所有语言包均使用相同的密钥。
## 发现过程
1. **通过**蓝牙**连接**到 WH-1000XM4(耳机已与手机配对)
2. **发现**了 RACE (Airoha Command Extensions) BLE GATT 服务
3. 使用 `RACE_STORAGE_PAGE_READ` (cmd `0x0403`) 从 flash 中 **dump** 了 59KB 的 CM4 固件
4. 在固件偏移量 `0x81F4` 处**定位**了 AES S-box
5. 从 ARM 向量表字面量池中**确定**了 runtime 基地址 `0x04200000`
6. **反汇编**了 FOTA 解密函数,追踪了从字面量池加载密钥的过程
完整技术细节:**[docs/WRITEUP.md](docs/WRITEUP.md)**
## 前置条件
- [Bun](https://bun.sh) ≥ 1.0 —— 用于 TypeScript CLI
- [uv](https://docs.astral.sh/uv/) —— 用于 Python 脚本(通过内联元数据自动解析依赖项)
## 自行提取密钥
如果您想独立验证密钥,可以从您自己配对的 WH-1000XM4 耳机中 dump 固件并从中提取密钥:
```
# 通过 BLE 导出固件并提取密钥
uv run cli/extract_key.py
# 或者,如果您已有固件导出文件:
uv run cli/extract_key.py --firmware your_dump.bin
# Bun 替代方案(需要固件导出文件):
bun run cli/extract.ts --extract-key your_dump.bin
```
该工具在固件二进制文件中搜索 AES S-box,查找相邻的以 null 结尾的 16 字节 ASCII 字符串,然后通过尝试解密语音包并检查有效的 LZMA 头来验证每个候选对。
## 项目结构
```
├── cli/
│ ├── extract.ts # Bun CLI tool (extract + key finder)
│ └── extract_key.py # Python BLE firmware dumper + key finder
├── docs/
│ └── WRITEUP.md # Full technical writeup
├── voice-packs/ # Downloaded .bin files (gitignored)
├── extracted/ # Extracted MP3 prompts (gitignored)
├── extract_all.py # Python alternative extractor
├── package.json
└── README.md
```
## 免责声明
本项目记录了出于教育目的而在个人拥有的硬件上进行的 security research。所分析的耳机是正常配对和连接的——不涉及任何未经授权的访问。
语音包 `.bin` 文件和提取的 MP3 提示音受 Sony Corporation 版权保护,**未包含**在此 repository 中。CLI 工具会在运行时直接从 Sony 的公共 CDN 下载它们。请勿重新分发解密后的语音包或提取的 MP3 文件。此工具仅供研究和互操作性目的使用。
## 许可证
MIT
标签:Bun, 云资产清单, 固件分析, 密钥提取, 物联网设备, 硬件黑客, 蓝牙, 逆向工具, 逆向工程, 音频解析