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

## Week 10
Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics

### Exercise 2: Add a Third Command

#### Objective
Find the comparison instruction `cmp r4, #0x32` ('2') in the `0x0020_dynamic-conditionals` binary using GDB, locate the branch target for case '2', and modify existing code so that pressing '3' (0x33) moves the servo to the center position (90°) by patching one of the existing comparisons and its corresponding angle value to `0x42b40000` (90.0f).

#### Prerequisites
- Completed Week 10 tutorial (GDB and hex editor sections)
- `0x0020_dynamic-conditionals.elf` and `0x0020_dynamic-conditionals.bin` 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 SG90 servo motor connected on GPIO 6

#### Task Description
The program has two active commands: '1' (0x31) moves the servo 0°→180° and '2' (0x32) moves it 180°→0°. Adding a completely new code path would require rewriting branch offsets throughout the binary. Instead, you will repurpose the '2' command by changing its comparison value from `0x32` ('2') to `0x33` ('3') and patching both of its angle values to `0x42b40000` (90.0f), so pressing '3' moves the servo to center and holds it there.

#### 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\0x0020_dynamic-conditionals.elf
```

**Connect to target:**

```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```

##### Step 2: Find the Comparison Instructions

Disassemble main and locate both `cmp` instructions:

```gdb
(gdb) disassemble 0x10000234,+250
```

Look for:

```
cmp  r4, #0x31      ; compare with '1'
beq  <target1>
cmp  r4, #0x32      ; compare with '2'
beq  <target2>
```

Note the address of the `cmp r4, #0x32` instruction.

##### Step 3: Examine the Comparison Byte

The `cmp r4, #0x32` instruction encodes `0x32` as an immediate. Examine the instruction bytes:

```gdb
(gdb) x/2bx <address_of_cmp_0x32>
```

You should see a byte containing `0x32`.

##### Step 4: Find the Angle Values for Case '2'

Follow the `beq` target for case '2' and look for the literal pool loads:

```gdb
(gdb) x/wx <literal_pool_for_case2_angle1>
(gdb) x/wx <literal_pool_for_case2_angle2>
```

Case '2' loads `0x43340000` (180.0f) first, then `0x00000000` (0.0f).

##### Step 5: Calculate the File Offsets

```
file_offset = address - 0x10000000
```

Note offsets for:
1. The `0x32` byte in the `cmp` instruction
2. Both angle literal pool entries for case '2'

##### Step 6: Encode the New Values

| Patch Target     | Original         | New              | Purpose                   |
| ---------------- | ---------------- | ---------------- | ------------------------- |
| Compare byte     | `32`             | `33`             | Match '3' instead of '2'  |
| Angle 1 (180.0f) | `00 00 34 43`   | `00 00 b4 42`   | 90.0f center position     |
| Angle 2 (0.0f)   | `00 00 00 00`   | `00 00 b4 42`   | 90.0f center position     |

##### Step 7: Patch with HxD

1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals\build\0x0020_dynamic-conditionals.bin`
2. Press **Ctrl+G** and go to the compare byte offset
3. Change `32` to `33`
4. Go to the first angle offset for case '2' and replace `00 00 34 43` with `00 00 b4 42`
5. Go to the second angle offset for case '2' and replace `00 00 00 00` with `00 00 b4 42`

###### Question 1: Why do we set both angle values to 90.0f instead of just one?

##### Step 8: Save and Convert

1. Click **File** → **Save As** → `0x0020_dynamic-conditionals-h.bin`

```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals
python ..\uf2conv.py build\0x0020_dynamic-conditionals-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 behavior:**
- Press '1' → servo sweeps 0° to 180° (unchanged)
- Press '3' → servo moves to **90° center** and stays
- Press '2' → now falls through to default "??" (no longer mapped)

#### Expected Output

After completing this exercise, you should be able to:
- Locate and patch comparison immediate values in ARM Thumb instructions
- Repurpose existing code paths instead of adding new ones
- Understand how `cmp` immediates are encoded in the instruction stream
- Combine multiple patches (comparison + data) for a single behavior change

#### Questions for Reflection

###### Question 1: Why is it easier to repurpose an existing command than to add a truly new third code path in the binary?

###### Question 2: The `cmp` instruction uses an 8-bit immediate field. What range of ASCII characters could you use as command keys?

###### Question 3: After your patch, pressing '2' now triggers the default "??" branch. Could you keep both '2' AND '3' working? What would that require?

###### Question 4: What would happen if you changed the comparison to `0x00`? Could a user ever trigger that command via `getchar()`?

#### Tips and Hints
- The `cmp rN, #imm8` instruction in Thumb has the immediate in the lower byte of the instruction word
- IEEE-754 for 90.0f: `0x42b40000` → little-endian `00 00 b4 42`
- Be careful not to confuse literal pool entries between case '1' and case '2' — trace the branch targets carefully
- The `getchar()` function reads one byte from UART, so any byte value 0x00-0xFF is theoretically possible
