# 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 1: Change Servo Angle Range

#### Objective
Find the IEEE-754 floating-point value `0x43340000` (180.0f) in the `0x0020_dynamic-conditionals` binary using GDB, calculate the file offset, patch it to `0x43070000` (135.0f) using a hex editor, then find and patch the `0x00000000` (0.0f) value to `0x42340000` (45.0f), and verify on hardware that the servo now sweeps from 45° to 135° instead of 0° to 180°.

#### 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 uses `servo_set_angle(0.0f)` and `servo_set_angle(180.0f)` to sweep the servo across its full range. The float values `0.0` (`0x00000000`) and `180.0` (`0x43340000`) are loaded from the literal pool into registers before the `bl servo_set_angle` calls. You will locate these values in the disassembly, find the corresponding bytes in the `.bin` file, and patch them to `45.0` (`0x42340000`) and `135.0` (`0x43070000`) so the servo sweeps a narrower 90° range centered at 90°.

#### 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 servo_set_angle Calls

Disassemble main and look for the `servo_set_angle` calls:

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

Look for instruction patterns like:

```
ldr  r0, [pc, #offset]     ; load float from literal pool
bl   servo_set_angle
```

There will be multiple pairs — one loading `0x00000000` (0.0f) and another loading `0x43340000` (180.0f).

##### Step 3: Examine the Literal Pool Values

Once you find the `ldr r0, [pc, #offset]` instructions, examine the literal pool entries they reference:

```gdb
(gdb) x/wx <literal_pool_address_for_180>
```

You should see `0x43340000` (180.0f in IEEE-754).

```gdb
(gdb) x/wx <literal_pool_address_for_0>
```

You should see `0x00000000` (0.0f in IEEE-754).

##### Step 4: Calculate the File Offsets

```
file_offset = literal_pool_address - 0x10000000
```

Note the file offsets for both 4-byte words.

##### Step 5: Encode the New Values

**IEEE-754 Encoding:**

| Angle | IEEE-754 Hex   | Little-Endian Bytes |
| ----- | -------------- | ------------------- |
| 0.0f  | `0x00000000`   | `00 00 00 00`       |
| 45.0f | `0x42340000`   | `00 00 34 42`       |
| 135.0f| `0x43070000`   | `00 00 07 43`       |
| 180.0f| `0x43340000`   | `00 00 34 43`       |

##### Step 6: 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 enter the file offset for the 180.0f value
3. You should see: `00 00 34 43`
4. Replace with: `00 00 07 43` (135.0f)
5. Press **Ctrl+G** and enter the file offset for the 0.0f value
6. You should see: `00 00 00 00`
7. Replace with: `00 00 34 42` (45.0f)

###### Question 1: How many literal pool entries reference `0x43340000`? Do you need to patch all of them?

##### Step 7: 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 8: 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 servo behavior:**
- Press '1' → servo sweeps from **45°** to **135°** (was 0° to 180°)
- Press '2' → servo sweeps from **135°** to **45°** (was 180° to 0°)
- The total sweep range should be noticeably smaller

#### Expected Output

After completing this exercise, you should be able to:
- Locate IEEE-754 floating-point values in the literal pool
- Understand the IEEE-754 single-precision encoding format
- Patch floating-point angle constants in embedded firmware
- Calculate file offsets from memory addresses

#### Questions for Reflection

###### Question 1: The value `180.0f` is encoded as `0x43340000` in IEEE-754. Break this down: what are the sign bit, exponent, and mantissa fields?

###### Question 2: Why is `0.0f` stored as `0x00000000` and not some other pattern? What makes zero special in IEEE-754?

###### Question 3: If you wanted to set the servo to exactly 90° (center), what IEEE-754 hex value would you use? Show the calculation.

###### Question 4: Could the compiler optimize `0.0f` differently — for example, using `movs r0, #0` instead of a literal pool load? How would that affect your patching strategy?

#### Tips and Hints
- IEEE-754 for 90.0f: sign=0, exponent=127+6=133=0x85, mantissa=0x340000 → `0x42b40000`
- There may be multiple references to `0x43340000` in the literal pool — the case '1' and case '2' branches each load both angles
- Be careful with `0x00000000` — make sure you are patching a float literal pool entry and not zeroed data
- Use `x/4wx <address>` in GDB to view several literal pool words at once
