rea-reverse

Binwalk 3 Guide: Install the Rust Version and Extract Firmware

Written for REA 6.4.0Updated 9 min read
On this page

Short answer: Binwalk 3 is a Rust rewrite of the firmware scanner, and its current release is 3.1.0 (October 2024 on GitHub and crates.io). Install it with cargo install binwalk, Homebrew (brew install binwalk), Kali’s binwalk3 package, or the project’s Docker build. Debian’s and Kali’s plain binwalk package is still the Python 2.4.3, so check binwalk --version before you follow any tutorial. Extraction needs external tools: if binwalk -e lists a signature but writes nothing, a helper such as sasquatch is almost always missing.

Who this is for: anyone who found an old Binwalk tutorial, ran its commands, and got different flags, different output or an empty extraction folder.

What you will learn:

  • How v3 differs from v2, flag by flag, including two letters that changed meaning.
  • How to install 3.1.0 on Linux, macOS and Kali, and what each method leaves out.
  • How to scan, extract and recurse, and where the output goes.
  • How to troubleshoot “nothing extracted”.
  • When to reach for Unblob instead, and how REA uses both.

All commands were run on 2026-10-14 against an open-source OpenWrt 25.12.5 image (openwrt-25.12.5-ath79-generic-tplink_archer-c7-v5-squashfs-sysupgrade.bin, checksum verified against OpenWrt’s sha256sums; I call it fw.bin below). Binwalk ran on macOS from Homebrew and on Linux in a Debian 13 arm64 container. I did not run the v2 package or the Docker build; those parts come from the official pages linked inline.

Use these tools on firmware you are entitled to analyze: your own devices, open-source builds or CTF images. See REA’s DISCLAIMER.md.

What changed from v2

The project README calls v3 “re-written in Rust for speed and accuracy”. The Speed and Accuracy wiki page explains the accuracy part: v3 uses parsers that validate each match and work out its size, so it can skip over a gzip or SquashFS body instead of reporting false “MySQL” or “Zlib” hits inside it. On the OpenWrt image, 3.1.0 reported exactly two regions (the uImage kernel and the SquashFS root filesystem) in 7 ms.

The command line is smaller. Comparing binwalk --help from 3.1.0 with the v2.4.3 help shown on Kali’s binwalk page:

Task v2.4.3 v3.1.0
Signature scan default, or -B default
Extract -e -e
Recursive -M (depth with -d) -M (no depth flag)
Output folder -C, default: current directory -C, default: extractions
JSON results -f/--log, -c for CSV -l/--log (JSON only)
Entropy -E plus -J, -N and others -E, saves a PNG
List signatures none -L/--list
Include / exclude -y / -x (regex on descriptions) -y / -x (signature names)
Custom carving -D/--dd, -z removed
Raw opcodes, diffing, offsets -A, -W, -o, -l/--length removed

Two letters changed meaning. -l was --length in v2 and is --log in v3, and -L was the entropy --low threshold and is now --list. An old script that passes -l 4096 will make v3 write a JSON file named 4096.

Also note that the wiki tracks the development branch. Its Carving File Data page documents --carve, and the entropy page mentions --png, but the 3.1.0 release has neither: binwalk --carve returns error: unexpected argument '--carve' found. If a documented flag is missing, check your version before you suspect your install.

Install Binwalk 3

The Supported Platforms page says Binwalk is “only officially support[ed] on 64-bit Linux”, with Ubuntu preferred, and that Windows and macOS are “largely untested”. Each install method gives you the binwalk binary, but not necessarily the extractors it calls.

Option A: cargo (any Linux, also macOS)

sudo apt install build-essential libfontconfig1-dev liblzma-dev   # build deps from the wiki
cargo install binwalk --version 3.1.0 --locked
binwalk --version    # binwalk 3.1.0

That is how I built it in the Debian 13 container (with Rust 1.98.1). The Cargo Installation page is explicit: “Cargo will not install external dependencies”. For those, the Compile From Source page has you clone the repository and run sudo ./binwalk/dependencies/ubuntu.sh, which installs 7-Zip, lz4, lzop, cpio, device-tree-compiler, onekey-sec’s sasquatch package and more.

Option B: Homebrew (macOS)

brew install binwalk     # formula: stable 3.1.0, depends on sevenzip

This gave me 3.1.0 on Apple silicon. 7-Zip comes with it, but sasquatch and dtc do not. My first -e run therefore extracted the kernel and failed on the filesystem (see troubleshooting below). For SquashFS on macOS, brew install squashfs and the manual dd plus unsquashfs route in Extract SquashFS from a Firmware .bin work.

Option C: Kali

sudo apt install binwalk3   # Kali package, version 3.1.0; the command is binwalk3

According to Kali’s binwalk3 page, the binary is called binwalk3, so binwalk on the same machine is still v2. On Debian, sources.debian.org lists binwalk 2.4.3 for trixie and sid and 2.3.4 for bookworm, and no binwalk3 package. Ubuntu builds its packages from Debian’s, so run apt-cache policy binwalk before you assume. The v2.4.3 help ends with: “Binwalk v2.x will reach EOL in 12/12/2025. Please migrate to binwalk v3.x”.

Option D: Docker (all extractors included)

The README calls Docker “the easiest way to install Binwalk and all dependencies”. The wiki builds it with sudo ./build_docker.sh from a clone and runs it as:

sudo docker run -t -v "$PWD":/analysis binwalkv3 -Me firmware.bin

I did not build this image; I list it because it is the officially recommended way to get every extractor at once.

Scan, extract and recurse

$ binwalk fw.bin
0           0x0           uImage firmware image, header size: 64 bytes, data size: 2741921 bytes, compression: lzma, ...
2741985     0x29D6E1      SquashFS file system, little endian, version: 4.0, compression: xz, inode count: 1214, ...
Analyzed 1 file for 85 file signatures (187 magic patterns) in 7.0 milliseconds
$ binwalk -e -C bw fw.bin
[+] Extraction of uimage data at offset 0x0 completed successfully
[+] Extraction of squashfs data at offset 0x29D6E1 completed successfully
$ ls bw/fw.bin.extracted
0  29D6E1
$ ls bw/fw.bin.extracted/29D6E1/squashfs-root
bin  dev  etc  init  lib  mnt  overlay  proc  rom  root ...

That successful run was on Linux, with sasquatch installed. Each region gets a folder named after its hex offset. On macOS, Binwalk also left a symlink to the input file inside the output folder.

-M scans every extracted file again. On the same image, binwalk -Me decompressed the kernel’s LZMA payload and found two device tree blobs and a CPIO archive inside it. In the Wiki’s words, results are color-coded by confidence: green when “file metadata and at least some portions of the file data were checked”, red when only the magic bytes matched.

For scripts, use the JSON log:

binwalk -q -l results.json fw.bin

Each region comes out with offset, size, name (for example squashfs), confidence (250 for both regions here) and description. Delete the file between runs: 3.1.0 appends a second array to an existing log, and the file stops being valid JSON (Python’s json.load failed with “Extra data” after two runs).

binwalk -E fw.bin writes an entropy graph to fw.bin.png in the current directory. Long flat stretches near 8 bits per byte mean compressed or encrypted data.

Troubleshooting: “binwalk is not extracting”

1. It is the wrong Binwalk. binwalk --version must print binwalk 3.1.0. If it prints v2 help or Binwalk v2.4.3, you are on the Python package. On Kali, use binwalk3.

2. An extractor is missing. Binwalk prints the exact command it tried. My macOS run printed:

ERROR binwalk::extractors::common] Failed to execute command sasquatch[".../fw.bin.extracted/29D6E1/squashfs_29D6E1.sqsh"]: No such file or directory (os error 2)
[-] Extraction of squashfs data at offset 0x29D6E1 failed!

During -Me, it also failed on dtc for the device trees. binwalk -L shows which helper each format needs. The ones you are most likely to miss are sasquatch (SquashFS), jefferson (JFFS2), ubireader_extract_images / ubireader_extract_files (UBI and UBIFS), 7zz (CramFS and archives) and dtc (device trees). onekey-sec publishes sasquatch as .deb files for amd64, arm64 and armhf. I could not build it on macOS, because its source needs the Linux header sys/sysinfo.h.

3. Too little output to see why. Errors go to stderr through Rust’s env_logger. Per the Errors and Debugging page, RUST_LOG=debug binwalk -Me fw.bin shows everything, and RUST_LOG=off hides it.

4. The data is encrypted or proprietary. If the scan finds a header and then only noise, run -E. A region that stays near 8 bits per byte with no recognizable signature is probably encrypted, and no extractor will open it. Check whether the vendor publishes unencrypted images or GPL source.

5. Not enough memory. The Limitations page says Binwalk “requires at least as much free memory as the size of the file(s) being analyzed”.

Binwalk vs Unblob

Unblob (onekey-sec, MIT license, Python on PyPI, current version 26.6.4) aims at the same job from another angle. I ran Unblob 26.6.4 and Binwalk 3.1.0 on the same OpenWrt image in the same Linux container, with the same sasquatch:

Binwalk 3.1.0 Unblob 26.6.4
Approach Signature scan with validating parsers, then extract Format parsers that find each chunk’s start and end, then extract
Unidentified bytes Not written out Carved as .unknown chunks (here the 64-byte uImage header and the 37,383-byte tail)
Recursion Opt-in with -M On by default, up to 10 levels (README)
Output names Hex offset: 29D6E1/squashfs-root Decimal range: 2741985-7368479.squashfs_v4_le_extract
Report JSON log with -l Rich summary table; JSON report with --report
Install Rust binary; extractors separate pip install unblob; extractors separate (unblob --show-external-dependencies checks them)
Platform per docs 64-bit Linux official Linux packages and Docker; the docs give no macOS install path

On this image, both recovered the same root filesystem. Unblob’s summary also broke down what it found recursively (ELF32, SQUASHFS_V4_LE, LZMA, TAR, GZIP, CPIO) and reported a 66.37% chunk identification ratio, which is a useful measure of how much of a blob you have explained. A practical split: use Binwalk for a fast first look and the offsets, and Unblob when you want everything carved, including the parts nobody recognized. Both are free and MIT-licensed, according to their package metadata as of 2026-10-14. On macOS, the PyPI install needs libmagic (brew install libmagic). Even then, --show-external-dependencies found only lz4 and zstd, so I ran Unblob extractions on Linux only.

Using both from REA

REA, the open-source project by morluto, does not bundle either tool. In 6.4.0, rea inspect-firmware-regions runs your Binwalk (its contract says “Binwalk 3.1.x (verified with 3.1.0)”) and rea extract-firmware runs your Unblob (“Unblob 26.6.x (verified with 26.6.4)”). Both are Linux-only and need util-linux prlimit, a procps ps, and absolute paths:

export REA_BINWALK_COMMAND=/usr/local/cargo/bin/binwalk
export REA_UNBLOB_COMMAND=/opt/unblob/bin/unblob
rea inspect-firmware-regions /root/fw/fw.bin --format json

In my Linux container this returned the same two regions, with engine.version 3.1.0 and the executable’s SHA-256 recorded. That makes it a quick way to confirm that the Binwalk you installed is the one you meant. On macOS, both commands refuse with “This integration requires Linux”. Firmware Analysis with REA covers the full workflow, and Verify a Real REA Install covers checking REA itself.

FAQ

Is there an official Windows build? No official one. The wiki lists Windows as largely untested. WSL2 with Ubuntu matches the supported platform.

Can I keep v2 and v3 side by side? Yes. Kali does this already (binwalk vs binwalk3). Elsewhere, install v3 with cargo into ~/.cargo/bin and call it by full path.

Why doesn’t v3 find the “Zlib” hits v2 used to show? Many were false positives inside other compressed data. v3’s validating parsers skip over the payloads they recognize.

Where did --dd go? 3.1.0 has no custom carving flag. Carve with dd using the offset and size from the scan, as in the SquashFS guide.

Authorised use: run Binwalk and Unblob only on firmware you own or may analyze, such as open-source images and CTF files.

Next steps