| name | analyzing-blackbox-firmware-hex |
| description | Reconstruct logic from embedded firmware — Intel-HEX (.hex), raw flash/ROM images (.bin/.img), and MCU dumps. Covers HEX→bin conversion with base-address recovery, CPU/arch identification, carving (binwalk), capstone disassembly with the right load base, and vector-table/entrypoint analysis. Use for .hex and raw firmware targets. |
| license | Apache-2.0 |
| metadata | {"domain":"reverse-engineering","formats":"ihex, bin, firmware, mcu"} |
Analyzing Black-Box Firmware / Intel-HEX
Scope
MCU and embedded firmware: Intel-HEX (.hex), raw flash/ROM dumps
(.bin/.img/.rom), and SoC images. These have no ELF container, so you must
supply CPU arch and load base yourself.
Workflow
-
Triage to confirm ihex vs raw, and check entropy (encrypted/compressed
regions show high entropy and resist disassembly).
-
Intel-HEX → flat binary. unpack mode=ihex (runs hex2bin.py). Record:
base_address — the real load/flash address (critical for correct addresses).
segments — gaps separate code, vector tables, config, and data.
-
Identify the CPU. Firmware rarely states its arch. Infer from:
- Base address & size (Cortex-M flash often at
0x08000000; AVR/8051 small flash).
- Vector table at the start: for ARM Cortex-M the first word is the initial
SP (points into RAM, e.g.
0x2000xxxx) and the second is the reset handler
(odd address → Thumb). Strong Cortex-M signal.
- Try arches and see which disassembles cleanly. Common MCU arches: ARM Thumb
(Cortex-M), ARM, AVR, MSP430, 8051, MIPS, RISC-V, PIC.
-
Carve composite images. Raw flash often bundles a bootloader + app +
filesystem. unpack mode=binwalk to find embedded filesystems (SquashFS, CramFS,
JFFS2), compressed blobs, and certificates; re-triage each carved piece. Linux
firmware → extract the rootfs and analyze its ELF binaries with
analyzing-blackbox-elf-object.
-
Disassemble at the right base. For bare MCU code use:
disasm arch=arm thumb=true base=<base_address> (set thumb for Cortex-M; pick
arch from step 3). For larger ARM/MIPS Linux firmware, rizin on the carved ELF.
Start at the reset handler from the vector table, follow bl/b calls.
-
Reconstruct logic & peripherals. Map memory-mapped I/O accesses (loads/stores
to peripheral base addresses from the chip's datasheet) to identify UART/SPI/GPIO/
timer usage. strings_scan reveals command tables, AT-commands, version strings,
and keys. Find the main loop / command dispatcher and document the state machine.
Notes
- Endianness matters; if disassembly is garbage, try the other endianness/arch.
- Unicorn (
py:unicorn) can emulate isolated routines (e.g. a checksum/decryption)
to recover outputs — model the inputs, no host execution of the firmware.
Report
Format & load base · memory layout/segments · CPU arch & evidence · vector table /
reset entry · carved components · peripherals & I/O · command/state machine ·
strings/keys · findings.