Wireshark USB 痕迹说明

use*_*772 15 usb wireshark

我正在尝试对 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               ............
Run Code Online (Sandbox Code Playgroud)

显然我错过了一些东西。关于wireshark显示如何与协议相关的一般解释,以及(基于它)上述跟踪的含义是受欢迎的!

我最初将其发布在 Stack Overflow 上,但被告知这不是直接的编程问题。希望它更适合这里。

Gus*_*Gus 16

USB URB 就像一个 IP 数据包,一个 USB 端点就像一个 IP 端口。USB 端点 0x00-0x7F 在主机上,端点 0x80-0xFF 在设备上(我认为)。因此,端点对传输方向进行编码。lsusb将向您显示设备支持的端点和传输类型。

我将在引号中使用“数据包”来表示wireshark 捕获的活动单位。这些实际上并不是通过线路发送的内容。例如,“数据包”将具有启动传输时的时间戳,即使这不是通过 USB 总线传输的。

我认为嗅探 USB 协议最令人困惑的方面是您会看到每个 USB URB 的两个 Wireshark“数据包”。当主机发起一些传输时,即URB_SUBMIT(Wireshark display filter 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 协议确实涉及一些握手和 ACK 和重传,但这都是由主机控制器处理的,不涉及操作系统。例如,我认为操作系统不会跟踪确认或重传。

顺便说一下,我正在使用以下命令来分析协议。除了进行上面的过滤之外,它只显示端点编号(十进制)和 USB 数据。这是在使用 usbmon1 设备进行嗅探的 GNU/Linux 机器上,并假设我要监视的 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


小智 6

WireShark USB 日志是在操作系统级别完成的。对于 Linux,它基于 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 */
};
Run Code Online (Sandbox Code Playgroud)