# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)

## Week 4
Variables in Embedded Systems: Debugging and Hacking Variables w/ GPIO Output Basics

### Exercise 2: Patch Binary to Change Variable Value

#### Objective
Use Ghidra's patching capabilities to modify the compiled binary, changing the value printed by the program from 43 to a different value of your choice, then convert and flash the modified binary to the Pico 2.

#### Prerequisites
- Completed Exercise 1 (binary imported and analyzed in Ghidra)
- Python installed for UF2 conversion
- `uf2conv.py` script available in your project directory
- Raspberry Pi Pico 2 connected via USB
- Serial monitor software (PuTTY, minicom, or screen)

#### Task Description
You will locate the instruction that loads the value 43 into a register, patch it to use a different value (70 in this example), export the modified binary, convert it to UF2 format, and flash it to verify the change.

#### Step-by-Step Instructions

##### Step 1: Open Your Ghidra Project

If you closed Ghidra from Exercise 1:
1. Launch `ghidraRun`
2. Open the project: `week04-ex01-intro-to-variables`
3. Double-click the binary file to open it

##### Step 2: Navigate to the Value Load Instruction

In Exercise 1, we found that `main()` calls `printf("age: %d\r\n", 0x2b)`.

**Find the assembly instruction:**
1. Click on the `main` function in the Symbol Tree
2. Look at the **Listing** window (assembly view)
3. Find the line with `movs r1, #0x2b`

The instruction should look like:
```assembly
10000xxx    21 2b    movs    r1, #0x2b
```

**What this instruction means:**
- Opcode: `21 2b` (encoded instruction bytes)
- Mnemonic: `movs r1, #0x2b`
- Operation: Move the immediate value 0x2b into register r1
- Register r1 will be used as the argument to printf

##### Step 3: Choose Your New Value

Let's change the value from `43` (0x2b) to `70` (0x46).

**Convert 70 to hexadecimal:**
- 70 ÷ 16 = 4 remainder 6
- Therefore: 70 decimal = 0x46 hexadecimal

You can verify this in Python:
```python
>>> hex(70)
'0x46'
>>> 0x46
70
```

##### Step 4: Patch the Instruction

Now we'll modify the binary:

1. **Right-click** on the instruction `movs r1, #0x2b`
2. Select **Patch Instruction**
3. A dialog appears showing the current instruction
4. Change `#0x2b` to `#0x46`
5. Press **Enter** or click **OK**

The instruction now reads:
```assembly
10000xxx    21 46    movs    r1, #0x46
```

**Visual confirmation:**
- The patched instruction should be highlighted (usually in red or orange)
- The bytes should change from `21 2b` to `21 46`
- The decompiled view should update to show `printf("age: %d\r\n", 0x46);`

##### Step 5: Verify the Patch in Decompile Window

Click on the `main` function again and check the **Decompile** window:

```c
int main(void)
{
    stdio_init_all();
    do {
        printf("age: %d\r\n", 0x46);  // Changed from 0x2b!
    } while (true);
}
```

Perfect! The decompiler recognized our patch.

##### Step 6: Export the Patched Binary

Now we need to save the modified binary:

1. Click **File** → **Export Program**
2. Set **Format** to: **Binary**
3. Navigate to your build directory:
   - `Embedded-Hacking\0x0005_intro-to-variables\build\`
4. Set **Filename** to: `0x0005_intro-to-variables-h.bin`
   - The `-h` suffix means "hacked"
5. Click **OK**

**Important:** Make sure you're exporting to the correct location!

##### Step 7: Convert to UF2 Format

The Pico 2 requires UF2 format. Open a terminal and run:

**Navigate to the project directory:**
```powershell
cd C:\path\to\Embedded-Hacking\0x0005_intro-to-variables
```

**Run the conversion:**
```powershell
python ..\uf2conv.py build\0x0005_intro-to-variables-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```

**Command breakdown:**
- `uf2conv.py` - The conversion script
- `--base 0x10000000` - XIP flash base address (where code runs from)
- `--family 0xe48bff59` - RP2350 family ID
- `--output build\hacked.uf2` - Output filename

**Expected output:**
```
Converting to uf2, output size: 57856, start address: 0x10000000
Wrote 57856 bytes to build\hacked.uf2
```

##### Step 8: Flash the Hacked Binary

**Enter bootloader mode:**
1. Disconnect your Pico 2 from USB
2. Hold down the **BOOTSEL** button
3. While holding BOOTSEL, plug in the USB cable
4. Release BOOTSEL
5. A drive called **RPI-RP2** appears

**Flash the binary:**
1. Open the RPI-RP2 drive
2. Drag and drop `build\hacked.uf2` onto the drive
3. The Pico will automatically reboot

##### Step 9: Verify the Changes

**Open your serial monitor:**

For PuTTY:
1. Select **Serial** connection type
2. Set the COM port (check Device Manager)
3. Set speed to **115200**
4. Click **Open**

For PowerShell:
```powershell
# Find the COM port
Get-PnpDevice -Class Ports | Where-Object {$_.FriendlyName -like "*USB Serial*"}

# Connect (replace COM3 with your port)
$port = new-Object System.IO.Ports.SerialPort COM3,115200,None,8,one
$port.Open()
while($true) { $port.ReadLine() }
```

**Expected output:**
```
age: 70
age: 70
age: 70
age: 70
...
```

🎉 **Success!** You've successfully patched a binary and changed its behavior!

#### Expected Output

After completing this exercise, you should:
- See `age: 70` printing instead of `age: 43`
- Have a patched binary file (`0x0005_intro-to-variables-h.bin`)
- Have a UF2 file (`hacked.uf2`)
- Understand the complete patching workflow

#### Questions for Reflection

###### Question 1: Why do we need to convert to UF2 format instead of flashing the raw .bin file?

###### Question 2: What is the significance of the base address 0x10000000 in the conversion command?

###### Question 3: What would happen if you patched the wrong instruction by mistake?

###### Question 4: How can you verify a patch was applied correctly before exporting?

#### Tips and Hints
- Always make a backup of the original binary before patching
- Use descriptive names like `-h` (hacked) or `-patch` for modified binaries
- Test your patches on hardware to ensure they work as expected
- If something goes wrong, you can always flash the original UF2 file
- Use `File → Export Program → Original File` to revert all patches

#### Next Steps
- Try patching to different values (100, 255, etc.)
- Proceed to Exercise 3 to learn about GPIO control
- Experiment with patching multiple values in the same binary

#### Additional Challenge
Instead of changing the value to 70, change it to 255 (0xFF) - the maximum value for a `uint8_t`. What do you observe? Now try changing it to 256 (0x100). What happens and why? (Hint: Think about the size limits of the instruction encoding.)
