逆向工程Creative Katana音箱以从Linux控制

Hacker News Top 工具

摘要

一位开发者逆向工程了专有的Creative Sound Blaster Katana V2X音箱的USB协议,以便从Linux控制它,记录了捕获流量、去混淆固件和分析命令的过程。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/11 13:58

# 逆向工程 Creative Katana V2X 音箱,实现 Linux 控制 原文链接:https://blog.nns.ee/2026/02/20/katana-v2x-re 我最近入手了一台 Creative Sound Blaster Katana V2X 音箱(名字真长),用来替换我那套老旧的罗技廉价电脑音箱。它们虽然陪了我很久,但听音乐或看电影的效果实在称不上好。 到货后,我设置好它,发现它有一个 USB 接口。除了能用作音频输入外,还允许用户配置音箱:设置均衡器、设置 LED 灯带的不同模式等等。遗憾的是,这需要使用(专有的)Creative App。更糟糕的是,这个 App 似乎只有 Windows 版本,而我不使用 Windows。虽然在虚拟机里能用,但实在不方便。 这似乎是我最爱做的事的绝佳机会:逆向工程专有应用、设备和协议,并编写工具与它们通信。 实物音箱(https://blog.nns.ee/img/2026-02-20-katana-v2x-re/v2x.png) ### 初步侦察(https://blog.nns.ee/2026/02/20/katana-v2x-re#initial-recon) 仅仅看了 Creative App 的安装目录,我就能判断这是一个 .NET 应用。这类应用通常有大量名为 `Named.Like.This.dll` 的 DLL 文件,每个对应一个 C# 模块。那个 `.exe.config` 文件也是一个明显标志。 Creative App 安装目录列表(https://blog.nns.ee/img/2026-02-20-katana-v2x-re/dir.png) 当我把 exe 和对应的 DLL 加载进 dnSpy(https://github.com/dnSpyEx/dnSpy,一个 .NET 反编译器)时,我的猜测得到了证实。不幸的是,我也发现大量模块被混淆了,读起来相当困难。 dnSpy 截图,显示混淆后的代码(https://blog.nns.ee/img/2026-02-20-katana-v2x-re/obfuscated.png) 我决定暂时搁置这个问题,把注意力转向 USB 通信本身。由于完全不了解音箱是如何与 App 通信的,我开始用 Wireshark(https://www.wireshark.org/)和 USBPcap(https://desowin.org/usbpcap/)记录所有 USB 流量。我甚至在打开 App 之前就开始记录,因为我想捕获尽可能多的通信。 App 发现我的音箱后,首先告诉我需要固件升级。我让它升级,然后检查了 USBPcap 输出。实际的固件更新载荷很容易识别,因为数据包比周围的数据包大得多。幸运的是,它似乎是一个明文的固件 blob! Wireshark 截图,显示第一个固件载荷数据包(https://blog.nns.ee/img/2026-02-20-katana-v2x-re/wireshark.png) 我写了一个脚本,从数据包捕获中提取了整个固件文件——关于这点后面还会提到。 ### 逆向工程协议(https://blog.nns.ee/2026/02/20/katana-v2x-re#reverse-engineering-the-protocol) Creative App(https://blog.nns.ee/img/2026-02-20-katana-v2x-re/app.png) 为了获取 App 允许用户执行的所有操作的捕获数据,我有条不紊地检查了每个选项,点击、更改,并为每个操作创建单独的捕获文件。这花了我几乎一整天,最终得到了大约 100 个不同的捕获文件。 这让我能够分析数据包,记下每个操作的用途,一段时间后,我对协议的运作方式有了相当清晰的认识。 通信通过 CDC ACM 串行接口进行,音箱在 Linux 上表现为 `/dev/ttyACM*`。 所有专有命令都使用一个简单的帧格式: ``` 5A [cmd] [len] [payload...] ``` `0x5A` 始终是静态的,很可能只是命令起始标记。`cmd` 是你要执行的操作的命令操作码。`len` 顾名思义是后续有效载荷的字节数,`payload` 是有效载荷(或子命令)本身。 响应也类似,通常有一个字节指示这是一个响应。 我不会逐一介绍所有不同的命令,但举个例子,以下是请求当前固件版本(作为子命令)的命令以及对应的响应: ``` Host -> Device: 5a 09 01 02 Device -> Host: 5a 09 12 02 10 "1.3.230619.1820\0" ``` ### 认证(https://blog.nns.ee/2026/02/20/katana-v2x-re#authentication) 在你能够发送命令之前,必须先通过一个质询-响应认证,使设备进入接受命令的模式。我不太确定为什么要这样做——也许 Creative*真的*不希望人们使用第三方应用来控制他们拥有的设备?无论如何,我也逆向分析了这部分。 从第一次捕获中,我可以看出设备和主机之间最早的通信之一如下: ``` Host -> Device: "whoareyou.MyApp8\r\n" Device -> Host: "whoareyou" 1e 04 83 32 [32 random bytes] "\r\n" Host -> Device: "unlock" [64 random bytes] "\r\n" Device -> Host: "unlock_OK\r\n" Host -> Device: "SW_MODE1\r\n" [... binary comms ...] ``` 这看起来像某种质询-响应,而 64 字节的随机数最初让我考虑简单的 (HMAC-)SHA512。然而,在 dnSpy 中搜索程序集里所有调用 SHA512(或任何哈希算法)的地方,并没有找到任何相关的内容。事实上,即使只搜索字符串 `whoareyou` 也一无所获。退一步,我对所有文件执行了 `grep whoareyou`,发现只有二进制 DLL `CTCDC.dll` 匹配。 将其加载到 Ghidra 中,并查看交叉引用,我最终找到了负责与设备初始通信的函数,这从检查响应如 `Unknown command` 和 `NotYet` 可以得到证实。 Ghidra 截图,显示反编译后的函数(https://blog.nns.ee/img/2026-02-20-katana-v2x-re/ghidra.png) 分析这个函数后,我推断它根本没有使用 SHA,而是使用某种奇怪的基于 AES-256-GCM 的认证。 质询消息格式: ``` whoareyou [1E 04] [83 32] [32-byte nonce] \r\n │ └─ 设备类型 (USB PID 0x3283 LE) └─ 质询头部 ``` 应用使用以下密钥,通过 AES-256-GCM 加密设备的 32 字节 nonce: ``` 1e 04 d3 1a 21 27 9b e3 46 f0 99 9d 6e c4 c3 fe be 98 90 18 69 c1 18 fb b1 25 6e 0c e0 7b 83 32 ``` 密钥本身并不直接存储在 DLL 中,而是由质询消息本身和 DLL 中的一些静态数据构建而成: - 字节 0-1:质询头部(`1E 04`) - 字节 2-3:DLL 静态数据(`D3 1A`) - 字节 4-27:DLL 静态数据(24 字节,来自 0x101dba78) - 字节 28-29:DLL 静态数据(`E0 7B`) - 字节 30-31:来自质询的 USB PID 字节(`83 32`) 由于质询头部是设备恒定的,这个密钥实际上对这个特定设备来说是硬编码的,但我想这个质询-响应机制是与其他设备共享的,只是密钥会不同。 响应的计算方式如下: 1. 为 `iv` 值生成 16 个随机字节 2. 使用 `iv[0:12]` 作为 GCM nonce 3. 加密 32 字节的质询 nonce:`(ciphertext, tag) = AES-256-GCM(key, iv[:12], nonce)` 4. 响应 = `"unlock"` + `iv` + `ciphertext` + `tag` + `"\r\n"` 这相当不寻常——通常,证明你知道共享秘密的工具是 HMAC。我不明白为什么 Creative 觉得需要绕这么多弯子来做一件本质上相同的事情。这种加密方案提供了完整性和机密性,但后者在这里似乎毫无意义,因为 nonce 双方都已经知道。只有完整性证明才重要。也许我忽略了什么,但整体感觉很奇怪。 ### v2x-ctl(https://blog.nns.ee/2026/02/20/katana-v2x-re#v2x-ctl) 有了所有缺失的拼图后,我创建了一个名为 v2x-ctl(https://crates.io/crates/v2x)的 Rust 库和 CLI 应用程序(或简称 `v2x`)。 如果你碰巧有 Katana V2X,并想从 Linux 上控制其设置,试试看吧!它是基于尽力而为原则开发的,我确保所有功能基本可用,但仅在最新固件版本(`1.3.230619.1820`)上测试过。理论上,这个应用程序也可能适用于其他 Sound Blaster 设备,但至少需要修改质询加密密钥和一些我目前硬编码的 ID。无论如何,如果你感兴趣并尝试了,请告诉我结果(https://blog.nns.ee/contact)。 回到固件升级的捕获,我可以推断出每个载荷数据包的结构如下: ``` [0:2] 5b 98 - 起始标记 [2:4] remaining_len - u16le,此字段之后所有内容的长度 [4] 04 - 命令(固件数据写入) [5] seq - 序列计数器(每 32 个数据包重置一次) [6:8] payload_len - u16le,此数据包中固件数据的长度 ``` 知道了这一点,我写了一个脚本,使用 `tshark` 从捕获中提取数据。 我得到了一个标识为 `CIFF` 的文件,据推测是 "Creative Image File Format" 的缩写,是一个带有不同部分的容器。我得到的文件有四种部分类型:`CINF`(设备信息,UTF-16LE 字符串)、`CIN2`(版本信息)、`DATA`(固件二进制本身)和 `CHK2`(校验和)。 具体来说,CIFF 格式本身似乎是: | 偏移量 | 大小 | 描述 | |--------|------|------| | `0x00` | 4 | 魔术字:`CIFF` | | `0x04` | 4 | u32 载荷大小(此字段之后所有内容,但**不包括** `CHK2`) | | `0x08` | ... | 部分(`CINF`、`CIN2`、`DATA`...、`CHK2`) | 每个部分遵循相同的 TLV 信封: | 偏移量 | 大小 | 描述 | |--------|------|------| | `0x00` | 4 | 魔术字 | | `0x04` | 4 | u32 部分大小(此字段之后的字节数) | | `0x08` | N | 部分载荷 | 在我提取的固件文件中,有多个 `DATA` 部分,分为两种子类型。 第一种是 `F` 类型,我这样命名是因为它的名称以 F 开头,我假设代表 *firmware*。名称是一个以 null 结尾的 UTF-16LE 字符串,填充到 32 字节,后面跟着原始的二进制数据。 第二种是 `H` 类型,原因类似,但我不知道这里的 `H` 代表什么,也许是 *host resource*?无论如何,这种类型的名称填充到 512 字节,而不仅仅是 32,但其它结构相同。 `CHK2` 部分是一个 32 字节的 SHA256 哈希,计算范围是从 CIFF 头部(偏移 `0x08` 之后)到 `CHK2` 部分开始之间的所有字节。 作为概述,这是我提取的固件容器的样子: | # | 魔术字 | 名称 | 偏移量 | 大小 | 内容 | |---|--------|------|--------|------|------| | 0 | `CINF` | - | `0x0008` | 96 | "Creative MarvelX One" | | 1 | `CIN2` | - | `0x0070` | 12 | 版本数据 | | 2 | `DATA` | `FBOOT` | `0x0084` | 231,208 | ARM32 启动加载器 | | 3 | `DATA` | `FMAIN` | `0x387B4` | 1,486,904 | ARM32 主固件 (FreeRTOS) | | 4 | `DATA` | `Hres/audio/audioprompts-en.pkg` | `0x1A37F4` | 41,472 | 音频提示 (Opus) | | 5 | `DATA` | `Hbin/marvelX-malcolm.bin` | `0x1AD9FC` | 291,430 | 8051 MCU 固件 | | 6 | `CHK2` | - | `0x1F4C6A` | 32 | SHA-256 校验和 | `BOOT` 和 `MAIN` 固件很有趣,我下一步将会研究它们。

相似文章

无需触碰,通过音箱入侵你的电脑

Hacker News Top

一位安全研究人员对 Creative Sound Blaster Katana V2X 的固件进行了逆向工程,发现了漏洞,攻击者可在15米范围内将音箱变成隐蔽的窃听工具和无需物理接触的 Rubber Ducky。

用于 Linux 的 Asus ZenVision 盖板 OLED 逆向工程用户空间驱动

Hacker News Top

这是一个针对 ASUS ZenVision 盖板 OLED 屏幕的逆向工程开源 Linux 用户空间驱动,允许用户在这块 256×64 的面板上显示图片和动画——而 ASUS 官方仅支持 Windows 平台。USB 协议通过 Ghidra 对 MyASUS 应用进行逆向分析后还原。

修复我的吉他音箱固件

Lobsters Hottest

作者通过UART和JTAG逆向工程了Yamaha THR10c吉他音箱的固件,转储并修补了它,以修复旁路增益问题,并构建了一个API。