6.4 KiB
Embedded Systems Reverse Engineering
Week 7
Constants in Embedded Systems: Debugging and Hacking Constants w/ 1602 LCD I2C Basics
Non-Credit Practice Exercise 1: Change Both LCD Lines
Objective
Patch the LCD display strings in the .bin file to change "Reverse" to "Exploit" on line 1 and "Engineering" to "Hacking!!!!" on line 2, using GDB to locate the string addresses, a hex editor to perform the patches, and the Pico 2 hardware to verify the changes on the physical LCD.
Prerequisites
- Completed Week 7 tutorial (GDB and hex editor sections)
0x0017_constants.binbinary 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 1602 LCD connected via I²C
Task Description
The LCD currently displays "Reverse" on line 1 and "Engineering" on line 2. You will find both string literals in flash memory using GDB, calculate their file offsets, and patch them to display custom text. The critical constraint is that replacement strings must be the same length as the originals (or shorter, padded with null bytes) — otherwise you'll corrupt adjacent data.
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\0x0017_constants.elf
Connect to target:
(gdb) target remote :3333
(gdb) monitor reset halt
Step 2: Locate the String Literals in Memory
From the tutorial, we know the strings are in the .rodata section:
(gdb) x/s 0x10003ee8
Output:
0x10003ee8: "Reverse"
(gdb) x/s 0x10003ef0
Output:
0x10003ef0: "Engineering"
Step 3: Examine the Raw Bytes
Look at the hex encoding of both strings:
(gdb) x/8xb 0x10003ee8
Output:
0x10003ee8: 0x52 0x65 0x76 0x65 0x72 0x73 0x65 0x00
R e v e r s e \0
(gdb) x/12xb 0x10003ef0
Output:
0x10003ef0: 0x45 0x6e 0x67 0x69 0x6e 0x65 0x65 0x72
E n g i n e e r
0x10003ef8: 0x69 0x6e 0x67 0x00
i n g \0
Step 4: Plan Your Replacement Strings
Original strings and their lengths:
- "Reverse" = 7 characters + null terminator = 8 bytes
- "Engineering" = 11 characters + null terminator = 12 bytes
Replacement strings (MUST be same length or shorter):
- "Exploit" = 7 characters ? (same as "Reverse")
- "Hacking!!!!" = 11 characters ? (same as "Engineering")
Build the ASCII hex for "Exploit":
| Character | Hex |
|---|---|
| E | 0x45 |
| x | 0x78 |
| p | 0x70 |
| l | 0x6c |
| o | 0x6f |
| i | 0x69 |
| t | 0x74 |
| \0 | 0x00 |
Build the ASCII hex for "Hacking!!!!":
| Character | Hex |
|---|---|
| H | 0x48 |
| a | 0x61 |
| c | 0x63 |
| k | 0x6b |
| i | 0x69 |
| n | 0x6e |
| g | 0x67 |
| ! | 0x21 |
| ! | 0x21 |
| ! | 0x21 |
| ! | 0x21 |
| \0 | 0x00 |
Step 5: Calculate File Offsets
file_offset = address - 0x10000000
- "Reverse" at
0x10003ee8? file offset0x3EE8 - "Engineering" at
0x10003ef0? file offset0x3EF0
Step 6: Patch String 1 — "Reverse" ? "Exploit"
- In HxD, open
C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0017_constants\build\0x0017_constants.bin - Press Ctrl+G and enter offset:
3EE8 - You should see:
52 65 76 65 72 73 65 00("Reverse\0") - Replace with:
45 78 70 6C 6F 69 74 00("Exploit\0")
Step 7: Patch String 2 — "Engineering" ? "Hacking!!!!"
- Press Ctrl+G and enter offset:
3EF0 - You should see:
45 6E 67 69 6E 65 65 72 69 6E 67 00("Engineering\0") - Replace with:
48 61 63 6B 69 6E 67 21 21 21 21 00("Hacking!!!!\0")
Step 8: Save and Convert
- Click File ? Save As ?
0x0017_constants-h.bin
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0017_constants
python ..\uf2conv.py build\0x0017_constants-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
Step 9: Flash and Verify
- Hold BOOTSEL and plug in your Pico 2
- Drag and drop
hacked.uf2onto the RPI-RP2 drive
Check the LCD:
- Line 1 should now show:
Exploit - Line 2 should now show:
Hacking!!!!
Expected Output
After completing this exercise, you should be able to:
- Locate string literals in flash memory using GDB
- Convert ASCII characters to hex bytes for patching
- Patch multiple strings in a single binary
- Understand the same-length constraint for string patching
Questions for Reflection
Question 1: Why must the replacement string be the same length (or shorter) as the original? What specific data would you corrupt if you used a longer string?
Question 2: The two strings "Reverse" and "Engineering" are stored only 8 bytes apart (0x3EE8 to 0x3EF0). "Reverse" is 7 characters + null = 8 bytes — it perfectly fills the gap. What would happen if you patched "Reverse" with "Reversal" (8 characters + null = 9 bytes)?
Question 3: If you wanted the LCD to display "Hello" on line 1 (5 characters instead of 7), what would you put in the remaining 2 bytes plus null? Write out the full 8-byte hex sequence.
Question 4: Could you change the LCD to display nothing on line 1 by patching just one byte? Which byte and what value?
Tips and Hints
- Use an ASCII table to convert characters: uppercase A-Z =
0x41-0x5A, lowercase a-z =0x61-0x7A - The null terminator
0x00marks the end of the string — anything after it is ignored bylcd_puts - If your replacement is shorter, pad with
0x00bytes to fill the original length - The 1602 LCD has 16 characters per line — you cannot display more than 16 characters per line regardless of string length
Next Steps
- Proceed to Exercise 2 to explore finding all string literals in the binary
- Try displaying reversed text: can you make it show "gninnignE" and "esreveR"?
- Use GDB to verify your patches before flashing:
set {char[8]} 0x10003ee8 = "Exploit"to test in RAM first