mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-07-12 23:26:33 +02:00
Added WEEK03
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 3
|
||||
Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive Firmware Analysis
|
||||
|
||||
### 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
|
||||
```
|
||||
Reference in New Issue
Block a user