CTXz / stm32f1-picopwner

Dump read-out protected STM32F1's with a Pi Pico - A Pi Pico implementation of @JohannesObermaier's, Marc Schink's and Kosma Moczek's Glitch and FPB attack to bypass RDP (read-out protection) level 1 on STM32F1 chips
181 stars 25 forks source link

[Idea] Universal loader. Also: Fix for devices with smaller RAM. #18

Closed deividAlfa closed 7 months ago

deividAlfa commented 7 months ago

This should remove the need of making different loaders for each RAM entry point. Also, setting 20KB RAM will cause a hardfault in any other STM32 with smaller RAM (102, 101, 100). So, limit RAM to 4KB to make it work with all.


ram_universal.ld Isolate ISR and Entry Vector in their own section, reserve 0x000-0x300 for them.

MEMORY
{
  FLASH (rx)    : ORIGIN = 0x08000000, LENGTH = 64K
  RAM_ISR (xrw) : ORIGIN = 0x20000000, LENGTH = 768                                         /* Reserve 0x000-0x300 for isr and entry point */
  RAM (xrw) : ORIGIN = ORIGIN(RAM_ISR)+LENGTH(RAM_ISR), LENGTH = 4K-LENGTH(RAM_ISR)     /* Limit RAM usage to 4KB for best compatibility */
}

SECTIONS
{
                                            /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector))                    /* Startup code */
    . = ALIGN(4);
    . = 0x100;
    *(.entryVec)                            /* entry vector position for SRAM execution */
  } >RAM_ISR


test.S Set the stack to 4KB to avoid possible hard faults. Fill ram 0x100-0x300 with jumps. Wherever the ram boots to, it'll jump to the correct place.

.section .isr_vector
isrVectors:
    .word 0x20001000                    /* Set stack to 4KB */
    .word _start+1
    .word vecNMI+1
    .word vecHardfault+1
    .word vecMemMan+1
    .word 0
    .word 0
    .word 0
                                            /* These is the stage 2 entry point */
    .word stage2+1

.section .entryVec
.rept 256                                   /* Fill 0x100-0x300 with jumps */
        b _start
.endr


dump.py

def sram_entry_offset_supported(entry_addr: int):
    return ((entry_addr >= 0x100) and (entry_addr < 0x300))

if sram_entry_offset_supported(sram_entry_point) == False:
    print(
        "SRAM entry point offset "
        + str(hex(sram_entry_point))
        + " is not supported, expected: 0x100-0x2FF"
    )
CTXz commented 7 months ago

Implemented in https://github.com/CTXz/stm32f1-picopwner/commit/3bdbdd64eb0c30af236b515af399e9bb58c8f19d. Will be merged into main along with some other changes.

I've only been able to test this on the F103, but I don't see any reason why this wouldn't work on other models. Obviously the trampoline has some overlap with the IVT, but since the affected interrupts aren't being used that's ok I suppose.

deividAlfa commented 7 months ago

Yep, shouldn't cause any issue, while bringing a lot of benefits! 👍🏻