逆向工程实战用usbmon解码USB键盘的原始通信数据当你的手指在键盘上敲击时一组神秘的十六进制代码正在USB总线上飞驰。这些看似随机的数字背后隐藏着从物理按键到操作系统事件的完整转化链条。本文将带你深入USB HID协议的底层使用Linux内核内置的usbmon工具捕获并解析键盘每一次击键产生的原始数据包。1. 搭建USB数据捕获环境1.1 内核模块准备现代Linux发行版通常已内置usbmon支持首先验证内核模块状态ls /sys/module/usbmon若目录不存在需加载模块sudo modprobe usbmondebugfs是usbmon的依赖文件系统检查挂载状态mount | grep debugfs未挂载时执行sudo mount -t debugfs none /sys/kernel/debug1.2 设备总线定位使用lsusb定位目标设备所在总线lsusb -v | grep -A5 Keyboard典型输出示例Bus 003 Device 002: ID 046d:c31c Logitech USB Keyboard这里003即为总线编号记下设备地址002用于后续过滤。2. 捕获键盘原始数据流2.1 实时监控数据包针对特定总线启动监控以总线3为例sudo cat /sys/kernel/debug/usb/usbmon/3u keyboard_capture.log按下几个按键后CtrlC终止捕获得到原始数据样本ffff8a1b12a8d400 1638297565 S Ci:3:002:0 s a1 01 0000 0001 0008 8 ffff8a1b12a8d400 1638297567 C Ci:3:002:0 0 8 0000000000000000 ffff8a1b12a8d400 1638298512 S Ci:3:002:0 s a1 01 0000 0001 0008 8 ffff8a1b12a8d400 1638298514 C Ci:3:002:0 0 8 00000400000000002.2 数据包结构解析usbmon输出的关键字段说明字段位置示例值含义1ffff8a1b12a8d400URB唯一标识符内核地址3Ci控制输入传输(Control Input)43:002:0总线:设备:端点号78 数据长度8字节方向为设备到主机9 00000400...实际传输的HID报告数据3. HID报告描述符解码3.1 报告描述符获取USB HID设备通过描述符定义数据格式获取键盘描述符sudo lsusb -v -d 046d:c31c | grep -A50 HID Device Descriptor关键输出片段HID Device Descriptor: bLength 9 bDescriptorType 33 bCountryCode 0 bNumDescriptors 1 bDescriptorType 34 wDescriptorLength 65 Report Descriptor: (length is 65) Item(Global): Usage Page, data [ 0x01 ] 1 Generic Desktop Controls Item(Local): Usage, data [ 0x06 ] 6 Keyboard Item(Main): Collection, data [ 0x01 ] 1 Application3.2 按键码映射表标准USB HID键盘的键码对应关系部分十六进制十进制按键0x044A/a0x055B/b0x066C/c0x077D/d0x1A26[/ {0x1B27]/ }0x2840Enter0x2941Escape4. 实战数据包分析4.1 单按键按下事件捕获到的数据样本ffff8a1b12a8d400 1638298514 C Ci:3:002:0 0 8 0000040000000000解析步骤数据部分0000040000000000按字节分组00 00 04 00 00 00 00 00第1字节00修饰键状态Shift/Ctrl/Alt等第3字节04对应键码表可知是字母A其余字节00保留位或同时按下的其他键4.2 组合键事件分析ShiftA组合击键的典型数据ffff8a1b12a8d400 1638301123 C Ci:3:002:0 0 8 0200040000000000关键区别第1字节变为02左Shift键的修饰位标志第3字节仍为04物理A键的扫描码4.3 数据包时序分析连续击键的时间戳差值计算timestamp1 1638297565 timestamp2 1638298512 delta_ms (timestamp2 - timestamp1) / 1000 print(f按键间隔{delta_ms:.1f}毫秒)输出示例按键间隔946.7毫秒5. 高级分析技巧5.1 使用Python解析数据自动化解析脚本示例import re def parse_usbmon(line): pattern r.* C Ci:\d:\d:\d \d \d ([0-9a-f]) match re.match(pattern, line) if match: return bytes.fromhex(match.group(1)) return None sample ffff8a1b12a8d400 1638298514 C Ci:3:002:0 0 8 0000040000000000 print(parse_usbmon(sample)) # 输出b\x00\x00\x04\x00\x00\x00\x00\x005.2 Wireshark联合分析将usbmon输出转换为pcapng格式text2pcap -T 147,147 keyboard_capture.log keyboard.pcap在Wireshark中应用USB HID解析器右键数据包 → Decode As → USBHID5.3 异常数据诊断常见问题数据模式及含义数据模式可能原因0000000000000000按键释放事件FF00FF0000000000全键按下防鬼跳测试0100000000000000左Ctrl键按下持续相同非零数据按键卡住或硬件故障在虚拟机环境中测试时可能会观察到额外的控制传输数据包这是虚拟化层与主机通信的正常现象。实际物理键盘的数据流通常更简洁主要集中在中断传输端点上。
逆向分析实战:用usbmon解码USB HID设备(如键盘/鼠标)的原始数据包
逆向工程实战用usbmon解码USB键盘的原始通信数据当你的手指在键盘上敲击时一组神秘的十六进制代码正在USB总线上飞驰。这些看似随机的数字背后隐藏着从物理按键到操作系统事件的完整转化链条。本文将带你深入USB HID协议的底层使用Linux内核内置的usbmon工具捕获并解析键盘每一次击键产生的原始数据包。1. 搭建USB数据捕获环境1.1 内核模块准备现代Linux发行版通常已内置usbmon支持首先验证内核模块状态ls /sys/module/usbmon若目录不存在需加载模块sudo modprobe usbmondebugfs是usbmon的依赖文件系统检查挂载状态mount | grep debugfs未挂载时执行sudo mount -t debugfs none /sys/kernel/debug1.2 设备总线定位使用lsusb定位目标设备所在总线lsusb -v | grep -A5 Keyboard典型输出示例Bus 003 Device 002: ID 046d:c31c Logitech USB Keyboard这里003即为总线编号记下设备地址002用于后续过滤。2. 捕获键盘原始数据流2.1 实时监控数据包针对特定总线启动监控以总线3为例sudo cat /sys/kernel/debug/usb/usbmon/3u keyboard_capture.log按下几个按键后CtrlC终止捕获得到原始数据样本ffff8a1b12a8d400 1638297565 S Ci:3:002:0 s a1 01 0000 0001 0008 8 ffff8a1b12a8d400 1638297567 C Ci:3:002:0 0 8 0000000000000000 ffff8a1b12a8d400 1638298512 S Ci:3:002:0 s a1 01 0000 0001 0008 8 ffff8a1b12a8d400 1638298514 C Ci:3:002:0 0 8 00000400000000002.2 数据包结构解析usbmon输出的关键字段说明字段位置示例值含义1ffff8a1b12a8d400URB唯一标识符内核地址3Ci控制输入传输(Control Input)43:002:0总线:设备:端点号78 数据长度8字节方向为设备到主机9 00000400...实际传输的HID报告数据3. HID报告描述符解码3.1 报告描述符获取USB HID设备通过描述符定义数据格式获取键盘描述符sudo lsusb -v -d 046d:c31c | grep -A50 HID Device Descriptor关键输出片段HID Device Descriptor: bLength 9 bDescriptorType 33 bCountryCode 0 bNumDescriptors 1 bDescriptorType 34 wDescriptorLength 65 Report Descriptor: (length is 65) Item(Global): Usage Page, data [ 0x01 ] 1 Generic Desktop Controls Item(Local): Usage, data [ 0x06 ] 6 Keyboard Item(Main): Collection, data [ 0x01 ] 1 Application3.2 按键码映射表标准USB HID键盘的键码对应关系部分十六进制十进制按键0x044A/a0x055B/b0x066C/c0x077D/d0x1A26[/ {0x1B27]/ }0x2840Enter0x2941Escape4. 实战数据包分析4.1 单按键按下事件捕获到的数据样本ffff8a1b12a8d400 1638298514 C Ci:3:002:0 0 8 0000040000000000解析步骤数据部分0000040000000000按字节分组00 00 04 00 00 00 00 00第1字节00修饰键状态Shift/Ctrl/Alt等第3字节04对应键码表可知是字母A其余字节00保留位或同时按下的其他键4.2 组合键事件分析ShiftA组合击键的典型数据ffff8a1b12a8d400 1638301123 C Ci:3:002:0 0 8 0200040000000000关键区别第1字节变为02左Shift键的修饰位标志第3字节仍为04物理A键的扫描码4.3 数据包时序分析连续击键的时间戳差值计算timestamp1 1638297565 timestamp2 1638298512 delta_ms (timestamp2 - timestamp1) / 1000 print(f按键间隔{delta_ms:.1f}毫秒)输出示例按键间隔946.7毫秒5. 高级分析技巧5.1 使用Python解析数据自动化解析脚本示例import re def parse_usbmon(line): pattern r.* C Ci:\d:\d:\d \d \d ([0-9a-f]) match re.match(pattern, line) if match: return bytes.fromhex(match.group(1)) return None sample ffff8a1b12a8d400 1638298514 C Ci:3:002:0 0 8 0000040000000000 print(parse_usbmon(sample)) # 输出b\x00\x00\x04\x00\x00\x00\x00\x005.2 Wireshark联合分析将usbmon输出转换为pcapng格式text2pcap -T 147,147 keyboard_capture.log keyboard.pcap在Wireshark中应用USB HID解析器右键数据包 → Decode As → USBHID5.3 异常数据诊断常见问题数据模式及含义数据模式可能原因0000000000000000按键释放事件FF00FF0000000000全键按下防鬼跳测试0100000000000000左Ctrl键按下持续相同非零数据按键卡住或硬件故障在虚拟机环境中测试时可能会观察到额外的控制传输数据包这是虚拟化层与主机通信的正常现象。实际物理键盘的数据流通常更简洁主要集中在中断传输端点上。