readme update

This commit is contained in:
Triss 2022-04-09 22:10:12 +02:00
parent cb7386bc6f
commit 60a5e08c7e
1 changed files with 47 additions and 24 deletions

View File

@ -5,40 +5,51 @@ Tools to try to dump the MSP430FR BSL, mainly targetting the [MSP430FR5994
## The idea ## The idea
The MSP430FR bootloader ('BSL') resides at 0x1000, this memory cannot be read, The MSP430FR bootloader ('BSL') resides at `0x1000`. This memory cannot be
and user code can only jump to 0x1000 or 0x1002 to run certian functions of the read, and user code can only jump to `0x1000` or `0x1002`, called the "Z-area",
BSL. Though, it is very likely that when the CPU is running from inside this to run certian functions of the BSL. Though, it is very likely that when the
memory region, it can access this memory as data, because that's often needed CPU is running from inside this memory region, it can access this memory as
to store eg. complex integer values, structs, lookup tables, and so on. data, as that is often needed to store eg. structs, lookup tables, and so on.
Several other "execute-only" memory implementations function in a similar way,
such as the Nintendo GameBoy Advance and DS boot ROMS ("BIOS"es, citation
below), as well as in other systems analyzed by Schink and Obermaier,
publication also linked below.
The BSL (according to [the datasheet The BSL (according to [the datasheet
](https://www.ti.com/lit/ug/slau550aa/slau550aa.pdf)) doesn't disable ](https://www.ti.com/lit/ug/slau550aa/slau550aa.pdf)) doesn't disable
interrupts. That means that you can still jump to it, and then interrupt it to interrupts. That means that, while the BSL is executing, it is possible to
jump to code controlled by the user. As this is an interrupt, it can inspect interrupt this execution flow to
jump to code controlled by the user. An interrupt can inspect and modify
the registers of the BSL code at the time when the interrupt happened, as well the registers of the BSL code at the time when the interrupt happened, as well
as the stack contents. Having a timer at the same frequency as the CPU, and as the stack contents. Having a timer at the same frequency as the CPU, and
having it dump the register+stack contents after a while, and doing that over having it dump the register and stack contents after a certain interval increasing
and over again while advancing the time-until-interrupt delay by one cycle by one cycle every iteration, it is possible to trace the instruction flow of
every iteration, you can get a view of what the CPU is doing while executing the CPU, as well as which registers and stack contents it is accessing, and how,
this hidden code (also, the MSP430 CPU is multicycling and uses variable-length even though the code itself is not visible. Furthermore, the MSP430 CPU uses a
instructions, so instruction timings and pc deltas can also be used as a side variable-length instruction set and instructions can use a variable amount of
channel to figure out which instruction is which). cycles, therefore these traces can also be used to infer more infromation about
which instructions are executed, as the `pc` CPU register will never point to
the middle of an instruction, and will only advance to the next instruction
depending on how long the current instruction takes to execute.
Function epilogues typically first pop a bunch of values off the stack and load Function epilogues typically first pop a number of values off the stack and
these back into registers, and then return. Additionally, if you're lucky, you load these back into registers, and then return. By controlling the stack
may also find a memory read right before the end of such an epilogue. pointer value, these can be used as a way to perform arbitrary reads. However,
as we are targetting nonwritable memory, an interrupt needs to happen before
the return occurs, otherwise CPU execution becomes very unpredictable.
You can find these epilogues by staring at many, many execution traces You can find these epilogues by staring at many, many execution traces
(obtained from these timer interrupts) and thinking really hard (this is the (obtained from these timer interrupts) and thinking really hard (this is the
hard, time-consuming and labor-intensive part). hard, time-consuming and labor-intensive part).
Then, by timing a DMA transfer such that it happens after a function is called Alternatively, by timing an interrupt or a DMA transfer such that it happens
but before it returns, it is possible to overwrite the memory popped off the after a function is called but before it returns, it is possible to overwrite
stack when an epilogue executes, thereby gaining control of a few register the memory popped off the stack when an epilogue executes, thereby gaining
values, and the program counter. Then you could redirect it to another piece of control of a few register values as well as the program counter. Then, CPU
code that does the memory read before returning. As you now (hopefully) have execution can be redirected to another code snippet performing the memory read
control over the address it reads from, you can use this as an arbitrary read before returning. With control over the address it reads from, this can be used
to read one word of the BSL, then return to use code to do the next iteration. as an arbitrary read to read one word of the BSL, then return to use code to do
the next iteration.
The "using interrupts to figure out what execute-only code is doing" trick was The "using interrupts to figure out what execute-only code is doing" trick was
first (afaik) used by Martin Korth to find such a gadget inside the Nintendo DS first (afaik) used by Martin Korth to find such a gadget inside the Nintendo DS
@ -64,7 +75,8 @@ described near the end, the article is quite large.
1. When the CPU is executing the BSL, it can perform data accesses to other BSL 1. When the CPU is executing the BSL, it can perform data accesses to other BSL
areas. Thus, if an arbitrary read gadget is found, it can be used to dump areas. Thus, if an arbitrary read gadget is found, it can be used to dump
the entire BSL region. the entire BSL region. This is the same issue as present in the Nintendo
DS ARM7 boot ROM.
1. The routine at `0x1002` provides such a gadget, *as indicatd in SLAU550AA*. 1. The routine at `0x1002` provides such a gadget, *as indicatd in SLAU550AA*.
1. The BSL execution is allowed to be interrutped, thus the instruction flow 1. The BSL execution is allowed to be interrutped, thus the instruction flow
can be traced by dumping CPU register values throughout the BSL execution. can be traced by dumping CPU register values throughout the BSL execution.
@ -101,3 +113,14 @@ described near the end, the article is quite large.
1. DMA: can a DMA transfer be used to change the stack contents during BSL 1. DMA: can a DMA transfer be used to change the stack contents during BSL
execution? (Most likely, just like interrupts can, I simply haven't checked.) execution? (Most likely, just like interrupts can, I simply haven't checked.)
## Hashes
This is the hash of the memory region `0x1000` to `0x17FF`, on an MSP430FR5994,
with BSL 00.08.35.B3:
| Hash function | value |
| MD5 | `4bb3bb753face80fffe1fef7a762884a` |
| SHA-1 | `1b4c13e006121a9b1c1ebcd4fbc6ec7c96cc017f` |
| SHA-256 | `e4d0d171013f847a357eebe5467bcd413ecb41dc01424b7e4ee636538d820766` |
| SHA-512 | `fed28a7e9643a551789075b79d9b04fa6e8cdca74d783c1c3830ece07e5c9141dda9532b3c442416a1ddab90d752e679c6918c0d5333ac6da9fd23ab6c33d1bb` |