Updated DS refs

This commit is contained in:
Kevin Thomas
2026-04-15 17:23:21 -04:00
parent 731800a12e
commit bc48a18731
210 changed files with 31410 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Basics
### Non-Credit Practice Exercise 1 Solution: Change the Sleep Duration
#### Answers
##### Sleep Duration Values
| Parameter | Original | Patched |
|---------------|-------------|-------------|
| Duration (ms) | 2000 | 5000 |
| Hex | 0x000007D0 | 0x00001388 |
| Little-endian | D0 07 00 00 | 88 13 00 00 |
##### Why a Literal Pool Is Needed
The value 2000 exceeds the 8-bit immediate range of `movs` (0255) and the 16-bit range is also impractical for a single-instruction load. The compiler stores `0x000007D0` in a **literal pool** near the function code and loads it with a `ldr r0, [pc, #offset]` instruction that reads the 32-bit word from the pool into `r0` before the `bl sleep_ms` call.
##### Patch Procedure
1. Find the literal pool entry containing `D0 07 00 00` in HxD
2. Replace with `88 13 00 00`
```
Before: D0 07 00 00 (2000)
After: 88 13 00 00 (5000)
```
##### Conversion and Flash
```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
```
##### Serial Output After Patch
```
arithmetic_operator: 50
increment_operator: 5
relational_operator: 0
logical_operator: 0
bitwise_operator: 12
assignment_operator: 11
Humidity: 51.0%, Temperature: 24.0°C
```
Output repeats every **5 seconds** instead of 2 seconds.
#### Reflection Answers
1. **Why can't 2000 be encoded as a movs immediate? What is the maximum value movs can hold?**
The `movs Rd, #imm8` instruction is a 16-bit Thumb encoding that has only 8 bits for the immediate value, giving a range of 0255. The value 2000 (`0x7D0`) is far beyond this range. Even the 32-bit Thumb-2 `movw` instruction can only encode 065535, which could handle 2000, but the compiler chose a literal pool approach. The literal pool is a general-purpose solution that works for any 32-bit value, including addresses and large constants.
2. **If you wanted to change the sleep to exactly 1 second (1000ms), what 4 bytes would you write in little-endian? Show your work.**
1000 decimal = `0x000003E8` hex. In little-endian byte order (LSB first): `E8 03 00 00`. Breakdown: byte 0 = `0xE8` (LSB), byte 1 = `0x03`, byte 2 = `0x00`, byte 3 = `0x00` (MSB).
3. **Could other code in the program reference the same literal pool entry containing 0x7D0? What would happen if it did?**
Yes, the compiler may share literal pool entries to save space. If another instruction also loads `0x7D0` from the same pool address (using its own `ldr rN, [pc, #offset]`), then patching that pool entry would change the value for ALL instructions that reference it. This is a risk with literal pool patching — you might unintentionally modify other parts of the program. To check, search for all `ldr` instructions whose PC-relative offset resolves to the same pool address.
4. **What would happen if you set sleep_ms to 0? Would the program crash or just run extremely fast?**
The program would not crash — `sleep_ms(0)` is a valid call that returns immediately. The loop would run as fast as the processor can execute it, printing operator values and reading the DHT11 sensor with no delay between iterations. The serial output would flood extremely quickly. However, the DHT11 sensor has a minimum sampling interval of about 1 second; reading it more frequently may return stale data or read errors ("DHT11 read failed"), but the program itself would continue running.
+141
View File
@@ -0,0 +1,141 @@
# 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 1: Change the Sleep Duration
#### Objective
Find the `sleep_ms(2000)` call in the `0x001a_operators` binary using GDB, identify the immediate value `0x7d0` (2000) being loaded into `r0`, calculate the file offset, patch it to `0x1388` (5000) using a hex editor, and verify on hardware that the serial output now prints every 5 seconds instead of every 2 seconds.
#### Prerequisites
- Completed Week 9 tutorial (GDB and hex editor sections)
- `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 program calls `sleep_ms(2000)` at the end of its main loop, causing a 2-second delay between each set of serial output. The value `2000` (`0x7D0`) is loaded into register `r0` before the `bl sleep_ms` call. You will locate this value in the disassembly, find the corresponding bytes in the `.bin` file, and patch them to `5000` (`0x1388`) so the loop runs every 5 seconds instead.
#### 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: Find the sleep_ms Call
Disassemble main and look for the `sleep_ms` call:
```gdb
(gdb) x/60i 0x10000234
```
Look for an instruction pattern like:
```
ldr r0, =0x7d0 ; 2000 milliseconds
bl sleep_ms
```
The value `0x7d0` will be loaded from the literal pool.
##### Step 3: Examine the Literal Pool Value
Once you find the `ldr r0, [pc, #offset]` instruction, examine the literal pool entry it references:
```gdb
(gdb) x/wx <literal_pool_address>
```
You should see `0x000007d0` (2000 in hex).
##### Step 4: Calculate the File Offset
```
file_offset = literal_pool_address - 0x10000000
```
Note the file offset of the 4-byte word containing `0x7d0`.
##### Step 5: Encode the New Value
The new value `5000` in hex is `0x1388`. In little-endian byte order:
| Value | Hex | Little-Endian Bytes |
| ----- | ---------- | ------------------- |
| 2000 | `0x000007D0` | `D0 07 00 00` |
| 5000 | `0x00001388` | `88 13 00 00` |
##### Step 6: Patch 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 the file offset you calculated
3. You should see: `D0 07 00 00`
4. Replace with: `88 13 00 00`
##### 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:**
- Output should now appear every **5 seconds** instead of every 2 seconds
- All operator values should remain unchanged (50, 5, 0, 0, 12, 11)
#### Expected Output
After completing this exercise, you should be able to:
- Locate literal pool values referenced by `ldr` instructions
- Understand little-endian byte ordering for 32-bit values
- Patch timing constants in embedded firmware
- Calculate file offsets from memory addresses
#### Questions for Reflection
###### Question 1: The value `2000` is stored in the literal pool as a 32-bit word, not as an immediate in the instruction. Why can't `2000` be encoded as an immediate in a single `movs` instruction?
###### Question 2: If you wanted to change the delay to exactly 1 second (1000ms = `0x3E8`), what bytes would you write in little-endian order?
###### Question 3: The literal pool value is shared — could other code in the binary also reference this same `0x7D0` value? How would you check?
###### Question 4: What would happen if you changed the sleep value to `0` (`00 00 00 00`)? Would the program crash or just run extremely fast?
#### Tips and Hints
- `movs` can only encode immediates 0-255; values larger than 255 must be loaded from the literal pool via `ldr`
- Always verify the bytes BEFORE patching — make sure you see `D0 07 00 00` at your calculated offset
- The literal pool is typically right after the function's `b.n` (loop branch) instruction
- Use a stopwatch or count "one-one-thousand" to verify the timing change
+66
View File
@@ -0,0 +1,66 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Basics
### Non-Credit Practice Exercise 2 Solution: Invert the Temperature Reading
#### Answers
##### IEEE-754 Sign Bit Flip
| Value | IEEE-754 Hex | Little-Endian Bytes | Sign Bit |
|---------|--------------|--------------------|---------|
| +0.1f | 0x3DCCCCCD | CD CC CC 3D | 0 |
| -0.1f | 0xBDCCCCCD | CD CC CC BD | 1 |
Only the **last byte** changes in little-endian: `3D``BD`. This flips bit 31 (the IEEE-754 sign bit) from 0 to 1, negating the value.
##### Patch at File Offset 0x42C
```
Offset 0x42C:
Before: CD CC CC 3D (+0.1f)
After: CD CC CC BD (-0.1f)
```
Only 1 byte changes: offset `0x42F` from `0x3D` to `0xBD`.
##### How the Temperature Changes
The DHT11 returns raw integer and decimal parts (e.g., integer=24, decimal=0). The firmware computes:
```
temperature = integer_part + (decimal_part × 0.1f)
```
With `vfma.f32 s15, s13, s11`: result = s15 + (s13 × s11) = integer + (decimal × 0.1f)
After patching to -0.1f: result = integer + (decimal × -0.1f)
For a reading of 24.5°C: original = 24 + (5 × 0.1) = 24.5°C, patched = 24 + (5 × -0.1) = 23.5°C
For a reading of 24.0°C: integer=24, decimal=0, so 24 + (0 × -0.1) = 24.0°C (unchanged when decimal is 0).
##### Serial Output After Patch
```
Humidity: 51.0%, Temperature: 23.5°C
```
(Temperature decimal contribution is inverted; effect depends on the decimal component.)
#### Reflection Answers
1. **Why does changing the byte from 0x3D to 0xBD negate the float? What specific bit is being flipped?**
In IEEE-754 single-precision format, bit 31 is the **sign bit**: 0 = positive, 1 = negative. The byte `0x3D` in binary is `0011 1101` and `0xBD` is `1011 1101` — only bit 7 of that byte differs, which corresponds to bit 31 of the 32-bit float (since it's the MSB of the last byte in little-endian storage). The exponent and mantissa bits remain identical, so the magnitude stays exactly `0.1` — only the sign changes.
2. **Why does patching one constant affect both humidity AND temperature? They use different vfma instructions (at 0x410 and 0x414) — so why are both affected?**
Both `vfma` instructions at `0x410` (humidity) and `0x414` (temperature) load the scaling constant from the **same literal pool entry** at offset `0x42C`. The compiler recognized that both computations use the same `0.1f` value and stored it only once to save space. Both `vldr s11, [pc, #offset]` instructions resolve to address `0x1000042C`. So patching that single 4-byte value changes the scaling factor for both humidity and temperature simultaneously.
3. **What is the IEEE-754 encoding of 0.5f? If the raw sensor decimal reading was 8, what would the computed value be with 0.5f instead of 0.1f?**
0.5f in IEEE-754: sign=0, exponent=126 (`0x7E`), mantissa=0. Hex = `0x3F000000`. Little-endian bytes: `00 00 00 3F`. With a raw decimal reading of 8: `8 × 0.5 = 4.0`. So if the integer part was 24, the result would be `24 + 4.0 = 28.0°C` instead of `24 + 0.8 = 24.8°C`.
4. **Could you achieve the same inversion by patching the vfma instruction instead of the constant? What instruction change would work?**
Yes. You could change `vfma.f32` (fused multiply-add: d = d + a×b) to `vfms.f32` (fused multiply-subtract: d = d - a×b). This would compute `temperature = integer - (decimal × 0.1f)` instead of `integer + (decimal × 0.1f)`, achieving the same sign inversion on the decimal contribution. The instruction encoding difference between `vfma` and `vfms` is typically a single bit in the opcode. However, this approach is more complex than simply flipping the sign bit of the constant.
+136
View File
@@ -0,0 +1,136 @@
# 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 2: Invert the Temperature Reading
#### Objective
Using GDB to locate the IEEE-754 scaling constant `0.1f` at file offset `0x42C`, patch it to `-0.1f` using a hex editor, and verify on hardware that the serial output now displays negative temperature values.
#### Prerequisites
- Completed Week 9 tutorial (GDB, Ghidra, and hex editor sections)
- `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 DHT11 driver uses a scaling constant of `0.1f` stored at address `0x1000042C` (file offset `0x42C`) to convert raw sensor data into human-readable values. By changing this constant to `-0.1f`, you will invert the decimal component of the temperature calculation, causing the reported temperature to drop. This exercise teaches IEEE-754 float encoding and how a single 4-byte patch can dramatically change sensor behavior.
#### 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 Scaling Constant
Examine the float constant at the known address:
```gdb
(gdb) x/wx 0x1000042c
```
Output:
```
0x1000042c: 0x3dcccccd
```
This is `0.1f` in IEEE-754 encoding (approximately — the repeating binary fraction makes it `0x3dcccccd`).
##### Step 3: Understand the IEEE-754 Encoding
**Current value (0.1f):**
| Field | Bits | Value |
| -------- | ---------- | ----- |
| Sign | `0` | Positive |
| Exponent | `01111011` | 123 (biased) |
| Mantissa | `10011001100110011001101` | ~1.6 |
**New value (-0.1f):**
- Flip only the sign bit (bit 31) from `0` to `1`
- `0x3dcccccd``0xbdcccccd`
| Value | Hex | Little-Endian Bytes |
| ------ | ------------ | ------------------- |
| 0.1f | `0x3dcccccd` | `cd cc cc 3d` |
| -0.1f | `0xbdcccccd` | `cd cc cc bd` |
> 💡 **Key insight:** To negate an IEEE-754 float, you only need to flip the most significant bit. In little-endian, this is the **last** byte — change `3d` to `bd`.
##### Step 4: Patch 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: `42C`
3. You should see: `cd cc cc 3d` (or `cc cc cc 3d`)
4. Replace with: `cd cc cc bd` (or `cc cc cc bd`)
> ⚠️ **Note:** The exact bytes may be `cc cc cc 3d` or `cd cc cc 3d` depending on compiler rounding. Just change the last byte from `3d` to `bd`.
##### Step 5: 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 6: 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 display with an inverted decimal component
- Humidity will also be affected (same constant is shared)
#### Expected Output
After completing this exercise, you should be able to:
- Decode and encode IEEE-754 floating-point values
- Understand that flipping one bit (sign bit) negates a float
- Patch floating-point constants in compiled binaries
- Predict how a constant change propagates through calculations
#### Questions for Reflection
###### Question 1: Why does changing one byte (`3d` → `bd`) negate the entire float value? What does the sign bit (bit 31) control in IEEE-754?
###### Question 2: The scaling constant `0.1f` is used by BOTH the humidity and temperature `vfma.f32` instructions. Why does patching this single constant affect both readings?
###### Question 3: If you wanted to change the constant to `0.5f` (`0x3f000000`, little-endian `00 00 00 3f`) instead of `-0.1f`, how would the temperature reading change? If the raw decimal part is 8, what would the new output be?
###### Question 4: Could you achieve negative temperature by patching the `vfma.f32` instruction itself instead of the constant? What instruction might you replace it with?
#### Tips and Hints
- IEEE-754 sign bit is the MSB (bit 31) — `0` = positive, `1` = negative
- In little-endian, the sign bit is in the **last** (highest address) byte
- Use an online IEEE-754 converter to verify your understanding
- If the output looks completely wrong (NaN, inf), you may have changed the wrong byte — start over with a fresh copy of the `.bin` file
+74
View File
@@ -0,0 +1,74 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Basics
### Non-Credit Practice Exercise 3 Solution: Add a Fixed Temperature Offset
#### Answers
##### Two Patches Required
This exercise requires **two** simultaneous patches to add a fixed +10°C offset to every temperature reading.
##### Patch 1: Instruction at Offset 0x414
Change `vfma.f32` to `vadd.f32`:
| Item | Original | Patched |
|------------|------------------------------|------------------------------|
| Instruction | vfma.f32 s15, s13, s11 | vadd.f32 s15, s15, s11 |
| Encoding | e6 ee a5 7a | b4 ee a5 7a |
| Operation | s15 = s15 + (s13 × s11) | s15 = s15 + s11 |
```
Offset 0x414:
Before: E6 EE A5 7A (vfma.f32)
After: B4 EE A5 7A (vadd.f32)
```
Only the first two bytes change: `E6 EE``B4 EE`.
##### Patch 2: Constant at Offset 0x42C
Change the constant from 0.1f to 10.0f:
| Value | IEEE-754 Hex | Little-Endian Bytes |
|--------|--------------|--------------------|
| 0.1f | 0x3DCCCCCD | CD CC CC 3D |
| 10.0f | 0x41200000 | 00 00 20 41 |
```
Offset 0x42C:
Before: CD CC CC 3D (0.1f)
After: 00 00 20 41 (10.0f)
```
##### Why Both Patches Are Needed
- **Original:** `vfma.f32` computes `temp = integer + (decimal × 0.1f)` — fractional scaling
- **After both patches:** `vadd.f32` computes `temp = integer + 10.0f` — fixed offset addition
- **If only constant changed:** `vfma.f32` would compute `temp = integer + (decimal × 10.0f)` — amplified decimal, not a fixed offset
##### Serial Output After Patch
```
Humidity: 51.0%, Temperature: 34.0°C
```
(Original 24.0°C + 10.0°C offset = 34.0°C)
#### Reflection Answers
1. **Why are both patches needed? What would happen if you only changed the constant to 10.0f but left vfma unchanged?**
If you only changed `0.1f` to `10.0f` but left `vfma.f32`, the computation would be `temp = integer + (decimal × 10.0f)`. For a reading of 24.5°C (integer=24, decimal=5): result = 24 + (5 × 10.0) = 74.0°C — wildly incorrect. The `vfma` instruction multiplies two operands and adds, so the constant serves as a multiplier for the decimal part. By changing to `vadd.f32`, we eliminate the multiplication entirely and just add the constant directly to the integer, giving `24 + 10.0 = 34.0°C`.
2. **The humidity vfma instruction at 0x410 was NOT changed. Both vfma instructions (0x410 and 0x414) load the same 0.1f constant from 0x42C. With the constant now 10.0f, what happens to the humidity computation?**
The humidity `vfma` at `0x410` now computes `hum = integer + (decimal × 10.0f)`. If the humidity decimal part is 0 (e.g., raw humidity = 51.0%), then `51 + (0 × 10.0) = 51.0%` — unchanged. But if the decimal part is non-zero (e.g., raw = 51.3%, decimal=3), the result would be `51 + (3 × 10.0) = 81.0%` — grossly incorrect. The DHT11 sensor's humidity decimal is often 0, so you might not notice the bug immediately, but it's a latent defect.
3. **If you wanted to add a 10°C offset to temperature WITHOUT affecting humidity, what additional patch(es) would you need?**
You would need to ensure humidity still uses the original `0.1f` scaling. Options: (1) Also change the humidity `vfma` at `0x410` to `vadd.f32` and create a separate literal pool entry with `0.1f` for it — but this requires finding free space. (2) More practically, place a second copy of `0.1f` (`CD CC CC 3D`) in unused space in the binary, and redirect the humidity `vldr` instruction's PC-relative offset to point to that new location instead of `0x42C`. (3) Alternatively, NOP out the humidity `vfma` entirely if the decimal contribution is negligible.
4. **Why do only the first 2 bytes differ between vfma and vadd? What do the last 2 bytes encode?**
In the ARM VFPv4 encoding, the first two bytes (`E6 EE` vs `B4 EE`) contain the **opcode** that distinguishes the operation type (fused multiply-add vs addition). The last two bytes (`A5 7A`) encode the **operand registers**: the source and destination VFP registers (s15, s13, s11). Since both instructions operate on the same registers, the operand encoding is identical. Only the operation code changes — this is a characteristic of the ARM instruction set where opcode and operand fields are cleanly separated.
+152
View File
@@ -0,0 +1,152 @@
# 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
+72
View File
@@ -0,0 +1,72 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Basics
### Non-Credit Practice Exercise 4 Solution: Find All printf Format Strings
#### Answers
##### Complete String Catalog
| # | String | Type | Used By |
|---|-----------------------------------------------------|---------------|-------------|
| 1 | `"arithmetic_operator: %d\r\n"` | Format string | printf #1 |
| 2 | `"increment_operator: %d\r\n"` | Format string | printf #2 |
| 3 | `"relational_operator: %d\r\n"` | Format string | printf #3 |
| 4 | `"logical_operator: %d\r\n"` | Format string | printf #4 |
| 5 | `"bitwise_operator: %d\r\n"` | Format string | printf #5 |
| 6 | `"assignment_operator: %d\r\n"` | Format string | printf #6 |
| 7 | `"Humidity: %.1f%%, Temperature: %.1f°C\r\n"` | Format string | printf #7 |
| 8 | `"DHT11 read failed\r\n"` | Plain string | puts |
##### Format Specifier Analysis
| Specifier | Meaning | Used In |
|-----------|------------------------------------------|---------------|
| `%d` | Signed decimal integer | Strings 16 |
| `%.1f` | Float with 1 decimal place | String 7 |
| `%%` | Literal percent sign (escaped) | String 7 |
| `\r\n` | Carriage return + line feed (0x0D 0x0A) | All strings |
| `°C` | UTF-8 degree symbol + C (0xC2 0xB0 0x43)| String 7 |
##### Expected Operator Output Values
| Operator | Expression | Value | Explanation |
|-----------------------|------------------------|-------|------------------------------------|
| arithmetic_operator | 5 × 10 | 50 | Multiplication |
| increment_operator | x++ (x=5) | 5 | Post-increment returns old value |
| relational_operator | 6 > 10 | 0 | False |
| logical_operator | (6>10) && (10>6) | 0 | Short-circuit: first operand false |
| bitwise_operator | 6 << 1 | 12 | Left shift = multiply by 2 |
| assignment_operator | 6 + 5 | 11 | Addition assignment |
##### GDB Search Commands
```gdb
(gdb) x/20s 0x10003e00
(gdb) x/50s 0x10003d00
```
##### Special Byte Sequences in Strings
| Sequence | Bytes | Meaning |
|----------|------------|---------------------|
| `\r\n` | 0x0D 0x0A | CRLF line ending |
| `%%` | 0x25 0x25 | Literal % character |
| `°` | 0xC2 0xB0 | UTF-8 degree symbol |
#### Reflection Answers
1. **The humidity/temperature format string contains %%. What would happen if you patched one of the % characters to a different character (e.g., changed %% to %,)?**
The `%%` escape produces a literal `%` in the output. If you change it to `%,` (bytes `25 2C`), `printf` would interpret `%,` as the start of a format specifier where `,` is the conversion character. Since `,` is not a valid `printf` conversion specifier, the behavior is **undefined** — most implementations would either print garbage, skip it, or consume the next argument from the stack incorrectly. This could corrupt the remaining output or even crash if `printf` tries to read a non-existent argument.
2. **If you changed "arithmetic_operator" to "hacked_operator__" (same length) in the binary, what would the serial output look like? Would the computed value change?**
The serial output would show `hacked_operator__: 50` instead of `arithmetic_operator: 50`. The **computed value (50) would not change** — it's determined by the actual multiplication instruction in the code, not by the format string. The format string is just a label for display purposes. The `%d` specifier still reads the same `r1` register value (50) passed as the second argument to `printf`.
3. **What happens if you make a format string 1 byte longer (e.g., add a character)? Where would the extra byte be stored?**
The extra byte would overwrite the **null terminator** (`0x00`) of the current string, and the byte after that is the first byte of the next consecutive string in `.rodata`. This effectively merges the two strings: `printf` would continue reading past the intended end into the next string's data until it finds another `0x00`. The output would include garbage characters from the adjacent string. If the adjacent data happens to contain `%` followed by a valid specifier, `printf` might try to read additional arguments from the stack, potentially causing a crash or information leak.
4. **The "DHT11 read failed" message uses puts instead of printf. Why would the compiler choose puts over printf for this particular string?**
The compiler (with optimizations enabled) recognizes that `printf("DHT11 read failed\r\n")` has **no format specifiers** — it's a plain string with no `%d`, `%s`, `%f`, etc. Since no formatting is needed, the compiler optimizes it to `puts("DHT11 read failed")` (which automatically appends a newline). This is a common GCC optimization (`-fprintf-return-value`) because `puts` is simpler and faster than `printf` — it doesn't need to parse the format string looking for specifiers. The `\r\n` may be handled slightly differently depending on the implementation, but the key insight is that the compiler automatically selects the more efficient function.
+140
View File
@@ -0,0 +1,140 @@
# 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 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
Binary file not shown.
File diff suppressed because it is too large Load Diff
+79
View File
@@ -0,0 +1,79 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Background grid decoration -->
<g opacity="0.06">
<line x1="0" y1="100" x2="1200" y2="100" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="200" x2="1200" y2="200" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="300" x2="1200" y2="300" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="400" x2="1200" y2="400" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="500" x2="1200" y2="500" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="600" x2="1200" y2="600" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="700" x2="1200" y2="700" stroke="#00ff41" stroke-width="1"/>
<line x1="200" y1="0" x2="200" y2="800" stroke="#00ff41" stroke-width="1"/>
<line x1="400" y1="0" x2="400" y2="800" stroke="#00ff41" stroke-width="1"/>
<line x1="600" y1="0" x2="600" y2="800" stroke="#00ff41" stroke-width="1"/>
<line x1="800" y1="0" x2="800" y2="800" stroke="#00ff41" stroke-width="1"/>
<line x1="1000" y1="0" x2="1000" y2="800" stroke="#00ff41" stroke-width="1"/>
</g>
<!-- Hex rain decoration -->
<g opacity="0.04" font-family="'Courier New',monospace" font-size="14" fill="#00ff41">
<text x="50" y="80">4F 70 65 6E 4F 43 44</text>
<text x="900" y="120">10 00 02 34 08 B5 01</text>
<text x="150" y="180">47 44 42 20 52 45 56</text>
<text x="800" y="240">20 08 20 00 FF AA 00</text>
<text x="80" y="350">52 50 32 33 35 30 00</text>
<text x="950" y="380">0A 0A 0F 12 12 1A 1A</text>
<text x="100" y="520">41 52 4D 76 38 2D 4D</text>
<text x="870" y="560">00 FF 41 00 D4 FF 88</text>
<text x="60" y="680">47 48 49 44 52 41 00</text>
<text x="920" y="720">FF 00 40 C0 C0 C0 00</text>
</g>
<!-- Corner accents -->
<polyline points="30,30 30,80 80,80" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
<polyline points="1170,30 1170,80 1120,80" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
<polyline points="30,770 30,720 80,720" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
<polyline points="1170,770 1170,720 1120,720" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
<!-- Top accent line -->
<rect x="100" y="140" width="1000" height="2" fill="#00ff41" opacity="0.4"/>
<!-- Course Title -->
<text x="600" y="210" text-anchor="middle" font-family="'Courier New',monospace" font-size="56" font-weight="bold" fill="#00ff41">Embedded Systems</text>
<text x="600" y="278" text-anchor="middle" font-family="'Courier New',monospace" font-size="56" font-weight="bold" fill="#00ff41">Reverse Engineering</text>
<!-- Divider -->
<rect x="300" y="310" width="600" height="2" fill="#00d4ff" opacity="0.6"/>
<!-- Week Number -->
<text x="600" y="380" text-anchor="middle" font-family="'Courier New',monospace" font-size="42" font-weight="bold" fill="#00d4ff">// WEEK 09</text>
<!-- Week Topic -->
<text x="600" y="440" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">Operators in Embedded Systems:</text>
<text x="600" y="478" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">Debugging and Hacking Operators</text>
<text x="600" y="516" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">w/ DHT11 Sensor Single-Wire Protocol</text>
<!-- Bottom accent line -->
<rect x="100" y="570" width="1000" height="2" fill="#00ff41" opacity="0.4"/>
<!-- University -->
<text x="600" y="635" text-anchor="middle" font-family="'Courier New',monospace" font-size="36" font-weight="bold" fill="#ffaa00">George Mason University</text>
<!-- Bottom badge -->
<rect x="400" y="670" width="400" height="40" rx="20" fill="none" stroke="#00ff41" stroke-width="1.5" opacity="0.5"/>
<text x="600" y="697" text-anchor="middle" font-family="'Courier New',monospace" font-size="20" fill="#00ff41" opacity="0.7">RP2350 // ARM Cortex-M33</text>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

+74
View File
@@ -0,0 +1,74 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">C Operators Overview</text>
<text class="dim" x="600" y="88" text-anchor="middle">Six Types of Operators in C</text>
<!-- Top Row -->
<rect class="pnl" x="30" y="110" width="370" height="195" rx="8"/>
<text class="amb" x="50" y="145">Arithmetic</text>
<rect x="50" y="160" width="330" height="120" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="txt" x="70" y="190">+ - * / %</text>
<text class="dim" x="70" y="220">Math operations</text>
<text class="grn" x="70" y="250">5 * 10 = 50</text>
<rect class="pnl" x="415" y="110" width="370" height="195" rx="8"/>
<text class="amb" x="435" y="145">Increment</text>
<rect x="435" y="160" width="330" height="120" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="txt" x="455" y="190">x++ ++x x--</text>
<text class="dim" x="455" y="220">Add/subtract by 1</text>
<text class="grn" x="455" y="250">x++ returns old val</text>
<rect class="pnl" x="800" y="110" width="370" height="195" rx="8"/>
<text class="amb" x="820" y="145">Relational</text>
<rect x="820" y="160" width="330" height="120" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="txt" x="840" y="190">&gt; &lt; &gt;= &lt;= == !=</text>
<text class="dim" x="840" y="220">Compare values</text>
<text class="grn" x="840" y="250">(6 &gt; 10) = false</text>
<!-- Bottom Row -->
<rect class="pnl" x="30" y="320" width="370" height="195" rx="8"/>
<text class="amb" x="50" y="355">Logical</text>
<rect x="50" y="370" width="330" height="120" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="txt" x="70" y="400">&amp;&amp; || !</text>
<text class="dim" x="70" y="430">Combine conditions</text>
<text class="grn" x="70" y="460">AND, OR, NOT</text>
<rect class="pnl" x="415" y="320" width="370" height="195" rx="8"/>
<text class="amb" x="435" y="355">Bitwise</text>
<rect x="435" y="370" width="330" height="120" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="txt" x="455" y="400">&lt;&lt; &gt;&gt; &amp; | ^ ~</text>
<text class="dim" x="455" y="430">Manipulate bits</text>
<text class="grn" x="455" y="460">6 &lt;&lt; 1 = 12</text>
<rect class="pnl" x="800" y="320" width="370" height="195" rx="8"/>
<text class="amb" x="820" y="355">Assignment</text>
<rect x="820" y="370" width="330" height="120" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="txt" x="840" y="400">+= -= *= /=</text>
<text class="dim" x="840" y="430">Assign and modify</text>
<text class="grn" x="840" y="460">x += 5 (x=x+5)</text>
<!-- Bottom: Context -->
<rect class="pnl" x="30" y="530" width="1140" height="120" rx="8"/>
<text class="sub" x="50" y="565">This Week's Program</text>
<text class="txt" x="50" y="600">0x001a_operators.c demonstrates all 6 types</text>
<text class="dim" x="50" y="630">DHT11 temperature/humidity sensor + operator calculations</text>
<!-- Key insight -->
<rect class="pnl" x="30" y="665" width="1140" height="80" rx="8"/>
<text class="red" x="50" y="700">KEY:</text>
<text class="txt" x="130" y="700">Compiler pre-computes constant expressions</text>
<text class="dim" x="50" y="725">In the binary, most operators become immediate values</text>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

+75
View File
@@ -0,0 +1,75 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">Arithmetic &amp; Increment</text>
<text class="dim" x="600" y="88" text-anchor="middle">Math Operations and Post/Pre Increment</text>
<!-- Arithmetic Panel -->
<rect class="pnl" x="30" y="110" width="555" height="290" rx="8"/>
<text class="sub" x="50" y="145">Arithmetic Operators</text>
<rect x="50" y="160" width="515" height="220" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="amb" x="70" y="195">+</text>
<text class="dim" x="130" y="195">5 + 10 = 15</text>
<text class="dim" x="360" y="195">Addition</text>
<text class="amb" x="70" y="230">-</text>
<text class="dim" x="130" y="230">10 - 5 = 5</text>
<text class="dim" x="360" y="230">Subtraction</text>
<text class="amb" x="70" y="265">*</text>
<text class="dim" x="130" y="265">5 * 10 = 50</text>
<text class="dim" x="360" y="265">Multiplication</text>
<text class="amb" x="70" y="300">/</text>
<text class="dim" x="130" y="300">10 / 5 = 2</text>
<text class="dim" x="360" y="300">Division</text>
<text class="amb" x="70" y="335">%</text>
<text class="dim" x="130" y="335">10 % 3 = 1</text>
<text class="dim" x="360" y="335">Modulus</text>
<!-- Increment Panel -->
<rect class="pnl" x="615" y="110" width="555" height="290" rx="8"/>
<text class="sub" x="635" y="145">Post vs Pre Increment</text>
<rect x="635" y="165" width="515" height="100" rx="6" fill="#00ff41" fill-opacity="0.08" stroke="#00ff41"/>
<text class="grn" x="655" y="195">Post: x++</text>
<text class="txt" x="655" y="225">Use value THEN increment</text>
<text class="dim" x="655" y="250">a = x++ --> a=5, x=6</text>
<rect x="635" y="275" width="515" height="100" rx="6" fill="#00d4ff" fill-opacity="0.08" stroke="#00d4ff"/>
<text class="cyn" x="655" y="305">Pre: ++x</text>
<text class="txt" x="655" y="335">Increment THEN use value</text>
<text class="dim" x="655" y="360">b = ++x --> x=7, b=7</text>
<!-- Trace Example -->
<rect class="pnl" x="30" y="415" width="1140" height="225" rx="8"/>
<text class="sub" x="50" y="450">Post-Increment Step by Step</text>
<rect x="50" y="465" width="1100" height="155" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="cyn" x="70" y="495">int x = 5;</text>
<text class="cyn" x="70" y="530">int result = x++;</text>
<text class="dim" x="470" y="495">Step 1: result = x</text>
<text class="grn" x="750" y="495">result gets 5</text>
<text class="dim" x="470" y="530">Step 2: x = x + 1</text>
<text class="grn" x="750" y="530">x becomes 6</text>
<text class="amb" x="70" y="575">Final: result = 5</text>
<text class="amb" x="400" y="575">x = 6</text>
<text class="dim" x="560" y="575">"Use first, THEN increment"</text>
<!-- Key -->
<rect class="pnl" x="30" y="655" width="1140" height="80" rx="8"/>
<text class="red" x="50" y="690">In our code:</text>
<text class="txt" x="250" y="690">int increment_operator = x++;</text>
<text class="dim" x="50" y="718">x was 5, so increment_operator = 5, then x becomes 6</text>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

+95
View File
@@ -0,0 +1,95 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">Relational &amp; Logical</text>
<text class="dim" x="600" y="88" text-anchor="middle">Comparing Values and Combining Conditions</text>
<!-- Relational Panel -->
<rect class="pnl" x="30" y="110" width="555" height="340" rx="8"/>
<text class="sub" x="50" y="145">Relational Operators</text>
<text class="dim" x="50" y="175">Compare two values --> true (1) or false (0)</text>
<rect x="50" y="190" width="515" height="240" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="amb" x="70" y="220">&gt;</text>
<text class="dim" x="130" y="220">6 &gt; 10</text>
<text class="red" x="310" y="220">false</text>
<text class="dim" x="400" y="220">Greater than</text>
<text class="amb" x="70" y="255">&lt;</text>
<text class="dim" x="130" y="255">6 &lt; 10</text>
<text class="grn" x="310" y="255">true</text>
<text class="dim" x="400" y="255">Less than</text>
<text class="amb" x="70" y="290">&gt;=</text>
<text class="dim" x="130" y="290">6 &gt;= 6</text>
<text class="grn" x="310" y="290">true</text>
<text class="dim" x="400" y="290">Greater/equal</text>
<text class="amb" x="70" y="325">&lt;=</text>
<text class="dim" x="130" y="325">6 &lt;= 10</text>
<text class="grn" x="310" y="325">true</text>
<text class="dim" x="400" y="325">Less or equal</text>
<text class="amb" x="70" y="360">==</text>
<text class="dim" x="130" y="360">6 == 10</text>
<text class="red" x="310" y="360">false</text>
<text class="dim" x="400" y="360">Equal to</text>
<text class="amb" x="70" y="395">!=</text>
<text class="dim" x="130" y="395">6 != 10</text>
<text class="grn" x="310" y="395">true</text>
<text class="dim" x="400" y="395">Not equal</text>
<!-- Logical Panel -->
<rect class="pnl" x="615" y="110" width="555" height="340" rx="8"/>
<text class="sub" x="635" y="145">Logical Operators</text>
<text class="dim" x="635" y="175">Combine conditions into one result</text>
<rect x="635" y="190" width="515" height="105" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="amb" x="655" y="220">&amp;&amp;</text>
<text class="dim" x="720" y="220">AND -- both must be true</text>
<text class="amb" x="655" y="255">||</text>
<text class="dim" x="720" y="255">OR -- at least one true</text>
<text class="amb" x="655" y="290">!</text>
<text class="dim" x="720" y="290">NOT -- inverts result</text>
<!-- Truth table for AND -->
<text class="dim" x="635" y="320">AND Truth Table</text>
<rect x="635" y="330" width="515" height="165" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="dim" x="655" y="355">A</text>
<text class="dim" x="755" y="355">B</text>
<text class="dim" x="855" y="355">A &amp;&amp; B</text>
<text class="red" x="655" y="385">false</text>
<text class="red" x="755" y="385">false</text>
<text class="red" x="855" y="385">false</text>
<text class="red" x="655" y="415">false</text>
<text class="grn" x="755" y="415">true</text>
<text class="red" x="855" y="415">false</text>
<text class="grn" x="655" y="445">true</text>
<text class="red" x="755" y="445">false</text>
<text class="red" x="855" y="445">false</text>
<text class="grn" x="655" y="475">true</text>
<text class="grn" x="755" y="475">true</text>
<text class="grn" x="855" y="475">true</text>
<!-- Bottom: Code Example -->
<rect class="pnl" x="30" y="465" width="1140" height="155" rx="8"/>
<text class="sub" x="50" y="500">In Our Code (x=6, y=10)</text>
<rect x="50" y="515" width="1100" height="85" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="cyn" x="70" y="545">bool relational = (x &gt; y);</text>
<text class="dim" x="560" y="545">(6 &gt; 10) = false = 0</text>
<text class="cyn" x="70" y="580">bool logical = (x&gt;y) &amp;&amp; (y&gt;x);</text>
<text class="dim" x="560" y="580">false &amp;&amp; true = false = 0</text>
<!-- Key -->
<rect class="pnl" x="30" y="635" width="1140" height="100" rx="8"/>
<text class="red" x="50" y="670">In the binary:</text>
<text class="txt" x="290" y="670">Both compile to immediate #0</text>
<text class="dim" x="50" y="700">Compiler pre-computes: constants are known at compile time</text>
<text class="dim" x="50" y="720">Result 0 = false, Result 1 = true</text>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

+89
View File
@@ -0,0 +1,89 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">Bitwise &amp; Assignment</text>
<text class="dim" x="600" y="88" text-anchor="middle">Bit Manipulation and Compound Assignment</text>
<!-- Bitwise Panel -->
<rect class="pnl" x="30" y="110" width="555" height="370" rx="8"/>
<text class="sub" x="50" y="145">Bitwise Operators</text>
<rect x="50" y="160" width="515" height="200" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="amb" x="70" y="190">&lt;&lt;</text>
<text class="dim" x="140" y="190">6 &lt;&lt; 1 = 12</text>
<text class="dim" x="360" y="190">Left shift</text>
<text class="amb" x="70" y="220">&gt;&gt;</text>
<text class="dim" x="140" y="220">6 &gt;&gt; 1 = 3</text>
<text class="dim" x="360" y="220">Right shift</text>
<text class="amb" x="70" y="250">&amp;</text>
<text class="dim" x="140" y="250">6 &amp; 3 = 2</text>
<text class="dim" x="360" y="250">AND</text>
<text class="amb" x="70" y="280">|</text>
<text class="dim" x="140" y="280">6 | 3 = 7</text>
<text class="dim" x="360" y="280">OR</text>
<text class="amb" x="70" y="310">^</text>
<text class="dim" x="140" y="310">6 ^ 3 = 5</text>
<text class="dim" x="360" y="310">XOR</text>
<text class="amb" x="70" y="340">~</text>
<text class="dim" x="140" y="340">~6</text>
<text class="dim" x="360" y="340">NOT (invert)</text>
<!-- Left shift diagram -->
<text class="dim" x="50" y="390">Left shift = multiply by 2</text>
<rect x="50" y="400" width="515" height="60" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text class="grn" x="70" y="425">0 0 0 0 0 1 1 0</text>
<text class="dim" x="370" y="425">= 6</text>
<text class="grn" x="70" y="448">0 0 0 0 1 1 0 0</text>
<text class="dim" x="370" y="448">= 12</text>
<!-- Assignment Panel -->
<rect class="pnl" x="615" y="110" width="555" height="370" rx="8"/>
<text class="sub" x="635" y="145">Assignment Operators</text>
<text class="dim" x="635" y="175">Shorthand for math + assign</text>
<rect x="635" y="190" width="515" height="200" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="amb" x="655" y="220">+=</text>
<text class="dim" x="720" y="220">x += 5</text>
<text class="dim" x="905" y="220">x = x + 5</text>
<text class="amb" x="655" y="255">-=</text>
<text class="dim" x="720" y="255">x -= 2</text>
<text class="dim" x="905" y="255">x = x - 2</text>
<text class="amb" x="655" y="290">*=</text>
<text class="dim" x="720" y="290">x *= 3</text>
<text class="dim" x="905" y="290">x = x * 3</text>
<text class="amb" x="655" y="325">/=</text>
<text class="dim" x="720" y="325">x /= 2</text>
<text class="dim" x="905" y="325">x = x / 2</text>
<text class="amb" x="655" y="360">%=</text>
<text class="dim" x="720" y="360">x %= 4</text>
<text class="dim" x="905" y="360">x = x % 4</text>
<!-- Code example -->
<text class="dim" x="635" y="415">In our code (x=6 after x++):</text>
<rect x="635" y="425" width="515" height="45" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text class="amb" x="655" y="453">x += 5 --> 6 + 5 = 11</text>
<!-- Bottom -->
<rect class="pnl" x="30" y="495" width="1140" height="120" rx="8"/>
<text class="sub" x="50" y="530">In Our Code (x=6, y=10)</text>
<rect x="50" y="545" width="1100" height="50" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="cyn" x="70" y="575">int bitwise = (x&lt;&lt;1);</text>
<text class="dim" x="500" y="575">6 &lt;&lt; 1 = 12 (0b0110 --> 0b1100)</text>
<!-- Binary output preview -->
<rect class="pnl" x="30" y="630" width="1140" height="110" rx="8"/>
<text class="sub" x="50" y="665">Expected Output</text>
<text class="txt" x="50" y="700">bitwise_operator: 12</text>
<text class="txt" x="470" y="700">assignment_operator: 11</text>
<text class="dim" x="50" y="725">Both pre-computed by compiler as immediates</text>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

+72
View File
@@ -0,0 +1,72 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">DHT11 Sensor</text>
<text class="dim" x="600" y="88" text-anchor="middle">Single-Wire Temperature and Humidity</text>
<!-- Left: Pinout and Specs -->
<rect class="pnl" x="30" y="110" width="555" height="260" rx="8"/>
<text class="sub" x="50" y="145">DHT11 Pinout</text>
<rect x="180" y="165" width="120" height="80" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
<text class="grn" x="205" y="212">DHT11</text>
<text class="dim" x="180" y="265">1:VCC 2:DATA 3:NC 4:GND</text>
<text class="dim" x="50" y="300">Humidity: 20-90% RH (+/-5%)</text>
<text class="dim" x="50" y="325">Temp: 0-50C (+/-2C)</text>
<text class="dim" x="50" y="350">Protocol: custom one-wire</text>
<!-- Right: Wiring -->
<rect class="pnl" x="615" y="110" width="555" height="260" rx="8"/>
<text class="sub" x="635" y="145">Wiring to Pico 2</text>
<rect x="635" y="165" width="100" height="45" rx="4" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
<text class="cyn" x="655" y="194">Pico</text>
<rect x="1040" y="165" width="100" height="45" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text class="grn" x="1055" y="194">DHT11</text>
<line x1="735" y1="178" x2="1040" y2="178" stroke="#ffaa00" stroke-width="2"/>
<line x1="735" y1="198" x2="1040" y2="198" stroke="#888" stroke-width="2"/>
<text class="dim" x="635" y="230">GPIO 4 = DATA</text>
<text class="dim" x="635" y="255">3.3V = VCC</text>
<text class="dim" x="635" y="280">GND = GND</text>
<!-- Communication Protocol -->
<rect class="pnl" x="635" y="295" width="555" height="75" rx="6"/>
<text class="dim" x="655" y="320">1. Host pulls LOW 18ms</text>
<text class="dim" x="655" y="345">2. DHT11 responds, sends 40 bits</text>
<!-- Source Code -->
<rect class="pnl" x="30" y="385" width="1140" height="380" rx="8"/>
<text class="sub" x="50" y="420">Source Code: 0x001a_operators.c</text>
<rect x="50" y="435" width="1100" height="310" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="cyn" x="70" y="465">int x = 5, y = 10;</text>
<text class="txt" x="70" y="495">int arithmetic = (x * y);</text>
<text class="dim" x="530" y="495">// 50</text>
<text class="txt" x="70" y="525">int increment = x++;</text>
<text class="dim" x="530" y="525">// 5 (post)</text>
<text class="txt" x="70" y="555">bool relational = (x &gt; y);</text>
<text class="dim" x="530" y="555">// false</text>
<text class="txt" x="70" y="585">bool logical = (x&gt;y)&amp;&amp;(y&gt;x);</text>
<text class="dim" x="530" y="585">// false</text>
<text class="txt" x="70" y="615">int bitwise = (x&lt;&lt;1);</text>
<text class="dim" x="530" y="615">// 12</text>
<text class="txt" x="70" y="645">int assignment = (x += 5);</text>
<text class="dim" x="530" y="645">// 11</text>
<text class="cyn" x="70" y="680">float hum, temp;</text>
<text class="txt" x="70" y="710">dht11_read(&amp;hum, &amp;temp);</text>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

+75
View File
@@ -0,0 +1,75 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">Variable Flow</text>
<text class="dim" x="600" y="88" text-anchor="middle">Tracing x Through Every Operator</text>
<!-- Variable trace table -->
<rect class="pnl" x="30" y="110" width="1140" height="650" rx="8"/>
<text class="sub" x="50" y="150">Tracing x Step-by-Step</text>
<!-- Header row -->
<text class="amb" x="50" y="195">Line</text>
<text class="amb" x="520" y="195">x</text>
<text class="amb" x="640" y="195">Result</text>
<line x1="50" y1="205" x2="1140" y2="205" stroke="#1a1a2e" stroke-width="1"/>
<!-- Row 1: init -->
<text class="cyn" x="50" y="240">int x = 5, y = 10;</text>
<text class="grn" x="520" y="240">5</text>
<text class="dim" x="640" y="240">x initialized to 5</text>
<!-- Row 2: arithmetic -->
<text class="txt" x="50" y="280">int arithmetic = (x * y);</text>
<text class="grn" x="520" y="280">5</text>
<text class="txt" x="640" y="280">arithmetic = 50</text>
<!-- Row 3: post-increment -->
<text class="txt" x="50" y="320">int increment = x++;</text>
<text class="red" x="520" y="320">5-->6</text>
<text class="txt" x="640" y="320">increment = 5</text>
<text class="dim" x="640" y="345">use THEN increment</text>
<!-- Row 4: relational -->
<text class="txt" x="50" y="385">bool relational = (x &gt; y);</text>
<text class="grn" x="520" y="385">6</text>
<text class="txt" x="640" y="385">relational = false</text>
<text class="dim" x="640" y="410">6 &gt; 10 is false</text>
<!-- Row 5: logical -->
<text class="txt" x="50" y="450">bool logical = (x&gt;y)&amp;&amp;(y&gt;x);</text>
<text class="grn" x="520" y="450">6</text>
<text class="txt" x="640" y="450">logical = false</text>
<text class="dim" x="640" y="475">false AND true = false</text>
<!-- Row 6: bitwise -->
<text class="txt" x="50" y="515">int bitwise = (x&lt;&lt;1);</text>
<text class="grn" x="520" y="515">6</text>
<text class="txt" x="640" y="515">bitwise = 12</text>
<text class="dim" x="640" y="540">0b0110 &lt;&lt; 1 = 0b1100</text>
<!-- Row 7: assignment -->
<text class="txt" x="50" y="580">int assignment = (x += 5);</text>
<text class="red" x="520" y="580">6-->11</text>
<text class="txt" x="640" y="580">assignment = 11</text>
<text class="dim" x="640" y="605">6 + 5 = 11</text>
<!-- DHT11 output -->
<line x1="50" y1="635" x2="1140" y2="635" stroke="#1a1a2e" stroke-width="1"/>
<text class="sub" x="50" y="670">DHT11 Output</text>
<text class="grn" x="50" y="705">Humidity: 51.0%</text>
<text class="grn" x="400" y="705">Temperature: 23.8C</text>
<text class="dim" x="50" y="735">dht11_read(&amp;hum, &amp;temp) -- passes addresses so function can write values</text>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

+77
View File
@@ -0,0 +1,77 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">Vector Table</text>
<text class="dim" x="600" y="88" text-anchor="middle">Finding Reset_Handler and main()</text>
<!-- Vector Table Structure -->
<rect class="pnl" x="30" y="110" width="555" height="280" rx="8"/>
<text class="sub" x="50" y="150">ARM Vector Table</text>
<text class="dim" x="50" y="178">Base address: 0x10000000</text>
<text class="amb" x="50" y="215">Offset</text>
<text class="amb" x="180" y="215">Contents</text>
<text class="amb" x="400" y="215">Purpose</text>
<line x1="50" y1="225" x2="565" y2="225" stroke="#1a1a2e" stroke-width="1"/>
<text class="grn" x="50" y="255">0x00</text>
<text class="txt" x="180" y="255">Initial SP</text>
<text class="dim" x="400" y="255">Stack ptr</text>
<text class="grn" x="50" y="290">0x04</text>
<text class="cyn" x="180" y="290">Reset_Handler</text>
<text class="dim" x="400" y="290">Entry point</text>
<text class="grn" x="50" y="325">0x08</text>
<text class="txt" x="180" y="325">NMI_Handler</text>
<text class="dim" x="400" y="325">NMI</text>
<text class="grn" x="50" y="360">0x0C</text>
<text class="txt" x="180" y="360">HardFault</text>
<text class="dim" x="400" y="360">Fault</text>
<!-- Little-Endian + Thumb Bit -->
<rect class="pnl" x="615" y="110" width="555" height="280" rx="8"/>
<text class="sub" x="635" y="150">Decoding the Address</text>
<text class="txt" x="635" y="190">At 0x10000004:</text>
<text class="grn" x="635" y="225">Bytes: 5d 01 00 10</text>
<text class="amb" x="635" y="265">Step 1: Reverse (little-endian)</text>
<text class="txt" x="635" y="295">10 00 01 5d = 0x1000015d</text>
<text class="amb" x="635" y="330">Step 2: Remove Thumb bit</text>
<text class="txt" x="635" y="360">0x1000015d - 1 = 0x1000015c</text>
<!-- Reset_Handler Flow -->
<rect class="pnl" x="30" y="410" width="1140" height="350" rx="8"/>
<text class="sub" x="50" y="450">Reset_Handler --> main()</text>
<text class="dim" x="50" y="485">Reset_Handler at 0x1000015c calls 3 functions:</text>
<rect x="50" y="505" width="1100" height="230" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
<text class="txt" x="70" y="540">Call 1: some_init()</text>
<text class="dim" x="450" y="540">Hardware initialization</text>
<text class="cyn" x="70" y="580">Call 2: main()</text>
<text class="amb" x="450" y="580">THIS IS WHAT WE WANT</text>
<text class="dim" x="450" y="605">Address: 0x10000234</text>
<text class="txt" x="70" y="645">Call 3: exit()</text>
<text class="dim" x="450" y="645">Never returns</text>
<text class="dim" x="70" y="685">The MIDDLE function call is always main()</text>
<text class="dim" x="70" y="710">Navigate to 0x10000234 in Ghidra to find it</text>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

+81
View File
@@ -0,0 +1,81 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">IEEE-754 Floats</text>
<text class="dim" x="600" y="88" text-anchor="middle">How Computers Store Decimal Numbers</text>
<!-- Float Layout Diagram -->
<rect class="pnl" x="30" y="110" width="1140" height="190" rx="8"/>
<text class="sub" x="50" y="150">32-bit Float Structure</text>
<!-- Bit field boxes -->
<rect x="50" y="170" width="80" height="50" rx="4" fill="#ff0040" fill-opacity="0.2" stroke="#ff0040"/>
<text class="red" x="70" y="202">S</text>
<text class="dim" x="55" y="240">1 bit</text>
<rect x="150" y="170" width="320" height="50" rx="4" fill="#ffaa00" fill-opacity="0.2" stroke="#ffaa00"/>
<text class="amb" x="260" y="202">Exponent</text>
<text class="dim" x="270" y="240">8 bits</text>
<rect x="490" y="170" width="660" height="50" rx="4" fill="#00d4ff" fill-opacity="0.2" stroke="#00d4ff"/>
<text class="cyn" x="740" y="202">Mantissa (Fraction)</text>
<text class="dim" x="760" y="240">23 bits</text>
<text class="dim" x="50" y="280">Value = (-1)^S x (1 + Mantissa) x 2^(Exponent - 127)</text>
<!-- Example: Decoding 0.1f -->
<rect class="pnl" x="30" y="320" width="1140" height="220" rx="8"/>
<text class="sub" x="50" y="360">Example: Decoding 0.1f</text>
<text class="txt" x="50" y="400">Little-endian bytes:</text>
<text class="grn" x="380" y="400">cd cc cc 3d</text>
<text class="txt" x="50" y="435">Reversed (big-endian):</text>
<text class="grn" x="380" y="435">0x3dcccccd</text>
<text class="amb" x="50" y="475">Sign: 0</text>
<text class="amb" x="250" y="475">Exp: 01111011 = 123</text>
<text class="amb" x="580" y="475">Mantissa: 1001100...</text>
<text class="txt" x="50" y="510">Exp - 127 = -4, so value = 1.6 x 2^(-4)</text>
<text class="grn" x="680" y="510">= 0.1</text>
<!-- Float Reference Table -->
<rect class="pnl" x="30" y="560" width="1140" height="200" rx="8"/>
<text class="sub" x="50" y="600">IEEE-754 Quick Reference</text>
<text class="amb" x="50" y="635">Value</text>
<text class="amb" x="200" y="635">Hex</text>
<text class="amb" x="430" y="635">Bytes (LE)</text>
<line x1="50" y1="645" x2="1140" y2="645" stroke="#1a1a2e" stroke-width="1"/>
<text class="txt" x="50" y="675">0.1</text>
<text class="grn" x="200" y="675">0x3dcccccd</text>
<text class="dim" x="430" y="675">cd cc cc 3d</text>
<text class="txt" x="700" y="675">1.0</text>
<text class="grn" x="820" y="675">0x3f800000</text>
<text class="dim" x="1020" y="675">00 00 80 3f</text>
<text class="txt" x="50" y="710">5.0</text>
<text class="grn" x="200" y="710">0x40a00000</text>
<text class="dim" x="430" y="710">00 00 a0 40</text>
<text class="txt" x="700" y="710">10.0</text>
<text class="grn" x="820" y="710">0x41200000</text>
<text class="dim" x="1020" y="710">00 00 20 41</text>
<text class="txt" x="50" y="740">-1.0</text>
<text class="grn" x="200" y="740">0xbf800000</text>
<text class="dim" x="430" y="740">00 00 80 bf</text>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

+64
View File
@@ -0,0 +1,64 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">Hacking the Float</text>
<text class="dim" x="600" y="88" text-anchor="middle">Changing the DHT11 Scaling Constant</text>
<!-- DHT11 Scaling Formula -->
<rect class="pnl" x="30" y="110" width="1140" height="150" rx="8"/>
<text class="sub" x="50" y="150">DHT11 Scaling Calculation</text>
<text class="txt" x="50" y="190">result = integer + (decimal x 0.1)</text>
<text class="dim" x="50" y="218">Example: temp = 23 + (8 x 0.1) = 23.8C</text>
<text class="amb" x="700" y="190">0.1f is our target!</text>
<!-- Key Offsets -->
<rect class="pnl" x="30" y="280" width="1140" height="200" rx="8"/>
<text class="sub" x="50" y="320">Key Offsets in Binary</text>
<text class="amb" x="50" y="360">Offset</text>
<text class="amb" x="200" y="360">Bytes</text>
<text class="amb" x="480" y="360">Meaning</text>
<line x1="50" y1="370" x2="1140" y2="370" stroke="#1a1a2e" stroke-width="1"/>
<text class="grn" x="50" y="400">0x410</text>
<text class="txt" x="200" y="400">a6 ee 25 7a</text>
<text class="dim" x="480" y="400">vfma.f32 s14,s12,s11 (humidity)</text>
<text class="grn" x="50" y="435">0x414</text>
<text class="txt" x="200" y="435">e6 ee a5 7a</text>
<text class="dim" x="480" y="435">vfma.f32 s15,s13,s11 (temp)</text>
<text class="red" x="50" y="470">0x42C</text>
<text class="cyn" x="200" y="470">cd cc cc 3d</text>
<text class="amb" x="480" y="470">0.1f -- the scaling constant</text>
<!-- The Hack -->
<rect class="pnl" x="30" y="500" width="1140" height="260" rx="8"/>
<text class="sub" x="50" y="540">The Hack: 0.1f --> 5.0f</text>
<text class="txt" x="50" y="580">At offset 0x42C, change:</text>
<rect x="50" y="600" width="500" height="50" rx="6" fill="#0a0a0f" stroke="#ff0040"/>
<text class="red" x="70" y="632">Original: cd cc cc 3d</text>
<text class="dim" x="380" y="632">(0.1f)</text>
<rect x="600" y="600" width="500" height="50" rx="6" fill="#0a0a0f" stroke="#00ff41"/>
<text class="grn" x="620" y="632">Patched: 00 00 a0 40</text>
<text class="dim" x="930" y="632">(5.0f)</text>
<text class="txt" x="50" y="685">New result: 23 + (8 x 5.0) = 63.0C</text>
<text class="dim" x="50" y="715">Decimal part is now multiplied by 5.0 instead of 0.1</text>
<text class="dim" x="50" y="740">Export .bin from Ghidra, convert to UF2, flash to Pico</text>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

+97
View File
@@ -0,0 +1,97 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<rect class="hdr" x="0" y="0" width="1200" height="100" rx="0"/>
<text class="title" x="600" y="52" text-anchor="middle">Operators &amp; DHT11 Hacking</text>
<text class="dim" x="600" y="88" text-anchor="middle">Operators, DHT11, IEEE-754, and Hacking</text>
<!-- Left: 6 Operator Types -->
<rect class="pnl" x="30" y="110" width="555" height="280" rx="8"/>
<text class="sub" x="50" y="150">6 Operator Types</text>
<text class="grn" x="50" y="185">Arithmetic</text>
<text class="dim" x="260" y="185">x * y = 50</text>
<text class="grn" x="50" y="215">Increment</text>
<text class="dim" x="260" y="215">x++ returns 5, x becomes 6</text>
<text class="grn" x="50" y="245">Relational</text>
<text class="dim" x="260" y="245">(6 &gt; 10) = false</text>
<text class="grn" x="50" y="275">Logical</text>
<text class="dim" x="260" y="275">false &amp;&amp; true = false</text>
<text class="grn" x="50" y="305">Bitwise</text>
<text class="dim" x="260" y="305">6 &lt;&lt; 1 = 12</text>
<text class="grn" x="50" y="335">Assignment</text>
<text class="dim" x="260" y="335">x += 5 = 11</text>
<text class="dim" x="50" y="370">Post-increment: use THEN increment</text>
<!-- Right: Key Addresses -->
<rect class="pnl" x="615" y="110" width="555" height="280" rx="8"/>
<text class="sub" x="635" y="150">Key Addresses</text>
<text class="cyn" x="635" y="190">0x10000000</text>
<text class="dim" x="870" y="190">Vector table</text>
<text class="cyn" x="635" y="225">0x10000004</text>
<text class="dim" x="870" y="225">Reset_Handler addr</text>
<text class="cyn" x="635" y="260">0x10000234</text>
<text class="dim" x="870" y="260">main()</text>
<text class="cyn" x="635" y="295">0x10000410</text>
<text class="dim" x="870" y="295">Humidity vfma</text>
<text class="cyn" x="635" y="330">0x10000414</text>
<text class="dim" x="870" y="330">Temp vfma</text>
<text class="red" x="635" y="365">0x1000042C</text>
<text class="dim" x="870" y="365">0.1f constant (hack)</text>
<!-- IEEE-754 -->
<rect class="pnl" x="30" y="410" width="555" height="160" rx="8"/>
<text class="sub" x="50" y="450">IEEE-754 Format</text>
<text class="txt" x="50" y="485">S(1) + Exp(8) + Mantissa(23)</text>
<text class="dim" x="50" y="515">(-1)^S x (1+M) x 2^(E-127)</text>
<text class="dim" x="50" y="545">0.1f = 0x3dcccccd = cd cc cc 3d</text>
<!-- Hack Workflow -->
<rect class="pnl" x="615" y="410" width="555" height="160" rx="8"/>
<text class="sub" x="635" y="450">Hack Workflow</text>
<text class="txt" x="635" y="485">1. Analyze in Ghidra</text>
<text class="txt" x="635" y="515">2. Find float at 0x42C</text>
<text class="txt" x="635" y="545">3. Patch cd cc cc 3d</text>
<!-- Bottom: Steps -->
<rect class="pnl" x="30" y="590" width="1140" height="170" rx="8"/>
<text class="sub" x="50" y="630">Binary Hacking Steps</text>
<text class="amb" x="50" y="665">Analyze</text>
<text class="txt" x="200" y="665">--></text>
<text class="amb" x="260" y="665">Identify</text>
<text class="txt" x="410" y="665">--></text>
<text class="amb" x="470" y="665">Offset</text>
<text class="txt" x="600" y="665">--></text>
<text class="amb" x="660" y="665">Patch</text>
<text class="txt" x="790" y="665">--></text>
<text class="amb" x="850" y="665">Export</text>
<text class="txt" x="990" y="665">--></text>
<text class="amb" x="1050" y="665">Test</text>
<text class="dim" x="50" y="700">Project: 0x001a_operators</text>
<text class="dim" x="50" y="730">Source: 0x001a_operators.c with DHT11 sensor on GPIO 4</text>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB