我正在尝试对 USB (HID) 设备进行逆向工程,但无法真正弄清楚我在 wireshark(Linux 或 Windows 上的 usbmon + wireshark)上看到的内容与 USB 协议有何关系?我已从 www.usb.org 查看了 USB 协议。
wireshark 显示什么?
1)每个数据包一行?(令牌、数据、握手)
2)每笔交易一行?(令牌+ [数据] + 握手)(我的猜测)
3)每个控制传输一行?
交易的方向也很奇怪(到/来自字段)。至少,它不符合我的期望 :-) ... 枚举的数据部分、隐藏报告等... 似乎有时与设置数据(8 个字节)一起显示,有时不显示... 我真的不知道 URB 是什么... 据我所知,USB 协议中没有提到这一点... 在我看来,wireshark/usbmon 在更高的堆栈级别进行跟踪,并尝试从中推断出线路上的情况...
下面给出了我所能看到的示例,我们在这里看到什么?
a) 我甚至无法在规格中找到 bmtype=0x20(设置的帧号=599)。
b)因为我有一个 HID 设备,所以我假设这可能是一个报告/功能配置(枚举在此阶段传递)。所以我可以同意方向(主机->设备)。但数据在哪里?或者这里没有数据阶段?那么第 600 帧是什么?
c)第 600 帧是什么?数据是什么?
d)帧 601 是什么?状态 ACK?... 但是数据和 ACK 有相同的来源吗?
No. Time Source Destination Protocol Length Info
599 67.996889 host 2.0 USB 36 URB_CONTROL out
Frame 599: 36 bytes on wire (288 bits), 36 bytes captured (288 bits)
USB URB
USBPcap pseudoheader length: 28
IRP ID: 0xfffffa800a1e2610
IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
URB Function: URB_FUNCTION_CLASS_DEVICE (0x001a)
IRP information: 0x00, Direction: FDO -> PDO
URB bus id: 1
Device address: 2
Endpoint: 0x00, Direction: OUT
URB transfer type: URB_CONTROL (0x02)
Packet Data Length: 8
Control transfer stage: Setup (0)
[Response in: 601]
[bInterfaceClass: Unknown (0xffff)]
URB setup
bmRequestType: 0x20
0... .... = Direction: Host-to-device
.01. .... = Type: Class (0x01)
...0 0000 = Recipient: Device (0x00)
bRequest: 0
wValue: 0x0000
wIndex: 0
wLength: 16
0000 1c 00 10 26 1e 0a 80 fa ff ff 00 00 00 00 1a 00 ...&............
0010 00 01 00 02 00 00 02 08 00 00 00 00 20 00 00 00 ............ ...
0020 00 00 10 00 ....
No. Time Source Destination Protocol Length Info
600 67.997889 2.0 host USB 44 URB_CONTROL out
Frame 600: 44 bytes on wire (352 bits), 44 bytes captured (352 bits)
USB URB
USBPcap pseudoheader length: 28
IRP ID: 0xfffffa800a1e2610
IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
URB Function: URB_FUNCTION_CONTROL_TRANSFER (0x0008)
IRP information: 0x01, Direction: PDO -> FDO
URB bus id: 1
Device address: 2
Endpoint: 0x00, Direction: OUT
URB transfer type: URB_CONTROL (0x02)
Packet Data Length: 16
Control transfer stage: Data (1)
[Request in: 599]
[Time from request: 0.001000000 seconds]
[bInterfaceClass: Unknown (0xffff)]
CONTROL response data
0000 1c 00 10 26 1e 0a 80 fa ff ff 00 00 00 00 08 00 ...&............
0010 01 01 00 02 00 00 02 10 00 00 00 01 05 04 0d 56 ...............V
0020 fb 82 c0 1d 10 18 cc 02 00 00 00 01 ............
No. Time Source Destination Protocol Length Info
601 67.997889 2.0 host USB 28 GET STATUS Status
Frame 601: 28 bytes on wire (224 bits), 28 bytes captured (224 bits)
USB URB
USBPcap pseudoheader length: 28
IRP ID: 0xfffffa800a1e2610
IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
URB Function: URB_FUNCTION_CONTROL_TRANSFER (0x0008)
IRP information: 0x01, Direction: PDO -> FDO
URB bus id: 1
Device address: 2
Endpoint: 0x00, Direction: OUT
URB transfer type: URB_CONTROL (0x02)
Packet Data Length: 0
Control transfer stage: Status (2)
[Request in: 599]
[Time from request: 0.001000000 seconds]
0000 1c 00 10 26 1e 0a 80 fa ff ff 00 00 00 00 08 00 ...&............
0010 01 01 00 02 00 00 02 00 00 00 00 02 ............
显然我遗漏了一些东西。欢迎对 wireshark 显示与协议的关系以及(基于此)上述跟踪的含义进行一般性解释!
我最初在 Stack Overflow 上发布了此问题,但被告知这不是一个直接的编程问题。希望它在这里更合适。
答案1
USB URB 类似于 IP 数据包,而 USB 端点类似于 IP 端口。USB 端点 0x00-0x7F 位于主机上,端点 0x80-0xFF 位于设备上(我认为)。因此,端点编码了传输的方向。lsusb
将显示设备支持哪些端点和哪些传输类型。
我将使用带引号的“数据包”来表示 wireshark 捕获的活动单位。这些并不是实际在网络上发送的内容。例如,“数据包”将带有传输启动时的时间戳,即使这不是通过 USB 总线传输的。
我认为嗅探 USB 协议最令人困惑的方面是,您会看到每个 USB URB 有两个 Wireshark“数据包”。当主机启动某些传输时,这是一个URB_SUBMIT
(Wireshark 显示过滤器usb.urb_type == URB_SUBMIT
)。当传输完成时,这是一个URB_COMPLETE
(Wireshark 显示过滤器usb.urb_type == URB_COMPLETE
)
据我所知,当从主机到设备进行传输时,SUBMIT
“数据包”包含实际传输的 USB 数据。当从设备到主机进行传输(一如既往地由主机发起)时,COMPLETE
“数据包”包含实际传输的 USB 数据。
从分析协议的角度来看,所有其他“数据包”都是干扰或 URB 错误。为了过滤掉干扰,我使用以下显示过滤器
!(usb.urb_type == URB_SUBMIT && usb.endpoint_address.direction == IN) && !(usb.urb_type == URB_COMPLETE && usb.endpoint_address.direction == OUT)
我相信 USB 协议确实涉及一些握手、确认和重传,但这些都由主机控制器处理,操作系统不参与。例如,我认为操作系统不会跟踪确认或重传。
顺便说一句,我正在使用以下命令来分析协议。除了执行上述过滤之外,它还仅显示端点编号(十进制)和 USB 数据。这是在 GNU/Linux 机器上使用 usbmon1 设备进行嗅探,并假设我要监视的 USB 设备位于总线 1 上并具有地址 11。
tshark -i usbmon1 -Y "usb.device_address == 11 && !(usb.urb_type == URB_SUBMIT && usb.endpoint_address.direction == IN) && !(usb.urb_type == URB_COMPLETE && usb.endpoint_address.direction == OUT)" -Tfields -e usb.endpoint_address -e usb.capdata
编辑:该字段endpoint_address
以前是endpoint_number
答案2
WireShark USB 日志是在操作系统级别完成的。对于 Linux,它基于 usbmon 生成的数据,而 usbmon 生成的数据基于 Linux 的内部 URB 结构这里。因此,查看内核和 WireShark 注释和文档可以最好地了解它是什么。
我从内核文档中发现,数据包是 usbmon 结构,后面跟着发送和接收的数据。这是结构(从这里):
struct usbmon_packet {
u64 id; /* 0: URB ID - from submission to callback */
unsigned char type; /* 8: Same as text; extensible. */
unsigned char xfer_type; /* ISO (0), Intr, Control, Bulk (3) */
unsigned char epnum; /* Endpoint number and transfer direction */
unsigned char devnum; /* Device address */
u16 busnum; /* 12: Bus number */
char flag_setup; /* 14: Same as text */
char flag_data; /* 15: Same as text; Binary zero is OK. */
s64 ts_sec; /* 16: gettimeofday */
s32 ts_usec; /* 24: gettimeofday */
int status; /* 28: */
unsigned int length; /* 32: Length of data (submitted or actual) */
unsigned int len_cap; /* 36: Delivered length */
union { /* 40: */
unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
struct iso_rec { /* Only for ISO */
int error_count;
int numdesc;
} iso;
} s;
int interval; /* 48: Only for Interrupt and ISO */
int start_frame; /* 52: For ISO */
unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */
unsigned int ndesc; /* 60: Actual number of ISO descriptors */
};