USB Descriptor and Request Parser

I wrote a tool to parse some USB data. You put in the data packet into the tool, and it’ll translate it into something you can understand.


The reason why I made this tool is because some USB traffic sniffers do not perform parsing on USB packets (especially the freeware ones), but the binary data can still be obtained. This tool will traverse through the binary data, and translate it into something human-readable, using the official documents from The three types of data this tool can handle are “USB Standard Descriptors”, “USB Standard Requests”, and “USB HID Report Descriptors”.

The “parse USB HID report descriptor” function is the reverse of the (horrible) “HID Descriptor Tool” provided by, and the display format is very similar.

Because USB devices are generally embedded devices, this tool is designed with the C programming language in mind. The output can be imported as an array initializer.

I was frustrated when I couldn’t find a tool for this, so I wrote it in hopes that it will become useful for everybody looking for such a tool.

16 thoughts on “USB Descriptor and Request Parser

  1. Ferenc

    Thank you for this. Great tool! I am using it to cross-check my own HID report descriptor parser.

    I found a bug. In pCollection(s,v) the lookup table begins with “Undefined” and it should begin with “Physical” since that is the corresponding collection with ID = 0.


  2. anonymous

    You might want to consider looking at UsbPcap , the project produced some dissectors that were included in the recent version of wireshark. While they do need improvement, and perhaps you might consider adding more functionality to them, they are quite nice for free, and since pcap format is very accessible, hopefully more analyzers will start dumping in that format natively.

    1. Admin Post author

      I also wish Total Phase Data Center can export as pcap.

      I use Wireshark very often for USB and Bluetooth but it’s a pain to generate *.pcap files since they are binary, I have to maintain several custom conversion scripts to do so. Sometimes I just want to do stuff in text/ASCII. I wish there was a XML or JSON format for pcap. (maybe there is and I haven’t found it)

      I use my own parser mainly to generate sane C comments so it’s readable once I put it into C code.

  3. Aki


    It is a great tool to decipher USB descriptors. Thank you!

    I think possible_errors is incremented in pDeviceClass function regardless of whether the class is valid or not. Can you review your code?


    function pDeviceClass(c)
    var tbl = [
    “Use class information in the Interface Descriptors”,

    “Vendor Specific”,

    var str = “”;
    if (c < tbl.length) {
    str = tbl[c];
    if (str != "") {
    str = "(" + str + ")";
    possible_errors++; <<<– increment the error regardlessly
    return str;

    1. Aki


      I tweaked the javascript locally so that possible_error is not incremented if the class is valid.
      Now, the “guess” feature for a sample standard request descriptor:
      81 06 00 22 00 00 D4 00
      is no longer working correctly.
      The script now thinks it is a standard Descriptor, not a standard Request Descriptor.
      What I found was that the possible_error from standard Descriptor parser *was* 1 because of the above coding and after changing the code, both standard Descriptor parser and standard Request Descriptor parser produce 0 (means both legal) and the script thinks the input is a standard Descriptor.

      Is there any way to penalize when the “81 06 00 22 00 00 D4 00” is being parsed as a standard Descriptor???

      The decoded output (as a standard Descriptor) is bogus but seems legal.
      Any suggestions would be greatly appreciated.

  4. Aki


    Your parser seems covers a wide range of descriptor types.
    But you didn’t cover a case for STRING descriptors.
    I’m wondering why you omitted the case as adding the case requires only minuscule efforts.
    Your comments on this would be greatly appreciated.

  5. Aki


    Me, again.
    I think I found a bug in your code.
    The bcd decoding was not correctly implemented.
    The following bcdUSB case should be displayed as 1.10 but 1.16 was shown instead.

    0x10, 0x01, // bcdUSB 1.16


  6. Jordan Klassen

    Hey, thanks for the tool; it would be great if you could host the source on github or something. Also, I’d like to put this into a package for nodejs on npm. I sent you an email with a bit more info.

  7. Nick Rishel

    Heads up there there’s a very minor bug in your parser, the comments generated for logical and physical minimums don’t take into account negative numbers, e.g.
    0x16, 0x00, 0x80, // Logical Minimum (32768)
    … should be…
    0x16, 0x00, 0x80, // Logical Minimum (-32768)

  8. beantowel

    Hi, Zhao, thanks for your tool. I’m now trying to develop a Force Feed Back joystick, and i almost did the same thing you do, i hope the PID (Physical Interface Device) usages can be add to the tool. I extract the definitions from the document “Device Class Definition for Physical Interface Devices (PID) Version 1.0” and that may be helpful to you:
    Furthermore, i wonder if there is any tool could help the debugging in MCU programming, i mean, can we just test our code in some sort of simulation environment on PC and get debug imformation directly?

  9. Rena

    With this report descriptor:

    05 01 09 04 A1 01 09 09 A1 00 05 01 09 30 09 31 09 32 09 33 09 34 09 35 09 40 09 41 09 42 09 46 95 0A 75 10 82 82 00 16 00 80 26 FF 7F C0 C0

    Your script says the logical minimum should be -32768 as I’d expect, but lsusb and Linux joystick driver seem to interpret it as +32768. Any idea?


Leave a Reply

Your email address will not be published. Required fields are marked *