Files
Embedded-Hacking/WEEKS/WEEK11/QUIZ11.md
T
2026-04-15 17:23:21 -04:00

187 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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