这次介绍一下USB逻辑分析仪。USB协议是比较复杂的通讯协议,使用差分信号进行传输,速度很快,编码上采用 NRZI 【参考1】,这样导致根本无法使用示波器之类的进行Debug (速度快,数据多,一直在变化)。因此,要想知道线路上究竟跑了什么数据只能使用专用的逻辑分析仪进行分析。下面是 Lecroy 出品的 Advisor T3 型USB分析仪,可以进行USB 2.0/3.0 协议的分析(不支持 USB Type C , 有专门额外的设备可以用来分析这个协议)。
下面是设备的正面,A口和B口分别连接在设备和主机上,对于USB HOST 和 Salve来说是透明的。
这是背面的照片,捕获的数据会通过这个接口输出。这是一个2.0的接口,因为内部存储空间有限,这个设备不适合长期抓取大量的数据。
下面尝试抓取 Arduino USB 串口(16U2)的数据,我们先编写一个简单的代码,一直向串口输出字符串:
void setup() { // put your setup code here, to run once: Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: Serial.println("www.lab-z.com"); delay(5000); }
启动工作机上的逻辑分析仪软件之后就可以开始抓取数据了,这是软件界面
抓取的过程是:
- 开始记录
- 插入 Arduino UNO
- 打开串口工具记录
- 从串口工具对 Arduino 发送数据
第一步:设置设备的地址,这里可以看到分配给 Arduino 的USB地址是 0x0F
第二步:HOST要求设备送出 Device Descriptor
REQUEST SUMMARY
Setup Data | 80 06 00 01 00 00 12 00 |
Direction | Device-to-host |
Type | Standard |
Recipient | Device |
bRequest | GET_DESCRIPTOR |
wValue | DEVICE |
wIndex | 0x0000 |
wLength | 0x0012 |
DECODING INFORMATION
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bRequest | 8 | 8 | GET_DESCRIPTOR | 0x06 | bRequest HexVal: 0x06 |
wValue | 16 | 16 | DEVICE type | 0x0100 | Type of Descriptor |
wIndex | 16 | 32 | 0x0000 | 0x0000 | index info |
DEVICE Descriptor
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength | 8 | 0 | 0x12 | 0x12 | Descriptor size is 18 bytes |
bDescriptorType | 8 | 8 | 0x01 | 0x01 | DEVICE Descriptor Type |
bcdUSB | 16 | 16 | 0x0110 | 0x0110 | USB Specification version 1.10 |
bDeviceClass | 8 | 32 | 0x02 | 0x02 | The device belongs to the Communication Device/Interface Class |
bDeviceSubClass | 8 | 40 | 0x00 | 0x00 | Subclass 0x00 not defined |
bDeviceProtocol | 8 | 48 | 0x00 | 0x00 | The device uses the No class specific protocol required Protocol |
bMaxPacketSize0 | 8 | 56 | 0x08 | 0x08 | Maximum packet size for endpoint zero is 8 |
idVendor | 16 | 64 | 0x2341 | 0x2341 | Vendor ID is 9025: No Company Matches Id |
idProduct | 16 | 80 | 0x0043 | 0x0043 | Product ID is 67 |
bcdDevice | 16 | 96 | 0x0001 | 0x0001 | The device release number is 0.01 |
iManufacturer | 8 | 112 | 0x01 | 0x01 | The manufacturer string descriptor index is 1 |
iProduct | 8 | 120 | 0x02 | 0x02 | The product string descriptor index is 2 |
iSerialNumber | 8 | 128 | 0xDC | 0xDC | The serial number string descriptor index is 220 |
bNumConfigurations | 8 | 136 | 0x01 | 0x01 | The device has 1 possible configurations |
第三步,上面的描述符提到这个设备有1个 Configuration Descriptor, 主机要求设备送出 Configuration Descriptor
REQUEST SUMMARY
Setup Data | 80 06 00 02 00 00 FF 00 |
Direction | Device-to-host |
Type | Standard |
Recipient | Device |
bRequest | GET_DESCRIPTOR |
wValue | CONFIGURATION, Index 0 |
wIndex | 0x0000 |
wLength | 0x00FF |
DECODING INFORMATION
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bRequest | 8 | 8 | GET_DESCRIPTOR | 0x06 | bRequest HexVal: 0x06 |
wValue | 16 | 16 | CONFIGURATION type, Index 0 | 0x0200 | Type of Descriptor |
wIndex | 16 | 32 | 0x0000 | 0x0000 | index info |
CONFIGURATION Descriptor (9 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength | 8 | 0 | 0x09 | 0x09 | Descriptor size is 9 bytes |
bDescriptorType | 8 | 8 | 0x02 | 0x02 | CONFIGURATION Descriptor Type |
wTotalLength | 16 | 16 | 0x003E | 0x003E | The total length of data for this configuration is 62. This includes the combined length of all the descriptors returned Warning : The Value of wTotalLength is not equal to real length |
bNumInterfaces | 8 | 32 | 0x02 | 0x02 | This configuration supports 2 interfaces |
bConfigurationValue | 8 | 40 | 0x01 | 0x01 | The value 1 should be used to select this configuration |
iConfiguration | 8 | 48 | 0x00 | 0x00 | The device doesn't have the string descriptor describing this configuration |
bmAttributes | 8 | 56 | 0xC0 | 0xC0 | Configuration characteristics : Bit 7: Reserved (set to one) 1 Bit 6: Self-powered 1 Bit 5: Remote Wakeup 0 |
bMaxPower | 8 | 64 | 0x32 | 0x32 | Maximum power consumption of the device in this configuration is 100 mA |
INTERFACE Descriptor (9 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength | 8 | 72 | 0x09 | 0x09 | Descriptor size is 9 bytes |
bDescriptorType | 8 | 80 | 0x04 | 0x04 | INTERFACE Descriptor Type |
bInterfaceNumber | 8 | 88 | 0x00 | 0x00 | The number of this interface is 0. |
bAlternateSetting | 8 | 96 | 0x00 | 0x00 | The value used to select the alternate setting for this interface is 0 |
bNumEndpoints | 8 | 104 | 0x01 | 0x01 | The number of endpoints used by this interface is 1 (excluding endpoint zero) |
bInterfaceClass | 8 | 112 | 0x02 | 0x02 | The interface implements the Communication Device/Interface class |
bInterfaceSubClass | 8 | 120 | 0x02 | 0x02 | The interface implements the Abstract Control Model Subclass |
bInterfaceProtocol | 8 | 128 | 0x01 | 0x01 | The interface uses the Common AT commands Protocol |
iInterface | 8 | 136 | 0x00 | 0x00 | The device doesn't have a string descriptor describing this iInterface |
Communication Class Specific INTERFACE Descriptor (5 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength.... | 8 | 144 | 0x05 | 0x05 | Size of the descriptor, in bytes |
bDescriptorType | 8 | 152 | 0x24 | 0x24 | CS_INTERFACE Descriptor Type |
bDescriptorSubType | 8 | 160 | 0x00 | 0x00 | Header Funtional Descriptor Subtype |
bcdCDC | 16 | 168 | 0x1001 | 0x1001 | USB Class Definitions for Communications the Communication specification version 10.01 |
Communication Class Specific INTERFACE Descriptor (4 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength.... | 8 | 184 | 0x04 | 0x04 | Size of the descriptor, in bytes |
bDescriptorType | 8 | 192 | 0x24 | 0x24 | CS_INTERFACE Descriptor Type |
bDescriptorSubType | 8 | 200 | 0x02 | 0x02 | Abstract Control Management Functional Descriptor Subtype |
bmCapabilities | 8 | 208 | 0x06 | 0x06 | Bit 0: Whether device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature 0 Bit 1: Whether device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State 1 Bit ... |
Communication Class Specific INTERFACE Descriptor (5 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength.... | 8 | 216 | 0x05 | 0x05 | Size of the descriptor, in bytes |
bDescriptorType | 8 | 224 | 0x24 | 0x24 | CS_INTERFACE Descriptor Type |
bDescriptorSubType | 8 | 232 | 0x06 | 0x06 | Union Functional Descriptor Subtype |
bControlInterface | 8 | 240 | 0x00 | 0x00 | The interface number of the Communications or Data Class interface |
bSubordinateInterface0 | 8 | 248 | 0x01 | 0x01 | Interface number of subordinate interface in the Union |
ENDPOINT Descriptor (7 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength | 8 | 256 | 0x07 | 0x07 | Descriptor size is 7 bytes |
bDescriptorType | 8 | 264 | 0x05 | 0x05 | ENDPOINT Descriptor Type |
bEndpointAddress | 8 | 272 | 0x82 | 0x82 | This is an IN endpoint with endpoint number 2 |
bmAttributes | 8 | 280 | 0x03 | 0x03 | Types - Transfer: INTERRUPT Low Power: No Pkt Size Adjust: No |
wMaxPacketSize | 16 | 288 | 0x0008 | 0x0008 | Maximum packet size for this endpoint is 8 Bytes. If Hi-Speed, 0 additional transactions per frame |
bInterval | 8 | 304 | 0xFF | 0xFF | The polling interval value is every 255 Frames. Undefined for Hi-Speed |
INTERFACE Descriptor (9 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength | 8 | 312 | 0x09 | 0x09 | Descriptor size is 9 bytes |
bDescriptorType | 8 | 320 | 0x04 | 0x04 | INTERFACE Descriptor Type |
bInterfaceNumber | 8 | 328 | 0x01 | 0x01 | The number of this interface is 1. |
bAlternateSetting | 8 | 336 | 0x00 | 0x00 | The value used to select the alternate setting for this interface is 0 |
bNumEndpoints | 8 | 344 | 0x02 | 0x02 | The number of endpoints used by this interface is 2 (excluding endpoint zero) |
bInterfaceClass | 8 | 352 | 0x0A | 0x0A | The interface implements the Data Interface class |
bInterfaceProtocol | 8 | 368 | 0x00 | 0x00 | The interface uses the No class specific protocol required Protocol |
bInterfaceSubClass | 8 | 360 | 0x00 | 0x00 | The Subclass code is 0 |
iInterface | 8 | 376 | 0x00 | 0x00 | The device doesn't have a string descriptor describing this iInterface |
ENDPOINT Descriptor (7 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength | 8 | 384 | 0x07 | 0x07 | Descriptor size is 7 bytes |
bDescriptorType | 8 | 392 | 0x05 | 0x05 | ENDPOINT Descriptor Type |
bEndpointAddress | 8 | 400 | 0x04 | 0x04 | This is an OUT endpoint with endpoint number 4 |
bmAttributes | 8 | 408 | 0x02 | 0x02 | Types - Transfer: BULK Pkt Size Adjust: No |
wMaxPacketSize | 16 | 416 | 0x0040 | 0x0040 | Maximum packet size for this endpoint is 64 Bytes. If Hi-Speed, 0 additional transactions per frame |
bInterval | 8 | 432 | 0x01 | 0x01 | The polling interval value is every 1 Frames. If Hi-Speed, 1 uFrames/NAK |
ENDPOINT Descriptor (7 bytes)
Field | Length (bits) | Offset (bits) | Decoded | Hex Value | Description |
bLength | 8 | 440 | 0x07 | 0x07 | Descriptor size is 7 bytes |
bDescriptorType | 8 | 448 | 0x05 | 0x05 | ENDPOINT Descriptor Type |
bEndpointAddress | 8 | 456 | 0x83 | 0x83 | This is an IN endpoint with endpoint number 3 |
bmAttributes | 8 | 464 | 0x02 | 0x02 | Types - Transfer: BULK Pkt Size Adjust: No |
wMaxPacketSize | 16 | 472 | 0x0040 | 0x0040 | Maximum packet size for this endpoint is 64 Bytes. If Hi-Speed, 0 additional transactions per frame |
bInterval | 8 | 488 | 0x01 | 0x01 | The polling interval value is every 1 Frames. If Hi-Speed, every 1 uFrames |
第五步,主机请求 String Descriptor
我不熟悉USB CDC 协议,因此上面只能做一个简单的使用实例。
最后,多说两句:这款分析仪的价格在 20万人民币,个人基本上不用考虑购买一个玩玩儿了。此外,近两年有一些国产的逻辑分析仪,价格只有国外的十分之一,但是我没有实验过。期待随着时间的推移,国产分析设备有所长进,甚至有一天能够对 USB协议产生影响。大多数情况下,USB设备的调试还是依靠Slave Device 本身的Debug 输出(比如:Uart),普通开发者也不会遇到传输上面的问题。
参考:
高大上的工具!
不知道usbkiller插进去能不能读取到killer的攻击力~ (误)
肯定不行