A guide to hardware hacking and reverse engineering - maintained by VoidStar Security LLC
Configure your hardware hacking environment
Learn serial communication fundamentals
Flash extraction and memory interfaces
Debug interfaces and firmware access
Analyze firmware with Ghidra
Advanced glitching techniques
A structured approach to analyzing embedded systems
Begin by understanding what the device does and defining your goals for analysis.
Open the device and document every component of interest on the PCB.
Determine what protocols are in use and how components communicate.
Interface with identified components to extract or manipulate data.
Modify data or system behavior to achieve your desired outcome.
Quick answers to frequently asked hardware hacking questions with links to detailed resources
Method 1: Logic Analyzer Measurement
Capture the UART signal and measure the width of the smallest pulse (one bit). The baud rate is 1 / bit_width. For example, a pulse width of ~8.68μs indicates 115200 baud.
Method 2: Common Baud Rates
Try standard rates in order: 115200, 9600, 57600, 38400, 19200. Most embedded devices use 115200 or 9600.
Method 3: PulseView Auto-detect
Use PulseView's UART decoder - it can often auto-detect the baud rate from captured signals.
# Calculate from pulse width measurement
# If smallest pulse = 8.68μs
baud = 1 / 0.00000868 = ~115200
📖 Detailed guide: UART Discovery and Firmware Extraction
Step 1: Visual Inspection
Look for unpopulated headers, test points labeled TCK/TMS/TDI/TDO, or 10/14/20 pin connectors. Check silkscreen for debug markings.
Step 2: Identify Ground and Power
Use a multimeter in continuity mode to find GND (connected to shield/ground plane) and VCC (typically 3.3V or 1.8V).
Step 3: Use JTAGenum or JTAGulator
Connect candidate pins to a JTAGenum device (Arduino-based) or JTAGulator. These tools brute-force pin combinations by looking for valid IDCODE responses.
# JTAG signals to identify:
TCK - Test Clock (output from debugger)
TMS - Test Mode Select (output)
TDI - Test Data In (output)
TDO - Test Data Out (input)
nTRST - Optional reset (output)
📖 Detailed guide: JTAG, SSDs and Firmware Extraction
🛠 Tool: go-jtagenum
OpenOCD configs have three main components: interface, transport, and target.
# Example: STM32 with FT2232H adapter
# interface config
source [find interface/ftdi/ft2232h-module-swd.cfg]
# transport selection
transport select swd
# target config
source [find target/stm32f2x.cfg]
# adapter speed (kHz)
adapter speed 1000
For unsupported chips:
# Minimal custom target config
set CHIPNAME custom_chip
set WORKAREASIZE 0x4000
source [find target/swj-dp.tcl]
swj_newdap $CHIPNAME cpu -expected-id 0x2ba01477
target create $CHIPNAME.cpu cortex_m \
-chain-position $CHIPNAME.cpu
📖 Advanced guide: SWD and OpenOCD for unsupported chips
📖 Example: Xbox Controller OpenOCD setup
SWD only requires two data pins (plus GND): SWDIO and SWCLK.
Step 1: Check Common Locations
Step 2: Identify Reset Pin
Find the reset pin (often labeled RST or nRST). Pulling it low should cause USB re-enumeration or visible device reset.
Step 3: Probe with OpenOCD
Try connecting candidate pins and running OpenOCD - it will report if it detects a valid SWD target.
# SWD pinout (4 pins minimum)
SWDIO - Data I/O (bidirectional)
SWCLK - Clock
GND - Ground
VCC - Target voltage reference (optional)
📖 Detailed guide: SWD on Xbox Controllers
Option 1: In-Circuit Reading
Connect a programmer (Raspberry Pi, BusPirate, FT2232H) to the chip while it's soldered. May require holding the CPU in reset or powering down other components.
Option 2: Chip Removal
Desolder the chip with hot air and read it in a socket/clip. More reliable but requires rework skills.
# Using flashrom with Raspberry Pi SPI
flashrom -p linux_spi:dev=/dev/spidev0.0 -r firmware.bin
# With FT2232H
flashrom -p ft2232_spi:type=2232H -r firmware.bin
# Verify with multiple reads
flashrom -p linux_spi:dev=/dev/spidev0.0 -r fw2.bin
md5sum firmware.bin fw2.bin # Should match!
Troubleshooting:
Step 1: Connect Probes
Identify the signals you want to capture (TX, RX, CLK, DATA, etc.) and connect logic analyzer channels. Always connect GND!
Step 2: Configure Capture
Set sample rate to at least 4x the expected signal frequency. For 115200 baud UART, use 1MHz+. For 10MHz SPI, use 40MHz+.
Step 3: Add Protocol Decoder
In PulseView, add a decoder matching your protocol (UART, SPI, I2C, JTAG) and configure parameters.
# Common PulseView decoders:
UART - Set baud rate, data bits, parity, stop bits
SPI - Set CLK, MOSI, MISO, CS channels + polarity
I2C - Set SDA and SCL channels
JTAG - Set TCK, TMS, TDI, TDO channels
Tools:
Step 1: Initial Scan
# Scan for file signatures
binwalk firmware.bin
# Check entropy (find compressed/encrypted sections)
binwalk -E firmware.bin
Step 2: Extract Contents
# Extract all recognized files
binwalk -e firmware.bin
# Extract with Matryoshka mode (recursive)
binwalk -eM firmware.bin
Step 3: Explore Filesystem
# For SquashFS
unsquashfs filesystem.squashfs
# For JFFS2
jefferson filesystem.jffs2 -d output/
# For UBIFS
ubireader_extract_files firmware.ubi
Common Findings:
Step 1: Import the Binary
File → Import File. Select the correct processor architecture (ARM, MIPS, x86) and set the base address if known.
Step 2: Auto Analysis
Let Ghidra run auto-analysis. Enable all analyzers for initial pass. This finds functions, strings, and cross-references.
Step 3: Find Entry Points
For Embedded Firmware:
# Common ARM Cortex-M memory map
0x00000000 - Vector table / Flash alias
0x08000000 - Flash memory
0x20000000 - SRAM
0x40000000 - Peripherals
📖 Full course: Introduction to Reverse Engineering with Ghidra
📖 Guide: Writing a Ghidra Loader for STM32
🛠 Resource: Hackaday U course materials
Visual Indicators:
Electrical Testing:
# With multimeter:
1. Find GND (continuity to shield/ground plane)
2. Find VCC (steady 3.3V or 1.8V to GND)
3. UART TX often shows ~3.3V at idle
4. UART RX often pulled high or floating
Common Interfaces by Pin Count:
Essential Tools (~$100-200):
Intermediate Tools (~$200-500):
Advanced Tools (~$500+):
Warning: Read protection bypass often requires advanced techniques and may be destructive. Always work on non-critical devices first.
Common Approaches:
Required Equipment:
# General workflow:
1. Capture power traces during boot
2. Identify security check timing
3. Configure glitch parameters (width, offset)
4. Iterate until successful bypass
5. Extract firmware via debug interface
📖 Case study: Trezor One RDP Bypass
📖 Presentation: Low Cost EMFI Attacks
🛠 Tool: Replicant fault injection resources
Step 1: Initial Analysis
# Look for magic bytes and patterns
hexdump -C firmware.bin | head -100
strings firmware.bin | grep -i "file\|name\|dir"
# Check entropy for compression
binwalk -E firmware.bin
Step 2: Identify Structure
Step 3: Use Kaitai Struct
Define the format declaratively and generate parsers:
meta:
id: custom_fs
endian: le
seq:
- id: magic
contents: "MYFS"
- id: num_files
type: u4
- id: files
type: file_entry
repeat: expr
repeat-expr: num_files
📖 Example: Parsing MinFS with Kaitai Struct
🛠 Tool: qnxmount - QNX filesystem parser
From self-paced learning to hands-on private training
Learn hardware hacking at your own pace with comprehensive video courses and hands-on labs.
Intensive hands-on training covering UART, SPI, JTAG, SWD, fault injection, and firmware analysis.
Need expert help with a specific target or project? Get personalized guidance from experienced hardware hackers.
Questions about training or consulting? Reach out directly:
contact@voidstarsec.comCourse materials for Ghidra training - complete learning resources with CrackMe challenges
C - 427 starsFault injection research and resources for voltage glitching attacks
PythonJTAG enumeration tool combining JTAGenum and jtagulator implementations
GoCollection of Ghidra utilities and references for reverse engineering
JavaReconstruct SPI flash images from logic analyzer captures
PythonScripts for instrumenting logic analyzers with sigrok-cli and Saleae
PythonFirmware example for fault injection on STM32F4 microcontrollers
CFault injection utilities for Raspberry Pi Pico-based attacks
MakefileJTAG debugging interface implementation for Raspberry Pi Pico
CRaspberry Pi-based raw NAND flash extraction tool
CFilesystem parsers for mounting QNX images
Python