# Embedded Systems Reverse Engineering [Repository](https://github.com/mytechnotalent/Embedded-Hacking) ## Week 6 Static Variables in Embedded Systems: Debugging and Hacking Static Variables w/ GPIO Input Basics ### Non-Credit Practice Exercise 1: Change the Static Variable Initial Value from 42 to 100 #### Objective Use GDB to locate the static variable `static_fav_num` in the `.data` section of the `0x0014_static-variables` binary, calculate the corresponding file offset, patch the initial value from `42` (`0x2A`) to `100` (`0x64`) using a hex editor, convert the patched binary to UF2 format, and flash it to the Pico 2 to verify the change. #### Prerequisites - Completed Week 6 tutorial (GDB section) - `0x0014_static-variables.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 connected via USB - Serial monitor software (PuTTY, minicom, or screen) #### Task Description You will use GDB to examine the static variable at its known RAM address (`0x200005a8`), trace back to where the initial value is stored in the `.data` section of flash, calculate the file offset in the `.bin` file, patch the byte from `0x2A` to `0x64` with a hex editor, and verify on hardware that the serial output now starts counting from `100` instead of `42`. #### 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\0x0014_static-variables.elf ``` **Connect to target:** ```gdb (gdb) target remote :3333 (gdb) monitor reset halt ``` ##### Step 2: Examine the Static Variable in RAM We know from the tutorial that the static variable lives at `0x200005a8`. Examine its current value: ```gdb (gdb) x/1db 0x200005a8 ``` You should see the current value (probably `42` or a count if the program has been running). ##### Step 3: Find Where the Initial Value Lives in Flash Static variables that are initialized get their starting values from the `.data` section in flash. The startup code copies these values from flash to RAM before `main()` runs. Examine the disassembly to find data copy references. The initial value `42` (`0x2A`) is stored somewhere in flash. Use GDB to search: ```gdb (gdb) find /b 0x10000000, 0x10010000, 0x2a ``` This searches the flash region for the byte `0x2A`. You may get multiple hits — look for one that is in the data initialization area (typically near the end of the code section). ##### Step 4: Confirm the Address Once you identify a candidate address, verify it by examining the surrounding bytes: ```gdb (gdb) x/8xb ``` The `0x2A` byte at this address should be the initialization value for our static variable. ##### Step 5: Calculate the File Offset The binary is loaded at base address `0x10000000`. To find the file offset: ``` file_offset = address - 0x10000000 ``` For example, if the initial value is at `0x10004xxx`: - File offset = `0x10004xxx` - `0x10000000` = `0x4xxx` ##### Step 6: Patch the Value with a Hex Editor 1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0014_static-variables\build\0x0014_static-variables.bin` 2. Press **Ctrl+G** (Go to offset) 3. Enter the calculated offset 4. You should see the byte `2A` at this position 5. Change `2A` to `64` (100 in decimal) 6. Click **File** ? **Save As** ? `0x0014_static-variables-h.bin` (in the same `build` directory) ##### Step 7: Convert to UF2 and Flash ```powershell cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0014_static-variables python ..\uf2conv.py build\0x0014_static-variables-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2 ``` 1. Hold BOOTSEL and plug in your Pico 2 2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive 3. Open your serial monitor ##### Step 8: Verify the Hack **Expected serial output:** ``` regular_fav_num: 42 static_fav_num: 100 ? Starts at 100 now! regular_fav_num: 42 static_fav_num: 101 regular_fav_num: 42 static_fav_num: 102 ... ``` The static variable now starts counting from 100 instead of 42! #### Expected Output After completing this exercise, you should be able to: - Use GDB `find` command to search for byte patterns in flash - Distinguish between RAM addresses (where the variable lives at runtime) and flash addresses (where the initial value is stored) - Calculate file offsets from memory addresses - Patch initialization values with a hex editor - Understand the `.data` section copy mechanism at startup #### Questions for Reflection ###### Question 1: Why does the initial value live in flash AND get copied to RAM? Why not just use flash directly? ###### Question 2: The static variable wraps around at 255 (since it's `uint8_t`). After patching the initial value to 100, after how many iterations will it overflow back to 0? ###### Question 3: If you also wanted to change the `regular_fav_num` constant from 42, would you patch the same area of the binary? Why or why not? ###### Question 4: What would happen if the `.data` section had TWO static variables — would their initial values be adjacent in flash? #### Tips and Hints - The `find` command in GDB can search for bytes, halfwords, or words in any memory range - Static variables with initial values are in `.data`; without initial values they're in `.bss` - The startup code (`crt0`) copies the entire `.data` section from flash to RAM before calling `main()` - HxD shows both hex and ASCII — the value `0x2A` is the ASCII character `*` #### Next Steps - Proceed to Exercise 2 to try a more complex hack (reversing GPIO logic) - Try patching the static variable to `0xFF` (255) and observe immediate overflow behavior - Look at the startup code in GDB to find the memcpy that copies `.data` from flash to RAM