mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-05-11 11:37:38 +02:00
131 lines
3.9 KiB
Markdown
131 lines
3.9 KiB
Markdown
# Embedded Systems Reverse Engineering
|
|
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
|
|
|
## Week 3
|
|
Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive Firmware Analysis
|
|
|
|
### Non-Credit Practice Exercise 1: Trace a Reset
|
|
|
|
#### Objective
|
|
Single-step through the first 10 instructions of the reset handler to understand exactly what happens when the RP2350 powers on or resets.
|
|
|
|
#### Prerequisites
|
|
- Raspberry Pi Pico 2 with debug probe connected
|
|
- OpenOCD and `arm-none-eabi-gdb` available in your PATH
|
|
- `build\0x0001_hello-world.elf` present and flashed to the board
|
|
- Week 3 environment setup completed (OpenOCD running, GDB connected)
|
|
|
|
#### Task Description
|
|
You will set a breakpoint at the reset handler (`0x1000015c`), trigger a reset, and step through each instruction one at a time while documenting what each instruction does.
|
|
|
|
#### Step-by-Step Instructions
|
|
|
|
##### Step 1: Start OpenOCD
|
|
|
|
```powershell
|
|
openocd ^
|
|
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
|
|
-f interface/cmsis-dap.cfg ^
|
|
-f target/rp2350.cfg ^
|
|
-c "adapter speed 5000"
|
|
```
|
|
|
|
##### Step 2: Launch GDB
|
|
|
|
```powershell
|
|
arm-none-eabi-gdb build\0x0001_hello-world.elf
|
|
```
|
|
|
|
##### Step 3: Connect to Target
|
|
|
|
```gdb
|
|
(gdb) target extended-remote :3333
|
|
```
|
|
|
|
##### Step 4: Set Breakpoint at Reset Handler
|
|
|
|
```gdb
|
|
(gdb) b *0x1000015c
|
|
```
|
|
|
|
**What this does:** Places a breakpoint at the very first instruction of the reset handler (the entry point after bootrom).
|
|
|
|
##### Step 5: Reset and Break
|
|
|
|
```gdb
|
|
(gdb) monitor reset halt
|
|
(gdb) c
|
|
```
|
|
|
|
**What this does:**
|
|
- `monitor reset halt` resets the chip and immediately halts it
|
|
- `c` continues execution until the breakpoint at the reset handler is hit
|
|
|
|
##### Step 6: Single-Step Through Instructions
|
|
|
|
Now step through the first 10 instructions, one at a time:
|
|
|
|
```gdb
|
|
(gdb) si
|
|
(gdb) disas $pc,+2
|
|
(gdb) info registers r0
|
|
```
|
|
|
|
Repeat `si` nine more times, examining each instruction.
|
|
|
|
**Example of what you'll see:**
|
|
|
|
**Instruction 1:**
|
|
```
|
|
0x1000015c <_reset_handler>: mov.w r0, #3489660928 @ 0xd0000000
|
|
```
|
|
**What it does:** Loads the SIO base address (0xd0000000) into r0
|
|
|
|
**Instruction 2:**
|
|
```
|
|
0x10000160 <_reset_handler+4>: ldr r0, [r0, #0]
|
|
```
|
|
**What it does:** Reads the CPUID register to determine which core is running
|
|
|
|
**Instruction 3:**
|
|
```
|
|
0x10000162 <_reset_handler+6>: cbz r0, 0x1000016a
|
|
```
|
|
**What it does:** If CPUID is 0 (Core 0), branch ahead to continue boot; otherwise handle Core 1
|
|
|
|
##### Step 7: Document Your Observations
|
|
|
|
For each of the 10 instructions:
|
|
1. Write down the address
|
|
2. Write down the assembly instruction
|
|
3. Explain what it does
|
|
4. Note any register changes using `info registers`
|
|
|
|
#### Expected Output
|
|
- You should see the reset handler check which core is running
|
|
- If you're on Core 0, you'll see it jump to the data copy section
|
|
- Register `r0` will contain CPUID value (should be 0)
|
|
- PC (program counter) advances with each `si` command
|
|
|
|
#### Questions for Reflection
|
|
|
|
###### Question 1: Why does the reset handler check the CPUID before doing anything else?
|
|
|
|
###### Question 2: What would happen if Core 1 tried to run the same initialization code as Core 0?
|
|
|
|
###### Question 3: Which registers are used in the first 10 instructions, and why those specific ones?
|
|
|
|
#### Tips and Hints
|
|
- Use `disas $pc,+20` to see upcoming instructions without stepping through them
|
|
- Use `info registers` to see all register values at any point
|
|
- If you step past where you wanted to stop, just `monitor reset halt` and start over
|
|
- Keep notes as you go—this is detective work!
|
|
|
|
#### Next Steps
|
|
- Try stepping all the way through to the data copy loop
|
|
- Set a breakpoint at `0x1000016c` (the data copy loop) and continue there directly
|
|
- Move on to Exercise 2 to calculate the stack size from the vector table
|
|
|
|
#### Additional Challenge
|
|
Set a breakpoint at `0x10000178` (the BSS clear phase) and continue execution to see how the reset handler transitions from data copying to BSS clearing.
|