Firmware Triage and Reverse Engineering Workflow

TL;DR


1. Firmware file types: what you might get

Common formats

A core reality

A raw binary does not tell you:

You must infer these from context.


2. The triage checklist (do this every time)

Step 1: Identify the file type

1
file firmware.bin

If it’s ELF, you’re in a much easier situation.

Step 2: Quick entropy/structure sense

1
2
hexdump -C firmware.bin | head
strings -a firmware.bin | head

Look for:

Step 3: Search for signatures

Even without specialized tools you can search for patterns:

1
grep -aobU $'\x7fELF' firmware.bin | head

This tells you if an ELF is embedded inside a larger blob.

Step 4: If ELF: extract structure immediately

1
2
3
4
readelf -h firmware.elf
readelf -S firmware.elf
readelf -l firmware.elf
readelf -s firmware.elf | head

Key questions:


3. If you have a .bin: how to recover likely load address

Strategy A: From the platform memory map

If you know the target memory map (for example, QEMU virt), you often know typical RAM/flash addresses.

Strategy B: From vector tables / reset patterns

On some architectures, the reset vector has a recognizable structure. On RISC-V, boot code often begins with a small prologue and jumps; patterns are less standardized than ARM vector tables, but you can still hunt for:

Strategy C: From absolute addresses in code

If the firmware includes absolute addresses (MMIO registers, RAM ranges), those addresses can reveal the platform.


4. A practical “first disassembly” approach (without committing too early)

Even without a GUI tool, you can do a sanity disassembly pass if you know the architecture.

Example: disassemble a raw binary as RV32

If you have GNU binutils that support RISC-V:

1
riscv64-unknown-elf-objdump -D -b binary -m riscv:rv32 firmware.bin | less

If the output is mostly illegal/garbage instructions, your assumptions might be wrong:


5. Carving: extracting sub-images from a blob

If you find an embedded ELF at offset O, extract it:

1
2
dd if=firmware.bin of=extracted.elf bs=1 skip=$O
file extracted.elf

If it’s a real ELF, you can now use all Chapter 2 methods.

If you find a filesystem or compression signature, you may need specialized tools (common in firmware work), but the workflow stays:


6. Turning findings into a map (the most underrated skill)

Create a simple analysis note like:

1
2
3
4
5
6
7
8
9
Firmware X
- size: ...
- type: ...
- possible arch: rv32im
- strings: ...
- suspected load address: ...
- suspected entry point: ...
- notable constants: ...
- next action: (emulate / disassemble / find UART logs / look for update format)

This makes your work reproducible and easier to share.


7. Minimal “firmware-style” practice lab (using your own sample)

  1. Take build/ld_demo.elf (from Chapter 7) and convert it to .bin.
  2. Pretend you don’t know what it is.
  3. Use only file, hexdump, strings, and objdump -b binary to identify it.
  4. Write down your best guess about:
    • architecture,
    • load address,
    • what the code does.

Then compare with the truth using readelf on the original ELF.


Exercises

  1. Embed an ELF into a larger blob (e.g., by concatenating with padding) and practice carving it out using grep -aob and dd.
  2. Create a raw binary with a known base address assumption (e.g., your linker origin) and see how your disassembly changes if you assume the wrong base.
  3. Pick 5 strings from a firmware image and write hypotheses about what subsystems they relate to.

How to test your answers


Summary

You learned a repeatable firmware triage workflow: identify → extract → validate → map → choose next analysis step.

Next: dynamic analysis with Frida (Dynamic Instrumentation Toolkit)-when it applies to IoT/firmware, what constraints exist, and how to do safe, reproducible hooking experiments.