MalHunt gets a major overhaul: Volatility3, smarter YARA handling, and better error recovery

If you have been following my open-source work, you probably know MalHunt, the memory forensics tool I built to automate malware hunting on top of Volatility. Yesterday I pushed a significant batch of updates that, taken together, amount to a near-complete rewrite of the project. Here is what changed and why it matters.
From a script to a proper Python package
The most visible change is structural. The original malhunt.py was a single 317-line script: practical, but not particularly maintainable or extensible. That file is gone. The codebase now lives under src/malhunt/ as a properly organized Python package:
src/malhunt/
├── core.py # orchestration logic
├── volatility.py # Volatility3 wrapper
├── scanner.py # YARA, Malfind, and network scanners
├── artifacts.py # artifact collection and ClamAV integration
├── models.py # data models
├── utils.py # utilities and YARA rule handling
└── __main__.py # CLI entry point
This separation makes each component independently testable and easier to extend. Speaking of testing: the project now ships with a full test suite covering the core logic, the scanner layer, and the Volatility wrapper, something the old script lacked entirely.
The package is installable via both pip and poetry, and dependency management is now handled through a pyproject.toml with a locked poetry.lock file. No more environment guesswork.
The big migration: Volatility2 → Volatility3
If you have been using the old version, the most important thing to know is that MalHunt now targets Volatility3 exclusively. The legacy v0.1 relied on Volatility2 and its --profile= flag; that approach is now gone.
Volatility3 works differently: it does automatic OS and version detection, it exposes plugins with updated names (windows.vadyarascan, windows.malfind, windows.netscan, and so on), and it handles symbol tables rather than profiles. The underlying subprocess management has been rebuilt accordingly, with proper timeout handling and a configurable retry strategy.
A migration guide is available in docs/MIGRATION.md for anyone upgrading from v0.1.
Smarter YARA rule handling
YARA rule management was one of the weakest points of the old tool. The new version addresses it on multiple levels.
Downloading rules from Yara-Forge. Instead of cloning a git repository, MalHunt now fetches the full Yara-Forge rule bundle directly via HTTP, caches it under ~/.malhunt/, and automatically refreshes it when the cache is more than a day old.
Text-based sanitization. Before using any YARA file, MalHunt strips out rule blocks that rely on imports or features not supported by the version of yara-python used by Volatility: import "math", import "cuckoo", import "hash", imphash patterns, and pe.number_of_signatures. This alone prevents a large category of failures on the 3300+ rules included in the Yara-Forge bundle.
Compile-and-prune validation. The sanitization pass handles known-bad patterns, but the YARA format is complex enough that a rule file can still fail to compile for other reasons. The new validate_and_prune_yara_rules_file() function takes a different approach: it actually compiles the file using yara-python, and when a compilation error occurs, it locates the offending rule block, removes it, and tries again. This loop repeats until the file compiles cleanly or a maximum iteration count is reached. The result is a YARA file that is guaranteed to work, even when the upstream source contains rules with edge-case syntax or undocumented dependencies.
Handling large scans without giving up. YARA scanning over a memory dump is slow. On large images it can easily take 15–20 minutes. The new VolatilityConfig now exposes a dedicated yara_timeout parameter (defaulting to 15 minutes) separate from the general command timeout. If a scan times out and the threshold is still below one hour, MalHunt doubles it and retries automatically. This prevents the tool from aborting unnecessarily on large forensic images, the kind you typically encounter in enterprise incident response.
Better error messages that actually help
One of the most frustrating aspects of working with Volatility is decoding its error output. MalHunt now puts effort into turning those errors into actionable feedback.
Structured error objects. The VolatilityError exception now carries the plugin name, the return code, and the full stdout and stderr from the failed command. Downstream code, and log files, can show exactly what went wrong and where, rather than just “Volatility command failed.”
Symbol recovery. When Volatility fails because Windows symbol tables (PDB files) are missing, MalHunt now attempts to recover automatically. It parses the error output for download URLs, tries both .pdb and .pd_ filename variants, and downloads the files into the correct directory structure. If the automatic recovery does not succeed, the tool generates a ready-to-run shell script containing all the download commands, so you can fix the problem in one step rather than hunting through Volatility documentation.
YARA dependency detection. A separate check catches the situation where yara-python is not installed in the same Python environment that the vol binary uses. In that case MalHunt raises a specific error:
“YARA backend not available for Volatility. Install yara-python in the same Python environment used by ‘vol’ (or use yara-x), then retry.”
That single sentence saves a lot of time compared to staring at a generic plugin-not-available stack trace.
Documentation
The project now ships with a proper docs/ directory covering architecture decisions, installation instructions for various environments, a full usage reference with CLI examples, and a 400-line troubleshooting guide. Not the most glamorous part of a release, but probably the one most people will actually use.
Upgrading
If you were using the old version, the upgrade path is straightforward:
pip install --upgrade malhunt
Or from source:
git clone https://github.com/andreafortuna/malhunt.git
cd malhunt
poetry install
Make sure you have Volatility3 (≥2.0.0) installed and accessible as vol in your PATH. ClamAV integration remains optional.
If you were running v0.1 with Volatility2, read the migration guide first: the command-line interface has changed and the profile-based approach no longer applies.
What is next
A few things are still on my list: Linux memory dump support has been tested but could use more coverage, the ClamAV integration needs updating to handle newer daemon configurations, and I want to add structured JSON output for easier integration with SIEM pipelines and case management tools. Pull requests and issues are welcome on GitHub.
MalHunt is released under the MIT license. It is intended for authorized forensic analysis and security research only.