# Embedded Systems Reverse Engineering [Repository](https://github.com/mytechnotalent/Embedded-Hacking) ## 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.bin` binary 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:** ```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\0x0017_constants.elf ``` **Connect to target:** ```gdb (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 (gdb) x/s 0x10003ee8 ``` Output: ``` 0x10003ee8: "Reverse" ``` ```gdb (gdb) x/s 0x10003ef0 ``` Output: ``` 0x10003ef0: "Engineering" ``` ##### Step 3: Examine the Raw Bytes Look at the hex encoding of both strings: ```gdb (gdb) x/8xb 0x10003ee8 ``` Output: ``` 0x10003ee8: 0x52 0x65 0x76 0x65 0x72 0x73 0x65 0x00 R e v e r s e \0 ``` ```gdb (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 offset `0x3EE8` - "Engineering" at `0x10003ef0` ? file offset `0x3EF0` ##### Step 6: Patch String 1 — "Reverse" ? "Exploit" 1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0017_constants\build\0x0017_constants.bin` 2. Press **Ctrl+G** and enter offset: `3EE8` 3. You should see: `52 65 76 65 72 73 65 00` ("Reverse\0") 4. Replace with: `45 78 70 6C 6F 69 74 00` ("Exploit\0") ##### Step 7: Patch String 2 — "Engineering" ? "Hacking!!!!" 1. Press **Ctrl+G** and enter offset: `3EF0` 2. You should see: `45 6E 67 69 6E 65 65 72 69 6E 67 00` ("Engineering\0") 3. Replace with: `48 61 63 6B 69 6E 67 21 21 21 21 00` ("Hacking!!!!\0") ##### Step 8: Save and Convert 1. Click **File** ? **Save As** ? `0x0017_constants-h.bin` ```powershell 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 1. Hold BOOTSEL and plug in your Pico 2 2. Drag and drop `hacked.uf2` onto 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 `0x00` marks the end of the string — anything after it is ignored by `lcd_puts` - If your replacement is shorter, pad with `0x00` bytes 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