(This is something I did a few months ago, and I really should have noted down all the details then so I covered everything. However hopefully these notes will remind me enough next time.)

When I first wanted to reverse engineer a USB device that only had Windows drivers the “easy” option was to take a Windows machine, install usbsnoop on it and capture the traffic as a bunch of verbose text files. It was a cumbersome procedure.

Recently I wanted to do a firmware upgrade of a ZTE 3G modem dongle, partly to provider unlock it and partly to try and enable some voice functionality. I was also hoping to sniff the traffic to see how to drive the voice side of things. These days I don’t have a dedicated Windows box, but I do have a Windows 7 KVM virtual machine. I hadn’t yet used the USB support in this, but I thought I’d see what it was capable of.

Firstly I had to explicitly enable USB2 - the device wasn’t happy with the default USB1 only stack that KVM enabled. That involved passing -usb -device usb-ehci,id=ehci to KVM. I also told KVM to grab all the ZTE devices with -device usb-host,bus=ehci.0,vendorid=0x19d2. I dropped a udev rules file into /etc/udev/rules.d to ensure any device nodes created belonged to my normal user.

This gave me a Windows setup that could see the USB dongle and install the appropriate drivers. It was also happy to do the firmware update (along with various device resets on the way as it changed USB ID - this is why I needed the udev rule, to ensure every time the device re-appeared it would be seen by the KVM instance without manual intervention).

After that was complete I investigated usbmon. modprobe usbmon created the appropriate /dev/usbmon<n> files and I chowned the appropriate bus to my normal user. Once this was done I was able to start Wireshark which rather nicely has full USB decoding support. Firing up the custom app in the Windows KVM guest I could see the traffic going back and forth to each of the device endpoints and work out what was going on.

All of this was much more flexible than using a standalone Windows box. Once I figured out that I needed to explicitly enable USB2 I was quite pleased with how simple USB access under KVM was. I also used lvm to create a snapshot of the Windows guest so at the end I could roll back all of the drivers I’d installed for the dongle. And being able to use Wireshark instead of trawling through dense text files helped a lot in seeing the command stream.