# 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

### Exercise 4: Find All printf Format Strings

#### Objective
Systematically search through the `0x001a_operators` binary using GDB and a hex editor to locate every `printf` format string, catalog their addresses, file offsets, contents, and purposes, and gain experience identifying data structures in compiled binaries.

#### Prerequisites
- Completed Week 9 tutorial (GDB section)
- `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)

#### Task Description
The `0x001a_operators` program contains multiple `printf` calls, each with a format string like `"arithmetic_operator: %d\r\n"`. These strings are stored in the `.rodata` section of flash memory. You will use GDB to trace each `printf` call to its format string argument, then verify the strings in HxD. You will also search for strings that are NOT directly referenced by `printf` (like the `"DHT11 read failed"` error message). This exercise builds your ability to map out all human-readable data in a binary.

#### 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: Disassemble Main to Find printf Calls

```gdb
(gdb) x/60i 0x10000234
```

Look for repeated patterns of:
```
ldr  r0, [pc, #offset]    ; Load format string address
movs r1, #value            ; Load the value to print
bl   printf                ; Call printf
```

Each `ldr r0` before a `bl printf` loads the format string address from the literal pool.

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

Find the literal pool after the loop branch (typically after the `b.n` instruction). Examine the word values:

```gdb
(gdb) x/10wx <literal_pool_start>
```

Each word that falls in the `0x10003xxx` range is likely a pointer to a string in `.rodata`.

##### Step 4: Read Each Format String

For each address found in the literal pool, use `x/s` to read the string:

```gdb
(gdb) x/s <address_from_literal_pool>
```

Document each one. You should find at least these format strings:
- `"arithmetic_operator: %d\r\n"`
- `"increment_operator: %d\r\n"`
- `"relational_operator: %d\r\n"`
- `"logical_operator: %d\r\n"`
- `"bitwise_operator: %d\r\n"`
- `"assignment_operator: %d\r\n"`
- `"Humidity: %.1f%%, Temperature: %.1f°C\r\n"`
- `"DHT11 read failed"`

##### Step 5: Build a String Catalog

Fill in a table like this (addresses will vary — use the ones you find):

| Address        | File Offset | String Content                          | Used By     |
| -------------- | ----------- | --------------------------------------- | ----------- |
| `0x10003xxx`   | `0x3xxx`    | `"arithmetic_operator: %d\r\n"`         | printf #1   |
| `0x10003xxx`   | `0x3xxx`    | `"increment_operator: %d\r\n"`          | printf #2   |
| `0x10003xxx`   | `0x3xxx`    | `"relational_operator: %d\r\n"`         | printf #3   |
| `0x10003xxx`   | `0x3xxx`    | `"logical_operator: %d\r\n"`            | printf #4   |
| `0x10003xxx`   | `0x3xxx`    | `"bitwise_operator: %d\r\n"`            | printf #5   |
| `0x10003xxx`   | `0x3xxx`    | `"assignment_operator: %d\r\n"`         | printf #6   |
| `0x10003xxx`   | `0x3xxx`    | `"Humidity: %.1f%%, Temperature: %.1f°C\r\n"` | printf #7 |
| `0x10003xxx`   | `0x3xxx`    | `"DHT11 read failed"`                   | puts        |

##### Step 6: Verify in HxD

1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators\build\0x001a_operators.bin`
2. For each string, press **Ctrl+G** and enter the file offset
3. Verify you can read the ASCII text in the right panel
4. Note how the strings are stored consecutively in memory, each terminated by `0x00`

##### Step 7: Search for Hidden Strings

Scroll through the `.rodata` region in HxD (typically starting around offset `0x3000`+) and look for any ASCII text in the right panel that you didn't find via `printf` calls. Library functions may have their own strings.

#### Expected Output

After completing this exercise, you should be able to:
- Trace `printf` calls to their format string arguments using GDB
- Read string addresses from literal pools
- Build a complete catalog of strings in a binary
- Navigate to specific offsets in a hex editor to verify string data

#### Questions for Reflection

###### Question 1: The format string `"Humidity: %.1f%%, Temperature: %.1f°C\r\n"` uses `%%` to print a literal percent sign. What would happen if you patched one of the `%` characters to a space (`0x20`)?

###### Question 2: If you patched the string `"arithmetic_operator: %d\r\n"` to `"HACKED_OPERATOR!: %d\r\n"` (same length, 27 characters + null), what would the serial output show? Would the actual computed value change?

###### Question 3: The strings are stored consecutively in `.rodata`. If you made `"arithmetic_operator: %d\r\n"` one byte longer, which string would be corrupted and how?

###### Question 4: Why does the compiler use `puts` instead of `printf` for `"DHT11 read failed"`? What's the difference between the two functions for strings with no format specifiers?

#### Tips and Hints
- Format strings always start with a printable ASCII character — look for bytes in the `0x20`-`0x7E` range
- The `\r\n` at the end of format strings shows up as bytes `0x0D 0x0A`
- Use HxD's **Search** → **Find** (Ctrl+F) with "Text string" mode to search for known text like "arithmetic"
- Strings in `.rodata` are typically 4-byte aligned, so there may be padding bytes (`0x00`) between them
- The `°` character in "°C" is a multi-byte UTF-8 sequence (`0xC2 0xB0`), not a single byte
