RadioOperator / CMSIS-DAP_for_STLINK-V3MINI

High-Speed CMSIS-DAP for STLINK-V3MINI ARM Debugger STM32F723IEK6
Apache License 2.0
175 stars 82 forks source link

Dumping the original firmware/bootloader #1

Open martonmiklos opened 4 years ago

martonmiklos commented 4 years ago

Hey @RadioOperator ,

In the past there were attempts to gather the STLink V2's firmware via downloading a dumper code through the official bootloader: https://lujji.github.io/blog/reverse-engineering-stlink-firmware/ https://lujji.github.io/blog/reverse-engineering-stlink-firmware-part2/

It might be useful to check whether it is possible with the V3 because using the factory bootloader for downloading custom code would be a great possibility I think. I do not have device at hand at the moment, but I will look after the possibilities later. I just opened this issue to give you a heads up.

martonmiklos commented 4 years ago

Well it seems that ST changed the encryption method of the firmware since @lujji worked on it (the best performance key does not outputs valid binary for the old f2_1.bin binaries too outputs valid binaries for the V2 firmwares and invalid for the V3 images). There is an another suspicious string "What are you doing" in their code, but it will be necessary to understand their updater changes.

lujji commented 4 years ago

What makes you think the output binary is invalid? As far as I can tell encryption and key are the same and decrypted f3_x binaries look ok in disassembly. Anyway, I should get my hands on a v3 programmer - it would be fun to play with.

RadioOperator commented 4 years ago

Hi, lujji, glad to hear you here, your great works would be very helpful, then we could recover the factory firmware, flexible!

martonmiklos commented 4 years ago

@lujji I just take a look on the f3 binaries and did not found any UTF strings in it, and the entropy looks weird.

lujji commented 4 years ago

Yeah, you're right, I looked at f2_3 instead of f3_2 :) Perhaps they're doing decryption on the MCU side (like they should have in the first place). edit: it does seem like the updater decrypts the binary only when version is less than 3.

martonmiklos commented 4 years ago

Where do you see that it does not decrypts it? I am reading the decompiled java code and did not see it yet.

lujji commented 4 years ago

@martonmiklos stlinkupgrade.core.c.class: search for the decryption key - you can see that it's used only when some parameter is less than 3, otherwise the array is used as is.

martonmiklos commented 4 years ago

@lujji Wait you are reverse engineered the native executable not the java one?

In the java codes the method to which the "best performance" key was passed appears to be called in two places with 2 args: kép

kép

The "What are you doing" string is also looks something like a key :)

I think I will pull the java code to IntelliJ and start refactoring the obfuscated code and put it to somewhere to git.

UweBonnes commented 4 years ago

Wouldn't https://github.com/jeanthom/stlink-tool be a good place to put it? Stlink-Tool works perfect to flash blackmagic debug probe reversible to an STLinkV2.

martonmiklos commented 4 years ago

Wouldn't https://github.com/jeanthom/stlink-tool be a good place to put it? Stlink-Tool works perfect to flash blackmagic debug probe reversible to an STLinkV2.

Haha I just came across that tool in the days, I wanted to mention here. What do you mean we should put there?

UweBonnes commented 4 years ago

I was referring to martonmiklos "I think I will pull the java code to IntelliJ and start refactoring the obfuscated code and put it to somewhere to git." So I meant if there is any work done on using the Stlink V3 bootloader, stlink-tool would probably be a good place to start.

Disasm commented 4 years ago

Hi guys. Going to present this without a comment. ./st-decrypt -i f3_2.bin -o f3_2.bin.dec -k ' .ST-Link.ver.3.'

However, while working on this I kinda locked my v3mini by updating it to the latest version with the official tool. Don't repeat my mistakes.

martonmiklos commented 4 years ago

@Disasm Nice job, the decrypted file seems to be valid. How did you locked your programmer? Have you tried to upload a cooked and encrypted firmware with the official tool?

Disasm commented 4 years ago

@martonmiklos, no, the newer official firmware (V3J6M2) locks the chip to the protection level 2, effectively preventing SWD from working. With such a locked chip you can still update (and downgrade) the firmware or upload your own. But SWD is disabled forever.

Disasm commented 4 years ago

And yes, I successfully uploaded my own firmware and dumped the bootloader via UART.

  1. Build your firmware with 0x08020000 base address.
  2. Convert it to binary and encrypt with st-decrypt
  3. Replace f3_{1,2}.bin files inside the official updater with the encrypted binary.
  4. Update as usual (you can use java -jar STLinkUpgrade.jar -force_prog to skip gui part).
martonmiklos commented 4 years ago

@Disasm you spared some time for me: I was just working on figuring out the app offset :D It is a bit funny to see that they reserved more than 128K for the bootloader.

The fact that ST disables the SWD makes me a bit sad, but still this is a thing.

Disasm commented 4 years ago

@martonmiklos I think that the answer is flash layout: the sectors have different sizes and they are used to store 4 different things and should be erased separately. The bootloader actually uses sectors 0 and 1 (first 32kB), sectors 2, 4 and 5..7 are used for other things.

martonmiklos commented 4 years ago

@martonmiklos I think that the answer is flash layout: the sectors have different sizes and they are used to store 4 different things and should be erased separately. The bootloader actually uses sectors 0 and 1 (first 32kB), sectors 2, 4 and 5..7 are used for other things.

That makes sense. I have forgotten that the F7 does not have uniform flash layout.

UweBonnes commented 4 years ago

@disasm: Protection level 2 would make it nearly impossible to reprogramm the chip. Probably it is some sector protection.

Consider to offer the bootloader at https://github.com/Krakenw/Stlink-Bootloaders.git

Disasm commented 4 years ago

@UweBonnes it is still possible to reprogram the chip with the ST bootloader (unless you erase it by accident). At least that's what I'm doing :) Additionally, I confirmed that Level2 protection is active on my chip by inspecting the FLASH_OPTCR register, I also found a piece of code in the firmware that enables this protection level.

martonmiklos commented 4 years ago

I also found a piece of code in the firmware that enables this protection level.

This screams for creating a patcher tool. ;)

Disasm commented 4 years ago

@martonmiklos yes, but... you can use one of the previous versions of the firmware without this code

martonmiklos commented 4 years ago

@Disasm yeah, but after a certain release the CubeIDE required me to update and it seems that my normal V3 (non mini) had been upgraded to the V3J6M2 version :(. Fortunately I have not used my mini since then.

Disasm commented 4 years ago

Here is the relevant part if you want to patch the firmware:

ROM:080298A4                 CMP     R2, #0xCC
ROM:080298A6                 BEQ     loc_80298CE

Jumping to this label skips the locking process. Firmware image: V3J6M2 (en.stsw-link007_V2-36-26.zip), file f3_1.bin

Note that this is not the only comparison. Seems like it's possible to protect your device from locking by writing S character into the config block at address 0x0801004C. It also checks the value at 0x08000204 (probably bootloader version?).

Disasm commented 4 years ago

Can confirm that firmware versions V3J2 to V3J5 (inclusive) do not touch option bytes, that is, do not enable any protection levels.

martonmiklos commented 4 years ago

@Disasm many thanks for this info!

suglover commented 4 years ago

I've just added an unprotected bootloader to https://github.com/Krakenw/Stlink-Bootloaders/pull/3 It skips flash protection and also has one of the bytes changed in a way that should prevent V3J6M2 firmware from protecting the flash to Level2. I haven't tested the last part yet.

RadioOperator commented 4 years ago

@Disasm @martonmiklos , and all, Thanks. I have two questions about the Level-2 protection issue:

  1. Original device with factory bootloader, after the user upgraded to V3J6M2, Level-2 enabled? or not.
  2. In future, if new V3 device comes with Level-2 protected firmware only, that's too bad, no SWD port for flashing user code likes my CMSIS-DAP.
Disasm commented 4 years ago

@RadioOperator

  1. I suppose yes. At least if booted at least once, and this happens right after fw upgrade.
  2. You can upload your CMSIS-DAP firmware via the same update mechanism stlink updater uses. This is even more convenient, as the user does not have to solder wires to the SWD connector.
RadioOperator commented 4 years ago

@Disasm thanks. If no SWD function, we cannot debug the code under MDK environment. The current unprotected devices will be more useful for someone. Or buy a 32F723EDISCOVERY kit.

To upload my CMSIS-DAP Hex code via USB into the IC, I can rebuild the code starting from address 0x08020000, am i right? And then, do I need to encrypt it by some software tools? sorry I did not study all details on this, could you give more tips, thanks.

Btw, using the Level-2 enabled board, could we still erase/flash the first 128KB to change to a new bootloader from internal? My dream is a new bootloader with USB MSD drag and drop function.

Disasm commented 4 years ago

@RadioOperator I bought another v3mini a week ago and it had quite an old firmware (V3J2M1 if I recall correctly). Also v3set has much more reliable (compared to v3mini) SWD connector, I use it currently for development.

I think it's possible to replace the bootloader even with Level2 protection enabled. You will have to flash the firmware that replaces it.

RadioOperator commented 4 years ago

@Disasm HI, I'm Win10 user, I have tried on st-decrypt and stlink-tool, both are not succeed. Too many issues I do not have time to handle.

I have generated 2 DAP firmware files (starting address from 0x08020000), could you help to encrypt it, then I will test it using ST-Link-007 (V2J3M1? pls tell me). Thanks. STLINKv3_firmware.zip

Disasm commented 4 years ago

@RadioOperator try this: STLINKv3_firmware_enc.zip I used this command: st-decrypt -i STLINKv3DAPv1_HID+VCP_stbl.bin -o STLINKv3DAPv1_HID+VCP_stbl.bin.enc -k ' .ST-Link.ver.3.' -e

st-decrypt is actually a shell script with the following contents:

#!/bin/sh

dir=$(dirname $(readlink -f $0))

java -cp $dir/dist/lib/commons-cli-1.3.1.jar:$dir/dist/st_decrypt.jar st_decrypt.ST_decrypt "$@"

stlink-tool doesn't work for stlink-v3 for now, because this probe has different protocol, but it's possible to update it in a way that it will support both v2 and v3.

RadioOperator commented 4 years ago

@Disasm Thanks. I use one of the encrypted file, replaced the f3_1 and f3_2 (same) in STLinkUpgrade.jar. The STLINK-007 prograssing bar is ok to the end, report "successful".......but seems not flashed internal ROM, the device still in STLINK-V3 and functions ok. I donot know what is wrong. Any suggestions?

Disasm commented 4 years ago

@RadioOperator check that files are actually replaced in the archive. Also check that you're using java updater and not native one.

RadioOperator commented 4 years ago

@Disasm Hi, this time, using java -jar STLinkUpgrade.jar -force_prog, finished a real flashing, . but my code not work, USB cannot enum. I'll check.....

My code is using a different USB-PID, should be same as in STLINKv3 bootloader PID? I'll try on this first.

Disasm commented 4 years ago

@RadioOperator check that you disable all the interrupts and set up clocks correctly. I use this sequence to clean up after the bootloader: https://github.com/Disasm/usb-otg-workspace/blob/7e92a9c4c6500d5a7ca403fb0c767d62161f5ebb/example-stlinkv3-board/src/lib.rs#L8-L21

RadioOperator commented 4 years ago

@Disasm Hi, Back to encrypt a bin file, using your cmd: $ java -cp $dir/dist/lib/commons-cli-1.3.1.jar:$dir/dist/st_decrypt.jar st_decrypt.ST_decrypt "$@" Error: Could not find or load main class st_decrypt.ST_decrypt

and using @lujji 's README instruction: $ java -jar st_decrypt.jar --key "encryption key" -i firmware.bin -o firmware_encrypted.bin --encrypt Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 14 at st_decrypt.ST_decrypt.str_to_arr(ST_decrypt.java:254) at st_decrypt.ST_decrypt.encodeAndWrite(ST_decrypt.java:180) at st_decrypt.ST_decrypt.writeFirmware(ST_decrypt.java:201) at st_decrypt.ST_decrypt.dump_fw(ST_decrypt.java:223) at st_decrypt.ST_decrypt.main(ST_decrypt.java:134)

do you know what happened? thanks.

Disasm commented 4 years ago

"encryption key" is 14 bytes long, you need a real key that is 16 bytes long.

RadioOperator commented 4 years ago

@Disasm Hi, sooooo easy, Done!

RadioOperator commented 4 years ago

Hi, @Disasm , What encryption key I have to use? I found, same BIN file, I cannot generate out identical encrypted file as you sent me before. I use java -jar st_decrypt.jar --key "best performance" -i firmware.bin -o f3_2.bin --encrypt Thanks

Disasm commented 4 years ago

@RadioOperator I posted the key twice on this thread ;)

Disasm commented 4 years ago

@martonmiklos FYI: I flashed the "unprotected" bootloader from https://github.com/Krakenw/Stlink-Bootloaders/pull/3 to my not-yet-locked stlink-v3mini and then updated to V3J6M2 with the utility from ST. Seems like everything is fine and SWD it still working. I used this openocd config file:

source [find interface/cmsis-dap.cfg]
interface swd
source [find target/stm32f7x.cfg]
init
halt
targets

stm32f2x unlock 0
reset halt
program Unprotected-3-Bootloader.bin 0x08000000
program v3mini2-config.bin exit 0x08010000

Note that the whole operation takes a while (erase operation is quite slow).

UPD Warning: you should have v3mini2-config.bin (1024-byte image dumped from 0x08010000) prior to running this script!

martonmiklos commented 4 years ago

@martonmiklos FYI: I flashed the "unprotected" bootloader from Krakenw/Stlink-Bootloaders#3 to my not-yet-locked stlink-v3mini and then updated to V3J6M2 with the utility from ST. Seems like everything is fine and SWD it still working. I used this openocd config file:

source [find interface/cmsis-dap.cfg]
interface swd
source [find target/stm32f7x.cfg]
init
halt
targets

stm32f2x unlock 0
reset halt
program Unprotected-3-Bootloader.bin 0x08000000
program v3mini2-config.bin exit 0x08010000

Note that the whole operation takes a while (erase operation is quite slow).

Thank you for your impressive work on this and sharing the results with us!

martonmiklos commented 3 years ago

Btw. folks @RadioOperator , @Disasm did any of you mapped the exposed side pins (castellated pins) of the debugger? I am wondering if the QUADSPI pins could be accessed or not (and I do not have my mini at my hand atm.)

Disasm commented 3 years ago

@martonmiklos have you seen this? https://github.com/RadioOperator/CMSIS-DAP_for_STLINK-V3MINI/blob/master/STLINK-V3MINI/Sch/STLINK-V3MINI_GPIOs.JPG

martonmiklos commented 3 years ago

@Disasm nope, but yes that was what I am looking for.

RadioOperator commented 3 years ago

@Disasm @martonmiklos Hi, Please check my new repo for STLINK-V3MINI, my dream MSC Bootloader (YAB) just on board: https://github.com/RadioOperator/Yet_Another_Bootloader

New problem: By now, my YAB only can be flashed into the chip by SWD tools. If we can use "stlink-updater" to do a bootloader update on v3mini board, that will be perfect. Especially for a "Level2 locked device". I do not have enough info to do this, I think you both, or other friends here, could study on this. /Thanks.

Disasm commented 3 years ago

I think it's possible to make a "main" firmware that flashes this bootloader to the first sectors and then upload this firmware via stlink updater. The same procedure could be useful for unlocking the stock bootloader.

martonmiklos commented 3 years ago

program v3mini2-config.bin exit 0x08010000

@Disasm May I ask you to post this file as well?