A Binary Ninja plugin that loads ESP32-series firmware images built with ESP-IDF or PlatformIO. Auto-detects the chip variant from the firmware header and configures the correct architecture, memory map, and ROM symbols.
| Chip | Chip ID | Architecture | ROM Symbols | Notes |
|---|---|---|---|---|
| ESP32 | 0x0000 | Xtensa LX6 | 2,713 | Requires xtensa architecture plugin |
| ESP32-S2 | 0x0002 | Xtensa LX7 | 1,107 | Requires xtensa architecture plugin |
| ESP32-S3 | 0x0009 | Xtensa LX7 | 3,545 | Requires xtensa architecture plugin |
| ESP32-C2 | 0x000C | RISC-V | 4,690 | Built-in rv32gc architecture |
| ESP32-C3 | 0x0005 | RISC-V | 3,055 | Built-in rv32gc architecture |
| ESP32-C5 | 0x0017 | RISC-V | 2,255 | Built-in rv32gc architecture |
| ESP32-C6 | 0x000D | RISC-V | 2,132 | Built-in rv32gc architecture |
| ESP32-H2 | 0x0010 | RISC-V | 1,221 | Built-in rv32gc architecture |
| ESP32-P4 | 0x0012 | RISC-V | 1,459 | Built-in rv32gc architecture |
RISC-V variants work out of the box with Binary Ninja's built-in rv32gc architecture. Xtensa variants (ESP32, ESP32-S2, ESP32-S3) require a third-party architecture plugin — the loader will detect the firmware and warn if the architecture is not available.
- Parses the ESP-IDF extended header format (magic
0xE9) for all ESP32 chip variants - Auto-detects the chip from the
chip_idfield in the extended header - Creates segments at correct memory addresses per chip (IRAM, IROM, DRAM, DROM, RTC)
- Loads ROM function and data symbols extracted from official Espressif ROM ELFs and ESP-IDF linker scripts
- Identifies the entry point and kicks off auto-analysis
Symlink this directory into your Binary Ninja plugins folder:
# macOS
ln -s /path/to/this/repo "$HOME/Library/Application Support/Binary Ninja/plugins/esp32-loader"
# Linux
ln -s /path/to/this/repo "$HOME/.binaryninja/plugins/esp32-loader"Open an ESP32 .bin firmware file in Binary Ninja. The loader will automatically detect it via the magic byte and chip ID, and offer to load it as "ESP32 Firmware."
A load setting is available to enable/disable ROM symbol loading.
./run_tests.sh # run all tests
./run_tests.sh -v # verbose output
./run_tests.sh -k "TestChipsTable" # run specific testsRequires pytest and a Binary Ninja license (headless API). The test script uses Binary Ninja's lastrun file to locate the installation automatically.
Test firmware for all 9 chip variants is expected in tests/firmware/ (not committed to the repo).
ROM symbols in rom/ are pre-generated and committed. To regenerate them:
pip install pyelftools
python scripts/extract_rom_symbols.pyThis downloads ROM ELFs from espressif/esp-rom-elfs and linker scripts from espressif/esp-idf, then merges them into per-chip JSON files.
ROM symbols were extracted from two sources:
- ROM ELFs: Official ROM ELFs from espressif/esp-rom-elfs (Apache 2.0, Copyright 2015-2022 Espressif Systems).
- Linker scripts: ESP-IDF ROM linker scripts from espressif/esp-idf (
components/esp_rom/<chip>/ld/).
The ghidra-esp32-flash-loader project (dynacylabs) was a reference for the firmware format and ROM ELF approach.
MIT