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

158 lines
5.9 KiB
Markdown

# 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 <candidate_address>
```
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