flashrom
Reads, writes and verifies SPI/LPC/parallel flash chips through a programmer like the CH341A, an FTDI adapter or a Bus Pirate. The standard tool for out-of-band firmware extraction.
flashrom is a utility for identifying, reading, writing and verifying SPI, LPC and parallel flash chips through a programmer such as a CH341A, an FTDI adapter or a Bus Pirate.
What it is
flashrom is the bridge between a host PC and a raw flash chip. It knows the command sets of thousands of flash parts (JEDEC IDs, sector sizes, erase opcodes) and drives a programmer over USB to talk to them. When firmware does not live behind a friendly bootloader, when there is no UART, no OTA, no vendor tool, flashrom is how you get at the bytes directly: clip onto the chip, read the whole image off, or write a modified one back.
Why it matters
On countless routers, cameras and appliances the firmware sits in an external SPI NOR flash, a small SOIC-8 chip marked 25xxx next to the SoC. That chip is the ground truth: whatever the CPU runs at boot, it fetched from there. flashrom lets you copy that image out for offline analysis, or write a patched image back to plant a change, all without desoldering and without cooperation from the running firmware. It is the standard tool for out-of-band, chip-level firmware extraction, the read that no software lock on the device can prevent.
How to use it
flashrom -p ch341a_spi # probe and identify the chip
flashrom -p ch341a_spi -r dump.bin # read the flash to a file
flashrom -p ch341a_spi -w new.bin # write (erases + programs + verifies)
flashrom -p ch341a_spi -V -r dump.bin # verbose, for debugging contacts
flashrom -p ch341a_spi:spispeed=128k -r dump.bin # slower clock if reads are unstable
flashrom -p ch341a_spi -c "W25Q64.V" -r dump.bin # force the chip model if autodetect is ambiguous
A read workflow with a ch341a and a soic8-clip: align pin 1 (see the diagram), clip on, flashrom -p ch341a_spi to confirm the part is detected, then read twice and compare:
flashrom -p ch341a_spi -r dump1.bin
flashrom -p ch341a_spi -r dump2.bin
sha256sum dump1.bin dump2.bin # the two hashes MUST match
Verify every read
Always take two reads and compare their hashes. If they differ, the clip contact is poor or the on-board CPU is contending for the SPI bus while you read. A single read that "looked fine" but was captured over a flaky contact is worse than no read: you will waste hours reversing a corrupted image. If the hashes will not converge, drop the SPI clock, reseat the clip, and if the SoC keeps fighting for the bus, hold it in reset or cut its power while you read the flash.
Pitfalls
- Voltage. Most SPI NOR is 3.3V; some are 1.8V. A CH341A that outputs 5V on its SPI lines can damage a 3.3V chip. Check the part and use a level-correct programmer or an adapter.
- In-circuit contention. With the chip still on the board, the SoC drives the same bus. Reads corrupt intermittently; hold the main CPU in reset, or desolder the flash for a clean read.
- Write means erase.
-werases before programming. A failed write mid-way can brick the device, so keep the originaldump.binas a known-good restore image. - Chip not detected. Autodetect fails on obscure parts; pass
-cwith the exact model, and double-check pin-1 alignment before assuming the clip is bad.
What it pairs with
flashrom produces the raw image that the rest of the toolchain consumes: hand dump.bin to binwalk to carve the filesystem, then to ghidra or radare2 to reverse the code. The physical side is a ch341a programmer plus a soic8-clip (or a bus-pirate as an alternative programmer); on ESP32 targets, esptool over UART is the easier equivalent that avoids clipping the chip at all.