Files
Embedded-Hacking/WEEK11/WEEK11-04.md
2026-03-19 15:01:07 -04:00

147 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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