Magic Extractor is a universal extraction tool for Windows that identifies a file with several detectors and routes it to the right bundled extractor. It aims to cover mainstream compression formats, the installers you actually see today, and a range of less common archivers.
It auto-detects 80+ formats — archives, installers, disk images, forensic
images (EWF/AFF/AD1), disc images, mail stores and modern codecs. See
formats.md for the full list.
Download the latest release, unzip it, and run:
magic-extractor.exe extract mystery.bin
See Examples for identify, list, carve, --recursive and --bruteforce.
cli: source code.bin: bundled detector and extractor binaries.detectors: DIE, Magika, binwalk (TrID's defs are converted todata/signatures.json).extractors: 7z, unrar, unace, unshield, lessmsi, dark (WiX), and more.
data: runtime configuration, loaded dynamically (see below).formats: one handler module per format family.
gui: optional tkinter front-end that wraps the CLI (see GUI).test: sample files per format (fixtures for the extraction/detection tests).tools: developer tooling (generate_data.py— builds the data files from handlers).
The compiled build keeps bin/, data/ and config.ini external to the exe so
they can be updated with a file swap; the path resolver in main.py finds them
beside the executable (frozen) or under cli/ (dev).
For normal extraction, detectors run in this order with early-exit — the first one that yields a known handler wins (cheapest first, so the ML model is usually skipped):
- puremagic — pure-python, no subprocess; a cheap MIME check for well-formed archives.
- built-in signatures — magic-byte patterns in
data/signatures.json; names archivers the engines miss (bcm, dgca, kgb, uharc, alzip, freearc, ...) with no external process. - DIE (Detect It Easy) — signature engine; the specialist for installers, PE and SFX.
- binwalk — short type keys (cpio, lzma, ...) and embedded content.
- Magika — Google's AI content-type detector, as a catch-all.
Each detector contributes uniquely (they are complementary, not redundant): the signature DB names archivers the engines miss, DIE handles installers/PE, binwalk catches a few types the others miss, puremagic/Magika cover MIME.
Each handler declares its own indicators via detection_mimes() /
detection_names() / detection_signatures(); tools/generate_data.py compiles
these into data/handlers.json and data/signatures.json (with an optional
data/extra_detections.json merged on top). TrID is not used.
Note: any format whose signature is missing from puremagic's
magic_data.json(or that puremagic reports only as a genericapplication/octet-stream) must declare a customdetection_signatures()entry in its handler — otherwise it will not be detected by content.
--bruteforcedisables early-exit: every detector runs and each detected handler is tried in turn (useful when the first guess is wrong).- Executables that no detector identifies fall back to the wrapped-exe installer handlers (BitRock, Clickteam, Inno, ...), which self-validate.
- The
carvesubcommand additionally uses binwalk's offset map to extract archives embedded at arbitrary offsets (e.g. inside firmware images).
The detection → handler routing map lives in data/handlers.json (hand-curated,
loaded at runtime); a generic-token blacklist lives in data/detection_blacklist.json.
See formats.md for the full list of formats and their handlers.
To add support for a new format, see docs/adding-a-handler.md — the end-to-end guide (handler class, detection declaration, DIE/TrID lookup, magic signatures, regenerating the routing data, bundling the tool, and testing).
Most users just download the release (see Quick Start). To run from source:
git clone <repo-url>
cd magic-extractor
pip install -r cli/requirements.txtMagic Extractor uses subcommands:
python cli/main.py extract <path> [output_dir] [options] # detect and extract
python cli/main.py identify <path> # report type + candidate handlers
python cli/main.py list <path> # list archive contents
python cli/main.py carve <path> [output_dir] [options] # carve embedded archives (binwalk offsets)A bare path with no subcommand defaults to extract (backward compatible):
python cli/main.py <path> <output_dir> [options]extract options:
-
--password <password>: password for encrypted archives. -
-r,--recursive: extract archives found inside the output (bounded by--max-depth, default 5). -
-b,--bruteforce: try every handler detected instead of stopping at the first. -
--open-output-folder <true|false>: open the output folder when done. -
--check-free-space <true|false>: warn if the output volume may lack room. -
--check-unicode <true|false>: warn about non-ASCII extracted names. -
--fix-file-extensions <true|false>: give extensionless extracted files a content-based extension (never overwrites an existing one). -
--create-log-files <true|false>: write a per-run log to the output dir.(Each defaults to its
config.inivalue when omitted; combine with--update-defaultsto persist the given value — e.g.--open-output-folder false --update-defaultsturns a previously-saved default off.) -
--no-fast-check: read the whole file for detection instead of the first 2048 bytes. -
--update-defaults: persist the given settings as defaults inconfig.ini.
carve options: --list (print the binwalk fragment table), --fragment N (carve one
fragment by index), --raw (carve every fragment, not only handler-known ones).
In the examples below,
magic-extractoris the built.exe. From source, replace it withpython cli/main.py— the arguments are identical.
Extract an archive — you don't need to know its type; it is auto-detected:
magic-extractor extract mystery.bin
# extracts into mystery_extracted/ next to the file
Identify a file without touching it — shows what each detector saw and which handler would run:
magic-extractor identify setup.exe
File: setup.exe
[DIE] detect inno setup installer
Candidate handlers (in order):
- FormatInnoSetupHandler
List an archive's contents (no extraction):
magic-extractor list backup.7z
Recursive — extract archives found inside the output (e.g. a .tar.gz, or an
installer that contains more archives), up to --max-depth levels:
magic-extractor extract app-1.0.tar.gz --recursive
Bruteforce — when detection is unsure, try every handler that matched instead of stopping at the first:
magic-extractor extract weird-archive.dat --bruteforce
Carve — pull archives that are embedded at some offset inside a bigger file (classic for firmware images). Inspect first, then carve:
magic-extractor carve router-firmware.bin --list
IDX OFFSET SIZE NAME DESCRIPTION
0 0x00000000 793,720 pe Windows PE binary
1 0x000c1c78 2,495,983 lzma LZMA compressed data
magic-extractor carve router-firmware.bin # carve + extract the known blobs
magic-extractor carve router-firmware.bin --fragment 1 # carve only fragment #1
An optional tkinter front-end (in gui/) wraps the CLI — a Universal-Extractor-style
window with drag-and-drop, a batch queue, run history and a Preferences dialog. It
shells out to the same main.py, so detection and extraction behave identically.
python gui/main.py # launch the window
python gui/main.py <file> [outdir] # prefill the source (and destination)
python gui/main.py <file> /scan # prefill and start in identify modeDrag-and-drop needs the optional tkinterdnd2 package (pip install -r gui/requirements.txt);
without it the window still works, minus drop support. It can also register an Explorer
context-menu entry from its Preferences dialog.
cd cli
pyinstaller --onefile main.py --name magic-extractor --collect-data puremagicThen copy bin/, data/ and config.ini next to dist/magic-extractor.exe.
CI does this automatically — see .github/workflows/release.yml.
MIT — see LICENSE.txt. Note: the bundled third-party extractor/detector
binaries under cli/bin/ keep their own licenses (some proprietary freeware)
and are not covered by MIT; verify their redistribution terms before shipping.
- Lead Developer: DSR! — xchwarze@gmail.com
- Thanks to all contributors.