ImHex Turns Mystery Bytes Into Structs
Stop squinting at hex dumps. ImHex's C-like pattern language paints fields directly onto the bytes as you describe them.
Every team has a drawer with a .dat file in it. Ours came from a dead vendor's machine controller: no schema, no docs, nobody left to ask. The reflex is a Python REPL, struct.unpack, print, squint, repeat.
That loop is the problem. ImHex — its author just posted a new walkthrough of file format reverse engineering — inverts it: you describe the structure, and the editor paints each field onto the bytes as you type.
Why this matters
Undocumented binary formats find every developer eventually: legacy exports, firmware images, save files, sensor logs. Blind parsing isn't hard, it's slow — every hypothesis costs a write-run-print cycle. Interactive annotation collapses that cycle to keystrokes, and the description you end up with is documentation you can hand to the next person.
How it works
Open the file and let the built-in magic database tell you if it's a known format. Then check the entropy view: flat high entropy means compressed or encrypted, while periodic dips usually mark record boundaries. Select any bytes and the data inspector shows every plausible interpretation live.
The real weapon is the pattern language. It reads like C: structs, fixed arrays, and a placement operator that pins a struct to an offset. Fields you've already parsed become variables — read count from the header, then declare entries[header.count]. Edit the pattern and annotations update instantly. Big-endian? be_u32. And check the community pattern store first — PNG, ELF, SQLite and dozens more are already done.
Where this helps
- Vendor exports with no schema. Map enough fields to write a real converter in whatever language your pipeline uses.
- Firmware dumps. Entropy dips point at config and calibration tables; pattern one and read values instead of hex-squinting.
- Save-file migrations. When the original developers are gone and users still need their data moved.
- IR triage. Pull config tables out of suspicious samples in a sandbox without writing a throwaway parser.
Watch out
It's a DSL shaped like C, not C. Length-prefixed strings, bitfields, and conditional sections are supported but get fiddly — budget an afternoon for fluency. Encrypted or compressed regions defeat it until you decode them elsewhere. Multi-gigabyte files can lag, so carve a representative sample first. And know your legal position: analyzing a format for interop is usually fine, but shipping a product around someone's proprietary format can violate their terms.
Try it yourself
# build a tiny "unknown" format
printf 'STRK' > save.dat
printf '\x01\x00' >> save.dat # version (u16 LE)
printf '\x02\x00\x00\x00' >> save.dat # count (u32 LE)
printf '\x2a\x00\x00\x00ITEM_01\x00' >> save.dat # entry 1
printf '\x2b\x00\x00\x00ITEM_02\x00' >> save.dat # entry 2
cat > pattern.hexpat <<'EOF'
struct Header {
char magic[4];
u16 version;
u32 count;
} header @ 0x00;
struct Entry {
u32 id;
char name[8];
} entries[header.count] @ 0x0A;
EOF
imhex save.dat # then load pattern.hexpat in the Patterns viewTL;DR
- What: ImHex's pattern language annotates raw bytes live from a C-like struct description — the pattern file doubles as format documentation.
- Why: Undocumented binaries stop being guess-and-check; iteration drops from code-run-print to typing.
- Try: Run the snippet, load the pattern, then point it at a mystery file you've been avoiding.