mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Merge pull request #1290 from HackTricks-wiki/research_update_src_todo_hardware-hacking_jtag_20250816_013818
Research Update Enhanced src/todo/hardware-hacking/jtag.md
This commit is contained in:
		
						commit
						ee35270a01
					
				@ -2,28 +2,120 @@
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
README.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
## JTAGenum
 | 
			
		||||
 | 
			
		||||
[**JTAGenum** ](https://github.com/cyphunk/JTAGenum)is a tool can be used with a Raspberry PI or an Arduino to find to try JTAG pins from an unknown chip.\
 | 
			
		||||
In the **Arduino**, connect the **pins from 2 to 11 to 10pins potentially belonging to a JTAG**. Load the program in the Arduino and it will try to bruteforce all the pins to find if any pins belongs to JTAG and which one is each.\
 | 
			
		||||
In the **Raspberry PI** you can only use **pins from 1 to 6** (6pins, so you will go slower testing each potential JTAG pin).
 | 
			
		||||
[**JTAGenum**](https://github.com/cyphunk/JTAGenum) is a tool you can load on an Arduino-compatible MCU or (experimentally) a Raspberry Pi to brute‑force unknown JTAG pinouts and even enumerate instruction registers.
 | 
			
		||||
 | 
			
		||||
### Arduino
 | 
			
		||||
- Arduino: connect digital pins D2–D11 to up to 10 suspected JTAG pads/testpoints, and Arduino GND to target GND. Power the target separately unless you know the rail is safe. Prefer 3.3 V logic (e.g., Arduino Due) or use a level shifter/series resistors when probing 1.8–3.3 V targets.
 | 
			
		||||
- Raspberry Pi: the Pi build exposes fewer usable GPIOs (so scans are slower); check the repo for the current pin map and constraints.
 | 
			
		||||
 | 
			
		||||
In Arduino, after connecting the cables (pin 2 to 11 to JTAG pins and Arduino GND to the baseboard GND), **load the JTAGenum program in Arduino** and in the Serial Monitor send a **`h`** (command for help) and you should see the help:
 | 
			
		||||
Once flashed, open the serial monitor at 115200 baud and send `h` for help. Typical flow:
 | 
			
		||||
 | 
			
		||||
- `l` find loopbacks to avoid false positives
 | 
			
		||||
- `r` toggle internal pull‑ups if needed
 | 
			
		||||
- `s` scan for TCK/TMS/TDI/TDO (and sometimes TRST/SRST)
 | 
			
		||||
- `y` brute‑force IR to discover undocumented opcodes
 | 
			
		||||
- `x` boundary‑scan snapshot of pin states
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
Configure **"No line ending" and 115200baud**.\
 | 
			
		||||
Send the command s to start scanning:
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
If you are contacting a JTAG, you will find one or several **lines starting by FOUND!** indicating the pins of JTAG.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
If a valid TAP is found you will see lines starting with `FOUND!` indicating discovered pins.
 | 
			
		||||
 | 
			
		||||
Tips
 | 
			
		||||
- Always share ground, and never drive unknown pins above target Vtref. If in doubt, add 100–470 Ω series resistors on candidate pins.
 | 
			
		||||
- If the device uses SWD/SWJ instead of 4‑wire JTAG, JTAGenum may not detect it; try SWD tools or an adapter that supports SWJ‑DP.
 | 
			
		||||
 | 
			
		||||
## Safer pin hunting and hardware setup
 | 
			
		||||
 | 
			
		||||
- Identify Vtref and GND first with a multimeter. Many adapters need Vtref to set I/O voltage.
 | 
			
		||||
- Level shifting: prefer bidirectional level shifters designed for push‑pull signals (JTAG lines are not open‑drain). Avoid auto‑direction I2C shifters for JTAG.
 | 
			
		||||
- Useful adapters: FT2232H/FT232H boards (e.g., Tigard), CMSIS‑DAP, J‑Link, ST‑LINK (vendor‑specific), ESP‑USB‑JTAG (on ESP32‑Sx). Connect at minimum TCK, TMS, TDI, TDO, GND and Vtref; optionally TRST and SRST.
 | 
			
		||||
 | 
			
		||||
## First contact with OpenOCD (scan and IDCODE)
 | 
			
		||||
 | 
			
		||||
OpenOCD is the de‑facto OSS for JTAG/SWD. With a supported adapter you can scan the chain and read IDCODEs:
 | 
			
		||||
 | 
			
		||||
- Generic example with a J‑Link:
 | 
			
		||||
```
 | 
			
		||||
openocd -f interface/jlink.cfg -c "transport select jtag; adapter speed 1000" \
 | 
			
		||||
  -c "init; scan_chain; shutdown"
 | 
			
		||||
```
 | 
			
		||||
- ESP32‑S3 built‑in USB‑JTAG (no external probe required):
 | 
			
		||||
```
 | 
			
		||||
openocd -f board/esp32s3-builtin.cfg -c "init; scan_chain; shutdown"
 | 
			
		||||
```
 | 
			
		||||
Notes
 | 
			
		||||
- If you get "all ones/zeros" IDCODE, check wiring, power, Vtref, and that the port isn’t locked by fuses/option bytes.
 | 
			
		||||
- See OpenOCD low‑level `irscan`/`drscan` for manual TAP interaction when bringing up unknown chains.
 | 
			
		||||
 | 
			
		||||
## Halting the CPU and dumping memory/flash
 | 
			
		||||
 | 
			
		||||
Once the TAP is recognized and a target script is chosen, you can halt the core and dump memory regions or internal flash. Examples (adjust target, base addresses and sizes):
 | 
			
		||||
 | 
			
		||||
- Generic target after init:
 | 
			
		||||
```
 | 
			
		||||
openocd -f interface/jlink.cfg -f target/stm32f1x.cfg \
 | 
			
		||||
  -c "init; reset halt; mdw 0x08000000 4; dump_image flash.bin 0x08000000 0x00100000; shutdown"
 | 
			
		||||
```
 | 
			
		||||
- RISC‑V SoC (prefer SBA when available):
 | 
			
		||||
```
 | 
			
		||||
openocd -f interface/ftdi/ft232h.cfg -f target/riscv.cfg \
 | 
			
		||||
  -c "init; riscv set_prefer_sba on; halt; dump_image sram.bin 0x80000000 0x20000; shutdown"
 | 
			
		||||
```
 | 
			
		||||
- ESP32‑S3, program or read via OpenOCD helper:
 | 
			
		||||
```
 | 
			
		||||
openocd -f board/esp32s3-builtin.cfg \
 | 
			
		||||
  -c "program_esp app.bin 0x10000 verify exit"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Tips
 | 
			
		||||
- Use `mdw/mdh/mdb` to sanity‑check memory before long dumps.
 | 
			
		||||
- For multi‑device chains, set BYPASS on non‑targets or use a board file that defines all TAPs.
 | 
			
		||||
 | 
			
		||||
## Boundary‑scan tricks (EXTEST/SAMPLE)
 | 
			
		||||
 | 
			
		||||
Even when the CPU debug access is locked, boundary‑scan may still be exposed. With UrJTAG/OpenOCD you can:
 | 
			
		||||
- SAMPLE to snapshot pin states while the system runs (find bus activity, confirm pin mapping).
 | 
			
		||||
- EXTEST to drive pins (e.g., bit‑bang external SPI flash lines via the MCU to read it offline if board wiring allows).
 | 
			
		||||
 | 
			
		||||
Minimal UrJTAG flow with an FT2232x adapter:
 | 
			
		||||
```
 | 
			
		||||
jtag> cable ft2232 vid=0x0403 pid=0x6010 interface=1
 | 
			
		||||
jtag> frequency 100000
 | 
			
		||||
jtag> detect
 | 
			
		||||
jtag> bsdl path /path/to/bsdl/files
 | 
			
		||||
jtag> instruction EXTEST
 | 
			
		||||
jtag> shift ir
 | 
			
		||||
jtag> dr  <bit pattern for boundary register>
 | 
			
		||||
```
 | 
			
		||||
You need the device BSDL to know boundary register bit ordering. Beware that some vendors lock boundary‑scan cells in production.
 | 
			
		||||
 | 
			
		||||
## Modern targets and notes
 | 
			
		||||
 | 
			
		||||
- ESP32‑S3/C3 include a native USB‑JTAG bridge; OpenOCD can speak directly over USB without an external probe. Very convenient for triage and dumps.
 | 
			
		||||
- RISC‑V debug (v0.13+) is widely supported by OpenOCD; prefer SBA for memory access when the core cannot be halted safely.
 | 
			
		||||
- Many MCUs implement debug authentication and lifecycle states. If JTAG appears dead but power is correct, the device may be fused to a closed state or requires an authenticated probe.
 | 
			
		||||
 | 
			
		||||
## Defenses and hardening (what to expect on real devices)
 | 
			
		||||
 | 
			
		||||
- Permanently disable or lock JTAG/SWD in production (e.g., STM32 RDP level 2, ESP eFuses that disable PAD JTAG, NXP/Nordic APPROTECT/DPAP).
 | 
			
		||||
- Require authenticated debug (ARMv8.2‑A ADIv6 Debug Authentication, OEM‑managed challenge‑response) while keeping manufacturing access.
 | 
			
		||||
- Don’t route easy test pads; bury test vias, remove/populate resistors to isolate TAP, use connectors with keying or pogo‑pin fixtures.
 | 
			
		||||
- Power‑on debug lock: gate the TAP behind early ROM enforcing secure boot.
 | 
			
		||||
 | 
			
		||||
## References
 | 
			
		||||
 | 
			
		||||
- OpenOCD User’s Guide – JTAG Commands and configuration. https://openocd.org/doc-release/html/JTAG-Commands.html
 | 
			
		||||
- Espressif ESP32‑S3 JTAG debugging (USB‑JTAG, OpenOCD usage). https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user