HW 5: Firmware Reverse Engineering
Covers: Week 9 Due: Friday of Week 10 — 4 December 2026, 23:59:59 Points: 100
Introduction
You have an image. Now find out what it does.
This assignment takes the firmware you extracted in HW #3 and turns it into understanding: loaded correctly into a disassembler, oriented without symbols, and analyzed to the point where you can state something true about the device’s security that you could not have known from the outside.
The skill being assessed is orientation. A raw firmware image gives you no headers, no symbols, no section table, and no entry point — just bytes. Getting from there to a readable listing is most of the work, and it is a repeatable procedure rather than an act of inspiration.
Prerequisites
You need, from earlier assignments:
- The firmware image from HW #3, and its SHA-256.
- The architecture and endianness from HW #1 Task 1.
- The flash layout from HW #3 Task 2.
If any of those are missing or wrong, fix them first. Every step below inherits their correctness.
Tasks
Task 1 — Load the image correctly
25 points.
- State the architecture, endianness, and processor variant you are loading, and cite the evidence from HW #1.
- Determine the load address. Do not guess. Use one of the following and
show your work:
- The pointer-histogram method from Week 9 — scan for aligned 32-bit values that look like pointers and find the cluster.
- For Cortex-M images, read the initial stack pointer and reset handler from the first two words of the vector table.
- A load address declared in a header, if the image has one — in which case show the header.
- Load the image into Ghidra at your determined base address, with the correct language and endianness. Include a screenshot of the import dialog showing your settings.
- Demonstrate the load address is correct. The test: cross-references resolve. Show a screenshot in which a string reference or a function pointer correctly resolves to its target. If you load at the wrong base, nothing resolves — and a listing where nothing resolves is the symptom you are checking for.
- Report how many functions Ghidra’s auto-analysis identified.
Task 1.4 is the pass/fail gate for the assignment. If cross-references do not resolve, stop and fix the base address before continuing; everything downstream will otherwise be nonsense.
Task 2 — Orient without symbols
20 points.
- Run
stringsagainst the image with offsets, and identify at least eight strings that look security-relevant. Include the command you used. - Pick three of them and, for each:
- Locate the string in Ghidra at its address.
- Follow the cross-reference to the function that uses it.
- Rename the function to something meaningful and explain your reasoning.
- Include a screenshot of the decompiled function.
- Produce a partial call graph — at least eight nodes — showing how your three renamed functions relate to each other and to the code around them. A hand-drawn or Mermaid diagram is fine; the point is the structure, not the rendering.
- Cross-reference at least one finding against the filesystem you extracted in HW #3 Task 4. A device path, config key, or URL appearing in both the binary and the filesystem connects the running configuration to the code consuming it — report that connection explicitly.
Task 3 — Analyze one security-relevant routine
25 points.
Choose one function and analyze it properly. Good candidates: an authentication check, a firmware-update verification routine, a network request parser, a cryptographic operation, or anything handling attacker-controlled input.
- State which function you chose and why it is security-relevant.
- Provide the decompiled listing, cleaned up: meaningful variable names, corrected types, and comments explaining what each block does.
- Describe the function’s behavior in prose. What are its inputs, what does it do with them, what does it return, and what does the caller do with the result?
- Identify at least one security-relevant property:
- A bug — an overflow, an off-by-one, a missing bounds check, a signedness error. Explain how it could be reached and by whom.
- Or a design weakness — a hardcoded secret, a check that can be bypassed, a comparison vulnerable to timing analysis, a verification whose result is ignored.
- Or, if the function is genuinely sound, explain why it is sound and what the implementer did right. This is a legitimate finding and is graded equally — but you must demonstrate it, not assert it.
- State how you would validate your conclusion on real hardware. You do not have to perform the validation; describe the experiment.
Note that item 4.3 is a full-credit answer. Reverse engineering that only ever reports vulnerabilities is reverse engineering that is telling you what you want to hear.
Task 4 — Bootloader and chain of trust
20 points.
- Identify the bootloader in your image. Report its type, version, and offset.
- Determine whether the image is signed or verified at boot. Report your evidence either way — a signature block, a public key in the bootloader, a verification routine, or the demonstrable absence of all three.
- Evaluate the chain of trust against the break points listed in Week 9. For each link — ROM to bootloader, bootloader to kernel, kernel to filesystem — state whether verification occurs and how you know.
- If the bootloader has an interactive console: state what an attacker with serial access could do. Be specific — name the variables or commands, and connect this back to the UART you found in HW #1.
- Write a short remediation section: what should the vendor change, in priority order, and what would each change cost them in engineering effort and field risk? Recommendations that ignore cost are not recommendations.
Task 5 — Graduate extension (CS 510 required, CS 410 extra credit)
CS 510 students must complete this task. CS 410 students may attempt it for up to 10 points of extra credit.
Choose one:
- Emulation. Get some portion of the firmware executing under QEMU or a comparable emulator. Document the peripheral stubs you had to write and where emulation diverged from hardware. Partial success with honest documentation of the failure point is full credit — this is genuinely hard.
- Diffing. You already have two versions of this device’s firmware: the 2.4.1 you dumped in HW #3 Part A, and the 2.5.0 you recovered from the packet capture in Part B. Diff them properly — extract both filesystems, compare them, and go further than the three differences HW #3 asked for. Determine which changes are security fixes, which are not, and what the vendor left alone. Silent security fixes, and silently unfixed problems, are both real and reportable phenomena.
- Automated triage. Write a script that ingests a firmware image and automatically reports architecture, likely base address, and candidate security-relevant functions. Evaluate it against at least two images and report precision honestly, including where it fails.
Submission
Commit hw5/hw5.md, your Ghidra project export, and any scripts you wrote.
Export your Ghidra work as a Ghidra Zip File (.gzf) so annotations
survive, or as a script-generated listing if the project is large. Do not commit
the firmware image itself — reference it by the SHA-256 recorded in HW #3.
Grading
| Item | Points | Required for |
|---|---|---|
| Task 1 — Load the image correctly | 25 | CS 410 and CS 510 |
| Task 2 — Orient without symbols | 20 | CS 410 and CS 510 |
| Task 3 — Analyze one security-relevant routine | 25 | CS 410 and CS 510 |
| Task 4 — Bootloader and chain of trust | 20 | CS 410 and CS 510 |
| Task 5 — Graduate extension | 10 | CS 510 required; CS 410 extra credit |
| Total | 100 | (CS 410 base total is 90 plus 10 extra credit available) |
References
- Ghidra — https://ghidra-sre.org/
- Ghidra documentation and course materials — https://github.com/NationalSecurityAgency/ghidra/tree/master/GhidraDocs
- U-Boot documentation — https://docs.u-boot.org/
- U-Boot verified boot (FIT images) — https://docs.u-boot.org/en/latest/usage/fit/index.html
- ARM Cortex-M vector table layout — https://developer.arm.com/documentation/dui0552/latest/
- QEMU system emulation — https://www.qemu.org/docs/master/system/
- OWASP Firmware Security Testing Methodology — https://github.com/scriptingxss/owasp-fstm
- Memory Corruption and Exploit Mitigations — ../memory-corruption.md
- Secure C — ../secure_c.md
Related course pages: Schedule · HW #3 · Final Project · Memory Corruption · Secure C
🛠️ Maintenance note: Ghidra’s import dialog and auto-analysis options change between major releases, so screenshots in lecture material date quickly — the procedure described here does not. If the course target changes to a Cortex-M part, Task 1.2.2 becomes the primary method rather than an alternative, and Task 1 should be reweighted accordingly.