# Embedded Systems Reverse Engineering [Repository](https://github.com/mytechnotalent/Embedded-Hacking) ## Week 9 Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics ### Non-Credit Practice Exercise 3: Add a Fixed Temperature Offset #### Objective Patch both the `vfma.f32` instruction at file offset `0x414` and the scaling constant at `0x42C` to replace the multiply-add with a simple add of `10.0f`, causing every temperature reading to be increased by exactly 10°C, and verify on hardware. #### Prerequisites - Completed Week 9 tutorial and Exercise 2 - `0x001a_operators.elf` and `0x001a_operators.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 DHT11 sensor connected #### Task Description The temperature calculation uses `vfma.f32 s15, s13, s11` which computes `s15 = s15 + (s13 × s11)` where `s11 = 0.1f`. You will make TWO patches: (1) change the `vfma.f32` instruction to `vadd.f32` so it performs addition instead of multiply-add, and (2) change the constant from `0.1f` to `10.0f`. The result: every temperature reading will have 10°C added to it. This exercise teaches ARM floating-point instruction encoding and multi-site patching. #### 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\0x001a_operators.elf ``` **Connect to target:** ```gdb (gdb) target remote :3333 (gdb) monitor reset halt ``` ##### Step 2: Verify the Current Instructions Examine the floating-point instructions near the temperature calculation: ```gdb (gdb) x/4bx 0x10000414 ``` Output: ``` 0x10000414: 0xe6 0xee 0xa5 0x7a ``` This is `vfma.f32 s15, s13, s11` — the temperature fused multiply-add. ##### Step 3: Verify the Current Constant ```gdb (gdb) x/wx 0x1000042c ``` Output: ``` 0x1000042c: 0x3dcccccd ``` This is `0.1f`. ##### Step 4: Understand the Two Patches **Patch 1 — Instruction at offset `0x414`:** | Original | Bytes (LE) | New | Bytes (LE) | | --------------------------- | --------------- | --------------------------- | --------------- | | `vfma.f32 s15, s13, s11` | `e6 ee a5 7a` | `vadd.f32 s15, s15, s11` | `b4 ee a5 7a` | > 🔍 Only the first two bytes change: `e6 ee` → `b4 ee`. The operand bytes `a5 7a` stay the same. **Patch 2 — Constant at offset `0x42C`:** | Original | Hex | LE Bytes | New | Hex | LE Bytes | | -------- | ------------ | --------------- | ----- | ------------ | --------------- | | 0.1f | `0x3dcccccd` | `cd cc cc 3d` | 10.0f | `0x41200000` | `00 00 20 41` | ##### Step 5: Patch the Instruction with HxD 1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators\build\0x001a_operators.bin` 2. Press **Ctrl+G** and enter offset: `414` 3. You should see: `e6 ee a5 7a` 4. Change the first two bytes: `e6 ee` → `b4 ee` 5. Result should be: `b4 ee a5 7a` ##### Step 6: Patch the Constant with HxD 1. Press **Ctrl+G** and enter offset: `42C` 2. You should see: `cd cc cc 3d` (or `cc cc cc 3d`) 3. Replace all 4 bytes with: `00 00 20 41` ##### Step 7: Save and Convert 1. Click **File** → **Save As** → `0x001a_operators-h.bin` ```powershell cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators python ..\uf2conv.py build\0x001a_operators-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 serial monitor:** - All operator values remain unchanged (50, 5, 0, 0, 12, 11) - Temperature should now read approximately **10°C higher** than the real temperature - Humidity will also be affected (the constant is shared) > ⚠️ **Note:** Since the constant at `0x42C` is shared between the humidity `vfma.f32` at `0x410` and the temperature one at `0x414`, changing it to `10.0f` will also affect humidity. The humidity instruction still uses `vfma` (multiply-add), so it will compute `humidity_int + (decimal × 10.0)` — producing very large humidity values. #### Expected Output After completing this exercise, you should be able to: - Distinguish between `vfma.f32` (multiply-add) and `vadd.f32` (add) encodings - Perform multi-site patches in a single binary - Understand how shared constants affect multiple code paths - Predict the side effects of patching shared data #### Questions for Reflection ###### Question 1: Why did we need to change BOTH the instruction AND the constant? What would happen if you only changed the constant to `10.0f` but left the `vfma.f32` instruction unchanged? ###### Question 2: The humidity `vfma.f32` at offset `0x410` was NOT changed to `vadd`. With the constant now set to `10.0f`, what formula does the humidity instruction compute? If the raw humidity integer is 51 and decimal is 0, what value would it display? ###### Question 3: If you wanted to add 10°C to temperature WITHOUT affecting humidity, you would need to change both instructions. What bytes would you write at offset `0x410` to change the humidity `vfma` to `vadd` as well, and what constant would preserve the original humidity calculation? ###### Question 4: The `vadd.f32 s15, s15, s11` encoding is `b4 ee a5 7a`. In the original `vfma.f32 s15, s13, s11` (`e6 ee a5 7a`), why do only the first two bytes differ? What do those bytes encode? #### Tips and Hints - Make BOTH patches before saving — if you only patch one, the results will be wrong - The `vfma` → `vadd` change only affects the first two bytes of the 4-byte instruction - `10.0f` in IEEE-754 is `0x41200000` — memorize this common value - Always start with a fresh copy of the `.bin` file if you need to redo the exercise - Compare the original and hacked serial output side by side to verify only temperature changed as expected