mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-05-17 21:44:45 +02:00
168 lines
4.4 KiB
Markdown
168 lines
4.4 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 2: Find the Stack Size
|
|
|
|
#### Objective
|
|
Calculate the size of the stack by examining the vector table, understanding the linker script's memory layout, and performing manual calculations.
|
|
|
|
#### Prerequisites
|
|
- Raspberry Pi Pico 2 with debug probe connected
|
|
- OpenOCD and `arm-none-eabi-gdb` available
|
|
- `build\0x0001_hello-world.elf` flashed to the board
|
|
- Understanding of memory regions from Week 3 Part 5 (Linker Script)
|
|
|
|
#### Task Description
|
|
You will examine the initial stack pointer value from the vector table, identify the stack limit, calculate the total stack size in bytes and kilobytes, and verify your calculations.
|
|
|
|
#### Background Information
|
|
|
|
From the Week 3 lesson, we learned:
|
|
- The initial stack pointer is stored at `0x10000000` (first entry in vector table)
|
|
- The linker script defines: `SCRATCH_Y: ORIGIN = 0x20081000, LENGTH = 4k`
|
|
- Stack top is calculated as: `ORIGIN + LENGTH = 0x20082000`
|
|
- The stack grows downward from high addresses to low addresses
|
|
|
|
#### Step-by-Step Instructions
|
|
|
|
##### Step 1: Connect and Halt
|
|
|
|
```gdb
|
|
(gdb) target extended-remote :3333
|
|
(gdb) monitor reset halt
|
|
```
|
|
|
|
##### Step 2: Examine the Initial Stack Pointer
|
|
|
|
```gdb
|
|
(gdb) x/x 0x10000000
|
|
```
|
|
|
|
**Expected output:**
|
|
```
|
|
0x10000000 <__vectors>: 0x20082000
|
|
```
|
|
|
|
This is the **top of the stack** (where the stack starts before growing downward).
|
|
|
|
##### Step 3: Find the Stack Limit
|
|
|
|
The stack limit is defined in the linker script and can be found by examining stack-related symbols or calculating from memory regions.
|
|
|
|
From the Week 3 lesson, the stack limit is `0x20078000`.
|
|
|
|
You can verify this in GDB:
|
|
|
|
```gdb
|
|
(gdb) info symbol __StackLimit
|
|
```
|
|
|
|
or check registers after boot:
|
|
|
|
```gdb
|
|
(gdb) info registers
|
|
```
|
|
|
|
Look for stack limit values or calculate: The main RAM starts at `0x20000000`, and SCRATCH_Y starts at `0x20081000`.
|
|
|
|
##### Step 4: Calculate Stack Size in Bytes
|
|
|
|
**Formula:**
|
|
```
|
|
Stack Size = Stack Top - Stack Limit
|
|
Stack Size = 0x20082000 - 0x20078000
|
|
```
|
|
|
|
Let's convert to decimal:
|
|
- `0x20082000` = 537,108,480 decimal
|
|
- `0x20078000` = 537,067,520 decimal
|
|
- Difference = 40,960 bytes
|
|
|
|
**Alternative hex calculation:**
|
|
```
|
|
0x20082000
|
|
- 0x20078000
|
|
-----------
|
|
0x0000A000 = 40,960 bytes
|
|
```
|
|
|
|
##### Step 5: Convert to Kilobytes
|
|
|
|
```
|
|
Bytes to KB = 40,960 ÷ 1,024 = 40 KB
|
|
```
|
|
|
|
So the stack is **40 KB** in size.
|
|
|
|
##### Step 6: Verify Using Memory Regions
|
|
|
|
Cross-check with the memory layout:
|
|
- **RAM**: `0x20000000` - `0x20080000` (512 KB)
|
|
- **SCRATCH_X**: `0x20080000` - `0x20081000` (4 KB)
|
|
- **SCRATCH_Y**: `0x20081000` - `0x20082000` (4 KB) ? Stack lives here
|
|
- **Stack range**: `0x20078000` - `0x20082000` (40 KB)
|
|
|
|
The stack extends from SCRATCH_Y down into the upper portion of main RAM.
|
|
|
|
##### Step 7: Examine Stack Usage at Runtime
|
|
|
|
You can see the current stack pointer value:
|
|
|
|
```gdb
|
|
(gdb) b main
|
|
(gdb) c
|
|
(gdb) info registers sp
|
|
```
|
|
|
|
**Expected output:**
|
|
```
|
|
sp 0x20081fc8 0x20081fc8
|
|
```
|
|
|
|
This shows the stack has used:
|
|
```
|
|
0x20082000 - 0x20081fc8 = 0x38 = 56 bytes
|
|
```
|
|
|
|
#### Expected Output
|
|
- Initial stack pointer: `0x20082000`
|
|
- Stack limit: `0x20078000`
|
|
- Stack size: **40,960 bytes** or **40 KB**
|
|
- Current stack usage (at main): approximately 56 bytes
|
|
|
|
#### Questions for Reflection
|
|
|
|
###### Question 1: Why is the stack 40 KB instead of just fitting in the 4 KB SCRATCH_Y region?
|
|
|
|
###### Question 2: What happens if the stack grows beyond 0x20078000?
|
|
|
|
###### Question 3: How would you detect a stack overflow during runtime?
|
|
|
|
###### Question 4: Why does the stack grow downward instead of upward?
|
|
|
|
#### Tips and Hints
|
|
- Use Windows Calculator in Programmer mode to convert hex to decimal
|
|
- Remember: 1 KB = 1,024 bytes (not 1,000)
|
|
- The stack pointer (SP) decreases as the stack grows (push operations)
|
|
- Use `bt` (backtrace) in GDB to see how much stack is currently in use
|
|
|
|
#### Next Steps
|
|
- Monitor the stack pointer as you step through functions to see it change
|
|
- Calculate stack usage for specific function calls
|
|
- Move on to Exercise 3 to examine all vector table entries
|
|
|
|
#### Additional Challenge
|
|
Write a GDB command to automatically calculate and display stack usage:
|
|
|
|
```gdb
|
|
(gdb) define stackusage
|
|
> set $used = 0x20082000 - $sp
|
|
> printf "Stack used: %d bytes (%d KB)\n", $used, $used/1024
|
|
> end
|
|
|
|
(gdb) stackusage
|
|
```
|