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.