desowin / usbpcap

USB packet capture for Windows
http://desowin.org/usbpcap
902 stars 170 forks source link

Odd output for certain USB functions when viewed in Wireshark #63

Closed MartyMacGyver closed 5 years ago

MartyMacGyver commented 5 years ago

tl;dr - I've been looking at the USB traffic to a simple little USB device (a fan with a programmable display), and couldn't figure out how the actual data was being sent. Turns out it's being captured but either the capture is wonky or Wireshark is incorrectly displaying this data.

USBpcap 1.2.0.4 (via the current version of Wireshark 2.6.4) on Windows 10 x64 shows all sorts of useful traffic: USB_CONTROL out, SET CONFIGURATION Status, USB_INTERRUPT in... but none of that appeared to have any data. In fact, other than IDs all the traffic from the host to the device (which the analyzer only showed being USB_CONTROL out traffic) was basically identical.

So, I gave USBlyzer a trial - it sees all that traffic, but it also sees URB_FUNCTION_CLASS_INTERFACE/URB_FUNCTION_CONTROL_TRANSFER traffic right before each of those USB_CONTROL out requests:

First frame, out to the device:

Device Object   FFFF838D8636DA60h
Driver Object   USBPcap

URB Function    URB_FUNCTION_CLASS_INTERFACE

Request Set Report
Report Type Output
Report Length   8

(I can see the raw 8 bytes in here)

Followed by another frame, also out to the device (though I'm not sure that's correct as it appears to be a response):

Device Object   FFFF838D8636DA60h
Driver Object   USBPcap

URB Function    URB_FUNCTION_CONTROL_TRANSFER
URB Status  USBD_STATUS_SUCCESS

Endpoint 0  Default Control

Request Set Report
Report Type Output
Report Length   8

The raw data (e.g., 40 23 94 84 94 84 94 27) appears to be what I expect (the format of the data is unclear but it's not compressed and varies in a way that strongly suggests it's exactly what I'm looking for). Clearly it's going through the USBPcap driver. Neither that traffic nor that data is in the Wireshark output.

That all said, I got curious and looked at the actual PCAP file in a hex editor... and there I see the those exact bytes, along with other unique patterns corresponding to the other requests I so far have only been able to view in USBlyzer.

And so I searched for that same hex data in Wireshark and also found... but as part of the URB_CONTROL in from the device, which is very peculiar (and apparently is not really what's happening on the wire). Here's an example that corresponds with the one above (I re-did the first test).

Frame from host to 1.2.0 (device):

Frame 61: 36 bytes on wire (288 bits), 36 bytes captured (288 bits)
    Encapsulation type: USB packets with USBPcap header (152)
    Arrival Time: Nov  6, 2018 00:49:17.477649000 Pacific Standard Time
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1541494157.477649000 seconds
    [Time delta from previous captured frame: 0.000047000 seconds]
    [Time delta from previous displayed frame: 0.000047000 seconds]
    [Time since reference or first frame: 0.623433000 seconds]
    Frame Number: 61
    Frame Length: 36 bytes (288 bits)
    Capture Length: 36 bytes (288 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: usb]
USB URB
    [Source: host]
    [Destination: 1.2.0]
    USBPcap pseudoheader length: 28
    IRP ID: 0xffff838d8e6aa010
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_CLASS_INTERFACE (0x001b)
    IRP information: 0x00, Direction: FDO -> PDO
        0000 000. = Reserved: 0x00
        .... ...0 = Direction: FDO -> PDO (0x0)
    URB bus id: 1
    Device address: 2
    Endpoint: 0x00, Direction: OUT
        0... .... = Direction: OUT (0)
        .... 0000 = Endpoint number: 0
    URB transfer type: URB_CONTROL (0x02)
    Packet Data Length: 8
    [Response in: 62]
    Control transfer stage: Setup (0)
    [bInterfaceClass: Unknown (0xffff)]
URB setup
    bmRequestType: 0x21
        0... .... = Direction: Host-to-device
        .01. .... = Type: Class (0x1)
        ...0 0001 = Recipient: Interface (0x01)
    bRequest: 9
    wValue: 0x0200
    wIndex: 0 (0x0000)
    wLength: 8

Frame from 1.2.0 (device) to host:

Frame 62: 36 bytes on wire (288 bits), 36 bytes captured (288 bits)
    Encapsulation type: USB packets with USBPcap header (152)
    Arrival Time: Nov  6, 2018 00:49:17.478230000 Pacific Standard Time
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1541494157.478230000 seconds
    [Time delta from previous captured frame: 0.000581000 seconds]
    [Time delta from previous displayed frame: 0.000581000 seconds]
    [Time since reference or first frame: 0.624014000 seconds]
    Frame Number: 62
    Frame Length: 36 bytes (288 bits)
    Capture Length: 36 bytes (288 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: usb]
USB URB
    [Source: 1.2.0]
    [Destination: host]
    USBPcap pseudoheader length: 28
    IRP ID: 0xffff838d8e6aa010
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_CONTROL_TRANSFER (0x0008)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 2
    Endpoint: 0x00, Direction: OUT
        0... .... = Direction: OUT (0)
        .... 0000 = Endpoint number: 0
    URB transfer type: URB_CONTROL (0x02)
    Packet Data Length: 8
    [Request in: 61]
    [Time from request: 0.000581000 seconds]
    Control transfer stage: Data (1)
    [bInterfaceClass: Unknown (0xffff)]
CONTROL response data: 40238494a4a4a467

So, the question I have is, where's the problem? Is this a case of USBPcap not saving the data correctly? Or is Wireshark failing to properly decode said data?

I've attached the PCAP of interest here (I'd include the USBlyzer file but it appears to have a lot more info buried in it than I'd want to post publicly - contact me if you're interested in that.)

Test5.zip

I came here first because - until I was halfway through writing this - it appeared the data wasn't getting collected to begin with. Clearly it is though but I'm not sure where the problem is. I'm also not sure what the authors of USBPcap have to do with the Wireshark side of things (especially when it comes to deciphering and displaying said pcap data). I'm happy to open this ticket up there if it's preferred.

(And as an aside my brief encounter here with USBlyzer - which hasn't been updated in years and which may not be accurately showing the direction of responses - reminds me why I like to use tools like Wireshark and USBPcap. At least here I have hope of getting an answer that may lead to an eventual fix if needed! Thanks in advance for any insight you may have on this vexing problem!)

MartyMacGyver commented 5 years ago

One small followup: tshark -r Test5.pcap -V produced the same peculiar output as shown above for Wireshark.

desowin commented 5 years ago

The bug is in USBPcap. It is the fact that USBD_TRANSFER_DIRECTION_OUT (0) is used as a bit mask - which makes the condition in USBPcapAnalyzeControlTransfer not working. I remember investigating this issue some weeks ago but I have no idea why I didn't fix it back then (most likely due to the fact that releasing updated driver on Windows 10 would need #57 to be fixed).

MartyMacGyver commented 5 years ago

Thanks for the quick reply! I honestly thought it was some weirdness in Wireshark itself. What's the roadmap to 1.3.0.0 (or possibly 1.2.0.5)?

The Readme is a bit confusing as far as the signing situation goes (TESTSIGNING never came up for me). Not sure how that's related to your #57.

desowin commented 5 years ago

@MartyMacGyver Beginning with Windows 10 Microsoft made it mandatory for all drivers to be Attestation Signed through their portal. The first Attestation signed USBPcap driver worked fine on the portal and thus you were able to install USBPcap on your computer without test signing. However, when I was doing the 1.2.0.4 release, I noticed that the driver signing didn't pass (and thus the 1.2.0.4 installer does use 1.2.0.3 driver for Windows 10). As the 1.2.0.4 release fixed a serious USBPcapCMD issue, I decided to release it with unchanged driver. And since the 1.2.0.4 release, non-USBPcap-related things kept me busy so that's probably the reason for the bug not being fixed...

To sum it up, even if I fixed this bug, it will not possible to install it on (normal user's) Windows 10 until #57 is fixed.

MartyMacGyver commented 5 years ago

Understood. Well, if you ever happen to ever have a test version to try out that a non-standard user like me could try out, I'll keep an eye out for it here. :-D Otherwise I'll keep an eye out for 1.3.0.0 (and will attempt to build this locally too).