Overview
flashrom is a utility for identifying, reading, writing, and verifying flash memory chips. It supports hundreds of flash chip types and numerous programmers (internal chipsets, USB devices, SPI interfaces, JTAG), making it essential for firmware extraction, modification, and hardware security research.
Installation
On Linux (Debian/Ubuntu)
# Install from repositories
sudo apt-get update
sudo apt-get install flashrom
# Or build from source
git clone https://review.coreboot.org/flashrom.git
cd flashrom
make
sudo make install
# Verify installation
flashrom --version
On macOS
# Using Homebrew
brew install flashrom
# Verify installation
flashrom --version
On Kali Linux
# Already included, but update
sudo apt-get update
sudo apt-get install flashrom
# Check available programmers
flashrom -p internal --list-supported
Supported Programmers
| Programmer Type | Examples | Use Case |
|---|
| Internal | coreboot BIOS, chipset | Motherboard firmware |
| USB | CH341a, FT232H, USB Blaster | External SPI programming |
| JTAG | OpenOCD, Tigard, Bus Pirate | Debug interface access |
| SPI | dirtyjtag, Raspberry Pi GPIO | Direct chip interface |
| Serial | Serial port adapters | Legacy devices |
| Parallel | Parallel port (legacy) | Old hardware |
Flash Chip Detection
Identify Connected Flash Chips
# Detect flash chip automatically
sudo flashrom -p internal
# Specify programmer explicitly
sudo flashrom -p internal:ich_spi_mode=auto
# List supported flash chips
flashrom --list-supported
# Verbose detection output
sudo flashrom -p internal -V
Probe with External Programmer
# Using CH341a USB programmer
sudo flashrom -p ch341a_spi
# Using FT232H
sudo flashrom -p ft2232_spi:type=232H,port=A
# Using Raspberry Pi GPIO
sudo flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512
# Using Bus Pirate
sudo flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M
# Get detailed chip info
sudo flashrom -p internal -c "chip_model" -i
# List chip name and capacity
sudo flashrom -p internal | grep -E "Found|Size"
# Detect all parameters without reading
sudo flashrom -p internal -n
Reading Firmware
Basic Firmware Backup
# Read entire flash to file
sudo flashrom -p internal -r firmware_backup.bin
# Read with verbose output
sudo flashrom -p internal -r firmware_backup.bin -V
# Read specific region only
sudo flashrom -p internal -l 0x000000 -s 0x100000 -r firmware_64kb.bin
# Verify read completed
ls -lh firmware_backup.bin
md5sum firmware_backup.bin
Multiple Reads for Verification
# Read firmware three times to verify consistency
sudo flashrom -p internal -r firmware_read1.bin
sudo flashrom -p internal -r firmware_read2.bin
sudo flashrom -p internal -r firmware_read3.bin
# Compare checksums
md5sum firmware_read*.bin
# Binary comparison
cmp firmware_read1.bin firmware_read2.bin && echo "Files identical"
Using External Programmers
# CH341a USB programmer
sudo flashrom -p ch341a_spi -r firmware_ch341.bin
# FT232H interface
sudo flashrom -p ft2232_spi:type=232H -r firmware_ft232.bin
# Raspberry Pi SPI
sudo flashrom -p linux_spi:dev=/dev/spidev0.0 -r firmware_pi.bin
# OpenOCD with JTAG
sudo flashrom -p openocd_spi -r firmware_openocd.bin
Writing Firmware
Backup Before Writing
# CRITICAL: Always backup first
sudo flashrom -p internal -r original_firmware.bin
# Verify backup size
ls -lh original_firmware.bin
# Create checksum
sha256sum original_firmware.bin > firmware.sha256
Writing Modified Firmware
# Write firmware image
sudo flashrom -p internal -w modified_firmware.bin
# Write with chip erase first
sudo flashrom -p internal -E
sudo flashrom -p internal -w modified_firmware.bin
# Write with progress output
sudo flashrom -p internal -w modified_firmware.bin -V
# Write specific region
sudo flashrom -p internal -l 0x1000 -s 0x10000 -w config_section.bin
Partial Writes
# Write only bootloader region
sudo flashrom -p internal -l 0x0 -s 0x10000 -w bootloader.bin
# Write only kernel region
sudo flashrom -p internal -l 0x10000 -s 0x100000 -w kernel.bin
# Write only filesystem region
sudo flashrom -p internal -l 0x110000 -s 0x6f0000 -w filesystem.bin
Verifying Flash Contents
Post-Write Verification
# Read back and compare
sudo flashrom -p internal -r verification.bin
cmp original_firmware.bin verification.bin
# Checksum comparison
sudo flashrom -p internal -r verify.bin
sha256sum verify.bin
sha256sum original_firmware.bin
# Verbose verification
sudo flashrom -p internal -v modified_firmware.bin
Byte-Level Verification
# Write with automatic verify
sudo flashrom -p internal -w firmware.bin --verify
# Manual verify with offset checking
sudo flashrom -p internal -r verify.bin
hexdump -C verify.bin | head -20
hexdump -C modified_firmware.bin | head -20
Erasing Flash Memory
Full Chip Erase
# Erase entire flash chip
sudo flashrom -p internal -E
# Erase with confirmation
sudo flashrom -p internal -E -y
# Erase specific region only
sudo flashrom -p internal -l 0x10000 -s 0x100000 -E
Sector-by-Sector Operations
# List sector layout
sudo flashrom -p internal -A
# Erase single sector (if supported)
sudo flashrom -p internal --erase-region=0x0,0x1000
# Erase multiple regions
sudo flashrom -p internal --erase-region=0x0,0x10000 --erase-region=0x100000,0x50000
Hardware Setup Guide
CH341a Programmer Wiring
CH341a Pin Layout:
GND -> Flash GND (pin 8)
3.3V -> Flash VCC (pin 4)
CLK -> Flash CLK (pin 6)
MOSI -> Flash SI (pin 5)
MISO -> Flash SO (pin 2)
CS -> Flash CS (pin 1)
FT232H Programmer Setup
# FT232H pin configuration
# Pin 1 (TDI) -> MOSI
# Pin 2 (GND) -> GND
# Pin 3 (TDO) -> MISO
# Pin 4 (TCK) -> CLK
# Pin 5 (3.3V) -> VCC
# Pin 9 (CS) -> Chip Select
# Install libftdi
sudo apt-get install libftdi-dev
# Load FTDI driver
sudo modprobe ftdi_sio
Raspberry Pi SPI Interface
# Enable SPI on Raspberry Pi
sudo raspi-config
# Navigate to: Interfacing Options > SPI > Enable
# Pin mapping for standard SPI:
GPIO 10 (MOSI) -> Flash SI
GPIO 9 (MISO) -> Flash SO
GPIO 11 (SCLK) -> Flash CLK
GPIO 8 (CE0) -> Flash CS
GND -> Flash GND
3.3V -> Flash VCC
# Test SPI connection
ls /dev/spidev*
# Read with Raspberry Pi
sudo flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -r firmware.bin
Firmware Security Research Workflows
# Detect BIOS flash chip
sudo flashrom -p internal
# Read BIOS firmware
sudo flashrom -p internal -r bios_backup.bin
# Analyze with binwalk
binwalk bios_backup.bin
# Extract components
binwalk -e bios_backup.bin
# Examine structure
strings bios_backup.bin | grep -E "BIOS|vendor|version"
# Connect programmer to target device
# Identify flash chip model from PCB
# Read firmware
sudo flashrom -p ch341a_spi -r device_firmware.bin
# Verify read
file device_firmware.bin
ls -lh device_firmware.bin
# Check for common formats
binwalk device_firmware.bin
strings device_firmware.bin | head -20
Bootloader Analysis
# Read full flash
sudo flashrom -p internal -r full_flash.bin
# Extract bootloader (usually first 64KB)
dd if=full_flash.bin of=bootloader.bin bs=1024 count=64
# Analyze bootloader
strings bootloader.bin | grep -E "boot|version"
hexdump -C bootloader.bin | head -20
# Compare bootloaders
sha256sum bootloader.bin /path/to/reference/bootloader.bin
Vulnerability Patching
# Read original firmware
sudo flashrom -p internal -r original.bin
# Create modified version
cp original.bin patched.bin
# (Use hex editor or dd to modify specific bytes)
# Verify patch location
hexdump -C original.bin | grep -A2 -B2 "patch_location"
hexdump -C patched.bin | grep -A2 -B2 "patch_location"
# Write patched firmware
sudo flashrom -p internal -E
sudo flashrom -p internal -w patched.bin --verify
Advanced Operations
Programming Entire Devices
# Read all flash
sudo flashrom -p internal -r device_full.bin
# Analyze components
binwalk -e device_full.bin
# Modify selected components
# (edit filesystem, kernel, etc)
# Rebuild complete image
cat bootloader.bin kernel.bin filesystem.bin > modified_full.bin
# Verify size matches original
ls -lh device_full.bin modified_full.bin
# Write new image
sudo flashrom -p internal -w modified_full.bin
Batch Operations
# Script for multiple device programming
#!/bin/bash
for device in device1 device2 device3; do
echo "Programming $device..."
sudo flashrom -p internal -w firmware_${device}.bin
sudo flashrom -p internal -v firmware_${device}.bin
[ $? -eq 0 ] && echo "SUCCESS: $device" || echo "FAILED: $device"
done
Recovery from Bricked Devices
# Connect external programmer
# Identify original firmware if available
# Erase corrupted flash
sudo flashrom -p ch341a_spi -E
# Write known-good firmware
sudo flashrom -p ch341a_spi -w original_firmware.bin
# Verify write
sudo flashrom -p ch341a_spi -v original_firmware.bin
# Power cycle device
Troubleshooting
Chip Not Detected
# Verify programmer connection
sudo flashrom -p internal -n
# Check for voltage issues
# (use multimeter: measure 3.3V on VCC pin)
# Try with verbose output
sudo flashrom -p internal -V
# Check system logs
dmesg | tail -20
Slow Read/Write Speed
# Check current SPI speed
sudo flashrom -p ch341a_spi
# Reduce speed if unreliable
sudo flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=256 -r firmware.bin
# Increase speed if reliable
sudo flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1024 -r firmware.bin
Permission Denied
# Run with sudo (safest approach)
sudo flashrom -p internal -r firmware.bin
# Or add user to plugdev group
sudo usermod -a -G plugdev $USER
newgrp plugdev
# Reload udev rules
sudo udevadm control --reload-rules
sudo udevadm trigger
Verify Failures
# Read multiple times to verify
sudo flashrom -p internal -r test1.bin
sudo flashrom -p internal -r test2.bin
cmp test1.bin test2.bin
# Check for bit errors
sha256sum test1.bin test2.bin
# Try different speed/voltage settings
Best Practices
- Always backup before writing to any flash device
- Verify checksums of backup files immediately after reading
- Use external programmer for critical devices (motherboards, BIOS)
- Test on non-critical hardware before working on valuable devices
- Double-check wiring before powering on any hardware
- Keep device powered during read/write operations
- Document modifications with timestamps and references
- Use protective equipment (ESD strap) when handling electronics
- Test recovery procedure with external programmer setup
- Maintain firmware backups in multiple secure locations
Common Chip Types
| Manufacturer | Series | Typical Uses | Notes |
|---|
| Winbond | W25Q (SPI) | BIOS, IoT | Most common |
| Macronix | MX25L (SPI) | Routers, embedded | Wide support |
| Spansion | S25FL (SPI) | Industrial | Reliable |
| Micron | MT25Q (SPI) | High-reliability | Aerospace-grade |
| SST | SST25VF (SPI) | Legacy systems | Older devices |
| Samsung | K8D (NAND) | Mobile devices | NAND flash |
| SK Hynix | HY27UF (NAND) | Legacy hardware | Older chips |
Using with Ghidra/IDA Pro
# Extract firmware
sudo flashrom -p internal -r firmware.bin
# Analyze with Ghidra
ghidra firmware.bin
# Identify memory layout
strings firmware.bin | grep -E "0x[0-9a-f]{8}"
Using with Binwalk
# Read and analyze
sudo flashrom -p internal -r firmware.bin
binwalk firmware.bin
# Extract components
binwalk -e firmware.bin
cd _firmware.bin.extracted
Resources