mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-04-01 09:00:18 +02:00
147 lines
5.4 KiB
Markdown
147 lines
5.4 KiB
Markdown
# Embedded Systems Reverse Engineering
|
||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||
|
||
## Week 11
|
||
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
|
||
|
||
### Non-Credit Practice Exercise 4: Change Blink Speed
|
||
|
||
#### Objective
|
||
Find the `blink_led(pin, 3, 50)` call in the `0x0026_functions` binary using GDB, identify the immediate value `0x32` (50) being loaded into `r2` (the delay parameter), calculate the file offset, and patch it to `0x19` (25) so that each LED blinks at double speed when activated by the IR remote.
|
||
|
||
#### Prerequisites
|
||
- Completed Week 11 tutorial (GDB and hex editor sections)
|
||
- `0x0026_functions.elf` and `0x0026_functions.bin` available in your build directory
|
||
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
|
||
- A hex editor (HxD, ImHex, or similar)
|
||
- Python installed (for UF2 conversion)
|
||
- Raspberry Pi Pico 2 with IR remote and LEDs on GPIO 16, 17, 18
|
||
|
||
#### Task Description
|
||
The `blink_led` function takes a delay parameter of `50`ms (`0x32`) in register `r2`. This value controls how long each LED stays on and off during the blink cycle. By patching this to `25`ms (`0x19`), the LEDs will blink twice as fast, creating a noticeably quicker flashing pattern when any IR remote button is pressed.
|
||
|
||
#### Step-by-Step Instructions
|
||
|
||
##### Step 1: Start the Debug Session
|
||
|
||
**Terminal 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"
|
||
```
|
||
|
||
**Terminal 2 - Start GDB:**
|
||
|
||
```powershell
|
||
arm-none-eabi-gdb build\0x0026_functions.elf
|
||
```
|
||
|
||
**Connect to target:**
|
||
|
||
```gdb
|
||
(gdb) target remote :3333
|
||
(gdb) monitor reset halt
|
||
```
|
||
|
||
##### Step 2: Find the blink_led Call
|
||
|
||
Disassemble main and look for the parameter setup before `bl blink_led`:
|
||
|
||
```gdb
|
||
(gdb) disassemble 0x10000234,+300
|
||
```
|
||
|
||
Look for:
|
||
|
||
```
|
||
movs r0, <pin> ; GPIO pin number
|
||
movs r1, #3 ; blink count
|
||
movs r2, #0x32 ; delay = 50ms
|
||
bl blink_led
|
||
```
|
||
|
||
Note the address of the `movs r2, #0x32` instruction.
|
||
|
||
##### Step 3: Examine the Instruction Encoding
|
||
|
||
Look at the raw bytes:
|
||
|
||
```gdb
|
||
(gdb) x/2bx <address_of_movs_r2_0x32>
|
||
```
|
||
|
||
The `movs r2, #0x32` instruction has `0x32` (50) as the immediate byte.
|
||
|
||
##### Step 4: Calculate the File Offset
|
||
|
||
```
|
||
file_offset = address - 0x10000000
|
||
```
|
||
|
||
Note the file offset of the byte containing `32`.
|
||
|
||
##### Step 5: Encode the New Value
|
||
|
||
| Parameter | Original | New | Effect |
|
||
| --------- | --------------- | --------------- | --------------- |
|
||
| Delay | `32` (50ms) | `19` (25ms) | 2x faster blink |
|
||
|
||
**Be careful:** `0x32` is also the ASCII code for '2'. Make sure you are patching the `movs r2` instruction and not a comparison value like `cmp r4, #0x32`.
|
||
|
||
##### Step 6: Patch with HxD
|
||
|
||
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
|
||
2. Press **Ctrl+G** and enter the file offset
|
||
3. You should see: `32`
|
||
4. Replace with: `19`
|
||
|
||
###### Question 1: How can you confirm you are patching the delay parameter and not some other `0x32` byte in the binary?
|
||
|
||
##### Step 7: Save and Convert
|
||
|
||
1. Click **File** → **Save As** → `0x0026_functions-h.bin`
|
||
|
||
```powershell
|
||
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
|
||
python ..\uf2conv.py build\0x0026_functions-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
|
||
```
|
||
|
||
##### Step 8: Flash and Verify
|
||
|
||
1. Hold BOOTSEL and plug in your Pico 2
|
||
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
|
||
|
||
**Check the behavior:**
|
||
- Press button 1 → Red LED blinks 3 times but **noticeably faster** (25ms on/off vs 50ms)
|
||
- Press button 2 → Green LED blinks 3 times at **double speed**
|
||
- Press button 3 → Yellow LED blinks 3 times at **double speed**
|
||
- The total blink sequence should complete in roughly half the original time
|
||
|
||
#### Expected Output
|
||
|
||
After completing this exercise, you should be able to:
|
||
- Locate function parameters in ARM Thumb `movs` instructions
|
||
- Distinguish between identical byte values used in different contexts
|
||
- Patch timing parameters to change observable hardware behavior
|
||
- Understand the relationship between delay values and perceived blink speed
|
||
|
||
#### Questions for Reflection
|
||
|
||
###### Question 1: The `blink_led` function calls `sleep_ms` internally with the delay value. If you set the delay to `1`ms (0x01), would you still see the LED blink, or would it appear constantly on?
|
||
|
||
###### Question 2: The value `0x32` appears in this binary as both a delay parameter (50ms) and potentially as an ASCII comparison ('2'). How would you systematically find ALL occurrences of `0x32` and determine which one to patch?
|
||
|
||
###### Question 3: If you wanted a delay of 500ms (0x1F4), the value would not fit in a `movs` immediate. How would the compiler handle this larger delay value?
|
||
|
||
###### Question 4: The blink function uses the delay for both the on-time and the off-time. Could you make the LED stay on longer than it stays off? What kind of patch would that require?
|
||
|
||
#### Tips and Hints
|
||
- `25` decimal = `0x19` hex — fits in one byte, so the `movs` encoding works directly
|
||
- Verify location by checking the surrounding instructions: `movs r1, #3` should be right before and `bl blink_led` right after
|
||
- The total blink time for 3 blinks at 50ms = 3 × (50 + 50) = 300ms; at 25ms = 3 × (25 + 25) = 150ms
|
||
- If there are multiple call sites for `blink_led`, each may have its own `movs r2, #0x32` that needs patching
|