使用 Rust 对 USB 设备进行逆向工程

几周前,作者用“AMD Ryzen 3950x”CPU 搭建了新工作站,为降低rust编译时间对其进行了调优,最终使用“Corsair H150i RGB PRO XT”AIO 来散热。但发现 Corsair 不提供 Linux 支持,只能在 Windows 中调整设置或查看状态。

作者开始通过嗅探软件与设备之间的通信来复制操作以在 Linux 中使用该设备,为此做了很多准备工作:

  • 阅读关于 USB 协议的资源,如[Usb Made Simple]、[DRIVE IT YOURSELF: USB CAR]、[libusb 文档]、[usb and libusb (video)]、[reverse engineering USB devices (video)]、[USB3 Specifications (PDF)]、[USB Complete 5th Edition (book)]等,了解 USB 由主机完全控制,控制设备需获取设备信息、配置端点、运行命令等步骤。
  • 在 Linux 机器上运行lsusb查看连接的 USB 设备,创建新的 rust 项目rcue,使用rusbbyteorder依赖库读取设备基本信息。
  • 捕获 USB 数据包,因仅在 Windows 上支持,作者创建了虚拟机并安装[Wireshark]和[USBPcap],后发现将USBPcapCMD.exe复制到wireshark\extcap目录可进行实时捕获。
  • 分析捕获的数据,发现设备通信序列,如请求设备描述符、配置端点、发送各种命令等,通过编写 Rust 代码来模拟这些操作,包括打开设备、获取设备信息、配置端点、发送命令(如SET_IDLESET_REPORTURB_INTERRUPT等)、读取数据等。
  • 经过多次尝试,成功读取到风扇转速和泵速等数据,但未找到冷却液温度数据,通过在线[hex editor]查找,确定风扇 1 的转速在响应的第 16 和 17 字节,风扇 2 和 3 分别在第 23 和 42 字节,泵速在第 30 字节,通过编写辅助函数打印这些值。
  • 最终通过观察和尝试,找到表示温度的字节(第 9 字节),并经过调整得到计算温度的公式(byte9 + (byte8/255)rdr.read_u16::<LittleEndian>().unwrap_or_default() as f32 / 256.0),成功读取并打印冷却液温度。

作者还提到由于已转向自定义回路冷却解决方案,不再继续研究 Corsair AIO,推荐读者查看开源项目[liquidctl]。如果喜欢该文章可点赞。

阅读 13
0 条评论