mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-05-24 00:14:04 +02:00
Refactor E and S
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 2
|
||||
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
|
||||
|
||||
### Non-Credit Practice Exercise 1 Solution: Change the Message
|
||||
|
||||
#### Answers
|
||||
|
||||
##### Attack Summary
|
||||
The goal is to write a custom message into SRAM at `0x20000000` and redirect `r0` to print it instead of the original `"hello, world"` string, without changing the source code.
|
||||
|
||||
##### GDB Commands
|
||||
|
||||
```gdb
|
||||
(gdb) target extended-remote :3333
|
||||
(gdb) monitor reset halt
|
||||
(gdb) b *0x1000023c # Breakpoint before __wrap_puts
|
||||
(gdb) c # Continue to breakpoint
|
||||
(gdb) set {char[20]} 0x20000000 = {'Y','o','u','r',' ','N','a','m','e','!','\r','\0'}
|
||||
(gdb) set $r0 = 0x20000000 # Redirect r0 to injected message
|
||||
(gdb) c # Resume - serial shows custom message
|
||||
```
|
||||
|
||||
##### Verification
|
||||
```gdb
|
||||
(gdb) x/s 0x20000000 # Should show your injected message
|
||||
(gdb) x/s 0x100019cc # Original string still in Flash
|
||||
```
|
||||
|
||||
#### Reflection Answers
|
||||
|
||||
1. **Why does the string have to live in SRAM instead of flash during runtime?**
|
||||
Flash memory is read-only at runtime. The original string at `0x100019cc` cannot be modified. SRAM starting at `0x20000000` is read-write, so that is where we must place our replacement string.
|
||||
|
||||
2. **What would happen if you forgot the null terminator in your injected string?**
|
||||
`puts()` reads characters until it encounters `\0`. Without it, `puts()` would continue reading past the intended string, printing garbage characters from adjacent memory until a null byte happens to appear. This could crash the program or leak sensitive data.
|
||||
|
||||
3. **How does changing `r0` alter the behavior of `puts()` without touching source code?**
|
||||
In the ARM calling convention, the first function argument is passed in `r0`. When `bl __wrap_puts` executes at `0x1000023c`, it reads the string address from `r0`. By changing `r0` from `0x100019cc` (original Flash string) to `0x20000000` (our SRAM string), we redirect what `puts()` prints.
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 2
|
||||
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
|
||||
|
||||
### Exercise 1: Change the Message
|
||||
### Non-Credit Practice Exercise 1: Change the Message
|
||||
|
||||
#### Objective
|
||||
Write your own message into SRAM and redirect `r0` so the running program prints it without changing the source code.
|
||||
@@ -14,7 +14,7 @@ Write your own message into SRAM and redirect `r0` so the running program prints
|
||||
- OpenOCD and `arm-none-eabi-gdb` available in your PATH
|
||||
- Serial monitor (PuTTY/minicom/screen) set to 115200 baud
|
||||
- `build\0x0001_hello-world.elf` present and flashed to the board
|
||||
- Week 2 setup steps (0a–0e) completed: OpenOCD, serial monitor, and GDB ready
|
||||
- Week 2 setup steps (0a–0e) completed: OpenOCD, serial monitor, and GDB ready
|
||||
|
||||
#### Task Description
|
||||
You will create a custom string in SRAM at `0x20000000`, point `r0` at it just before `puts()` runs, and watch the live output change to your message.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 2
|
||||
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
|
||||
|
||||
### Non-Credit Practice Exercise 2 Solution: Use a Different SRAM Address
|
||||
|
||||
#### Answers
|
||||
|
||||
##### Attack Summary
|
||||
Write the payload to `0x20001000` instead of `0x20000000` to demonstrate that multiple safe SRAM locations can be used for injection.
|
||||
|
||||
##### GDB Commands
|
||||
|
||||
```gdb
|
||||
(gdb) b *0x1000023c
|
||||
(gdb) c
|
||||
(gdb) set {char[14]} 0x20001000 = {'h','a','c','k','e','d','!','!','!','\r','\0'}
|
||||
(gdb) set $r0 = 0x20001000
|
||||
(gdb) c
|
||||
```
|
||||
|
||||
##### Verification
|
||||
```gdb
|
||||
(gdb) x/s 0x20001000 # Shows "hacked!!!\r"
|
||||
```
|
||||
|
||||
#### Reflection Answers
|
||||
|
||||
1. **How can you ensure `0x20001000` does not collide with stack usage?**
|
||||
The stack pointer was observed at `0x20082000` (top of stack) and grows downward. Since `0x20001000` is far below the stack region, there is substantial separation. Use `info registers sp` in GDB to verify the current stack pointer is well above your injection address.
|
||||
|
||||
2. **What symptoms would indicate you overwrote an active stack frame?**
|
||||
The program would crash when attempting to return from a function. Symptoms include: unexpected address exceptions, invalid memory access faults, or the program jumping to random addresses. The Link Register return path gets corrupted.
|
||||
|
||||
3. **How would you pick a safe SRAM offset in a larger program with dynamic allocations?**
|
||||
Start from the bottom of SRAM (`0x20000000`) for small static payloads, working upward. Check the linker script to understand memory regions. In this simple program with no heap allocations, both `0x20000000` and `0x20001000` are safe. In larger programs, examine the `.bss` and `.data` section boundaries.
|
||||
+3
-3
@@ -1,17 +1,17 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 2
|
||||
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
|
||||
|
||||
### Exercise 2: Use a Different SRAM Address
|
||||
### Non-Credit Practice Exercise 2: Use a Different SRAM Address
|
||||
|
||||
#### Objective
|
||||
Practice writing to an alternate SRAM location and redirecting `r0` so your message prints from `0x20001000` instead of `0x20000000`.
|
||||
|
||||
#### Prerequisites
|
||||
- Raspberry Pi Pico 2 with debug probe connected
|
||||
- OpenOCD, `arm-none-eabi-gdb`, and a serial monitor ready (Week 2 steps 0a–0e complete)
|
||||
- OpenOCD, `arm-none-eabi-gdb`, and a serial monitor ready (Week 2 steps 0a–0e complete)
|
||||
- `build\0x0001_hello-world.elf` flashed and running
|
||||
- Comfortable setting breakpoints at `0x1000023c`
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 2
|
||||
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
|
||||
|
||||
### Non-Credit Practice Exercise 3 Solution: Examine Memory Around Your String
|
||||
|
||||
#### Answers
|
||||
|
||||
##### GDB Commands
|
||||
|
||||
```gdb
|
||||
(gdb) set {char[14]} 0x20000000 = {'h','a','c','k','y',',',' ','w','o','r','l','d','\r','\0'}
|
||||
(gdb) x/20b 0x20000000
|
||||
```
|
||||
|
||||
##### Byte Dump Output
|
||||
|
||||
```
|
||||
0x20000000: 0x68 0x61 0x63 0x6b 0x79 0x2c 0x20 0x77
|
||||
0x20000008: 0x6f 0x72 0x6c 0x64 0x0d 0x00 0x00 0x00
|
||||
0x20000010: 0x00 0x00 0x00 0x00
|
||||
```
|
||||
|
||||
##### ASCII Mapping
|
||||
|
||||
| Offset | Hex Value | Character |
|
||||
|--------|-----------|-----------|
|
||||
| 0x00 | `0x68` | h |
|
||||
| 0x01 | `0x61` | a |
|
||||
| 0x02 | `0x63` | c |
|
||||
| 0x03 | `0x6b` | k |
|
||||
| 0x04 | `0x79` | y |
|
||||
| 0x05 | `0x2c` | , (comma) |
|
||||
| 0x06 | `0x20` | (space) |
|
||||
| 0x07 | `0x77` | w |
|
||||
| 0x08 | `0x6f` | o |
|
||||
| 0x09 | `0x72` | r |
|
||||
| 0x0a | `0x6c` | l |
|
||||
| 0x0b | `0x64` | d |
|
||||
| 0x0c | `0x0d` | \r (carriage return) |
|
||||
| 0x0d | `0x00` | \0 (null terminator) |
|
||||
|
||||
#### Reflection Answers
|
||||
|
||||
1. **Which bytes mark the end of the printable string, and why are they needed?**
|
||||
The last two meaningful bytes are `0x0d` (carriage return `\r`) and `0x00` (null terminator `\0`). The null terminator signals the end of the string to `puts()`. Without it, `puts()` would read past the intended string and print garbage memory until a null byte is encountered.
|
||||
|
||||
2. **How would misaligned writes show up in the byte view?**
|
||||
If you write to an incorrect address or use wrong character offsets, the byte dump would show unexpected values at wrong positions. Characters would appear shifted, and adjacent data structures could be corrupted.
|
||||
|
||||
3. **What risks arise if you overwrite bytes immediately after your string?**
|
||||
Overwriting adjacent bytes could corrupt other data structures in SRAM, such as variables, linked lists, or runtime metadata. This could cause unpredictable crashes or silent data corruption depending on what occupies those memory locations.
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 2
|
||||
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
|
||||
|
||||
### Exercise 3: Examine Memory Around Your String
|
||||
### Non-Credit Practice Exercise 3: Examine Memory Around Your String
|
||||
|
||||
#### Objective
|
||||
Inspect the byte-level layout of your injected string in SRAM and correlate bytes to characters.
|
||||
@@ -49,7 +49,7 @@ If needed, re-inject a payload:
|
||||
```
|
||||
|
||||
##### Step 5: Decode the Output
|
||||
- Map each byte to ASCII: e.g., `0x68` → `h`, `0x0d` → `\r`, `0x00` → `\0`.
|
||||
- Map each byte to ASCII: e.g., `0x68` ? `h`, `0x0d` ? `\r`, `0x00` ? `\0`.
|
||||
- Note any bytes before/after the string to ensure you did not overwrite adjacent data.
|
||||
|
||||
##### Step 6: Resume Execution
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 2
|
||||
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
|
||||
|
||||
### Non-Credit Practice Exercise 4 Solution: Automate the Hack
|
||||
|
||||
#### Answers
|
||||
|
||||
##### GDB Command Definition
|
||||
|
||||
```gdb
|
||||
(gdb) define hack
|
||||
> set {char[14]} 0x20000000 = {'h','a','c','k','y',',',' ','w','o','r','l','d','\r','\0'}
|
||||
> set $r0 = 0x20000000
|
||||
> c
|
||||
> end
|
||||
```
|
||||
|
||||
##### Usage
|
||||
|
||||
```gdb
|
||||
(gdb) b *0x1000023c
|
||||
(gdb) c
|
||||
(gdb) hack # Executes all three commands at once
|
||||
```
|
||||
|
||||
##### Expected Serial Output
|
||||
|
||||
```
|
||||
hello, world
|
||||
hello, world
|
||||
hello, world
|
||||
hacky, world <-- HACKED! (after hack command executed)
|
||||
hacky, world
|
||||
```
|
||||
|
||||
#### Reflection Answers
|
||||
|
||||
1. **How could you parameterize the command to accept different strings or addresses?**
|
||||
Standard GDB `define` blocks do not support function parameters directly. However, you can use GDB convenience variables (`set $myaddr = 0x20000000`) and reference them in the macro, or create multiple specific commands like `hack_addr1`, `hack_addr2`. For advanced parameterization, use GDB Python scripting.
|
||||
|
||||
2. **What happens if you define `hack` before setting the breakpoint - will it still work as expected?**
|
||||
The `define` command only creates a macro; it does not execute immediately. The breakpoint must be set and hit before invoking `hack`. The sequence matters: set breakpoint -> run/continue to hit breakpoint -> then call `hack`. Defining the macro before or after the breakpoint does not matter as long as you invoke it at the right time.
|
||||
|
||||
3. **How would you adapt this pattern for multi-step routines (e.g., patch, dump, continue)?**
|
||||
Extend the `define` block with additional commands:
|
||||
```gdb
|
||||
(gdb) define hack_verbose
|
||||
> set {char[14]} 0x20000000 = {'h','a','c','k','y',',',' ','w','o','r','l','d','\r','\0'}
|
||||
> x/20b 0x20000000
|
||||
> set $r0 = 0x20000000
|
||||
> info registers r0
|
||||
> c
|
||||
> end
|
||||
```
|
||||
This dumps memory and registers before continuing, providing verification at each step.
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 2
|
||||
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
|
||||
|
||||
### Exercise 4: Automate the Hack
|
||||
### Non-Credit Practice Exercise 4: Automate the Hack
|
||||
|
||||
#### Objective
|
||||
Create a reusable GDB command that injects a string into SRAM, repoints `r0`, and resumes execution with a single call.
|
||||
@@ -56,7 +56,7 @@ You will define a custom GDB command `hack` that writes a payload to `0x20000000
|
||||
|
||||
###### Question 1: How could you parameterize the command to accept different strings or addresses?
|
||||
|
||||
###### Question 2: What happens if you define `hack` before setting the breakpoint—will it still work as expected?
|
||||
###### Question 2: What happens if you define `hack` before setting the breakpoint—will it still work as expected?
|
||||
|
||||
###### Question 3: How would you adapt this pattern for multi-step routines (e.g., patch, dump, continue)?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user