-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Similar keyboard: KBP v60Mini #4
Comments
Very interesting! Thanks for noticing this. It seems there is likely some entity "CYKB" that develops these keyboards and firmware for Vortex, Cooler Master, and KBParadise, at the least. Thus we have seen the same update protocol on a number of Holtek-based keyboards. I looked at your repo, decrypting the cykb112_v107 firmware worked fine, looks like thumb code to me. The firmware is based at 0x2c00, same as the pok3r. As for next steps, you will want to disassemble the firmware, write a patch for the update protocol that will allow pok3rtool to read the contents of flash off the chip, circumventing the JTAG flash protection, and upload this patched firmware. With a dump of the whole flash, you can disassemble the bootloader, and get any constant data that may not be included in the firmware updates. I will poke at that firmware a bit this weekend. I know waaaayyyyy too much about these Holtek chips and Thumb by now, so it shouldn't take too long to make the patch mentioned above, if it's anything like the patch for the pok3r. You can also look at my disassembly of the pok3r firmware, under disassemble/pok3r/v117. Ignore the .sym files, they are used for a super unstable disassembly tool I am working on. It looks like the KBP v60 Mini uses the HT32F1755, rather than the 1654 and 1655 the Vortex keyboards use. I haven't read up on the differences, but they are probably very similar. The firmware I am working on for the Vortex keyboard would probably work on the KBP v60, accounting for the different matrices. I've wanted to try a Matias KBP v60 Mini for some time, maybe I'll have to get one now... |
Hey, thanks for the tips! EDIT What if I brick it? What will I need to fix it? |
Yes, I should elaborate. The reason for patching the firmware and updating it is explicitly to allow the bootloader to be obtained. The bootloader can't be read directly with JTAG, because the flash protection is enabled, so flash can only be read by code executing from flash (not SRAM). Until you have a copy of the bootloader, you want to be very careful. Once you crack the firmware and have all of the code/data needed, you can connect a JTAG debugger and erase the chip, clearing the flash protection, then write the firmware back. After that, you can be much less careful, since you can always restore it. I am 3/3 so far, so fingers crossed. If you do end up bricking it, all is not lost. You will need a JTAG debugger (https://www.adafruit.com/product/1369). This is an essential tool for embedded development anyway, so I do recommend. If you get a JTAG debugger, I have a fork (https://github.com/ChaoticConundrum/openocd-ht32) of OpenOCD that supports writing/erasing the HT32 internal flash. If you end up actually erasing the bootloader, you would have to rewrite it, which might not be difficult, using the pok3r's bootloader for reference. ChibiOS seems to only support ST chips, so it would take a lot of porting to get TMK working on Holtek chips. I am working on the USB stack for my custom firmware now, once that works, everything else shouldn't be difficult. |
Would you be able to perform a USB packet capture of a firmware update on the KBP v60? I am skeptical of the disassembly from the decoded firmware. Parts of it are fine, and other parts are less so. Namely, the reset handler at 0x2d54 jumps to 0x3fc0, which should be a clock init function, but which starts with an undefined instruction. Here is the full disassembly: If you could record the USB packets in a firmware update with Wireshark, I can compare what the updater is sending to the keyboard to the decoded firmware, and look for issues with the decoding. For reference: https://wiki.wireshark.org/CaptureSetup/USB |
Sure, I did one beforehand: For that reason, I think it's the same as the Pok3r, when the firmware is encrypted and decrypted on the fly in the keyboard, or something like that. I also have found a porting guide for ChibiOS on other boards, it seems it's not so difficult to port (2nd or 3rd paragraph, I think?) http://wiki.chibios.org/dokuwiki/doku.php?id=chibios:guides:port_guide edit I found the relevant code that zeroes out the flash, as in the Pok3r:
Hope this helped! |
Yes, that's all very useful. I'll look into ChibiOS some more, I'm sure many people would be very happy to have TMK on the pok3r. Their documentation is out of date, but I'll look through the templates and examples. I also need to pin down exactly how TMK builds on top of ChibiOS. I'm not really sure what to make of that pcap, it doesn't look anything like the pok3r pcaps I have. Maybe I'm looking in the wrong place, but it looks like parts of the protocol may be different. Either way, it looks like you found the flash reading code at 0x4ad2. Everything around that code looks the same as the pok3r. So, I replaced that If you are feeling adventurous, this firmware updater should allow flash to be read out of the KBP v60. Feel free to check my work before risking your keyboard. This is the same method that originally cracked the pok3r. I believe it is relatively low-risk, because the modified code is only run when you use the read commands. If it has problems, you can always reset to the bootloader and re-flash from there. If you run that updater and your keyboard seems fine (if it works, I don't know if there is any integrity checking, there wasn't for any of the Vortex keyboards), you can use the Good luck! |
Yes, I tried the patched program on Windows, tried to dump the flash and it seems to have worked! 👍 By looking at the disassembly, I noticed that there are no more zeroes on the important parts of the dump, and it looks like a complete dump, but some instructions are still undefined or illegal, and I don't know if it's normal or not... (There's a lot of free space BTW, especially at the end of the dump, they didn't insert too much stuff, apparently) |
That's very good news. Your flash dump looks perfect, everything is pretty much what I'd expect. Note that there are two pieces of firmware in there, the bootloader at Do you mean pok3rtool reports the version as Since this firmware is the "true" firmware, I compared it to the version decoded from the updater. Here are the highlights: Similar to the pok3r firmware, part of the firmware is encrypted again in the updater, and decrypted on the keyboard. This is why we want the bootloader, so we can figure out how to do this encryption, and send new firmware to the bootloader with pok3rtool. Here is the instruction we changed to allow the flash to be read. The extra data is here is not part of the firmware, it is likely the firmware metadata stored in the updater. |
Interesting! So what will be the next course of action? Should I try to figure out how the encryption works in the bootloader? By the way, both I'll update my repository with the new information, much obliged 🥇 |
My plan so far has been to just replace the updateable firmware and leave the bootloaders intact. This way you can use the official updaters to put the original firmware (or new firmware) back on the keyboards. This also means in order to use pok3rtool to upload custom firmware, we have to encrypt the firmware the way the bootloader expects it. So, if you want to follow my method, you should reverse-engineer the decryption in the bootloader, and write a class in pok3rtool to implement it. (probably start from the ProtoPOK3R class). If you don't care about backwards compatibility, you could always write a simple new bootloader. I am working on porting ChibiOS's HAL to the HT32F1655 and 1654, which will cover all the vortex boards. I'll also look at how different the HT32F1755 would be, it may use a lot of the same peripherals. I don't know why pok3rtool started reading |
lovin all of this.
…On Sun, Mar 19, 2017 at 11:32 AM Charlie Waters ***@***.***> wrote:
My plan so far has been to just replace the updateable firmware and leave
the bootloaders intact. This way you can use the official updaters to put
the original firmware (or new firmware) back on the keyboards. This also
means in order to use pok3rtool to upload custom firmware, we have to
encrypt the firmware the way the bootloader expects it.
So, if you want to follow my method, you should reverse-engineer the
decryption in the bootloader, and write a class in pok3rtool to implement
it. (probably start from the ProtoPOK3R class). If you don't care about
backwards compatibility, you could always write a simple new bootloader.
I am working on porting ChibiOS's HAL to the HT32F1655 and 1654, which
will cover all the vortex boards. I'll also look at how different the
HT32F1755 would be, it may use a lot of the same peripherals.
I don't know why pok3rtool started reading 1.0.7id#. From the flash, I
would have expected it to always read that, pok3rtool expect a null
terminator. I have to assume the version it was changed at some point, but
I don't know why the official updater would do that. I will fix it in
pok3rtool, to use the version length right before the string.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#4 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA4_rt_DcgwmG7AzfGC3Boda1dI1Hcvjks5rnXSngaJpZM4MPuPS>
.
|
Hi, I've got updates:
Pok3r flash from 2188 to 21b8:
The same is for the v60 from 20f4 to 2124:
I guess the swap key should be the same... but what do I need exactly to write a similar class to Thanks! |
For the POK3R, there were two sets of encryption. The first is decrypted by the update exe, which we don't need to worry about (and you already broke). After that, part of the firmware is still encrypted (first two images a few comments back), and it is sent to the keyboard like this. The encrypted part of the firmware is decoded on the keyboard. This consists of an XOR and a byte swap. I just confirmed that the XOR and swap encryption is the same as on the POK3R. However, what I am not sure of is the format this is sent in over USB for the update. When I read through the POK3R update pcaps, I see write addresses, and some bits of unencrypted firmware, like the vector table. I don't see that in the V60mini pcaps, so I believe the update packet format is different, or some other encryption is applied, etc. I recommend finding the place USB packets are handled in the firmware, and following how they are handled/decoded for write commands. This is the direct reverse-engineering approach, which I did for the POK3R RGB. It is fairly tedious, but at least you know exactly what's going on. You can use the POK3R firmware as a guide to find the code you're looking for. |
Just a second though: what did you use to sniff the USB packets? UsbPCap or a Windows VM under Linux? That's because my pcap is encapsulated with USBPcap on Windows, and it's different from the packets under usbmon. Thanks! |
The POK3R packet captures I'm using for comparison were captured with USBPcap through Wireshark on Windows. The pcap you sent me earlier in this thread has the same packet headers, size, etc. I'm looking at the "Leftover Capture Data" (e.g. the payload) of USB interrupt transfers to the keyboard. If you open the v60mini.pcap in wireshark and use the filter Packet 352 in that capture looks exactly like the response to the command that would read the version number (same data as flash for the version number, except 1.0.6 instead of 1.0.7).
Compare this to the POK3R response packet 545 in dump/to117.pcapng in this repo. So, 352 looks normal.
Before it, packet 544 sends the read command, to read 52 bytes from 0x2800.
But on the v60mini capture, what should be the read command doesn't look right at all.
In fact, all of the OUT packets in the v60mini capture look like this, as opposed to the clear format in the POK3R OUT command packets. I can't make much of it, which is why I have no idea if the flash update commands are the same as the POK3R. Actually, given these packets, I don't know how pok3rtool is even able to read the version from the v60mini. Generally I would solve mysteries like this before writing more code. |
Well, I have another pcap captured yesterday on the update to the patched version, maybe that one's too old or I didn't capture it right. In the meantime, I'll try to figure out something by confronting the flash and the packets. 0-47: Keyboard connected via USB edit2 It seems that the version is actually sent 2 times in this pcap? (174, 184) edit3 It seems that pok3rtool is also capable of rebooting the keyboard into bootloader and out. edit4 Here's an excerpt from an old conversation with Sprite on Reddit:
Basically the USB data packets are encrypted with a rand() implementation, and the problem is where to find it? The POK3R fw doesn't use it, weird. edit5 yep, there it is: (from signsrch on the patched updater exe)
signsrch also can place an INT3 byte for debugging on the rand() offset. |
Thanks for the info. The pcap looks about the same, with a different version number returned from the read commands. The version is written as As for this encryption, I don't completely get how it works yet, but I have learned some things. I've done more disassembly on the v60mini firmware, and compared the code to the POK3R firmware. The safest way to test this would be to use the pok3rtool to set the version string, because this uses the same write commands as the firmware update. If that works, I would expect a firmware update to work. |
It works! Very nice! But that doesn't solve the problem of how the USB packets are actually encrypted and how to decrypt them eventually, just to be safe. The only thing left to try is the actual firmware update from Cheers! |
Very nice. Yes, a firmware update should work. I've done everything I can to make the update procedure as safe as possible. Use the firmware_v107.bin image I sent earlier: kbpv60_firmware.zip. This was dumped from the keyboard, so we know that it works. While there is some safety from uploading non-firmware files on the keyboard (it checks the stack and reset vectors), uploading the wrong firmware can cause the keyboard to get stuck, preventing another update. So, Also, what are the USB VID and PID for the v60 mini? It looks like it will be simple to add "support" to pok3rtool. As for the encryption... the same code is present in the pok3r firmware, but it never did anything, so I never figured it out then. I can't think of any reason we would want to encrypt update packets, now that we've reverse engineered it. I would say we are completely safe just using the unencrypted update commands. There won't be any new information in those encrypted packets. If you want to implement that encryption / decryption as an exercise, be my guest, but I'd say you don't strictly need to. |
Oh, alright then. Guess I'll call it a day then. Output from lsusb:
YESSSS! IT WORKS!!! |
Man, that's great! The only thing left is porting TMK or QMK with ChibiOS! Speaking of which, is there a way to boot a firmware directly from USB instead of flashing it every time? I would like to thank you again for all the help and I'm looking forward to hear what you think. |
That's great news! It takes 2 lines to add support for the the KBP v60 mini to pok3rtool, so I will do that shortly. Yes, TMK / ChibiOS porting is in the works. Because of all the forks involved it lives in another repository. I will push it to github when there is something interesting to show. (by the way, QMK is an AVR-only fork of TMK, and AFAIK doesn't use ChibiOS). As for booting from USB, you could write a bootloader to download firmware to SRAM, and jump to it. The trouble is, the size of SRAM is very limited, and the firmware also uses some SRAM. Here is the breakdown of the chips and firmware:
It may work for some, but you would have to link it very carefully. It's not a bad idea, but I'm not personally worried about bricking a board (JTAG debugger totally worth it). Also, it would really be pretty difficult to wear out a flash chip by manually rewriting it for each code change. Typically flash chips can be erased tens to hundreds of thousands of times, so issues are only usually encountered when you have something that periodically writes the flash for a long time. I expect the HT32 chips use NOR flash, but the documentation doesn't confirm this. Well, we have firmware, and we can flash the v60mini, so I think I can close this issue now. When I've made some more progress with ChibiOS for the HT32F1654 and 1655, I'll make it public, and if you want, you could try your hand at porting it for the 1755 too. That will be done eventually one way or another, because I think I've seen at least one other keyboard that uses the 1755. Cheers! |
Thanks for adding support to your tool, I appreciate it. Cheers! |
Hi, I tried your tool with a similar keyboard that shares the same microcontroller as the POK3R, the KBParadise v60Mini.
I can confirm your tool works correctly and reads the version after changing the PID:
Could you give me any indication on how to go on from here?
Me and other people have started a repo here, and the decryption already works:
https://github.com/pellettiero/V60Mini-firmhack
Thanks!
The text was updated successfully, but these errors were encountered: