Wednesday, 29 December 2004
Published 12/29/2004 00:40:35 (Eastern Standard Time, UTC-05:00)

Earlier this month, I bought the USB Wireless Security Lock from ThinkGeek

It is an interesting device, but I was immediately dissapointed by it.

  • It does not support multiple displays.  I read this in the ThinkGeek description, and was not entirely sure what that meant - it could mean many things.  Turns out that when you have multiple displays this device is totally ineffectual because:
  • It locks your system by displaying a full-screen windows application that tries its best to be the topmost window, and tries its best to keep you from accessing the applications and system it hides beneath it.

So I thought, hmmm, could I possibly write software to do this better?

Well the first step of doing this is to reverse engineer how the hardware works.

How the Hardware Works

The software that ships with the product is proprietary and closed-source.  I have no real skills decompiling anything other than .NET assemblies, so I quickly decided this was of no help to me.

There are no specifications or documentation about the hardware that can be found by performing a reasonable Google search.

I decided then, that my first course of action was to find the device entry in the Device Manager.  With my reasonable ignorance of the inner workings of USB at the time, it took me a while to look under “Human Interface Devices”.  Luckily, I found a USB Human Interface Device listed that would disappear when I unplugged the receiver from my computer!

The details of the device included this snippet: “Location 0 (Cypress Ultra Mouse)”.  Aha!  It immediately dawned on me they just used the guts from a cheapo USB wireless mouse.  Very industrious.

I was dismayed by the scant 3 pages of results it found for “Cypress Ultra Mouse” on Google.  The majority seemed to be Linux users complaining about it not working in such-and-such kernel.  I did see mention of “Packard Bell Cypress Ultra Mouse”, so at least my guess about it being a cheapo wireless mouse was confirmed!

I never really pondered it until now, but surely wireless mice must have unique identifiers (within a product family at least) to prevent interference when multiple mice are used on separate systems in close proximity.  This aspect alone is what enables this product – a hardware token with a unique device identifier.

At this point, I had to go through an accelerated education in the USB specification, investigation into ways to access USB devices from C# and .NET, which resulted in a re-acquaintance to win32 Interop (SUCK).

There are a number of .NET USB libraries that are shit.  I finally came across one called USBSharp, which is really just very a thin wrapper (read: consists of DllImport signatures, and the structs required to support those external methods) of all the native win32 calls required to find and open a USB HID device.  My proof of concept code to initially attach to the usb receiver was almost entirely lifted from the example program that came with USBSharp.

The real pay dirt was the sample program itself, as it gave me my first insight into the data passed to the receiver by the key fob.  The program allowed me to enumerate the HID devices on my machine, pick one, and then read the raw bytes from it and display it in a text box!

From the raw data a protocol was quickly deduced.  Before even seeing the raw data, based on an educated guess and the rhythmically synchronized blinking lights on the fob and the receiver, I suspected the system operated on the concept of “heartbeats”.

The fob lights up and sends a signal every 2 seconds.  The receiver interprets the wireless data, and creates what is called, in USB terms, a “report”.  The report length is 5 bytes long.  Having access to only two key fobs, I believe I was able to deduce what the bytes mean, but I realize that these deductions may be incomplete.

Here is the byte layout for the key fobs.  A fob is seemingly capable of only 2 distinct signals/reports.  One when the device is sending a heartbeat, and another when it is initially turned on.

So, I believe that the 3rd and 4th bytes comprise the key fob’s device id.  It also appears that you can tell an initial activation from a heartbeat, by the presence of an 8 in the 2nd byte, and a 1 in the 5th byte.

What is odd, is that these reports are duplicated.  Each time the lights on the fob and the receiver light up, and it is a heartbeat, the heartbeat code is sent 3 times in quick succession.  What is even more odd is that the report for an initial activation is duplicated even more times - but seemingly randomly, anywhere between 11 and 26 times.  I wonder if this is possibly part of the protocol, but I cannot think of any way it could be.

Confusion by these duplicated reports aside, I do not understand why you would discern between the key fob being turned on, and a heartbeat.  I am assuming this serves some purpose for a wireless mouse, and they just left it in, rather than modify the default behavior of the hardware.

I am assuming there are other artifacts from the hardware starting out as a wireless mouse – perhaps something to indicate remaining battery life?

Armed with these assumptions, and a guess of what the protocol is, I started coding a proof of concept.