Before I would be able to write Snake, I first had to tackle one last thing: I needed to figure out a clean way to upload the modified firmware. While I could use the ROM USB bootloader, the accompanying program for it was a Windows-tool and I'd have to open up the keyboard and bridge the header every time I'd want to use it. Instead, I decided to see if I could solve the still outstanding mystery of the weird corrupted firmware I decrypted earlier. If I could figure out how that works, I could make a Linux-based firmware upload tool for my own code. It would also make distribution of the hack easier: I wouldn't have to distribute any copyrighted Coolermaster code or binaries, I could just instruct people to grab the firmware update and decrypt that to something I could work with.
If anything, the corruption wasn't some extra encryption that was decrypted by the firmware update executable: I checked that by comparing the firmware as I had decrypted it against the packets in the USB stream I captured. The firmware corruption did not end up in the flash: checking against the flash dump I did showed the corrupted bit was indeed different. Comparing the two actually lead to a certain pattern: I suspected the controller itself did some XORring and perhaps some re-arranging of the bytes before burning them in flash.
Now ofcourse I could stare at the differences until I found out what the trick was, like I did with the
firmware encryption. This time however, I did already have the code loaded in the disassembler, so why
not check there? And indeed, I found a nice little something in the disassembly:
Basically, there's a counter that counts the amount of firmware flash packets that are sent to the keyboard. If that count is between 10 and 100, the firmware is going to assume the packets are mangled and will invoke a routine to de-mangle them.
The mangling, again, wasn't very hard: it's just an XOR with a 52-byte key, plus some swapping of the bytes in each 32-bit word which is dependent on the previously-mentioned flash packet counter. I quickly wrote an encryption and decryption routine in C to mimic what I saw in the firmware, and added that to the code I had before. It could now also decrypt a firmware update into the data that would be written to flash, and also take a file containing that and sending it to the keyboard.