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

5.4 KiB
Raw Permalink Blame History

Embedded Systems Reverse Engineering

Repository

Week 11

Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics

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 50ms (0x32) in register r2. This value controls how long each LED stays on and off during the blink cycle. By patching this to 25ms (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:

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:

arm-none-eabi-gdb build\0x0026_functions.elf

Connect to target:

(gdb) target remote :3333
(gdb) monitor reset halt

Disassemble main and look for the parameter setup before bl blink_led:

(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) 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 FileSave As0x0026_functions-h.bin
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 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?

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