Skip to content
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

Support for coolermaster's masterkeys pro models #6

Open
igorcalabria opened this issue Feb 20, 2020 · 18 comments
Open

Support for coolermaster's masterkeys pro models #6

igorcalabria opened this issue Feb 20, 2020 · 18 comments

Comments

@igorcalabria
Copy link

Hi, I'm trying to add support for these models and I figured you guys could help me get past some issues. This is my first RE project, so feel free to point at any bizarre thing I'm doing.

Ok, so here's what I've got so far

  1. Reversed part of the fw updater software. Basically, I've traced fread calls to figure out where the fw is inside the executable. This also led me to a de-mangling function that partially "decrypts" the firmware. A funny thing that I've noticed is that it reads both the fw version string and the actual fw twice, from different locations. Maybe they're trying to "protect" patching?

  2. As expected, the extracted binary is still "encrypted". I brute forced a 52 byte XOR key and it worked partially, some readable strings appeared and the vector table at the top took some shape.

  3. At this point, I began looking for similar firmwares so I could fix the rest of the XOR key, turns out that my firmware is really similar to the one used by cypher model. I managed to fix the rest of key and now I may have a working dump.

  4. Fiddled a bit with pok3rtool to add the right HID's for my model and both info and version commands worked. The offsets looks the same as cypher model(got it from the vector table) and the commands working point to that too, but I'm not sure.

The thing that broke my legs, is that I can't run the official update to capture the protocol. My model is already at the last version and It seems they never released a update for an ISO model. This means that I basically have two alternatives

  • Patching the fw updater to bypass all layout and version checks
  • Use this tool to upload my dump, but I'm not sure if the offsets and protocol are the same as cypher

Both alternatives seems kinda dangerous, since I'm not sure what happens if a different layout is used. Any pointers?
Oh, and I also could use some help understanding the boot model for these devices. From the data sheets, I thought that vector table was loaded from 0x0, but all of the firmwares start at an offset in the flash and they also have a vector table. If there was a builtin fw at 0x0, why the uploaded fw also needs a vector table?

Any help is really appreciated, so thanks in advance. This project was a great source of information

@ChaoticEnigma
Copy link
Member

ChaoticEnigma commented Feb 21, 2020

I don't know which keyboard you are looking at, but I found a firmware updater for the CM Masterkeys Pro L White on CM's website. I was able to extract and decrypt the firmware with my existing program. See updatepackage.cpp. I just added the following to the packages array:

// Cooler Master Masterkeys Pro L
{ 0x38cc849b2e54b6df,   MAAV102 },

And ran it as:

pok3rtool decode masterkeys-pro-l-white-v1.08.exe v108.bin

You will notice in the output there are six "sections". There are actually three firmware images with different layouts: US, EU, and KR(?). For each there is a firmware section, and a version info section. That is why you see the code reading from multiple locations. You'll have to hack updatepackage.cpp to dump the correct firmware section.

I broke the XOR key for one firmware updater a long time ago, and it keeps working. You can compare the XOR key you found to the one at the bottom of proto_cykb.cpp.

I suspect pok3rtool will work as-is for uploading firmware to this keyboard. You can try some of the more harmless commands before trying to flash firmware. The bootloader command will reset the keyboard to the bootloader. You can confirm it is in the bootloader with the version command. The setversion command will write the version string.

I assume your goal is to extract the bootloader? I've done this on a bunch of these keyboards. My method is to disassemble and patch the application to allow me to read flash unrestricted using the update protocol. Look at https://github.com/pok3r-custom/pok3r_re_firmware/blob/master/disassemble/core/v104/patch_v104.txt for an idea of what these patches look like. With the patched firmware, the pok3rtool dump command will dump the whole flash, which I can extract the bootloader from.

@ChaoticEnigma
Copy link
Member

ChaoticEnigma commented Feb 21, 2020

I'll try to explain how the boot process works.

There is a builtin bootloader firmware at 0x0 in flash. The bootloader will look for the main application firmware at a specific address. It looks like the firmware is loaded at 0x3000 (it should be a multiple of 0x400 to align to the flash page size). Different keyboards place the firmware at slightly different locations, depending on the size of the bootloader. The flash page before the application (e.g. 0x2c00) contains some information about the firmware, including the version string. The bootloader does a couple of things before jumping to the main firmware:

  • Check the initial SP and Reset vectors at 0x3000 are not erased
  • Check the version string at 0x2c00 is not erased
  • Check for a specific "key" in the application firmware at (e.g.) 0x3bf8 (older versions of the firmware, like on the POK3R, don't do this). This is to prevent booting the wrong firmware for that specific keyboard.

If any of these tests fail, the bootloader works as a simple keyboard. The firmware download function can also be used when the bootloader is running.

If all the checks pass, the bootloader jumps to the application firmware. The reason the application has its own vector table is so that different interrupt handlers can be different in the application. The VTOR register (vector table offset) can be used to specify the base of the vector table, for exactly this use case.

@igorcalabria
Copy link
Author

I don't know which keyboard you are looking at

My model is the masterkeys pro m white model. I'll run your tool and compare the output against my own version.

I assume your goal is to extract the bootloader?

Yeah. Thanks a lot for the info. The boot process makes a lot more sense now, and I'll try to patch the firmware in a similar way to your example. I'm also guessing that flashing a non matching layout won't break the usb protocol, so I could eventually fix it on my own if some keys stop working. Have you ever flashed a mismatched layout?

@igorcalabria
Copy link
Author

igorcalabria commented Feb 29, 2020

It worked, got a full firmware dump and the patch is pretty much the same as your example

FW offset is 3200

        00006388 ff 28           cmp        r0,#0xff                                         
        0000638a 05 d1           bne        LAB_00006398
        0000638c 68 68           ldr        r0,[r5,#0x4]
        0000638e 3c 21           mov        r1,#0x3c
        00006390 30 e0           b          LAB_000063f4
        00006392 00 bf           nop
        00006394 00 bf           nop
        00006396 00 bf           nop

If you are interested, I could PR the changes. It's only a few modifications adding the correct device ids and mappings.

hansemro added a commit to hansemro/re-masterkeys that referenced this issue Jun 2, 2022
Also moves firmware files to a new directory to avoid naming conflicts
with RGB variant.

Patch from Igor Calabria (@igorcalabria):
pok3r-custom/pok3rtool#6 (comment)

NOTE: Patch has not been tested aside from patch author.
hansemro added a commit to hansemro/re-masterkeys that referenced this issue Jun 2, 2022
Also moves firmware files to a new directory to avoid naming conflicts
with RGB variant.

Patch from Igor Calabria (@igorcalabria):
pok3r-custom/pok3rtool#6 (comment)

NOTE: Patch has not been tested aside from patch author.
hansemro added a commit to hansemro/re-masterkeys that referenced this issue Jun 2, 2022
Also moves firmware files to a new directory to avoid naming conflicts
with RGB variant.

Patch from Igor Calabria (@igorcalabria):
pok3r-custom/pok3rtool#6 (comment)

NOTE: Patch has not been tested aside from patch author.
@hansemro
Copy link
Contributor

hansemro commented Jun 5, 2022

I am interested in this effort! I started working on support for Pro S RGB, but ran into issues along the way.

From my testing poking around USB with python scripts (and looking at disassembly), I found Pro S RGB had a lot in common with both POK3R and CYKB protocols (documented partially mateuszradomski/re-masterkeys#1). With my findings, I started working on my own fork to better support my device (and other cooler master keyboards): https://github.com/hansemro/pok3rtool/tree/cooler-master-dev.

Unfortunately, I ended up bricking my keyboard by erasing firmware region (@0x3400) in my attempt to write patched firmware with pok3rtool. This result is leading me to believe that something is wrong with the write command (which works fine for setting version). @ChaoticEnigma if you have time, can you help identify the cause of the issue? I have packet captures of firmware upgrade via OEM software and my failed attempt with custom pok3rtool.

pok3rtool attempt:
pok3rtool_fw_flash_attempt_with_erase.zip
flash_log.txt

OEM:
fw-upgrade.zip

Pro S RGB firmware: https://github.com/hansemro/re-masterkeys/tree/Pro_S_RGB/binaries/Pro_S_RGB

@ciarancoffey
Copy link

@hansemro did you make any progress on the Pro S RGB? I have one here if I can create any dumps for you.

@hansemro
Copy link
Contributor

@ciarancoffey No further progress on fixing USB writes with Pro S RGB as I did not get a replacement keyboard.

@hansemro
Copy link
Contributor

hansemro commented Aug 27, 2022

@ciarancoffey Picked up one Pro S RGB and one Pro L White for cheap. I am going to learn from my mistake and avoid directly wiping my board before I figure out how to write to an arbitrary address.

@hansemro
Copy link
Contributor

Managed to dump Pro L White bootloader and firmware without much difficulty.

Documented here: mateuszradomski/re-masterkeys#3.

FW Patch + dump can be found here: https://github.com/hansemro/re-masterkeys/tree/Pro_L_White/binaries/Pro_L_White

pok3rtool with this patch should be sufficient: https://github.com/hansemro/re-masterkeys/blob/Pro_L_White/patches/pok3rtool/ProLWhite.patch

@hansemro
Copy link
Contributor

hansemro commented Sep 9, 2022

The glaring difference between my failed pok3rtool flash attempt and OEM software is that I did not encode firmware before writing. I did not notice this since I was not being thorough...

# bad pok3rtool
0000   01 01 [6c 06] 08 36 00 00 3b 36 00 00 40 f0 01 03
0010   94 e8 07 00 98 47 10 34 ac 42 f6 d3 ff f7 b6 ff
0020   94 a1 00 00 b4 a1 00 00 70 b5 8c 18 10 f8 01 5b
0030   15 f0 07 03 01 d1 10 f8 01 3b 2a 11 06 d1 10 f8
# OEM
0000   01 01 [db c9] 08 36 00 00 3b 36 00 00 a9 a5 ea 54
0010   55 42 c1 ad cb 47 98 10 d3 bd ac f6 ff f7 00 b6
0020   00 a1 94 ff 00 a1 b4 00 e7 4a 8f 73 54 f7 1f 0e
0030   f3 00 e5 f7 52 7b ab ba 44 6e 54 7f f8 d1 06 10
# pok3rtool after encoding firmware (with ProtoPOK3R::encode_firmware)
0000  01 01 [db c9] 08 36 00 00 3b 36 00 00 a9 a5 ea 54
0010  55 42 c1 ad cb 47 98 10 d3 bd ac f6 ff f7 00 b6
0020  00 a1 94 ff 00 a1 b4 00 e7 4a 8f 73 54 f7 1f 0e
0030  f3 00 e5 f7 52 7b ab ba 44 6e 54 7f f8 d1 06 10

Simulation logs (comment out packet send and recv):
pok3rtool_without_encoding-simulation.log
pok3rtool_with_encoding-simulation.log

@hansemro
Copy link
Contributor

hansemro commented Sep 9, 2022

Firmware patch for Pro S RGB is confirmed working on my (unlocked; previously-bricked) Pro S RGB with modified Vortex Core bootloader. Relevant commit: hansemro/re-masterkeys@d5290ee

Now I just need to flash my new Pro S RGB with stock bootloader (although it is on 1.1.5 firmware that cannot be recovered).

@hansemro
Copy link
Contributor

hansemro commented Sep 9, 2022

Yup. Fixed firmware flashing with hansemro@11b822d. Did a firmware upgrade from 1.1.5 to 1.2.2.

Flashing patched firmware (from 1.2.2):

$ pok3rtool_cm -t prosrgb flash 1.2.3 ProSRGB_fw_patched.bin --ok                                                                                
Opened MasterKeys Pro S RGB                                                                                                                                                
Update Firmware: ProSRGB_fw_patched.bin                                                                                                                                    
Reset to Bootloader                                                                                                                                                        
Current Version: 1.2.2                                                                                                                                                     
Clear Version                                                                                                                                                              
Erase...                                                                                                                                                                   
Write...                                                                                                                                                                   
Check...                                                                                                                                                                   
Flashed succesfully                                                                                                                                                        
Clear Version                                                                                                                                                              
Writing Version: 1.2.3                                                                                                                                                     
Reset to Firmware                                                                                                                                                          
true
$ pok3rtool_cm -t prosrgb dump flash.dump                                                                                                        
WARNING: THIS TOOL IS RELATIVELY UNTESTED, AND HAS A VERY REAL RISK OF CORRUPTING YOUR KEYBOARD, MAKING IT UNUSABLE WITHOUT EXPENSIVE DEVELOPMENT TOOLS. PROCEED AT YOUR OW
N RISK.                                                                                                                                                                    
Type "OK" to continue:                                                                                                                                                     
OK                                                                                                                                                                         
Proceeding...                                                                                                                                                              
Opened MasterKeys Pro S RGB                                                                                                                                                
Dump Flash                                                                                                                                                                 
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%                                                                                                            
Out: flash.dump, 65520 bytes
$ xxd flash.dump | head -n 5
00000000: 480d 0020 1901 0000 2501 0000 2501 0000  H.. ....%...%...
00000010: 2501 0000 2501 0000 2501 0000 0000 0000  %...%...%.......
00000020: dff8 0cd0 00f0 30f8 0048 0047 8924 0000  ......0..H.G.$..
00000030: 480d 0020 0168 8d46 4168 0847 4115 0000  H.. .h.FAh.GA...
00000040: 40ea 0103 9b07 03d0 09e0 08c9 121f 08c0  @...............

@hansemro
Copy link
Contributor

hansemro commented Sep 9, 2022

@ciarancoffey We should be good now :) https://github.com/hansemro/re-masterkeys/blob/Pro_S_RGB/binaries/Pro_S_RGB/flash.dump

Time for me to recover my other board.

EDIT: fully recovered my board!

@hansemro
Copy link
Contributor

hansemro commented Oct 18, 2022

@ChaoticEnigma Got QMK up on the Pro S RGB and wrote fully working (3-cascade) MBIA043 RGB matrix driver. This should hopefully be useful for Vortex boards with the same LED driver (although it is unclear to me how RGB is achieved with 2-cascade configuration).

Note: I only flashed on board with security bits cleared, so I am not sure if I will run into hardfaults if I try flashing on a spare board with those bits set.

MBIA043 info: mateuszradomski/re-masterkeys#1 (comment)
MBIA043 driver: https://github.com/hansemro/qmk_firmware/blob/prosrgb_mbia043_dev/keyboards/masterkeys/prosrgb/mbia043.c

@hansemro
Copy link
Contributor

image

On GK68XS, RGB is not separated by IC but by the individual channels on the ICs. This is likely what is being done for keyboards with just 2 LED drivers.

@ChaoticEnigma
Copy link
Member

@hansemro That's awesome work, very cool! I was out of town last week, best I could do at the time was an emote!

It looks like I'll have to get back on the Vortex boards soon. I'll be stealing your MBIA043 driver!

I believe I did trace out the POK3R RGB LED rows/columns, and I think it's exactly as you say for the GK68XS.

@hansemro
Copy link
Contributor

@ChaoticEnigma It is only fair since pok3rtool and your firmware disassembly annotations were incredibly useful.

@hansemro
Copy link
Contributor

hansemro commented Oct 30, 2022

Here is Pro L White QMK port with MBI5042 LED driver support: https://github.com/hansemro/qmk_firmware/tree/prolwhite_mbi5042_test/keyboards/masterkeys/prolwhite
This unfortunately requires a chibios patch to align vector table to 512 bytes instead of 1024 (since FW starts at 0x3200), so I am not sure if I will be able upstream support for this keyboard.

MBI5042 driver: https://github.com/hansemro/qmk_firmware/blob/prolwhite_mbi5042_test/keyboards/masterkeys/prolwhite/mbi5042.c

One thing to note here is that you may need additional "LED matrix to LED index" look-up-matrix if LED matrix and Key matrix do not map to the same keys (as done on Pro L White). On Pro S RGB, LED and Key matrices were mapped to the same keys so I did not have to define this extra mapping.

@ChaoticEnigma Let me know if you have questions or improvements.

Update: Patch is no longer required with hansemro/qmk_firmware@afaff36

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants