From 2e6ef05ddb6b158679d0372e0c060adf96078b6b Mon Sep 17 00:00:00 2001 From: lopqto Date: Mon, 2 Feb 2026 18:29:25 +0330 Subject: [PATCH] patterns: Add pattern for ESP8266 firmware --- README.md | 1 + patterns/esp8266.hexpat | 66 ++++++++++++++++++++ tests/patterns/test_data/esp8266.hexpat.bin | Bin 0 -> 4342 bytes 3 files changed, 67 insertions(+) create mode 100644 patterns/esp8266.hexpat create mode 100644 tests/patterns/test_data/esp8266.hexpat.bin diff --git a/README.md b/README.md index ccd8378b..5a8f5524 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | DTED | | [`patterns/dted.hexpat`](patterns/dted.hexpat) | Digital Terrain Elevation Data (DTED) | | ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries | | ESP32 Image | | [`patterns/esp32_image.hexpat`](patterns/esp32_image.hexpat) | Firmware image format for the ESP32 chip family | +| ESP8266 Image | | [`patterns/esp8266.hexpat`](patterns/esp8266.hexpat) | ESP8266 Firmware Image v1 | | EVTX | `application/x-ms-evtx` | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log | | EXFAT | | [`patterns/fs/exfat.hexpat`](patterns/fs/exfat.hexpat) | Extensible File Allocation Table (exFAT) | | EXFAT (DFIR) | | [`patterns/DFIR/exFAT.hexpat`](patterns/DFIR/exFAT.hexpat) | Imported by DISK_PARSER.hexpat | diff --git a/patterns/esp8266.hexpat b/patterns/esp8266.hexpat new file mode 100644 index 00000000..63a6b17c --- /dev/null +++ b/patterns/esp8266.hexpat @@ -0,0 +1,66 @@ +#pragma author lopqto +#pragma description ESP8266 Firmware Image v1 +#pragma endian little +#pragma magic [ 0xE9 ] @ 0x00 + +/* + * References: + * https://github.com/espressif/esptool/blob/master/esptool/bin_image.py + * https://github.com/esp8266/esp8266-wiki/wiki/ + */ + +import std.mem; + +const u8 ESP8266_IMAGE_MAGIC = 0xE9; + +enum esp8266_flash_mode_t : u8 { + QIO = 0, + QOUT = 1, + DIO = 2, + DOUT = 3 +}; + +enum esp8266_flash_freq_t : u8 { + FREQ_40M = 0, + FREQ_26M = 1, + FREQ_20M = 2, + FREQ_80M = 0xF +}; + +enum esp8266_flash_size_t : u8 { + FLASH_256KB = 0, + FLASH_512KB = 1, + FLASH_1MB = 2, + FLASH_2MB = 3, + FLASH_4MB = 4, + FLASH_2MB_CTR = 5, + FLASH_8MB = 8, + FLASH_16MB = 9 +}; + +bitfield flash_config_t { + esp8266_flash_freq_t freq : 4; + esp8266_flash_size_t size : 4; +}; + +struct header { + u8 magic [[comment("ESP8266 image magic, 0xE9")]]; + u8 segment_count [[comment("Number of segments following header")]]; + esp8266_flash_mode_t flash_mode [[comment("0=QIO, 1=QOUT, 2=DIO, 3=DOUT")]]; + flash_config_t flash_config [[comment("High 4 bits: size, Low 4 bits: freq")]]; + u32 entrypoint [[comment("Entry point address")]]; +}; + +struct segment { + u32 load_addr [[comment("Load address in memory")]]; + u32 size [[comment("Size of segment data")]]; + u8 data[size] [[comment("Segment data bytes")]]; +}; + +// Main v1 image at offset 0 +header bootloader_header @ 0x00; +segment bootloader_segments[bootloader_header.segment_count] @ 0x08; + +// Optional: Second image at 0x1000 (common in ESP8266 flash layout) +header user_header @ 0x1000; +segment user_segments[user_header.segment_count] @ 0x1008; diff --git a/tests/patterns/test_data/esp8266.hexpat.bin b/tests/patterns/test_data/esp8266.hexpat.bin new file mode 100644 index 0000000000000000000000000000000000000000..2de22b264abe57be955849f932377d652f9526ed GIT binary patch literal 4342 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