Skip to content

Reverse Engineering USB Protocol

Martin edited this page Mar 25, 2018 · 3 revisions

Up to date documentation at https://github.com/openrazer/openrazer/wiki/Reverse-Engineering-USB-Protocol

Prerequisites

There are a few things you will need when reverse engineering the USB protocol device. Firstly you will need a device 😉. You will also need an additional keyboard, Virtualbox, VirtuaBox Extensions Pack, a Windows VM (I normally use 7 for this), Razer Synapse installed on the VM and Wireshark. It goes without saying that you have access to root privileges. I would suggest that the Windows VM have only the Razer software on it and that's it, makes for a better testing environment.

Before attempting to do anything you will need to pass the USB device of whatever you are reverse engineering through to the Virtualbox VM. If synapse can recognise it and control it then you are in luck.

I would also familarise yourself with the wireshark interface as it will be used extensively.

Phase 1 - (Research)

Before you start reverse engineering you want to learn as much about the device as you can. The main thing would be a list of features. Throughout the rest of this "tutorial" I will be using the Razer BlackWidow Chroma as an example.

The Chroma has full RGB backlit keys which are each individually addressable. This tells us two things, firstly that as the keyboard can access a whole spectrum of colours it wouldn't be a bad assumption to think that the keyboard using RGB (aka 1byte = RED, 1byte = GREEN, 1byte = BLUE, 3bytes total) to represent colours, similar to how you would represent colour in HTML like #FF0000 (RED). Secondly as each of the keys are individually addressable this means each key is probably represented by an RGB backlit value. So how might they accomplish this feature? you could send a Key ID and an RGB value to the keyboard to set up a key, this is OK but would take ages for lots of keys. You could send all of the keys RGB values but that's a lot of data. What we have found is that you set the keys on the keyboard on a row by row basis.

The Chroma has brightness settings, so it stands to reason that you would send a brightness value to the keyboard. Etc...

What I normally do is go through the Razer Synapse app and take screenshots of all the various features and buttons you can click on.

Insert snaps of razer synapse app options

Phase 2 (Setup)

When you start monitoring the USB traffic you will get a whole host of rubbish unless you filter out the unnecessary information. To create a Wireshark filter you will need the USB bus ID and the USB device ID, running lsusb will give you something similar to this. As you can see the bus ID is 5 and the device ID is 3. Other useful things to note is the USB Vendor ID is 0x1532 and the USB Product ID is 0x0203.

$ lsusb
Bus 005 Device 003: ID 1532:0203 Razer USA, Ltd

You will need to monitor USB traffic, to do this you will need to enable it in the kernel. To do so you need to load the kernel module using the following command as root.

modprobe usbmon

Now you are ready to start Wireshark, start it as root. Then click on the button that says "Interface List", this will bring up a dialog with all the interfaces you can record from (you might have to expand the window downwards). Tick all the "usbmon" interfaces and hit start. Wireshark should start and if any USB devices are active then it will be spamming the screen with packets. At the top of Wireshark there is a filter bar, using the filter below will filter out all irrelevant USB devices. The filter is pretty self explanatory and can be adapted to suit your needs.

usb.bus_id == 5 && usb.device_address == 3

Pictures of greyed out areas like interface list, the checkboxes etc...

Ok now the reason you have the additional keyboard is because when your logging all USB traffic to the keyboard you don't want to log the traffic your generating when your just trying to use the computer - I think that makes sense.

Open Synapse and set the device to its most inert state so in the case of the keyboard I set it to the None effect.

Phase 3 (Reverse Engineering)

Once Wireshark is running, synapse is open and controlling the device we are good to start. Now here is where the repetitive fun begins. When the Razer Synapse app sends commands to the keyboard it uses a specific format. From that we can hopefully create a compatible driver.

Clear any data Wireshark has captured, (a green lopsided triangle with a restart circular arrow). Now we are going to find out how the static mode is done. Switch the keyboard between the None and Static mode a few times. Stop the recording, save the packets. Repeat that a second time, starting at the beginning of the paragraph then move onto another feature.

Pictures of recording

Phase 4 (Command Decoding)

The Razer protocol is built up of various fields.

  • Start Byte, its 0x00 if its PC -> Device, its 0x02 when its Device -> PC.
  • ID Byte, this is normally 0xFF but it can vary.
  • Reserved Bytes, this is 3 bytes of 0, 0x000000
  • Number of parameters byte, this signifies how many bytes are after the command byte.
  • Reserved Byte, not sure what this byte is for.
  • Command Byte, this signifies what action is being done, like change effect for example.
  • Sub command Byte, this is part of the parameters but has been split out for some reason.
  • Parameters, this is a varying number of bytes.

On the wireshark screen, you should see a field called left over data should have a string that looks something like the below (First line is static effect, to illustrate what is being done I added in the wave effect line).

00ff00000004030a0600ff00000000000000000000000000...
00ff00000002030a01020000000000000000000000000000...

You can decode this so that it makes more sense.

Start | ID | Reserved | Num Params | Reserved | Command | Sub Cmd | Params | Effect
00      FF    000000       04           03        0A         06     00FF00 | Static (Green RGB Value)
00      FF    000000       02           03        0A         01     02     | Wave (Direction Down)

The Number of bytes in Sub Cmd + Params should equal the number (remember its hex) in "Num Params"

After gathering lots of data, like the static effect in various colours, or the wave effect in each direction you can see we are starting to understand how the Synapse App works.