# 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 ### Non-Credit Practice 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 ``` You should see `0x43340000` (180.0f in IEEE-754). ```gdb (gdb) x/wx ``` 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
` in GDB to view several literal pool words at once