wiki:Linux/Ubuntu/USBmonitoring

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.

Next