Should you be able to brick a keyboard just by writing a driver to flash the lights on it? We don’t think so either. [TheNotary] got quite the shock when embarking on a seemingly straightforward project to learn C++ on the x86-64 architecture with Windows and sent it straight to Silicon Heaven with only a few seemingly innocent USB packets.
The project was a custom driver for the XVX S-K80 mechanical keyboard, aiming to flash LED patterns across the key LEDs and perhaps send custom images to the integrated LCD. When doing this sort of work, the first thing you need is the documentation of the communications protocols. Obviously, this was not an option with a closed-source project, so the next best thing is to spy on the existing Windows drivers and see how they worked. Using Wireshark to monitor the USB traffic whilst twiddling with the colour settings, it was clear that communications were purely over HID messages, simplifying subsequent analysis. Next, they used x32dbg (now x64dbg, but whatever) to attach to the existing driver process and trap a few interesting Windows system calls. After reading around the Windows API, a few candidate functions were identified and trapped. This gave them enough information to begin writing code to reproduce this behaviour. Then things got a bit odd.
There apparently was a lot of extra protocol baggage when performing simple tasks such as lighting an LED. They shortened the sequence to reduce the overhead and noticed an additional byte that they theorized must encode the number of packets to expect in case only a subset of the LEDs were being programmed. Setting this to 0x01 and sending LED code for single keys appeared to work and was much faster but seemed unreliable. After a short experiment with this mystery value, [TheNotary] reverted the code to send all the packets for the full LED set as before, forgetting to correct this mystery value from the 0xFF it was programmed to during the experiment. They were surprised that all the LEDs and LCD were switched off. They were then horrified when the keyboard never powered up again. This value appeared to have triggered an obscure firmware bug and bricked it—a sad end to what would have been a fun little learning project.
Keyboard hacks are so plentiful it’s hard to decide where to start. How about upgrading the keyboard of your trusty ZX81? Here’s a lovely, minimal mechanical keyboard powered by a Pi Pico, and finally while we’re thinking about drivers bricking your stuff, who can forget FTDI gate? We may never forgive that one.
Header image: Martin Vorel, CC BY-SA 4.0.
Using HID as the base protocol is something most hw hackers should get familiar with. Really comfy.
agree, everyone should at least be able to write a descriptor. a good two thirds of my hacks are hid devices.
would you happen to know a good source of tutorial for learning these?
Oh yes I have done exactly the same thing reverse engineering a Flexray module. I changed one byte in the SCN config to 0xFF and it induced a buffer overflow. This stopped the config from loading at both startup and in provisioning so no module function and also no ability to update over UDS. That was fun.
SELF-DESTRUCT CODE makes it sound intentional. I’d guess this is just a buffer overflow that somehow resulted in firmware being corrupted.
I’ve heard of pagers like that
recent news on the pager front has been interesting. at least they answered the question who terrorizes the terrorists.
they went further, now it’s popping GSMR radios
Further still, anything with a battery.
Clickbait. I kind of suspect they to tell you to not go rooting around in there. You do it and mess something up and it is self destruct code? Sorry, but no.
Interesting story, but the Stuxnet reference is all wrong. Siemens didn’t have a bug in their controllers that led to their destruction, that was a spectacularly well designed abuse of the enrichment process employing temperatures and pressures to precipitate solid UF6 onto the centrifuges’ rotors, causing them to physically destroy themselves.
Didn’t the Stuxnet attack include the Siemens devices stop reporting their actual data and instead return fake data to the industrial control system?
Like the speed of the centrifuges?
Referencing it here is still wrong. And the article’s title is clickbait BS – where is the self destruct code?
Yes, Stuxnet included a man-in-the-middle in the VFD firmware that reported the correct frequency even as it was being massively changed to overstress the centrifuges.
A downvote for this article, there is no evidence of a self destruct code found though reverse engineering, but most likely some obscure bug that got triggered.
But apparently the flash of this thing is writable, so you can take up the challenge to write new firmware.
Pretty much what I came here to say. I’d also like to offer the observation that instead of a bug what may have been accidentally triggered was the keyboard’s microcontroller firmware re-flashing code. It stands to reason that the manufacturer would build in a means of updating the keyboard’s firmware for use during manufacturing or for patching bugs in the field.
Yeah, OP could have just inadvertently triggered the thing to start an update or something (EG erase its flash and await a download that never came) maybe not great design but pretty benign for the average keyboard.
i had a pen tablet (no display, just an input device) with an rs232 serial connector on it and i wrote a little program to read the protocol and it worked well enough (very simple, comparable to a serial mouse) so then i made a program to actually have fun with my new input device and from the very first time i tried to run that program, the thing was bricked.
never occurred to me to blame my reverse engineering process for that unsatisfying result :)
but probably that’s because i was reading from the tablet instead of writing to it
I’m guessing there are about 9 packets worth of leds on the keyboard, he was monitoring the commands for writing LED colors to flash, the sleeps were time for flash writes to occur, and the “coincidence” of 0x09 was how manybpackets of flash to erase to prepare for the new LED data. Sooooo…. erasing 0xff packets…….
Brilliant, Brian, I think this is the solves the mystery, great insight! Usually these low-quality products don’t spend any more time than the bare minimum to ship a product. Why spend extra money writing a single self destruct code when you could spend less to get many :D
Self-Destructing devices are underrated!
Sounds like they triggered some kind of firmware update and then corrupted the firmware. Still bad vendor to not have any kind of validation on firmware update packets.
Yeah, I’ve seen more than a few of these be implemented extremely poorly, with HID commands providing direct access to erase or rewrite all of flash without the slightest range checking, locking or recovery measures implemented.
I’ve added “self destruct” operations to some products to slow down the end product getting copied. The factory was running a second shift and private labeling the extra units, including our firmware binaries. I added a quick hack that over-wrote the boot vector jump call immediately, then ran the self-test code and halted. Once we got the stuff back to the final assembly area, the real code got flashed in. Fun times.
But yeah, this might have been just discovering the firmware update command and sending erroneous data. Kind of a crappy bootloader though, usually we do error checks before allowing a flash write, and even holding a previous image in flash to revert in case the new load fails (at the cost of doubling your flash requirement!).