Updated DS refs
@@ -0,0 +1,186 @@
|
||||
# Week 11 Quiz: Structures, Functions, NEC IR Protocol, and .ELF Analysis
|
||||
|
||||
## Instructions
|
||||
Choose the best answer for each question. There is only one correct answer per question.
|
||||
|
||||
---
|
||||
|
||||
## Questions
|
||||
|
||||
### Question 1
|
||||
The `simple_led_ctrl_t` struct has members `led1_pin` (uint8_t), `led2_pin` (uint8_t), `led3_pin` (uint8_t), `led1_state` (bool), `led2_state` (bool), `led3_state` (bool). What is the total struct size and how are the members laid out in memory starting at address `0x2000000`?
|
||||
|
||||
A) 12 bytes — each member is padded to 2 bytes for alignment
|
||||
B) 6 bytes — members are stored consecutively: `0x2000000`=led1_pin, `0x2000001`=led2_pin, `0x2000002`=led3_pin, `0x2000003`=led1_state, `0x2000004`=led2_state, `0x2000005`=led3_state
|
||||
C) 24 bytes — each member is stored as a 4-byte word
|
||||
D) 3 bytes — bool members are stored as single bits packed together
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 2 – Memory Layout table showing "Total struct size: 6 bytes" with each `uint8_t` and `bool` member occupying 1 byte in consecutive addresses
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
### Question 2
|
||||
What is the difference between the dot operator (`.`) and the arrow operator (`->`) when accessing struct members?
|
||||
|
||||
A) The dot operator is for reading; the arrow operator is for writing
|
||||
B) The dot operator is used with a struct variable (`leds.led1_pin`); the arrow operator is used with a pointer to a struct (`ptr->led1_pin`), which is shorthand for `(*ptr).led1_pin`
|
||||
C) The dot operator accesses public members; the arrow operator accesses private members
|
||||
D) There is no difference — they are interchangeable for any struct
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 1 – "struct_variable.member ← Use with actual struct" and "pointer_to_struct->member ← Use with pointer to struct; The arrow (->) is shorthand for (*pointer).member"
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
### Question 3
|
||||
The NEC IR protocol sends a 32-bit data frame. What are the four 8-bit fields in order, and what is the purpose of the inverse fields?
|
||||
|
||||
A) Command, address, data, checksum — the checksum verifies integrity
|
||||
B) Address, address inverse, command, command inverse — the inverse fields provide error checking by containing the bitwise complement of their counterparts
|
||||
C) Start, device ID, button code, stop — the stop field marks end of transmission
|
||||
D) Preamble, channel, volume, repeat — the repeat field handles held buttons
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 4 – NEC Protocol Frame diagram: "Address (8-bit), Address Inverse (8-bit), Command (8-bit), Command Inverse (8-bit)" preceded by "Leader Pulse (9ms HIGH, 4.5ms LOW)"
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
### Question 4
|
||||
The compiler "flattens" `gpio_init(leds.led1_pin)` for all three LEDs into individual `movs` and `bl` instructions. What does this look like in assembly, and why does it matter for reverse engineering?
|
||||
|
||||
A) The assembly uses `ldr r0, [struct_ptr, #offset]` with struct offsets preserved — the struct is visible in the disassembly
|
||||
B) The assembly becomes `movs r0, #0x10; bl gpio_init; movs r0, #0x11; bl gpio_init; movs r0, #0x12; bl gpio_init` — the struct abstraction disappears and you only see individual values, so you must recognize patterns like sequential numbers 16, 17, 18
|
||||
C) The compiler generates a loop that iterates over struct members — you see `add r0, #1` incrementing through pins
|
||||
D) The struct members are stored in a lookup table and accessed via index — you see `ldr r0, [table, r1]`
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 7 – "The struct abstraction DISAPPEARS at the assembly level! We just see individual values being loaded and used" with the assembly showing `movs r0, #0x10`, `movs r0, #0x11`, `movs r0, #0x12`
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
### Question 5
|
||||
Why does the `leds_all_off` function take a `simple_led_ctrl_t *leds` pointer instead of a `simple_led_ctrl_t leds` value?
|
||||
|
||||
A) Pointers are required for all function parameters in ARM Thumb mode
|
||||
B) Passing by pointer is efficient (only 4 bytes for the address instead of copying the entire struct) and allows the function to modify the original struct
|
||||
C) The compiler cannot pass structs by value in C
|
||||
D) Pointers are needed because structs are always stored in flash, not SRAM
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 6 – "WHY use pointers? • Efficient: Only 4 bytes (address) instead of entire struct • Allows modification: Function can change the original"
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
### Question 6
|
||||
The NEC command codes for the IR remote are: button 1 = `0x0C`, button 2 = `0x18`, button 3 = `0x5E`. In the `ir_to_led_number` function, how does the assembly check which button was pressed?
|
||||
|
||||
A) The function uses a lookup table indexed by the NEC code
|
||||
B) The function uses sequential `cmp` instructions comparing the NEC code against `0x0C`, `0x18`, and `0x5E`, with conditional branches to return 1, 2, or 3 respectively
|
||||
C) The function uses bitwise AND to mask out the button number from the NEC frame
|
||||
D) The function calculates `ir_command / 0x0C` to determine the LED number
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 5 – Function example: "if (ir_command == 0x0C) return 1; if (ir_command == 0x18) return 2;" and NEC Command Codes table
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
### Question 7
|
||||
What are the advantages of analyzing an `.elf` file in Ghidra instead of a `.bin` file?
|
||||
|
||||
A) `.elf` files are smaller and faster to analyze
|
||||
B) `.elf` files contain symbol information (function names, variable labels), section headers (`.text`, `.data`, `.rodata`), and possibly debug info — none of which exist in a raw `.bin` file
|
||||
C) `.elf` files include the source code embedded in them
|
||||
D) `.elf` files are encrypted and Ghidra can decrypt them
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 18, Step 50 – ".BIN: No symbols, raw bytes only, no debug info; .ELF: Function/variable names, .text/.data/.rodata sections, may include debug symbols"
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
### Question 8
|
||||
When the tutorial swaps LED 1 (GPIO 16/Red) and LED 3 (GPIO 18/Yellow) by patching `0x10` to `0x12` and `0x12` to `0x10`, the terminal log still says "LED 1 activated on GPIO 16". Why is this a security concern?
|
||||
|
||||
A) The log file becomes corrupted and unreadable
|
||||
B) The hardware behavior no longer matches what the logs report — this is log desynchronization, which means an attacker can change physical behavior while forensic logs show normal operation
|
||||
C) The patched binary will crash when the log function tries to print
|
||||
D) The GPIO numbers in the log are encrypted so they cannot be verified
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 19, Step 57 – "Terminal shows: 'LED 1 activated on GPIO 16' (WRONG — it's actually GPIO 18!)" and "Again, logs don't match reality!" and Key Takeaway 9
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
### Question 9
|
||||
The `blink_led` function is called as `blink_led(pin, 3, 50)`. In the ARM calling convention, which registers hold these three arguments?
|
||||
|
||||
A) `r0` = pin, `r1` = 3 (blink count), `r2` = 50 (delay in ms) — the first four parameters go in `r0`-`r3` in order
|
||||
B) `r1` = pin, `r2` = 3, `r3` = 50 — `r0` is reserved for the return value
|
||||
C) All three are pushed onto the stack — registers are only used for pointer arguments
|
||||
D) `r0` = 50, `r1` = 3, `r2` = pin — arguments are passed in reverse order
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 17 and general ARM calling convention used throughout – arguments go in `r0`, `r1`, `r2`, `r3` in order; Week 9 Key Takeaway 4 – "Arguments go in r0-r3"
|
||||
|
||||
**Correct Answer: A**
|
||||
|
||||
---
|
||||
|
||||
### Question 10
|
||||
Even though you analyzed the `.elf` file in Ghidra to find function names and struct patterns, you still patch the `.bin` file for flashing. Why?
|
||||
|
||||
A) Ghidra cannot export modified `.elf` files
|
||||
B) The `.bin` file contains only the raw firmware bytes that get written directly to flash at `0x10000000` — the `.elf` file contains metadata (headers, sections, symbols) that is not part of the actual firmware and would not be understood by the UF2 conversion tool
|
||||
C) The `.elf` file is read-only and cannot be modified
|
||||
D) The Pico 2 hardware rejects `.elf` files during BOOTSEL flashing
|
||||
|
||||
> 📖 **Reference:** Week 11, Part 19, Step 55 – "IMPORTANT: Even though we analyzed the .elf, we patch the .bin!" and the .BIN vs .ELF comparison table showing .bin is for "Flashing to hardware" while .elf is for "Analysis and debugging"
|
||||
|
||||
**Correct Answer: B**
|
||||
|
||||
---
|
||||
|
||||
## Answer Key
|
||||
|
||||
1. B - 6 bytes total; all members are 1 byte each (uint8_t and bool), stored consecutively with no padding
|
||||
2. B - Dot is for struct variables; arrow is for struct pointers and is shorthand for `(*ptr).member`
|
||||
3. B - Address, address inverse, command, command inverse — inverses provide error checking
|
||||
4. B - Struct operations flatten to individual `movs`/`bl` sequences; struct abstraction disappears in assembly
|
||||
5. B - Pointer passing is efficient (4 bytes vs full struct copy) and allows modification of the original
|
||||
6. B - Sequential `cmp` instructions compare against each NEC code and branch to return the LED number
|
||||
7. B - `.elf` files provide symbols, section headers, and debug info that `.bin` files lack
|
||||
8. B - Log desynchronization: physical behavior diverges from logs, hiding attacks from forensic analysis
|
||||
9. A - ARM calling convention: first four args in `r0`-`r3` in order — pin, count, delay
|
||||
10. B - `.bin` contains raw firmware for flash; `.elf` has metadata not usable by UF2 conversion or hardware
|
||||
|
||||
---
|
||||
|
||||
## Scoring Guide
|
||||
|
||||
- **10 correct**: Excellent! You have a strong grasp of Week 11 concepts
|
||||
- **8-9 correct**: Very good! Review the topics you missed
|
||||
- **6-7 correct**: Good start. Go back and review the key concepts
|
||||
- **5 or fewer**: Review the Week 11 material again and try the practice exercises
|
||||
|
||||
---
|
||||
|
||||
## Topics Covered
|
||||
|
||||
This quiz tests your understanding of:
|
||||
- C struct memory layout: consecutive byte storage and total size calculation
|
||||
- Dot operator vs arrow operator for struct vs pointer-to-struct access
|
||||
- NEC infrared protocol: 32-bit frame structure with address/command and inverse fields
|
||||
- Compiler struct flattening: how struct member accesses become individual `movs` instructions
|
||||
- Pass-by-pointer efficiency: 4-byte address vs full struct copy, and modification capability
|
||||
- NEC command code comparison using `cmp`/`beq` instruction sequences
|
||||
- `.elf` vs `.bin` file analysis: symbols, sections, and debug info advantages
|
||||
- Log desynchronization: security implications of hardware behavior diverging from logged output
|
||||
- ARM calling convention: `r0`-`r3` for the first four function parameters in order
|
||||
- Analysis vs patching workflow: analyze `.elf` for information, patch `.bin` for flashing
|
||||
@@ -0,0 +1,66 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 11
|
||||
Functions in Embedded Systems: Debugging and Hacking Functions w/ IR Remote and Multi-LED Control
|
||||
|
||||
### Non-Credit Practice Exercise 1 Solution: Add a Fourth LED
|
||||
|
||||
#### Answers
|
||||
|
||||
##### Struct Layout (simple_led_ctrl_t)
|
||||
|
||||
| Offset | Field | Size | Original Value | Hex |
|
||||
|--------|------------|--------|----------------|------|
|
||||
| 0 | led1_pin | 1 byte | GPIO 16 | 0x10 |
|
||||
| 1 | led2_pin | 1 byte | GPIO 17 | 0x11 |
|
||||
| 2 | led3_pin | 1 byte | GPIO 18 | 0x12 |
|
||||
| 3 | led1_state | 1 byte | false (0) | 0x00 |
|
||||
| 4 | led2_state | 1 byte | false (0) | 0x00 |
|
||||
| 5 | led3_state | 1 byte | false (0) | 0x00 |
|
||||
|
||||
Total struct size: **6 bytes** (3 pin bytes + 3 state bytes).
|
||||
|
||||
##### Assembly Initialization Pattern
|
||||
|
||||
```asm
|
||||
movs r0, #0x10 ; led1_pin = 16
|
||||
strb r0, [r4, #0] ; struct offset 0
|
||||
movs r0, #0x11 ; led2_pin = 17
|
||||
strb r0, [r4, #1] ; struct offset 1
|
||||
movs r0, #0x12 ; led3_pin = 18
|
||||
strb r0, [r4, #2] ; struct offset 2
|
||||
```
|
||||
|
||||
##### Patch: Add GPIO 19 at Struct Offset 3
|
||||
|
||||
Writing `0x13` to offset 3 **overwrites led1_state**:
|
||||
|
||||
| Offset | Before | After | Impact |
|
||||
|--------|-------------|-------------|----------------------|
|
||||
| 3 | 0x00 (led1_state = false) | 0x13 (led4_pin = GPIO 19) | led1_state corrupted |
|
||||
|
||||
##### GDB Verification
|
||||
|
||||
```gdb
|
||||
(gdb) b *0x10000280
|
||||
(gdb) c
|
||||
(gdb) x/8bx <struct_address>
|
||||
```
|
||||
|
||||
Before patch: `10 11 12 00 00 00`
|
||||
After patch: `10 11 12 13 00 00`
|
||||
|
||||
#### Reflection Answers
|
||||
|
||||
1. **The original struct has 6 members (3 pins + 3 states) in 6 bytes. If you add a fourth pin at offset 3, you overwrite led1_state. What is the practical impact on LED 1 behavior?**
|
||||
The byte `0x13` (decimal 19) is written to offset 3, which the program reads as `led1_state`. Since `bool` in C treats any non-zero value as `true`, `led1_state` would be interpreted as `true` (on) immediately after the struct is initialized. LED 1 would appear to be in the "on" state from the start, regardless of whether the user pressed button 1. The `leds_all_off` function may reset it to 0, but every time the struct is re-initialized on the stack (each loop iteration), the corrupted state returns. The fourth LED at GPIO 19 would need additional `gpio_init` and `gpio_set_dir` calls to actually function — just writing the pin number into the struct doesn't configure the GPIO hardware.
|
||||
|
||||
2. **How would you verify the exact struct layout and offsets using GDB's memory examination commands?**
|
||||
Set a breakpoint after struct initialization (`b *0x10000280`), then `x/6bx <struct_base>` to see all 6 bytes. Verify: offsets 0–2 should show `10 11 12` (pin values), offsets 3–5 should show `00 00 00` (state values). Use `x/1bx <struct_base+N>` for individual fields. To find the struct base, examine `r4` at the breakpoint since the `strb r0, [r4, #N]` instructions use r4 as the base. You can also use `p/x $r4` to get the base address, then `x/6bx $r4` for the complete layout.
|
||||
|
||||
3. **If the get_led_pin function uses a bounds check (e.g., if led_num > 3 return 0), what additional patch would you need?**
|
||||
You would need to find the comparison instruction in `get_led_pin` (at approximately `0x100002a0`) — likely a `cmp rN, #3` followed by a conditional branch. Patch the immediate from `#3` to `#4` so the bounds check allows led_num = 4. For example, if the check is `cmp r1, #3; bhi default`, change `03` to `04` in the `cmp` instruction's immediate byte. Without this patch, passing led_num=4 would fail the bounds check and return 0 (no pin), so the fourth LED would never be addressed.
|
||||
|
||||
4. **Could you extend the struct without overwriting existing fields by finding free space elsewhere in the binary? What challenges would that introduce?**
|
||||
You could find unused space (padding, NOP sleds, or unused data) and place the extended struct there. However, this introduces major challenges: (1) Every instruction that references the original struct address via `r4` would need to be redirected to the new location. (2) All `strb`/`ldrb` offsets would need updating. (3) Stack-allocated structs are recreated each loop iteration — you'd need to change the stack frame size (`sub sp, sp, #N`). (4) Functions that receive the struct pointer as an argument would need their call sites updated. In practice, relocating a struct in a compiled binary is extremely complex and error-prone — overwriting adjacent fields is the pragmatic (if destructive) approach.
|
||||
@@ -0,0 +1,156 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 11
|
||||
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
|
||||
|
||||
### Non-Credit Practice Exercise 1: Add a Fourth LED
|
||||
|
||||
#### Objective
|
||||
Find the struct initialization pattern in the `0x0026_functions` binary using GDB where `led1_pin` (0x10), `led2_pin` (0x11), and `led3_pin` (0x12) are stored, locate an unused byte in the struct memory region, and patch it to include a fourth LED on GPIO 19 (0x13) by extending the struct data and modifying the `ir_to_led_number` function to handle a fourth button mapping.
|
||||
|
||||
#### Prerequisites
|
||||
- Completed Week 11 tutorial (GDB and hex editor sections)
|
||||
- `0x0026_functions.elf` and `0x0026_functions.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 IR remote and LEDs on GPIO 16, 17, 18 (and GPIO 19 wired for the new LED)
|
||||
|
||||
#### Task Description
|
||||
The `simple_led_ctrl_t` struct stores three LED pin numbers: `led1_pin` (16/0x10), `led2_pin` (17/0x11), `led3_pin` (18/0x12). These are stored as consecutive bytes in the struct initialization. You will find where the struct is initialized in the binary, locate the `movs` instructions that set the pin values, and add `led4_pin` = 19 (0x13) by patching a nearby unused or default byte. You will also need to find where `ir_to_led_number` returns values 1, 2, or 3 and adjust the NEC command comparison to map a fourth button to LED 4.
|
||||
|
||||
#### 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\0x0026_functions.elf
|
||||
```
|
||||
|
||||
**Connect to target:**
|
||||
|
||||
```gdb
|
||||
(gdb) target remote :3333
|
||||
(gdb) monitor reset halt
|
||||
```
|
||||
|
||||
##### Step 2: Find the Struct Initialization
|
||||
|
||||
Disassemble main and look for the struct pin assignments:
|
||||
|
||||
```gdb
|
||||
(gdb) disassemble 0x10000234,+300
|
||||
```
|
||||
|
||||
Look for consecutive `movs` instructions:
|
||||
|
||||
```
|
||||
movs r0, #0x10 ; led1_pin = 16
|
||||
strb r0, [r4, #0] ; store to struct offset 0
|
||||
movs r0, #0x11 ; led2_pin = 17
|
||||
strb r0, [r4, #1] ; store to struct offset 1
|
||||
movs r0, #0x12 ; led3_pin = 18
|
||||
strb r0, [r4, #2] ; store to struct offset 2
|
||||
```
|
||||
|
||||
##### Step 3: Examine the Struct in Memory
|
||||
|
||||
Set a breakpoint after initialization and examine the struct:
|
||||
|
||||
```gdb
|
||||
(gdb) break *0x10000280
|
||||
(gdb) monitor reset halt
|
||||
(gdb) continue
|
||||
(gdb) x/8bx <struct_base_address>
|
||||
```
|
||||
|
||||
You should see: `10 11 12 00 00 00` — the three pin values followed by the state booleans (all false/0x00).
|
||||
|
||||
##### Step 4: Find the `get_led_pin` Function
|
||||
|
||||
Look for the function that reads from the struct based on LED number:
|
||||
|
||||
```gdb
|
||||
(gdb) disassemble 0x100002a0,+50
|
||||
```
|
||||
|
||||
This function takes a struct pointer and LED number and returns the GPIO pin by reading from a struct offset.
|
||||
|
||||
##### Step 5: Calculate File Offsets
|
||||
|
||||
```
|
||||
file_offset = address - 0x10000000
|
||||
```
|
||||
|
||||
Note offsets for:
|
||||
1. The `movs r0, #0x12` instruction (last pin assignment)
|
||||
2. The byte after `led3_pin` in the struct (where `led4_pin` would go)
|
||||
|
||||
##### Step 6: Plan the Patches
|
||||
|
||||
| Patch Target | Original | New | Purpose |
|
||||
| --------------------- | -------- | ------ | ------------------------- |
|
||||
| Struct byte after 0x12 | `00` | `13` | Add led4_pin = GPIO 19 |
|
||||
|
||||
###### Question 1: The struct layout has `led3_pin` at offset 2 and `led1_state` at offset 3. If you write `0x13` to offset 3, what happens to `led1_state`?
|
||||
|
||||
##### Step 7: Patch with HxD
|
||||
|
||||
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
|
||||
2. Navigate to the struct initialization area
|
||||
3. Apply the patches identified in Step 6
|
||||
|
||||
##### Step 8: Save and Convert
|
||||
|
||||
1. Click **File** → **Save As** → `0x0026_functions-h.bin`
|
||||
|
||||
```powershell
|
||||
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
|
||||
python ..\uf2conv.py build\0x0026_functions-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
|
||||
```
|
||||
|
||||
##### Step 9: 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 behavior:**
|
||||
- Existing buttons 1, 2, 3 should still control their LEDs
|
||||
- Verify with GDB that the struct now contains `10 11 12 13` at the pin offsets
|
||||
|
||||
#### Expected Output
|
||||
|
||||
After completing this exercise, you should be able to:
|
||||
- Understand struct memory layout and member offsets
|
||||
- Identify struct initialization patterns in ARM assembly
|
||||
- Patch struct data members in binary firmware
|
||||
- Reason about the consequences of overwriting adjacent struct fields
|
||||
|
||||
#### Questions for Reflection
|
||||
|
||||
###### Question 1: The original struct has 6 members (3 pins + 3 states) in 6 bytes. If you add a fourth pin at offset 3, you overwrite `led1_state`. What is the practical impact on LED 1 behavior?
|
||||
|
||||
###### Question 2: How would you verify the exact struct layout and offsets using GDB's memory examination commands?
|
||||
|
||||
###### Question 3: If the `get_led_pin` function uses a bounds check (e.g., `if led_num > 3 return 0`), what additional patch would you need?
|
||||
|
||||
###### Question 4: Could you extend the struct without overwriting existing fields by finding free space elsewhere in the binary? What challenges would that introduce?
|
||||
|
||||
#### Tips and Hints
|
||||
- GPIO 19 = `0x13` in hex
|
||||
- The struct is likely stack-allocated, so the initialization `movs`/`strb` sequence happens every loop iteration
|
||||
- Overwriting `led1_state` (offset 3) with `0x13` means LED 1 will appear as "on" (non-zero boolean) — this may cause LED 1 to be on at startup
|
||||
- The `get_led_pin` function likely uses the LED number as an index into the struct — trace how it calculates the offset
|
||||
@@ -0,0 +1,62 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 11
|
||||
Functions in Embedded Systems: Debugging and Hacking Functions w/ IR Remote and Multi-LED Control
|
||||
|
||||
### Non-Credit Practice Exercise 2 Solution: Change Blink Count
|
||||
|
||||
#### Answers
|
||||
|
||||
##### Blink Count Parameter
|
||||
|
||||
| Parameter | Original | Patched |
|
||||
|-------------|---------|---------|
|
||||
| Blink count | 3 | 5 |
|
||||
| Hex | 0x03 | 0x05 |
|
||||
| Register | r1 | r1 |
|
||||
| Instruction | movs r1, #3 | movs r1, #5 |
|
||||
|
||||
##### Assembly Context (blink_led Call)
|
||||
|
||||
```asm
|
||||
movs r0, <pin> ; r0 = GPIO pin number
|
||||
movs r1, #3 ; r1 = blink count ← PATCH THIS
|
||||
movs r2, #0x32 ; r2 = delay (50ms)
|
||||
bl blink_led ; blink_led(pin, 3, 50)
|
||||
```
|
||||
|
||||
##### Patch
|
||||
|
||||
The immediate byte in `movs r1, #3` is the first byte of the 2-byte Thumb instruction:
|
||||
|
||||
```
|
||||
Before: 03 21 (movs r1, #3)
|
||||
After: 05 21 (movs r1, #5)
|
||||
```
|
||||
|
||||
File offset = instruction address - 0x10000000.
|
||||
|
||||
##### Behavior After Patch
|
||||
|
||||
| Button | LED | Original | Patched |
|
||||
|--------|--------|-------------------|---------------------|
|
||||
| 1 | Red | Blinks 3×, stays on | Blinks 5×, stays on |
|
||||
| 2 | Green | Blinks 3×, stays on | Blinks 5×, stays on |
|
||||
| 3 | Yellow | Blinks 3×, stays on | Blinks 5×, stays on |
|
||||
|
||||
Total blink time at 50ms delay: 5 × (50 + 50) = **500ms** (was 300ms).
|
||||
|
||||
#### Reflection Answers
|
||||
|
||||
1. **movs rN, #imm8 can encode values 0–255. What is the maximum blink count with a single byte patch?**
|
||||
The maximum is **255** (`0xFF`). The `movs Rd, #imm8` Thumb instruction uses a full 8-bit immediate field, giving an unsigned range of 0–255. Setting the blink count to 255 would make each LED blink 255 times per button press — at 50ms on + 50ms off per blink, that's 255 × 100ms = **25.5 seconds** of blinking before the LED stays on. A count of 0 would skip the blink loop entirely (LED turns on immediately with no blinking).
|
||||
|
||||
2. **Why is blink count in r1 and not r0? What does r0 hold at this point?**
|
||||
The ARM calling convention (AAPCS) passes the first four function arguments in registers `r0`, `r1`, `r2`, `r3` in order. The `blink_led` function signature is `blink_led(uint8_t pin, uint8_t count, uint32_t delay_ms)`. So `r0` = pin (the GPIO number of the LED to blink), `r1` = count (how many times to blink), and `r2` = delay_ms (the delay in milliseconds between on/off transitions). The blink count is the second parameter, hence `r1`.
|
||||
|
||||
3. **If you wanted a blink count larger than 255 (e.g., 1000), what instruction sequence would the compiler generate instead of movs?**
|
||||
For values exceeding 255, the compiler would use a 32-bit Thumb-2 `movw r1, #imm16` instruction, which can encode 0–65535. For example, `movw r1, #1000` would be 4 bytes: `40 F2 E8 31` (encoding `movw r1, #0x3E8`). For values exceeding 65535, the compiler would add `movt r1, #imm16` to set the upper 16 bits, or use a literal pool load (`ldr r1, [pc, #offset]`). The function parameter type (`uint8_t`) would still truncate to 0–255, so a count of 1000 would wrap to 232 (1000 mod 256) unless the function uses a wider type internally.
|
||||
|
||||
4. **Is there one shared movs r1, #3 instruction for all three LEDs, or does each blink_led call have its own? How can you tell?**
|
||||
Each `blink_led` call likely has its **own** `movs r1, #3` instruction. The compiler generates separate parameter setup sequences for each `bl blink_led` call site — the `movs r0, <pin>` instruction before each call loads a different GPIO pin. You can verify by disassembling the full range (`disassemble 0x10000234,+300`) and counting how many `movs r1, #3` instructions appear before `bl blink_led` calls. If there are three separate call sites with three separate `movs r1, #3` instructions, you need to **patch all three** to change the blink count for every LED. If only one is patched, only that LED's blink count changes.
|
||||
@@ -0,0 +1,144 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 11
|
||||
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
|
||||
|
||||
### Non-Credit Practice Exercise 2: Change Blink Count
|
||||
|
||||
#### Objective
|
||||
Find the `blink_led(pin, 3, 50)` call in the `0x0026_functions` binary using GDB, identify the immediate value `#3` being loaded into `r1` (the blink count parameter), calculate the file offset, and patch it to `#5` so that each LED blinks 5 times instead of 3 when activated by the IR remote.
|
||||
|
||||
#### Prerequisites
|
||||
- Completed Week 11 tutorial (GDB and hex editor sections)
|
||||
- `0x0026_functions.elf` and `0x0026_functions.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 IR remote and LEDs on GPIO 16, 17, 18
|
||||
|
||||
#### Task Description
|
||||
The `blink_led` function is called with three parameters: the GPIO pin number, a blink count of `3`, and a delay of `50`ms. The blink count is loaded as a small immediate value (`movs r1, #3`) directly in the instruction before the `bl blink_led` call. You will locate this instruction, find the byte encoding the `#3` immediate, and patch it to `#5` so the LEDs blink 5 times per button press.
|
||||
|
||||
#### 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\0x0026_functions.elf
|
||||
```
|
||||
|
||||
**Connect to target:**
|
||||
|
||||
```gdb
|
||||
(gdb) target remote :3333
|
||||
(gdb) monitor reset halt
|
||||
```
|
||||
|
||||
##### Step 2: Find the blink_led Call
|
||||
|
||||
Disassemble main and look for the function call sequence:
|
||||
|
||||
```gdb
|
||||
(gdb) disassemble 0x10000234,+300
|
||||
```
|
||||
|
||||
Look for the parameter setup before `bl blink_led`:
|
||||
|
||||
```
|
||||
movs r0, <pin> ; GPIO pin number (from get_led_pin)
|
||||
movs r1, #3 ; blink count = 3
|
||||
movs r2, #0x32 ; delay = 50ms
|
||||
bl blink_led
|
||||
```
|
||||
|
||||
Note the address of the `movs r1, #3` instruction.
|
||||
|
||||
##### Step 3: Examine the Instruction Encoding
|
||||
|
||||
Look at the raw bytes of the `movs r1, #3` instruction:
|
||||
|
||||
```gdb
|
||||
(gdb) x/2bx <address_of_movs_r1_3>
|
||||
```
|
||||
|
||||
In Thumb encoding, `movs r1, #imm8` has the immediate in the lower byte. You should see a byte containing `03`.
|
||||
|
||||
##### Step 4: Calculate the File Offset
|
||||
|
||||
```
|
||||
file_offset = address - 0x10000000
|
||||
```
|
||||
|
||||
Note the file offset of the byte containing `03`.
|
||||
|
||||
##### Step 5: Encode the New Value
|
||||
|
||||
| Parameter | Original | New | Encoding |
|
||||
| ---------- | -------- | ---- | -------------- |
|
||||
| Blink count | `03` | `05` | `movs r1, #5` |
|
||||
|
||||
##### Step 6: Patch with HxD
|
||||
|
||||
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
|
||||
2. Press **Ctrl+G** and enter the file offset
|
||||
3. You should see: `03`
|
||||
4. Replace with: `05`
|
||||
|
||||
###### Question 1: The `movs r1, #3` is a 2-byte Thumb instruction. Which byte contains the immediate — the first or the second?
|
||||
|
||||
##### Step 7: Save and Convert
|
||||
|
||||
1. Click **File** → **Save As** → `0x0026_functions-h.bin`
|
||||
|
||||
```powershell
|
||||
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
|
||||
python ..\uf2conv.py build\0x0026_functions-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 behavior:**
|
||||
- Press button 1 → Red LED blinks **5 times** (was 3), then stays on
|
||||
- Press button 2 → Green LED blinks **5 times** (was 3), then stays on
|
||||
- Press button 3 → Yellow LED blinks **5 times** (was 3), then stays on
|
||||
- Count carefully — you should see exactly 5 on/off cycles
|
||||
|
||||
#### Expected Output
|
||||
|
||||
After completing this exercise, you should be able to:
|
||||
- Locate small immediate values in Thumb `movs` instructions
|
||||
- Understand Thumb instruction encoding for immediate operands
|
||||
- Patch function parameters by modifying instruction immediates
|
||||
- Verify behavioral changes by counting observable events
|
||||
|
||||
#### Questions for Reflection
|
||||
|
||||
###### Question 1: The `movs rN, #imm8` instruction can encode values 0-255. What is the maximum blink count you could set with a single byte patch?
|
||||
|
||||
###### Question 2: Why is the blink count passed in `r1` and not `r0`? What does `r0` hold at this point in the calling convention?
|
||||
|
||||
###### Question 3: If you wanted to set the blink count to 256 or higher, the `movs` immediate would not be enough. What instruction sequence would the compiler need to generate instead?
|
||||
|
||||
###### Question 4: The same `blink_led` function is called for all three buttons. Does that mean there is only one `movs r1, #3` to patch, or could there be multiple call sites?
|
||||
|
||||
#### Tips and Hints
|
||||
- Small immediates (0-255) are encoded directly in the `movs` instruction — no literal pool needed
|
||||
- The ARM calling convention uses `r0`, `r1`, `r2`, `r3` for the first four function parameters in order
|
||||
- Look for `movs r1, #3` right before `bl blink_led` — there may be one shared call site or multiple per button
|
||||
- If there are multiple `movs r1, #3` instructions (one per case), you need to patch all of them for consistent behavior
|
||||
@@ -0,0 +1,70 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 11
|
||||
Functions in Embedded Systems: Debugging and Hacking Functions w/ IR Remote and Multi-LED Control
|
||||
|
||||
### Non-Credit Practice Exercise 3 Solution: Swap All Three LEDs
|
||||
|
||||
#### Answers
|
||||
|
||||
##### GPIO Rotation Patch
|
||||
|
||||
| Struct Member | Original | Patched | Effect |
|
||||
|--------------|-----------------|-----------------|---------------------|
|
||||
| led1_pin | 0x10 (GPIO 16 Red) | 0x11 (GPIO 17 Green) | Button 1 → Green |
|
||||
| led2_pin | 0x11 (GPIO 17 Green) | 0x12 (GPIO 18 Yellow) | Button 2 → Yellow |
|
||||
| led3_pin | 0x12 (GPIO 18 Yellow) | 0x10 (GPIO 16 Red) | Button 3 → Red |
|
||||
|
||||
##### Assembly Patches
|
||||
|
||||
Three single-byte patches in `movs` immediate fields:
|
||||
|
||||
```
|
||||
Patch 1 (led1_pin): 10 → 11
|
||||
Before: 10 20 (movs r0, #0x10)
|
||||
After: 11 20 (movs r0, #0x11)
|
||||
|
||||
Patch 2 (led2_pin): 11 → 12
|
||||
Before: 11 20 (movs r0, #0x11)
|
||||
After: 12 20 (movs r0, #0x12)
|
||||
|
||||
Patch 3 (led3_pin): 12 → 10
|
||||
Before: 12 20 (movs r0, #0x12)
|
||||
After: 10 20 (movs r0, #0x10)
|
||||
```
|
||||
|
||||
##### GDB Verification
|
||||
|
||||
```gdb
|
||||
(gdb) b *0x10000280
|
||||
(gdb) c
|
||||
(gdb) x/6bx <struct_address>
|
||||
```
|
||||
|
||||
Before patch: `10 11 12 00 00 00`
|
||||
After patch: `11 12 10 00 00 00`
|
||||
|
||||
##### Behavior After Patch
|
||||
|
||||
| Button (IR) | NEC Code | Terminal Log | Actual LED |
|
||||
|------------|----------|---------------------------|-----------|
|
||||
| Button 1 | 0x0C | "LED 1 activated on GPIO 16" | Green (GPIO 17) |
|
||||
| Button 2 | 0x18 | "LED 2 activated on GPIO 17" | Yellow (GPIO 18) |
|
||||
| Button 3 | 0x5E | "LED 3 activated on GPIO 18" | Red (GPIO 16) |
|
||||
|
||||
The terminal logs are **desynchronized** from actual behavior.
|
||||
|
||||
#### Reflection Answers
|
||||
|
||||
1. **Terminal log still says "LED 1 activated on GPIO 16" even though GPIO 17 (Green) is actually blinking. Why don't the logs update automatically?**
|
||||
The `printf` format strings and their arguments are separate from the struct pin assignments. The log message "LED 1 activated on GPIO 16" is generated from hardcoded format strings or from reading the **original** pin value before our patch takes effect. The GPIO number in the log comes from a different code path — likely a format string like `"LED %d activated on GPIO %d\r\n"` where the GPIO value was loaded from the struct at a different point or is computed independently. Since we only patched the `movs` instructions that store pin values into the struct, the logging code still uses whatever values it computes independently.
|
||||
|
||||
2. **If the struct initialization used ldr from a literal pool instead of movs immediates, how would the patching differ?**
|
||||
With literal pool loads, the pin values would be stored as 32-bit words in a data area near the function code. You would need to: (1) find the `ldr r0, [pc, #offset]` instruction, (2) calculate the PC-relative offset to locate the literal pool entry, (3) navigate to the pool address in the hex editor, and (4) modify the 4-byte value there. For example, GPIO 16 would be `10 00 00 00` (little-endian) in the pool. This is more work than patching a 1-byte `movs` immediate, and you'd need to verify no other code shares the same pool entry. The `movs` approach is simpler because the value is encoded directly in the instruction.
|
||||
|
||||
3. **Could you achieve the same LED rotation by patching gpio_init/gpio_put calls instead of the struct initialization? Which approach is cleaner?**
|
||||
Patching `gpio_init` and `gpio_put` calls would require finding every call site that references each GPIO pin and modifying the pin argument. This is scattered throughout multiple functions (`process_ir_led_command`, `blink_led`, `leds_all_off`). The struct initialization approach is **far cleaner** — three adjacent `movs` instructions in one location control the entire mapping. By patching the struct data at its source, every function that reads from the struct automatically gets the new values. This demonstrates the power of data-driven design: changing the data at one point affects all code that uses it.
|
||||
|
||||
4. **In a real attack, why is log desynchronization (display says one thing, hardware does another) dangerous for forensic analysis?**
|
||||
Log desynchronization is dangerous because forensic investigators rely on logs to reconstruct what happened. If logs show "LED 1 on GPIO 16" but the hardware actually activated GPIO 17, investigators would draw incorrect conclusions about which physical device was controlled. In industrial systems, this could mask sabotage — operators see "normal" readings while equipment is being misused. In security systems, tampered firmware could log "door locked" while actually unlocking it. The logs become actively misleading, not just incomplete. This is a form of **anti-forensics** that makes post-incident analysis unreliable and can delay or prevent discovery of the actual attack.
|
||||
@@ -0,0 +1,150 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 11
|
||||
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
|
||||
|
||||
### Non-Credit Practice Exercise 3: Swap All Three LEDs
|
||||
|
||||
#### Objective
|
||||
Find the struct initialization instructions where `led1_pin` = 0x10 (GPIO 16, Red), `led2_pin` = 0x11 (GPIO 17, Green), and `led3_pin` = 0x12 (GPIO 18, Yellow) are written in the `0x0026_functions` binary using GDB, calculate the file offsets, and rotate the GPIO values so that button 1→Green (0x11), button 2→Yellow (0x12), and button 3→Red (0x10), then verify on hardware that the LED mapping has shifted.
|
||||
|
||||
#### Prerequisites
|
||||
- Completed Week 11 tutorial (GDB and hex editor sections)
|
||||
- `0x0026_functions.elf` and `0x0026_functions.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 IR remote and LEDs on GPIO 16, 17, 18
|
||||
|
||||
#### Task Description
|
||||
The struct initialization sets `led1_pin` = 16 (0x10), `led2_pin` = 17 (0x11), `led3_pin` = 18 (0x12) using `movs` instructions that store each value into the struct. By patching the immediate values in these three `movs` instructions, you can rotate the LED assignment: `led1_pin` = 17 (Green), `led2_pin` = 18 (Yellow), `led3_pin` = 16 (Red). This means button 1 will light the Green LED, button 2 the Yellow LED, and button 3 the Red LED.
|
||||
|
||||
#### 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\0x0026_functions.elf
|
||||
```
|
||||
|
||||
**Connect to target:**
|
||||
|
||||
```gdb
|
||||
(gdb) target remote :3333
|
||||
(gdb) monitor reset halt
|
||||
```
|
||||
|
||||
##### Step 2: Find the Three movs Instructions
|
||||
|
||||
Disassemble main and find the struct pin initialization:
|
||||
|
||||
```gdb
|
||||
(gdb) disassemble 0x10000234,+300
|
||||
```
|
||||
|
||||
Look for three consecutive `movs`/`strb` pairs:
|
||||
|
||||
```
|
||||
movs r0, #0x10 ; led1_pin = 16 (Red)
|
||||
strb r0, [r4, #0]
|
||||
movs r0, #0x11 ; led2_pin = 17 (Green)
|
||||
strb r0, [r4, #1]
|
||||
movs r0, #0x12 ; led3_pin = 18 (Yellow)
|
||||
strb r0, [r4, #2]
|
||||
```
|
||||
|
||||
Note the address of each `movs` instruction.
|
||||
|
||||
##### Step 3: Examine the Instruction Bytes
|
||||
|
||||
Check the raw encoding of each `movs`:
|
||||
|
||||
```gdb
|
||||
(gdb) x/2bx <address_of_movs_0x10>
|
||||
(gdb) x/2bx <address_of_movs_0x11>
|
||||
(gdb) x/2bx <address_of_movs_0x12>
|
||||
```
|
||||
|
||||
Each will have the GPIO pin number as the immediate byte.
|
||||
|
||||
##### Step 4: Calculate the File Offsets
|
||||
|
||||
```
|
||||
file_offset = address - 0x10000000
|
||||
```
|
||||
|
||||
Note the offset of the immediate byte in each of the three `movs` instructions.
|
||||
|
||||
##### Step 5: Plan the Rotation
|
||||
|
||||
| Struct Member | Original | New | Effect |
|
||||
| ------------- | ----------------- | ----------------- | ---------------- |
|
||||
| `led1_pin` | `10` (GPIO 16 Red) | `11` (GPIO 17 Green) | Button 1 → Green |
|
||||
| `led2_pin` | `11` (GPIO 17 Green) | `12` (GPIO 18 Yellow) | Button 2 → Yellow |
|
||||
| `led3_pin` | `12` (GPIO 18 Yellow) | `10` (GPIO 16 Red) | Button 3 → Red |
|
||||
|
||||
##### Step 6: Patch with HxD
|
||||
|
||||
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
|
||||
2. Go to the first `movs` immediate offset and change `10` to `11`
|
||||
3. Go to the second `movs` immediate offset and change `11` to `12`
|
||||
4. Go to the third `movs` immediate offset and change `12` to `10`
|
||||
|
||||
###### Question 1: All three patches are single-byte changes in `movs` immediates. Why is this simpler than patching literal pool entries?
|
||||
|
||||
##### Step 7: Save and Convert
|
||||
|
||||
1. Click **File** → **Save As** → `0x0026_functions-h.bin`
|
||||
|
||||
```powershell
|
||||
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
|
||||
python ..\uf2conv.py build\0x0026_functions-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 behavior:**
|
||||
- Press button 1 → **Green** LED blinks (was Red)
|
||||
- Press button 2 → **Yellow** LED blinks (was Green)
|
||||
- Press button 3 → **Red** LED blinks (was Yellow)
|
||||
- Terminal still says "LED 1 activated on GPIO 16" — but the actual LED is Green (GPIO 17)
|
||||
|
||||
#### Expected Output
|
||||
|
||||
After completing this exercise, you should be able to:
|
||||
- Locate struct initialization patterns in ARM Thumb assembly
|
||||
- Patch multiple `movs` immediates to rotate data values
|
||||
- Understand the disconnect between logged values and actual hardware behavior
|
||||
- Recognize log desynchronization as a security concern
|
||||
|
||||
#### Questions for Reflection
|
||||
|
||||
###### Question 1: The terminal log still says "LED 1 activated on GPIO 16" even though GPIO 17 (Green) is actually blinking. Why don't the logs update automatically?
|
||||
|
||||
###### Question 2: If the struct initialization used `ldr` from a literal pool instead of `movs` immediates, how would the patching approach differ?
|
||||
|
||||
###### Question 3: Could you achieve the same LED rotation by patching the `gpio_init` and `gpio_put` calls instead of the struct? Which approach is cleaner and why?
|
||||
|
||||
###### Question 4: In a real attack scenario, why is log desynchronization (logs say one thing, hardware does another) particularly dangerous for forensic analysis?
|
||||
|
||||
#### Tips and Hints
|
||||
- The three `movs` instructions are likely within 10-20 bytes of each other — use `x/20i` to see them all at once
|
||||
- The `movs rN, #imm8` immediate is in the lower byte of the 2-byte Thumb instruction
|
||||
- Make sure you patch the `movs` for the struct initialization, not any other `movs #0x10/0x11/0x12` that may exist elsewhere
|
||||
- Verify by examining the struct in memory after initialization: `x/6bx <struct_address>` should show `11 12 10` for the pin bytes
|
||||
@@ -0,0 +1,60 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 11
|
||||
Functions in Embedded Systems: Debugging and Hacking Functions w/ IR Remote and Multi-LED Control
|
||||
|
||||
### Non-Credit Practice Exercise 4 Solution: Change Blink Speed
|
||||
|
||||
#### Answers
|
||||
|
||||
##### Delay Parameter
|
||||
|
||||
| Parameter | Original | Patched |
|
||||
|----------|-------------|--------------|
|
||||
| Delay | 50ms | 25ms |
|
||||
| Hex | 0x32 | 0x19 |
|
||||
| Register | r2 | r2 |
|
||||
| Instruction | movs r2, #0x32 | movs r2, #0x19 |
|
||||
|
||||
##### Assembly Context
|
||||
|
||||
```asm
|
||||
movs r0, <pin> ; r0 = GPIO pin
|
||||
movs r1, #3 ; r1 = blink count
|
||||
movs r2, #0x32 ; r2 = delay 50ms ← PATCH THIS
|
||||
bl blink_led ; blink_led(pin, 3, 50)
|
||||
```
|
||||
|
||||
##### Patch
|
||||
|
||||
```
|
||||
Before: 32 22 (movs r2, #0x32 = 50ms)
|
||||
After: 19 22 (movs r2, #0x19 = 25ms)
|
||||
```
|
||||
|
||||
**Warning:** The byte `0x32` is also ASCII '2'. Verify you're patching the correct `movs r2` instruction by checking surrounding bytes — `movs r1, #3` (`03 21`) should appear immediately before, and `bl blink_led` immediately after.
|
||||
|
||||
##### Timing Comparison
|
||||
|
||||
| Metric | Original (50ms) | Patched (25ms) |
|
||||
|-------------------|-----------------|----------------|
|
||||
| On-time per blink | 50ms | 25ms |
|
||||
| Off-time per blink| 50ms | 25ms |
|
||||
| One blink cycle | 100ms | 50ms |
|
||||
| 3 blinks total | 300ms | 150ms |
|
||||
| Perceived speed | Normal | 2× faster |
|
||||
|
||||
#### Reflection Answers
|
||||
|
||||
1. **If delay = 1ms (0x01), would you still see the LED blink, or would it appear constantly on?**
|
||||
At 1ms on/off (2ms per cycle, 500Hz flicker), the LED would appear **constantly on** to the human eye. Human flicker fusion threshold is approximately 60Hz — anything above that appears as a steady light. At 500Hz, the LED is switching far too fast for the eye to perceive individual blinks. The LED would look like it's at roughly 50% brightness (since it's on half the time) compared to being fully on. The 3 blinks would complete in just 6ms total, appearing as a brief flash rather than distinct blinks.
|
||||
|
||||
2. **0x32 appears as both the delay value (50ms) and potentially ASCII '2'. How would you systematically find ALL occurrences of 0x32 and determine which to patch?**
|
||||
Search the binary for all `0x32` bytes, then examine the **context** of each occurrence: (1) Check the byte following `0x32` — if it's `0x22`, this is `movs r2, #0x32` (the delay parameter). If it's `0x2C`, it's `cmp r4, #0x32` (comparing against ASCII '2'). (2) Examine surrounding instructions: the delay `0x32` will be preceded by `movs r1, #3` (blink count) and followed by `bl blink_led`. A comparison `0x32` will be near `beq`/`bne` branches. (3) Use GDB to disassemble the region (`x/10i <addr-4>`) and read the instruction mnemonic. (4) Cross-reference with the function structure — delay patches are in `blink_led` call setup, comparisons are in `ir_to_led_number` or similar dispatcher functions.
|
||||
|
||||
3. **For a delay of 500ms (0x1F4), the value won't fit in a movs immediate (max 255). How would the compiler handle it?**
|
||||
For 500 (`0x1F4`), the compiler would use either: (1) A 32-bit `movw r2, #0x1F4` Thumb-2 instruction (4 bytes), which can encode any 16-bit immediate (0–65535). (2) A literal pool load: `ldr r2, [pc, #offset]` that reads `0x000001F4` from a nearby data word. The `movw` approach is preferred for values 256–65535 because it's a single instruction with no data dependency. For values exceeding 65535, a literal pool or `movw`+`movt` pair would be necessary.
|
||||
|
||||
4. **The blink function uses the delay for both on-time and off-time (symmetrical blink). Could you make the LED stay on longer than off by patching only one instruction?**
|
||||
Not with a single patch to the `movs r2` instruction, because `blink_led` uses the same delay parameter for both the on-phase and off-phase `sleep_ms` calls internally. To create asymmetric blink timing, you would need to patch **inside** the `blink_led` function itself — find the two `sleep_ms` calls within the blink loop and modify their delay arguments independently. For example, find the `ldr`/`movs` that sets up `r0` before each `bl sleep_ms` inside `blink_led`, and patch one to a different value. This would require disassembling `blink_led` to locate both `sleep_ms` call sites.
|
||||
@@ -0,0 +1,146 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
|
||||
|
||||
## Week 11
|
||||
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
|
||||
|
||||
### Non-Credit Practice Exercise 4: Change Blink Speed
|
||||
|
||||
#### Objective
|
||||
Find the `blink_led(pin, 3, 50)` call in the `0x0026_functions` binary using GDB, identify the immediate value `0x32` (50) being loaded into `r2` (the delay parameter), calculate the file offset, and patch it to `0x19` (25) so that each LED blinks at double speed when activated by the IR remote.
|
||||
|
||||
#### Prerequisites
|
||||
- Completed Week 11 tutorial (GDB and hex editor sections)
|
||||
- `0x0026_functions.elf` and `0x0026_functions.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 IR remote and LEDs on GPIO 16, 17, 18
|
||||
|
||||
#### Task Description
|
||||
The `blink_led` function takes a delay parameter of `50`ms (`0x32`) in register `r2`. This value controls how long each LED stays on and off during the blink cycle. By patching this to `25`ms (`0x19`), the LEDs will blink twice as fast, creating a noticeably quicker flashing pattern when any IR remote button is pressed.
|
||||
|
||||
#### 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\0x0026_functions.elf
|
||||
```
|
||||
|
||||
**Connect to target:**
|
||||
|
||||
```gdb
|
||||
(gdb) target remote :3333
|
||||
(gdb) monitor reset halt
|
||||
```
|
||||
|
||||
##### Step 2: Find the blink_led Call
|
||||
|
||||
Disassemble main and look for the parameter setup before `bl blink_led`:
|
||||
|
||||
```gdb
|
||||
(gdb) disassemble 0x10000234,+300
|
||||
```
|
||||
|
||||
Look for:
|
||||
|
||||
```
|
||||
movs r0, <pin> ; GPIO pin number
|
||||
movs r1, #3 ; blink count
|
||||
movs r2, #0x32 ; delay = 50ms
|
||||
bl blink_led
|
||||
```
|
||||
|
||||
Note the address of the `movs r2, #0x32` instruction.
|
||||
|
||||
##### Step 3: Examine the Instruction Encoding
|
||||
|
||||
Look at the raw bytes:
|
||||
|
||||
```gdb
|
||||
(gdb) x/2bx <address_of_movs_r2_0x32>
|
||||
```
|
||||
|
||||
The `movs r2, #0x32` instruction has `0x32` (50) as the immediate byte.
|
||||
|
||||
##### Step 4: Calculate the File Offset
|
||||
|
||||
```
|
||||
file_offset = address - 0x10000000
|
||||
```
|
||||
|
||||
Note the file offset of the byte containing `32`.
|
||||
|
||||
##### Step 5: Encode the New Value
|
||||
|
||||
| Parameter | Original | New | Effect |
|
||||
| --------- | --------------- | --------------- | --------------- |
|
||||
| Delay | `32` (50ms) | `19` (25ms) | 2x faster blink |
|
||||
|
||||
**Be careful:** `0x32` is also the ASCII code for '2'. Make sure you are patching the `movs r2` instruction and not a comparison value like `cmp r4, #0x32`.
|
||||
|
||||
##### Step 6: Patch with HxD
|
||||
|
||||
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
|
||||
2. Press **Ctrl+G** and enter the file offset
|
||||
3. You should see: `32`
|
||||
4. Replace with: `19`
|
||||
|
||||
###### Question 1: How can you confirm you are patching the delay parameter and not some other `0x32` byte in the binary?
|
||||
|
||||
##### Step 7: Save and Convert
|
||||
|
||||
1. Click **File** → **Save As** → `0x0026_functions-h.bin`
|
||||
|
||||
```powershell
|
||||
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
|
||||
python ..\uf2conv.py build\0x0026_functions-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 behavior:**
|
||||
- Press button 1 → Red LED blinks 3 times but **noticeably faster** (25ms on/off vs 50ms)
|
||||
- Press button 2 → Green LED blinks 3 times at **double speed**
|
||||
- Press button 3 → Yellow LED blinks 3 times at **double speed**
|
||||
- The total blink sequence should complete in roughly half the original time
|
||||
|
||||
#### Expected Output
|
||||
|
||||
After completing this exercise, you should be able to:
|
||||
- Locate function parameters in ARM Thumb `movs` instructions
|
||||
- Distinguish between identical byte values used in different contexts
|
||||
- Patch timing parameters to change observable hardware behavior
|
||||
- Understand the relationship between delay values and perceived blink speed
|
||||
|
||||
#### Questions for Reflection
|
||||
|
||||
###### Question 1: The `blink_led` function calls `sleep_ms` internally with the delay value. If you set the delay to `1`ms (0x01), would you still see the LED blink, or would it appear constantly on?
|
||||
|
||||
###### Question 2: The value `0x32` appears in this binary as both a delay parameter (50ms) and potentially as an ASCII comparison ('2'). How would you systematically find ALL occurrences of `0x32` and determine which one to patch?
|
||||
|
||||
###### Question 3: If you wanted a delay of 500ms (0x1F4), the value would not fit in a `movs` immediate. How would the compiler handle this larger delay value?
|
||||
|
||||
###### Question 4: The blink function uses the delay for both the on-time and the off-time. Could you make the LED stay on longer than it stays off? What kind of patch would that require?
|
||||
|
||||
#### Tips and Hints
|
||||
- `25` decimal = `0x19` hex — fits in one byte, so the `movs` encoding works directly
|
||||
- Verify location by checking the surrounding instructions: `movs r1, #3` should be right before and `bl blink_led` right after
|
||||
- The total blink time for 3 blinks at 50ms = 3 × (50 + 50) = 300ms; at 25ms = 3 × (25 + 25) = 150ms
|
||||
- If there are multiple call sites for `blink_led`, each may have its own `movs r2, #0x32` that needs patching
|
||||
@@ -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 11</text>
|
||||
|
||||
<!-- Week Topic -->
|
||||
<text x="600" y="440" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">Structures and Functions in</text>
|
||||
<text x="600" y="478" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">Embedded Systems: Debugging and Hacking</text>
|
||||
<text x="600" y="516" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">w/ IR Remote Control & NEC 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.5 KiB |
@@ -0,0 +1,70 @@
|
||||
<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 Structures (Structs)</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">Grouping Related Data Together</text>
|
||||
|
||||
<!-- What is a Struct -->
|
||||
<rect class="pnl" x="30" y="110" width="1140" height="200" rx="8"/>
|
||||
<text class="sub" x="50" y="150">What is a Struct?</text>
|
||||
<text class="txt" x="50" y="185">A user-defined type that groups</text>
|
||||
<text class="txt" x="50" y="215">related variables under one name</text>
|
||||
<text class="dim" x="50" y="250">Like a form with multiple fields</text>
|
||||
<text class="dim" x="50" y="275">-- each field holds different data</text>
|
||||
|
||||
<!-- Struct Definition -->
|
||||
<rect class="pnl" x="30" y="330" width="555" height="300" rx="8"/>
|
||||
<text class="sub" x="50" y="370">Struct Definition</text>
|
||||
<rect x="50" y="385" width="515" height="230" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="cyn" x="70" y="413">typedef struct {</text>
|
||||
<text class="txt" x="100" y="441">uint8_t led1_pin;</text>
|
||||
<text class="txt" x="100" y="469">uint8_t led2_pin;</text>
|
||||
<text class="txt" x="100" y="497">uint8_t led3_pin;</text>
|
||||
<text class="txt" x="100" y="525">bool led1_state;</text>
|
||||
<text class="txt" x="100" y="553">bool led2_state;</text>
|
||||
<text class="txt" x="100" y="581">bool led3_state;</text>
|
||||
<text class="cyn" x="70" y="607">} simple_led_ctrl_t;</text>
|
||||
|
||||
<!-- Why Use Structs -->
|
||||
<rect class="pnl" x="615" y="330" width="555" height="300" rx="8"/>
|
||||
<text class="sub" x="635" y="370">Why Use Structs?</text>
|
||||
<text class="grn" x="635" y="410">1.</text>
|
||||
<text class="txt" x="680" y="410">Organization</text>
|
||||
<text class="dim" x="680" y="435">Related data stays together</text>
|
||||
<text class="grn" x="635" y="470">2.</text>
|
||||
<text class="txt" x="680" y="470">Readability</text>
|
||||
<text class="dim" x="680" y="495">Code easier to understand</text>
|
||||
<text class="grn" x="635" y="530">3.</text>
|
||||
<text class="txt" x="680" y="530">Scalability</text>
|
||||
<text class="dim" x="680" y="555">Easy to add more features</text>
|
||||
<text class="grn" x="635" y="590">4.</text>
|
||||
<text class="txt" x="680" y="590">Pass to Functions</text>
|
||||
|
||||
<!-- Struct Container Visualization -->
|
||||
<rect class="pnl" x="30" y="650" width="1140" height="110" rx="8"/>
|
||||
<text class="sub" x="50" y="682">simple_led_ctrl_t leds</text>
|
||||
<rect x="50" y="695" width="170" height="45" rx="6" fill="#0a0a0f" stroke="#00ff41"/>
|
||||
<text class="grn" x="65" y="724">pin1: 16</text>
|
||||
<rect x="240" y="695" width="170" height="45" rx="6" fill="#0a0a0f" stroke="#00ff41"/>
|
||||
<text class="grn" x="255" y="724">pin2: 17</text>
|
||||
<rect x="430" y="695" width="170" height="45" rx="6" fill="#0a0a0f" stroke="#00ff41"/>
|
||||
<text class="grn" x="445" y="724">pin3: 18</text>
|
||||
<rect x="630" y="695" width="160" height="45" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="dim" x="645" y="722">state1: 0</text>
|
||||
<rect x="810" y="695" width="160" height="45" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="dim" x="825" y="722">state2: 0</text>
|
||||
<rect x="990" y="695" width="160" height="45" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="dim" x="1005" y="722">state3: 0</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,85 @@
|
||||
<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">Struct Memory Layout</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">How Structs Are Stored and Accessed</text>
|
||||
|
||||
<!-- Memory Layout Table -->
|
||||
<rect class="pnl" x="30" y="110" width="1140" height="280" rx="8"/>
|
||||
<text class="sub" x="50" y="150">Memory Layout (6 bytes total)</text>
|
||||
|
||||
<text class="amb" x="50" y="190">Address</text>
|
||||
<text class="amb" x="230" y="190">Member</text>
|
||||
<text class="amb" x="500" y="190">Size</text>
|
||||
<text class="amb" x="650" y="190">Value</text>
|
||||
<line x1="50" y1="200" x2="1140" y2="200" stroke="#1a1a2e" stroke-width="1"/>
|
||||
|
||||
<text class="cyn" x="50" y="230">0x20000000</text>
|
||||
<text class="txt" x="250" y="230">led1_pin</text>
|
||||
<text class="dim" x="500" y="230">1 byte</text>
|
||||
<text class="grn" x="680" y="230">16 (0x10)</text>
|
||||
|
||||
<text class="cyn" x="50" y="260">0x20000001</text>
|
||||
<text class="txt" x="250" y="260">led2_pin</text>
|
||||
<text class="dim" x="500" y="260">1 byte</text>
|
||||
<text class="grn" x="680" y="260">17 (0x11)</text>
|
||||
|
||||
<text class="cyn" x="50" y="290">0x20000002</text>
|
||||
<text class="txt" x="250" y="290">led3_pin</text>
|
||||
<text class="dim" x="500" y="290">1 byte</text>
|
||||
<text class="grn" x="680" y="290">18 (0x12)</text>
|
||||
|
||||
<text class="cyn" x="50" y="320">0x20000003</text>
|
||||
<text class="txt" x="250" y="320">led1_state</text>
|
||||
<text class="dim" x="500" y="320">1 byte</text>
|
||||
<text class="txt" x="680" y="320">0 (false)</text>
|
||||
|
||||
<text class="cyn" x="50" y="350">0x20000004</text>
|
||||
<text class="txt" x="250" y="350">led2_state</text>
|
||||
<text class="dim" x="500" y="350">1 byte</text>
|
||||
<text class="txt" x="680" y="350">0 (false)</text>
|
||||
|
||||
<text class="cyn" x="50" y="380">0x20000005</text>
|
||||
<text class="txt" x="250" y="380">led3_state</text>
|
||||
<text class="dim" x="500" y="380">1 byte</text>
|
||||
<text class="txt" x="680" y="380">0 (false)</text>
|
||||
|
||||
<!-- Dot Operator -->
|
||||
<rect class="pnl" x="30" y="410" width="555" height="170" rx="8"/>
|
||||
<text class="sub" x="50" y="450">Dot Operator ( . )</text>
|
||||
<text class="dim" x="50" y="478">Use with struct variable</text>
|
||||
<rect x="50" y="492" width="515" height="70" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="txt" x="70" y="520">leds.led1_pin = 16;</text>
|
||||
<text class="txt" x="70" y="548">leds.led1_state = true;</text>
|
||||
|
||||
<!-- Arrow Operator -->
|
||||
<rect class="pnl" x="615" y="410" width="555" height="170" rx="8"/>
|
||||
<text class="sub" x="635" y="450">Arrow Operator ( -> )</text>
|
||||
<text class="dim" x="635" y="478">Use with pointer to struct</text>
|
||||
<rect x="635" y="492" width="515" height="70" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="txt" x="655" y="520">ptr->led1_pin = 16;</text>
|
||||
<text class="dim" x="655" y="548">// same as (*ptr).led1_pin</text>
|
||||
|
||||
<!-- Designated Initializer -->
|
||||
<rect class="pnl" x="30" y="600" width="1140" height="160" rx="8"/>
|
||||
<text class="sub" x="50" y="640">Designated Initializers</text>
|
||||
<rect x="50" y="655" width="740" height="85" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="cyn" x="70" y="683">simple_led_ctrl_t leds = {</text>
|
||||
<text class="grn" x="100" y="713">.led1_pin = 16, .led2_pin = 17, .led3_pin = 18</text>
|
||||
<text class="cyn" x="70" y="730">};</text>
|
||||
<text class="dim" x="820" y="690">Clear which value goes</text>
|
||||
<text class="dim" x="820" y="715">to which member</text>
|
||||
<text class="dim" x="820" y="740">Order doesn't matter</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,88 @@
|
||||
<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">NEC IR Protocol</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">Infrared Remote Control Communication</text>
|
||||
|
||||
<!-- How IR Works -->
|
||||
<rect class="pnl" x="30" y="110" width="1140" height="140" rx="8"/>
|
||||
<text class="sub" x="50" y="150">How IR Works</text>
|
||||
<text class="txt" x="50" y="185">Remote sends invisible light pulses</text>
|
||||
<text class="txt" x="50" y="215">IR receiver on GPIO 5 reads signal</text>
|
||||
<text class="dim" x="600" y="185">IR LED flashes in specific patterns</text>
|
||||
<text class="dim" x="600" y="215">Each pattern = different button</text>
|
||||
|
||||
<!-- NEC Frame -->
|
||||
<rect class="pnl" x="30" y="270" width="1140" height="200" rx="8"/>
|
||||
<text class="sub" x="50" y="310">NEC Protocol Frame (32 bits)</text>
|
||||
|
||||
<rect x="50" y="330" width="180" height="50" rx="6" fill="#0a0a0f" stroke="#ffaa00"/>
|
||||
<text class="amb" x="80" y="362">Leader</text>
|
||||
<rect x="240" y="330" width="180" height="50" rx="6" fill="#0a0a0f" stroke="#00d4ff"/>
|
||||
<text class="cyn" x="268" y="362">Address</text>
|
||||
<rect x="430" y="330" width="180" height="50" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="txt" x="455" y="362">Addr Inv</text>
|
||||
<rect x="620" y="330" width="180" height="50" rx="6" fill="#0a0a0f" stroke="#00ff41"/>
|
||||
<text class="grn" x="648" y="362">Command</text>
|
||||
<rect x="810" y="330" width="180" height="50" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="txt" x="840" y="362">Cmd Inv</text>
|
||||
<rect x="1000" y="330" width="130" height="50" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="dim" x="1030" y="362">Stop</text>
|
||||
|
||||
<text class="dim" x="80" y="410">9ms+4.5ms</text>
|
||||
<text class="dim" x="280" y="410">8-bit</text>
|
||||
<text class="dim" x="460" y="410">8-bit check</text>
|
||||
<text class="dim" x="660" y="410">8-bit</text>
|
||||
<text class="dim" x="850" y="410">8-bit check</text>
|
||||
|
||||
<text class="dim" x="50" y="450">Leader says "attention!", address identifies device, command is the button pressed</text>
|
||||
|
||||
<!-- Command Code Table -->
|
||||
<rect class="pnl" x="30" y="490" width="555" height="200" rx="8"/>
|
||||
<text class="sub" x="50" y="530">NEC Command Codes</text>
|
||||
|
||||
<text class="amb" x="50" y="570">Button</text>
|
||||
<text class="amb" x="200" y="570">NEC Code</text>
|
||||
<text class="amb" x="380" y="570">LED</text>
|
||||
<line x1="50" y1="580" x2="565" y2="580" stroke="#1a1a2e" stroke-width="1"/>
|
||||
|
||||
<text class="txt" x="50" y="610">1</text>
|
||||
<text class="grn" x="200" y="610">0x0C</text>
|
||||
<text class="red" x="380" y="610">Red (GP16)</text>
|
||||
|
||||
<text class="txt" x="50" y="640">2</text>
|
||||
<text class="grn" x="200" y="640">0x18</text>
|
||||
<text class="grn" x="380" y="640">Green (GP17)</text>
|
||||
|
||||
<text class="txt" x="50" y="670">3</text>
|
||||
<text class="grn" x="200" y="670">0x5E</text>
|
||||
<text class="amb" x="380" y="670">Yellow (GP18)</text>
|
||||
|
||||
<!-- Wiring -->
|
||||
<rect class="pnl" x="615" y="490" width="555" height="200" rx="8"/>
|
||||
<text class="sub" x="635" y="530">Hardware Wiring</text>
|
||||
<text class="cyn" x="635" y="565">GPIO 5</text>
|
||||
<text class="txt" x="800" y="565">IR Receiver (VS1838B)</text>
|
||||
<text class="cyn" x="635" y="595">GPIO 16</text>
|
||||
<text class="txt" x="800" y="595">Red LED + 220 ohm</text>
|
||||
<text class="cyn" x="635" y="625">GPIO 17</text>
|
||||
<text class="txt" x="800" y="625">Green LED + 220 ohm</text>
|
||||
<text class="cyn" x="635" y="655">GPIO 18</text>
|
||||
<text class="txt" x="800" y="655">Yellow LED + 220 ohm</text>
|
||||
|
||||
<!-- Bottom -->
|
||||
<rect class="pnl" x="30" y="710" width="1140" height="50" rx="8"/>
|
||||
<text class="dim" x="50" y="742">Projects: 0x0023_structures and 0x0026_functions</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,91 @@
|
||||
<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">Functions in C</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">Reusable Blocks of Code</text>
|
||||
|
||||
<!-- Function Anatomy -->
|
||||
<rect class="pnl" x="30" y="110" width="1140" height="195" rx="8"/>
|
||||
<text class="sub" x="50" y="150">Anatomy of a Function</text>
|
||||
<rect x="50" y="168" width="1100" height="50" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="cyn" x="70" y="200">int ir_to_led_number(int ir_command) {</text>
|
||||
|
||||
<text class="amb" x="70" y="235">^^^</text>
|
||||
<text class="amb" x="128" y="235">^^^^^^^^^^^^^^^^</text>
|
||||
<text class="amb" x="372" y="235">^^^^^^^^^^^^^^</text>
|
||||
<text class="dim" x="70" y="258">ret</text>
|
||||
<text class="dim" x="128" y="258">function name</text>
|
||||
<text class="dim" x="372" y="258">parameter</text>
|
||||
|
||||
<rect x="50" y="270" width="1100" height="35" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="grn" x="70" y="295">if (ir_command == 0x0C) return 1;</text>
|
||||
<text class="dim" x="600" y="295">// body + return value</text>
|
||||
|
||||
<!-- Function Types Table -->
|
||||
<rect class="pnl" x="30" y="325" width="555" height="245" rx="8"/>
|
||||
<text class="sub" x="50" y="365">Function Types</text>
|
||||
|
||||
<text class="amb" x="50" y="400">Type</text>
|
||||
<text class="amb" x="330" y="400">Example</text>
|
||||
<line x1="50" y1="410" x2="565" y2="410" stroke="#1a1a2e" stroke-width="1"/>
|
||||
|
||||
<text class="txt" x="50" y="440">No params, no ret</text>
|
||||
<text class="dim" x="330" y="440">leds_all_off()</text>
|
||||
|
||||
<text class="txt" x="50" y="470">Params, no return</text>
|
||||
<text class="dim" x="330" y="470">blink_led(..)</text>
|
||||
|
||||
<text class="txt" x="50" y="500">No params, return</text>
|
||||
<text class="dim" x="330" y="500">ir_getkey()</text>
|
||||
|
||||
<text class="txt" x="50" y="530">Params + return</text>
|
||||
<text class="dim" x="330" y="530">ir_to_led_num()</text>
|
||||
|
||||
<text class="txt" x="50" y="560">Struct pointer</text>
|
||||
<text class="dim" x="330" y="560">get_led_pin()</text>
|
||||
|
||||
<!-- Key Functions -->
|
||||
<rect class="pnl" x="615" y="325" width="555" height="245" rx="8"/>
|
||||
<text class="sub" x="635" y="365">Key Functions</text>
|
||||
|
||||
<text class="grn" x="635" y="400">ir_to_led_number(cmd)</text>
|
||||
<text class="dim" x="635" y="425">Maps NEC code to LED 1/2/3</text>
|
||||
|
||||
<text class="grn" x="635" y="460">get_led_pin(leds, num)</text>
|
||||
<text class="dim" x="635" y="485">Returns GPIO pin for LED</text>
|
||||
|
||||
<text class="grn" x="635" y="520">blink_led(pin, cnt, ms)</text>
|
||||
<text class="dim" x="635" y="545">Blinks LED cnt times</text>
|
||||
|
||||
<!-- Call Chain - Vertical Flow -->
|
||||
<rect class="pnl" x="30" y="590" width="1140" height="170" rx="8"/>
|
||||
<text class="sub" x="50" y="630">Function Call Chain</text>
|
||||
|
||||
<text class="cyn" x="50" y="665">main()</text>
|
||||
<text class="dim" x="200" y="665">--></text>
|
||||
<text class="amb" x="250" y="665">process_ir_led_command()</text>
|
||||
|
||||
<text class="txt" x="100" y="695">1. leds_all_off()</text>
|
||||
<text class="dim" x="400" y="695">Turn all LEDs off</text>
|
||||
|
||||
<text class="txt" x="100" y="725">2. ir_to_led_number()</text>
|
||||
<text class="dim" x="400" y="725">Map NEC to LED</text>
|
||||
|
||||
<text class="txt" x="700" y="695">3. get_led_pin()</text>
|
||||
<text class="dim" x="950" y="695">Get GPIO pin</text>
|
||||
|
||||
<text class="txt" x="700" y="725">4. blink_led()</text>
|
||||
<text class="dim" x="950" y="725">Blink + stay on</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,66 @@
|
||||
<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">Struct Pointers in Functions</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">Passing Data Efficiently</text>
|
||||
|
||||
<!-- Why Pointers -->
|
||||
<rect class="pnl" x="30" y="110" width="555" height="160" rx="8"/>
|
||||
<text class="sub" x="50" y="150">Why Pass by Pointer?</text>
|
||||
<text class="grn" x="50" y="185">Efficient</text>
|
||||
<text class="dim" x="250" y="185">4 bytes (address) not 6</text>
|
||||
<text class="grn" x="50" y="215">Modifiable</text>
|
||||
<text class="dim" x="250" y="215">Function can change original</text>
|
||||
<text class="grn" x="50" y="245">Standard</text>
|
||||
<text class="dim" x="250" y="245">Embedded systems practice</text>
|
||||
|
||||
<!-- Arrow Operator -->
|
||||
<rect class="pnl" x="615" y="110" width="555" height="160" rx="8"/>
|
||||
<text class="sub" x="635" y="150">Arrow Operator</text>
|
||||
<text class="txt" x="635" y="185">leds->led1_pin</text>
|
||||
<text class="dim" x="635" y="215">Same as (*leds).led1_pin</text>
|
||||
<text class="dim" x="635" y="245">Use -> when leds is a pointer</text>
|
||||
|
||||
<!-- leds_all_off -->
|
||||
<rect class="pnl" x="30" y="290" width="555" height="200" rx="8"/>
|
||||
<text class="sub" x="50" y="330">leds_all_off()</text>
|
||||
<rect x="50" y="348" width="515" height="125" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="cyn" x="70" y="378">void leds_all_off(</text>
|
||||
<text class="cyn" x="100" y="408">simple_led_ctrl_t *leds) {</text>
|
||||
<text class="txt" x="100" y="438">gpio_put(leds->led1_pin, 0);</text>
|
||||
<text class="txt" x="100" y="463">gpio_put(leds->led2_pin, 0);</text>
|
||||
|
||||
<!-- blink_led -->
|
||||
<rect class="pnl" x="615" y="290" width="555" height="200" rx="8"/>
|
||||
<text class="sub" x="635" y="330">blink_led()</text>
|
||||
<rect x="635" y="348" width="515" height="125" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="cyn" x="655" y="378">void blink_led(uint8_t pin,</text>
|
||||
<text class="cyn" x="685" y="408">uint8_t count, uint32_t ms){</text>
|
||||
<text class="txt" x="685" y="438">gpio_put(pin, true);</text>
|
||||
<text class="txt" x="685" y="463">sleep_ms(ms);</text>
|
||||
|
||||
<!-- process_ir_led_command -->
|
||||
<rect class="pnl" x="30" y="510" width="1140" height="250" rx="8"/>
|
||||
<text class="sub" x="50" y="550">process_ir_led_command() -- Main Command Processor</text>
|
||||
<rect x="50" y="568" width="1100" height="170" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="cyn" x="70" y="598">int process_ir_led_command(int cmd,</text>
|
||||
<text class="cyn" x="100" y="628">simple_led_ctrl_t *leds, uint8_t blink_count) {</text>
|
||||
<text class="txt" x="100" y="660">leds_all_off(leds);</text>
|
||||
<text class="dim" x="600" y="660">// turn all off first</text>
|
||||
<text class="txt" x="100" y="690">int num = ir_to_led_number(cmd);</text>
|
||||
<text class="dim" x="600" y="690">// map NEC to LED</text>
|
||||
<text class="txt" x="100" y="720">blink_led(get_led_pin(leds, num),</text>
|
||||
<text class="dim" x="600" y="720">// blink then stay on</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,57 @@
|
||||
<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">Structures Source Code</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">0x0023_structures.c</text>
|
||||
|
||||
<!-- Source Code -->
|
||||
<rect class="pnl" x="30" y="110" width="1140" height="520" rx="8"/>
|
||||
<text class="sub" x="50" y="150">Full Source</text>
|
||||
<rect x="50" y="168" width="1100" height="445" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
|
||||
<text class="dim" x="70" y="198">#include <stdio.h></text>
|
||||
<text class="dim" x="70" y="225">#include "pico/stdlib.h"</text>
|
||||
<text class="dim" x="70" y="252">#include "ir.h"</text>
|
||||
|
||||
<text class="cyn" x="70" y="285">typedef struct {</text>
|
||||
<text class="txt" x="100" y="312">uint8_t led1_pin, led2_pin, led3_pin;</text>
|
||||
<text class="txt" x="100" y="339">bool led1_state, led2_state, led3_state;</text>
|
||||
<text class="cyn" x="70" y="366">} simple_led_ctrl_t;</text>
|
||||
|
||||
<text class="cyn" x="70" y="400">int main(void) {</text>
|
||||
<text class="txt" x="100" y="427">stdio_init_all();</text>
|
||||
<text class="amb" x="100" y="454">simple_led_ctrl_t leds = {</text>
|
||||
<text class="grn" x="130" y="481">.led1_pin=16, .led2_pin=17, .led3_pin=18</text>
|
||||
<text class="amb" x="100" y="508">};</text>
|
||||
|
||||
<text class="txt" x="100" y="540">gpio_init(leds.led1_pin);</text>
|
||||
<text class="dim" x="500" y="540">// init 16, 17, 18</text>
|
||||
<text class="txt" x="100" y="567">ir_init(5);</text>
|
||||
<text class="dim" x="500" y="567">// IR on GPIO 5</text>
|
||||
<text class="txt" x="100" y="594">while (true) {</text>
|
||||
<text class="dim" x="500" y="594">// main loop</text>
|
||||
|
||||
<!-- Program Flow -->
|
||||
<rect class="pnl" x="30" y="650" width="1140" height="110" rx="8"/>
|
||||
<text class="sub" x="50" y="685">Main Loop Flow</text>
|
||||
<text class="txt" x="50" y="715">ir_getkey()</text>
|
||||
<text class="dim" x="230" y="715">--></text>
|
||||
<text class="txt" x="270" y="715">check NEC code</text>
|
||||
<text class="dim" x="490" y="715">--></text>
|
||||
<text class="txt" x="530" y="715">set state</text>
|
||||
<text class="dim" x="680" y="715">--></text>
|
||||
<text class="txt" x="720" y="715">gpio_put()</text>
|
||||
<text class="dim" x="50" y="740">0x0C=LED1(red) 0x18=LED2(green) 0x5E=LED3(yellow)</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,73 @@
|
||||
<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">Struct Flattening</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">How Compilers Transform Structs</text>
|
||||
|
||||
<!-- C Level -->
|
||||
<rect class="pnl" x="30" y="110" width="555" height="220" rx="8"/>
|
||||
<text class="sub" x="50" y="150">C Code (High Level)</text>
|
||||
<rect x="50" y="168" width="515" height="140" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="cyn" x="70" y="198">gpio_init(leds.led1_pin);</text>
|
||||
<text class="dim" x="70" y="225">// leds.led1_pin = 16</text>
|
||||
<text class="cyn" x="70" y="258">gpio_init(leds.led2_pin);</text>
|
||||
<text class="dim" x="70" y="285">// leds.led2_pin = 17</text>
|
||||
|
||||
<!-- Assembly Level -->
|
||||
<rect class="pnl" x="615" y="110" width="555" height="220" rx="8"/>
|
||||
<text class="sub" x="635" y="150">Assembly (Flattened)</text>
|
||||
<rect x="635" y="168" width="515" height="140" rx="6" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text class="grn" x="655" y="198">movs r0, #0x10</text>
|
||||
<text class="dim" x="900" y="198">// 16</text>
|
||||
<text class="txt" x="655" y="225">bl gpio_init</text>
|
||||
<text class="grn" x="655" y="258">movs r0, #0x11</text>
|
||||
<text class="dim" x="900" y="258">// 17</text>
|
||||
<text class="txt" x="655" y="285">bl gpio_init</text>
|
||||
|
||||
<!-- The Key Insight -->
|
||||
<rect class="pnl" x="30" y="350" width="1140" height="130" rx="8"/>
|
||||
<text class="sub" x="50" y="390">The Key Insight</text>
|
||||
<text class="red" x="50" y="425">Struct abstraction DISAPPEARS</text>
|
||||
<text class="txt" x="520" y="425">at assembly level</text>
|
||||
<text class="dim" x="50" y="455">You see individual values (16, 17, 18) not struct names</text>
|
||||
|
||||
<!-- Struct Member Mapping -->
|
||||
<rect class="pnl" x="30" y="500" width="1140" height="260" rx="8"/>
|
||||
<text class="sub" x="50" y="540">Struct Member Mapping</text>
|
||||
|
||||
<text class="amb" x="50" y="575">Assembly</text>
|
||||
<text class="amb" x="280" y="575">Struct Member</text>
|
||||
<text class="amb" x="560" y="575">Physical</text>
|
||||
<text class="amb" x="800" y="575">NEC Code</text>
|
||||
<line x1="50" y1="585" x2="1140" y2="585" stroke="#1a1a2e" stroke-width="1"/>
|
||||
|
||||
<text class="grn" x="50" y="615">0x10 (16)</text>
|
||||
<text class="txt" x="280" y="615">led1_pin</text>
|
||||
<text class="red" x="560" y="615">Red LED</text>
|
||||
<text class="cyn" x="800" y="615">0x0C</text>
|
||||
|
||||
<text class="grn" x="50" y="645">0x11 (17)</text>
|
||||
<text class="txt" x="280" y="645">led2_pin</text>
|
||||
<text class="grn" x="560" y="645">Green LED</text>
|
||||
<text class="cyn" x="800" y="645">0x18</text>
|
||||
|
||||
<text class="grn" x="50" y="675">0x12 (18)</text>
|
||||
<text class="txt" x="280" y="675">led3_pin</text>
|
||||
<text class="amb" x="560" y="675">Yellow LED</text>
|
||||
<text class="cyn" x="800" y="675">0x5E</text>
|
||||
|
||||
<text class="dim" x="50" y="710">Sequential values (16,17,18) reveal the struct pattern</text>
|
||||
<text class="dim" x="50" y="735">Recognize patterns to reconstruct original structs in Ghidra</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -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">Hacking Structures</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">Swapping GPIO Pin Assignments</text>
|
||||
|
||||
<!-- The Hack -->
|
||||
<rect class="pnl" x="30" y="110" width="555" height="200" rx="8"/>
|
||||
<text class="sub" x="50" y="150">Swap LED 1 and LED 2</text>
|
||||
<text class="txt" x="50" y="185">Find gpio_init values:</text>
|
||||
<text class="red" x="50" y="220">0x10 (16)</text>
|
||||
<text class="amb" x="230" y="220">--></text>
|
||||
<text class="grn" x="290" y="220">0x11 (17)</text>
|
||||
<text class="red" x="50" y="255">0x11 (17)</text>
|
||||
<text class="amb" x="230" y="255">--></text>
|
||||
<text class="grn" x="290" y="255">0x10 (16)</text>
|
||||
<text class="dim" x="50" y="290">Swap the two byte values</text>
|
||||
|
||||
<!-- Result -->
|
||||
<rect class="pnl" x="615" y="110" width="555" height="200" rx="8"/>
|
||||
<text class="sub" x="635" y="150">Result After Hack</text>
|
||||
|
||||
<text class="amb" x="635" y="185">Before:</text>
|
||||
<text class="txt" x="635" y="215">Btn 1 --> GPIO 16 --> Red</text>
|
||||
<text class="txt" x="635" y="245">Btn 2 --> GPIO 17 --> Green</text>
|
||||
|
||||
<text class="amb" x="635" y="275">After:</text>
|
||||
<text class="grn" x="790" y="275">SWAPPED!</text>
|
||||
|
||||
<!-- Before/After Detail -->
|
||||
<rect class="pnl" x="30" y="330" width="555" height="150" rx="8"/>
|
||||
<text class="sub" x="50" y="370">Before (Normal)</text>
|
||||
<text class="txt" x="50" y="405">Btn 1 (0x0C) --> GPIO 16</text>
|
||||
<text class="red" x="450" y="405">Red</text>
|
||||
<text class="txt" x="50" y="435">Btn 2 (0x18) --> GPIO 17</text>
|
||||
<text class="grn" x="450" y="435">Green</text>
|
||||
<text class="dim" x="50" y="465">Log and LED match correctly</text>
|
||||
|
||||
<rect class="pnl" x="615" y="330" width="555" height="150" rx="8"/>
|
||||
<text class="sub" x="635" y="370">After (Hacked)</text>
|
||||
<text class="txt" x="635" y="405">Btn 1 (0x0C) --> GPIO 17</text>
|
||||
<text class="grn" x="1035" y="405">Green!</text>
|
||||
<text class="txt" x="635" y="435">Btn 2 (0x18) --> GPIO 16</text>
|
||||
<text class="red" x="1035" y="435">Red!</text>
|
||||
<text class="dim" x="635" y="465">Log says RED but GREEN lights</text>
|
||||
|
||||
<!-- Log Desynchronization -->
|
||||
<rect class="pnl" x="30" y="500" width="1140" height="180" rx="8"/>
|
||||
<text class="sub" x="50" y="540">Log Desynchronization</text>
|
||||
|
||||
<text class="amb" x="50" y="575">Terminal Log:</text>
|
||||
<text class="txt" x="300" y="575">NEC command: 0x0C</text>
|
||||
<text class="dim" x="600" y="575">(expects Red)</text>
|
||||
|
||||
<text class="amb" x="50" y="610">Physical LED:</text>
|
||||
<text class="grn" x="300" y="610">GREEN LED on</text>
|
||||
<text class="red" x="600" y="610">MISMATCH!</text>
|
||||
|
||||
<text class="dim" x="50" y="645">Operator sees correct logs but WRONG behavior</text>
|
||||
|
||||
<!-- Stuxnet Reference -->
|
||||
<rect class="pnl" x="30" y="700" width="1140" height="60" rx="8"/>
|
||||
<text class="sub" x="50" y="735">Stuxnet:</text>
|
||||
<text class="dim" x="250" y="735">False "normal" data to operators, equipment destroyed</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,73 @@
|
||||
<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">.ELF vs .BIN Analysis</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">Ghidra Analysis of 0x0026_functions</text>
|
||||
|
||||
<!-- Comparison Table -->
|
||||
<rect class="pnl" x="30" y="110" width="1140" height="220" rx="8"/>
|
||||
<text class="sub" x="50" y="150">.ELF vs .BIN Comparison</text>
|
||||
|
||||
<text class="amb" x="50" y="190">Feature</text>
|
||||
<text class="amb" x="350" y="190">.BIN File</text>
|
||||
<text class="amb" x="700" y="190">.ELF File</text>
|
||||
<line x1="50" y1="200" x2="1140" y2="200" stroke="#1a1a2e" stroke-width="1"/>
|
||||
|
||||
<text class="txt" x="50" y="230">Symbols</text>
|
||||
<text class="red" x="350" y="230">None</text>
|
||||
<text class="grn" x="700" y="230">Function names</text>
|
||||
|
||||
<text class="txt" x="50" y="260">Sections</text>
|
||||
<text class="red" x="350" y="260">Raw bytes only</text>
|
||||
<text class="grn" x="700" y="260">.text .data .rodata</text>
|
||||
|
||||
<text class="txt" x="50" y="290">Debug info</text>
|
||||
<text class="red" x="350" y="290">None</text>
|
||||
<text class="grn" x="700" y="290">May include debug</text>
|
||||
|
||||
<text class="txt" x="50" y="320">Use case</text>
|
||||
<text class="txt" x="350" y="320">Flash to device</text>
|
||||
<text class="txt" x="700" y="320">Analysis + debug</text>
|
||||
|
||||
<!-- Ghidra Import -->
|
||||
<rect class="pnl" x="30" y="350" width="555" height="200" rx="8"/>
|
||||
<text class="sub" x="50" y="390">Importing .BIN</text>
|
||||
<text class="txt" x="50" y="425">Manual setup required:</text>
|
||||
<text class="dim" x="50" y="450">ARM Cortex 32 little endian</text>
|
||||
<text class="dim" x="50" y="480">Block: .text</text>
|
||||
<text class="dim" x="50" y="505">Base: 10000000</text>
|
||||
<text class="dim" x="50" y="530">No function names</text>
|
||||
|
||||
<rect class="pnl" x="615" y="350" width="555" height="200" rx="8"/>
|
||||
<text class="sub" x="635" y="390">Importing .ELF</text>
|
||||
<text class="txt" x="635" y="425">Auto-detected by Ghidra:</text>
|
||||
<text class="grn" x="635" y="450">ARM format recognized</text>
|
||||
<text class="grn" x="635" y="480">Sections auto-loaded</text>
|
||||
<text class="grn" x="635" y="505">Symbol tree populated</text>
|
||||
<text class="grn" x="635" y="530">Named functions visible</text>
|
||||
|
||||
<!-- Important Note -->
|
||||
<rect class="pnl" x="30" y="570" width="1140" height="100" rx="8"/>
|
||||
<text class="sub" x="50" y="610">Important Rule</text>
|
||||
<text class="red" x="50" y="645">Analyze the .ELF</text>
|
||||
<text class="dim" x="350" y="645">for symbol information</text>
|
||||
<text class="grn" x="650" y="645">Patch the .BIN</text>
|
||||
<text class="dim" x="900" y="645">for flashing</text>
|
||||
|
||||
<!-- Workflow -->
|
||||
<rect class="pnl" x="30" y="690" width="1140" height="70" rx="8"/>
|
||||
<text class="sub" x="50" y="722">Export Workflow</text>
|
||||
<text class="dim" x="50" y="742">Patch .bin in Ghidra --> uf2conv.py --> flash to Pico 2</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,85 @@
|
||||
<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">Structs & IR Protocol</text>
|
||||
<text class="dim" x="600" y="88" text-anchor="middle">Structs, Functions, IR, and Hacking</text>
|
||||
|
||||
<!-- Structs -->
|
||||
<rect class="pnl" x="30" y="110" width="555" height="180" rx="8"/>
|
||||
<text class="sub" x="50" y="150">C Structures</text>
|
||||
<text class="txt" x="50" y="185">Group related data together</text>
|
||||
<text class="dim" x="50" y="210">Dot (.) for variables</text>
|
||||
<text class="dim" x="50" y="235">Arrow (->) for pointers</text>
|
||||
<text class="dim" x="50" y="260">Designated init: .pin = 16</text>
|
||||
|
||||
<!-- NEC Protocol -->
|
||||
<rect class="pnl" x="615" y="110" width="555" height="180" rx="8"/>
|
||||
<text class="sub" x="635" y="150">NEC IR Protocol</text>
|
||||
<text class="txt" x="635" y="185">32-bit frame: addr + cmd</text>
|
||||
<text class="cyn" x="635" y="215">0x0C</text>
|
||||
<text class="dim" x="750" y="215">Button 1</text>
|
||||
<text class="cyn" x="635" y="245">0x18</text>
|
||||
<text class="dim" x="750" y="245">Button 2</text>
|
||||
<text class="cyn" x="635" y="275">0x5E</text>
|
||||
<text class="dim" x="750" y="275">Button 3</text>
|
||||
|
||||
<!-- Functions -->
|
||||
<rect class="pnl" x="30" y="310" width="555" height="160" rx="8"/>
|
||||
<text class="sub" x="50" y="350">Functions</text>
|
||||
<text class="txt" x="50" y="385">Reusable blocks, one job each</text>
|
||||
<text class="dim" x="50" y="410">ir_to_led_number()</text>
|
||||
<text class="dim" x="50" y="435">get_led_pin() / blink_led()</text>
|
||||
<text class="dim" x="50" y="460">process_ir_led_command()</text>
|
||||
|
||||
<!-- Struct Flattening -->
|
||||
<rect class="pnl" x="615" y="310" width="555" height="160" rx="8"/>
|
||||
<text class="sub" x="635" y="350">Assembly Flattening</text>
|
||||
<text class="txt" x="635" y="385">Structs vanish in assembly</text>
|
||||
<text class="dim" x="635" y="410">Only see values: 0x10 0x11 0x12</text>
|
||||
<text class="dim" x="635" y="435">Pattern recognition is key</text>
|
||||
<text class="dim" x="635" y="460">.ELF has symbols, .BIN doesn't</text>
|
||||
|
||||
<!-- Key Addresses -->
|
||||
<rect class="pnl" x="30" y="490" width="555" height="150" rx="8"/>
|
||||
<text class="sub" x="50" y="530">Key Values</text>
|
||||
<text class="cyn" x="50" y="565">0x10000234</text>
|
||||
<text class="dim" x="250" y="565">main()</text>
|
||||
<text class="cyn" x="50" y="595">GPIO 5</text>
|
||||
<text class="dim" x="250" y="595">IR receiver</text>
|
||||
<text class="cyn" x="50" y="625">GPIO 16/17/18</text>
|
||||
<text class="dim" x="250" y="625">Red/Green/Yellow</text>
|
||||
|
||||
<!-- Hacking -->
|
||||
<rect class="pnl" x="615" y="490" width="555" height="150" rx="8"/>
|
||||
<text class="sub" x="635" y="530">Hacking Techniques</text>
|
||||
<text class="amb" x="635" y="565">GPIO swap</text>
|
||||
<text class="dim" x="850" y="565">0x10 <--> 0x11</text>
|
||||
<text class="amb" x="635" y="595">Log desync</text>
|
||||
<text class="dim" x="850" y="595">Logs lie!</text>
|
||||
<text class="amb" x="635" y="625">Stuxnet</text>
|
||||
<text class="dim" x="850" y="625">Same concept</text>
|
||||
|
||||
<!-- Projects -->
|
||||
<rect class="pnl" x="30" y="660" width="555" height="100" rx="8"/>
|
||||
<text class="sub" x="50" y="695">Projects</text>
|
||||
<text class="dim" x="50" y="722">0x0023_structures</text>
|
||||
<text class="dim" x="50" y="744">0x0026_functions</text>
|
||||
|
||||
<!-- Takeaway -->
|
||||
<rect class="pnl" x="615" y="660" width="555" height="100" rx="8"/>
|
||||
<text class="sub" x="635" y="695">Key Takeaway</text>
|
||||
<text class="dim" x="635" y="722">Patch bytes, mislead logs</text>
|
||||
<text class="dim" x="635" y="744">hardware does what YOU say</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |