USB Monitoring
When developing or hacking USB device drivers for Linux it is often necessary to capture raw USB packets in a Windows environment to understand exactly how to talk to the device. The reason for this is the Windows drivers are usually complete, and by observing the way they talk to the device, it is possible to understand the protocol and data formats used.
To avoid having to run a Windows USB snoop application on a physical machine, or in a virtual machine guest, the usbmon facility of the Linux kernel can be used. Pete Zaitcev's usbmon userspace application uses this facility to dump information on the raw packets. It is possible to use Wireshark too, provided a recent (mid-2008) CVS version of libpcap is used. The libpcap version provides access to raw USB devices as well as network interfaces.
With Linux providing the raw capture facility, a virtual machine Windows guest can be used and the USB device's drivers installed into it. When the USB device is connected using the virtual machine hypervisor connection commands, the Linux packet capture will see and record everything the Windows driver does to initialise and work with the device.
Requirements
Enhanced Ubuntu Packages From My PPA
There are several enhanced Ubuntu packages I've prepared and put in my Ubuntu PPA to make setting-up quick and easy. To use them add my repository to apt's sources list:
sudo sh -c "echo 'deb http://ppa.launchpad.net/intuitivenipple/ubuntu $(lsb_release -sc) main' >/etc/apt/sources.list.d/intuitivenipple.list" sudo apt-get update
Later, to remove it, do:
sudo rm /etc/apt/sources.list.d/intuitivenipple.list sudo apt-get update
Kernel Build Options
The kernel must have been built with support for the debug file-system and USB monitoring. In the kernel .config file that is:
CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_FS=y CONFIG_USB_MON=y
The good news is, Ubuntu Hardy kernels are built with these options enabled so no custom kernel build is required to use the usbmon facility.
Mount Debug File-System
sudo mount -t debugfs / /sys/kernel/debug
Because Ubuntu Hardy (and many other distributions) no longer use the USB device file-system, set it up and provide an alias:
sudo mkdir -p /dev/bus/usb/.usbfs sudo mount -t usbfs /dev/bus/usb/.usbfs -obusmode=0700,devmode=0600,listmode=0644 sudo ln -s .usbfs/devices /dev/bus/usb/devices sudo mount --rbind /dev/bus/usb /proc/bus/usb
Load USBmon Kernel Module
sudo modprobe usbmon
Get USBmon Application
Ubuntu Debian Package
Install the package I've prepared:
sudo apt-get install usbmon
Build Manually
cd ~ wget http://people.redhat.com/zaitcev/linux/usbmon.5.tar.gz cd usbmon make
Get libpcap With USB Support
Note: libpcap CVS is currently unavailable so I've been unable to build the Ubuntu package or complete the manual build instructions
This is required only if you intend using Wireshark to monitor the packets (highly recommended!)
Ubuntu Package
Ensure my PPA is already added to apt's source list (see the instructions above).
Install the libpcap with USB support package:
# sudo apt-get install libpcap=0.9.8-rXXXX-usb~ppa1h
Checkout From CVS Repository
mkdir tcpdump cd tcpdump cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master login # password is anoncvs cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout libpcap
Configure
Before configuring the development headers of several other libraries libpcap depends on are required. With Ubuntu that simply requires:
sudo apt-get build-dep libpcap
Note: this takes advantage if the existing Ubuntu libpcap package's Build-Depends list. The CVS package might require additional and/or later version of some libraries.
Configure options:
./configure ...
Build
make
Virtual Machine
Running Windows in a virtual machine (VM) guest gives a lot of control over the analysis process. It is possible to freeze the VM, inspect its memory, and add or remove USB devices from the command-line.
Ubuntu Package of kvm-74 With USB sys Support
I've recently submitted patches to qemu/kvm that enable use of Hardy's USB sys file-system. Until now it had been a problem since qemu/kvm still used the now-deprecated proc mount of the USB file-system. I patched on top of kvm-74 so again, the enhanced package from my PPA is required:
sudo apt-get install kvm
Multiple Monitors
If using more than one display monitor (always useful because it avoids having to switch between windows constantly) there are a couple of options. With Xinerama the screens are part of one large desktop so just drag the VM guest to a free display. If using independent X screens prefix the hypervisor start-up command with DISPLAY=... to have the VM guest window on another screen but retain the command-line terminal on the current screen, e.g:
DISPLAY=:0.1 kvm ...
Starting
Using kvm, the Intel hardware-accelerated version of qemu, the process is simple. Assuming a prepared Windows XP SP2 guest image is available:
DISPLAY=:0.1 kvm -name WindowsXP -m 512 -usb -monitor stdio -hda WindowsXPSP2.qcow2 -k en-gb
Controlling
Control of the VM guest will be via the console command-line (-monitor stdio) so once the guest has started it is possible to do:
QEMU 0.9.1 monitor - type 'help' for more information
(qemu) info usbhost
husb: trying to open /proc/bus/usb/devices
husb: could not open /proc/bus/usb/devices
husb: trying to open /dev/bus/usb/devices
husb: could not open /dev/bus/usb/devices
husb: trying to open /sys/bus/usb/devices
husb: using /dev/bus/usb
Device 1.1, speed 480 Mb/s
Hub: USB device 0000:0000, EHCI Host Controller
Device 2.1, speed 12 Mb/s
Hub: USB device 0000:0000, UHCI Host Controller
Device 3.1, speed 12 Mb/s
Hub: USB device 0000:0000, UHCI Host Controller
Device 4.1, speed 12 Mb/s
Hub: USB device 0000:0000, UHCI Host Controller
Device 5.1, speed 12 Mb/s
Hub: USB device 0000:0000, UHCI Host Controller
Device 1.3, speed 480 Mb/s
Class 00: USB device 054c:0281, UMH-U09
Device 1.4, speed 480 Mb/s
Class ef: USB device 05ca:1836
Device 3.2, speed 12 Mb/s
Class 00: USB device 093a:2601, VGA Single Chip
Device 4.2, speed 12 Mb/s
Class e0: USB device 044e:300d, UGX
(qemu) usb_add host:093a:2601
husb: open device 3.3
husb: opened /dev/bus/usb/003/003
husb: config #1 need -1
husb: 1 interfaces claimed for configuration 1
husb: grabbed usb device 3.3
(qemu) husb: config #1 need 1
husb: 1 interfaces claimed for configuration 1
husb: config #1 need 1
husb: 1 interfaces claimed for configuration 1
husb: config #1 need 1
husb: 1 interfaces claimed for configuration 1
husb: config #1 need 1
husb: 1 interfaces claimed for configuration 1
Windows Driver Installation
At this point Windows will detect the device and (in XP) display the Found New Hardware Wizard.
Packet Capture
Wireshark
The http://wiki.wireshark.org/CaptureSetup/USB Wireshark Wiki has an overview of USB packet capture.
