Lately I came back to reverse engineering project that I started few years ago. Direct reason for such a long break was being stuck at attempts in using usbmon to capture USB traffic. The traffic that I wanted to sniff was between router and modem that connects to it via USB. As is usual with this kind of devices there is no SDK available and compiling custom kernel module for such system, while has huge educational value, is most likely going to end up with failure. So definitely I needed another way around this problem. Fortunately I have DSLogic logic analyzer, that could easily record such a slow protocol as USB. Then a bit of exporting and you get pcap file for wireshark. This might sound like a simple task, but I am going to show that it is not necessarily is.
Hardware
In theory it is too obvious to describe. 4 wires and 2 USB-A connectors at both ends. Boring. But in practice it is not that simple.
Now I have to explain why. In theory the shorter the cable, the better. Otherwise you are going to have degraded performance due to transmission problems. But problem is with DSView program, or capabilities of hardware. With USB 2.0 I was not able to decode any traffic with DSView. USB 2.0 is low voltage protocol, so it barely touches 0.5V. From what I was able to observe with oscilloscope you would need to set threshold at around 0.25V, while DSView allows you to set it to either 0.2V, or 0.3V. None of them works in this case. So why this ugly three part cable is better? The trick is to force USB controller to downgrade to USB version 1. This ancient standard used 3V3 logic for communications. So we need cable that is bad enough to stop working as USB 2.0, but good enough to maintain full-speed USB transmission 🙂 That is how I did it. I guess adding some resistor could decrease required length, but cables alone works too, so why bother?
DSView
As we now know how and why should we connect our devices, we can go on to next part, which is DSView. There is nothing special here, but just in case, this is how my configuration looks like:
Important here is to set at least 100 MHz sampling, so if your analyzer does not support it, it might not work for you despite USB being 48 MHz. I don’t want to get deep into quantization problems, so let me end it here.Edit: USB Full Speed is 12 MHz, while USB 2.0 is 480 MHz, so that’s why we needed downgrade to USB Full Speed. Sampling lower than 100 MHz should work as long as it is at least 24 MHz.
Now if you are going to capture the moment of plugging the device in, it is worth to set up some cursor at the beginning of USB transmission. Otherwise DSView might show you an error and refuse to decode further. Also if you are as crazy as me to set capture time to 20s, be prepared for your computer to slow down significantly, or set also cursor, where you want decoder to stop decoding.
And this is what you should see after zooming in:
Once you have your desired transmission fully decoded, it is time to export decoded USB packets. DSView is not the best tool to analyze USB transmission, unless you look for physical layer problems. But I assume, you are not. So hit diskette button at top of Protocol List Viewer and select this format:
What you are going to get is something like that:
Id,Time[ns],USB packet: Packet fields
0,3427756600.00000000000000000000,SYNC: 00000001
1,3427757260.00000000000000000000,PID: SOF
2,3427757930.00000000000000000000,Frame: 656
3,3427758840.00000000000000000000,CRC5: 0x02
4,3428756590.00000000000000000000,SYNC: 00000001
5,3428757250.00000000000000000000,PID: SOF
6,3428757920.00000000000000000000,Frame: 657
7,3428758830.00000000000000000000,CRC5: 0x1D
8,3429756580.00000000000000000000,SYNC: 00000001
9,3429757240.00000000000000000000,PID: SOF
10,3429757910.00000000000000000000,Frame: 658
11,3429758820.00000000000000000000,CRC5: 0x15
12,3430756570.00000000000000000000,SYNC: 00000001
13,3430757230.00000000000000000000,PID: SOF
14,3430757900.00000000000000000000,Frame: 659
15,3430758810.00000000000000000000,CRC5: 0x0A
16,3431756560.00000000000000000000,SYNC: 00000001
Don’t worry about a lot of SOF packets. Once we get it to wireshark, they can be easily hidden with a filter.
TXT to PCAP?
Until that point we were using freely available tools. But if you have gotten here before me, you would know there is no way forward. But for me it is no problem, I created my own way 😀
Let me present you cute little utility that does exactly what it is supposed to do. It is called txt2pcap.py and can be downloaded from my Github Gist, or with wget:
wget 'https://gist.github.com/v3l0c1r4pt0r/94bc6954a9491916581ffd291addd36e/raw/8cb20605d0e6d0f65db78d21fc753f4014f8f11a/txt2pcap.py'
Then you just call it like that and it works:
python3 ./txt2pcap.py < decoder.txt > decoder.pcap
I have to note here that in the current version, I omitted timestamps in pcap records, simply because I did not need them. But as always any contribution is welcome. Also if you encounter any problems, do not hesitate to contact me.
I hope that during that project I will have opportunity to show more interesting things. For sure I already have Wireshark plugin written in Lua as a result of this sniffing, so expect it to at least appear on my Github some time in the near future. It’s not the nicest code I wrote in my life, but was enough to identify what kind of hacks device authors made to make it as incompatible as possible 🙂