Wiki / Concepts

Entropy

A measure of how random data is, from 0 to 8 bits per byte. Plotted across a firmware image it reveals compression, encryption, and where interesting regions begin.

Entropy across a firmware image
Header / vectors ~1.0
Executable code ~6.0
Padding (0xFF) ~0.0
Compressed rootfs ~7.7
Encrypted blob ~7.99
Bits-per-byte annotated per region. Code sits near 6.0, compressed data near 7.7, and a truly encrypted region pins against 8.0 with no compression header in front of it. The jump from a low-entropy header straight to ~8.0 is the classic encryption tell.

Entropy is a measure of how unpredictable a block of data is, expressed in bits per byte from 0 (constant, empty, or perfectly repetitive) to 8 (statistically indistinguishable from random). It is Shannon entropy applied byte-by-byte over a sliding window, and plotting it across a firmware image is one of the fastest ways to understand a binary you have never seen before.

What it is

For a window of bytes, entropy counts how evenly the 256 possible byte values are distributed. All-zero padding scores near 0; English text or opcodes cluster around a handful of common values and score in the middle; data that uses every byte value equally scores near 8. The number does not tell you what the data is, only how surprising each byte is on average, which turns out to be enough to classify large regions at a glance.

Why it matters

Entropy tells you what you are looking at before you spend time on it. A long stretch at maximum entropy is either compressed or encrypted, and distinguishing the two decides your next move: a compressed filesystem you can simply extract, versus an encrypted blob that needs a key first. It also localizes the interesting parts of a dump, keys, certificates, and packed payloads all show up as sharp entropy spikes against a low-entropy background, so an entropy graph is effectively a map of where to dig.

Rough guide

  • 0.0 to 3.0: empty flash, 0x00/0xFF padding, or highly repetitive data.
  • 4.5 to 6.5: executable code and structured binary data.
  • 7.0 to 7.85: compressed data (gzip, LZMA, XZ, squashfs).
  • 7.9 to 8.0: encrypted data, or an already-compressed archive.

How to check it

Two standard tools cover almost every case. binwalk -E renders an entropy curve across the whole image; ent gives you hard statistics on a carved region.

binwalk -E firmware.bin            # entropy graph of the whole image
binwalk -E --save firmware.bin     # write the plot to PNG for the report
ent extracted_region.bin           # chi-square + entropy of one carved region

ent prints an entropy figure and a chi-square distribution. An entropy of 7.9998 with a chi-square percentage that "would exceed this value randomly less than 0.01%" is the signature of good encryption or already-compressed data. A region that reads 7.6 and sits behind an LZMA or squashfs magic almost certainly extracts cleanly.

How to read the graph

A sudden jump to near-8.0 right after a low-entropy header, with no compression signature in front of it, is the classic sign of an encrypted partition. If binwalk's signature scan finds a gzip, LZMA, XZ, or squashfs magic at the start of the high-entropy region, it is compressed and extractable instead. Flat regions at 0.0 are erased or unused flash; a noisy mid-band around 6.0 is code. Always cross-check the entropy curve against the signature scan before concluding.

Pitfalls

  • High entropy is necessary but not sufficient for encryption: compressed data is also high-entropy, and the two are only told apart by the presence or absence of a compression header.
  • A short high-entropy blob may just be a key, a certificate, or a JPEG, not a whole encrypted partition. Window size matters; a small window exaggerates local spikes.
  • Base64 or hex-encoded ciphertext has lower entropy (about 6.0 and 4.0 respectively) because it uses a restricted alphabet, so an encrypted secret can hide in plain sight below the 8.0 line.

Further reading