mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-04-01 17:10:20 +02:00
158 lines
5.9 KiB
Markdown
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
|