pakunoda
Extract Volatility 3 ISF profiles from raw Linux memory dumps via BTF and kallsyms.
Volatility 3 needs a symbol profile (ISF JSON) that matches the exact kernel of the
machine you captured. Normally you build one with dwarf2json from a vmlinux with
debug symbols, which means tracking down the matching kernel debug package — often
impossible for an unknown or long-decommissioned host. pakunoda skips that step
entirely: it reads the metadata the kernel embeds about itself in its own .rodata
(BTF type information, the kallsyms symbol table, and the linux_banner string) out
of the raw dump and reconstructs the ISF profile directly. No vmlinux, no debug
packages, no matching kernel, no network access.
Installation
Requires Python 3.10 or later.
git clone https://github.com/monkeywave/pakunoda.git
cd pakunoda
pip install -e .
To run the test suite, install the development extras instead:
pip install -e ".[dev]"
pytest
Usage
Generate a profile from a dump. With no -o, the profile is written next to the
dump as <dumpname>_profile.isf.json:
pakunoda extract my-webserver-new.lime
Point -o at a directory (existing, or with a trailing slash to have it created)
to write the default filename inside it:
pakunoda extract my-webserver-new.lime -o ~/cases/webserver/
Or name the output file exactly:
pakunoda extract my-webserver-new.lime -o webserver.isf.json
Other commands:
pakunoda probe <dump>— report which artifacts (banner, DTB, BTF, kallsyms) were found and where, without generating a profile.pakunoda info <isf.json | dump>— summarise either kind of file. Given a profile it reports type and symbol counts, the kernel banner, and whether key structs are present; given a memory dump it reports the container format, size, physical segments and the kernel found inside. Which one it is comes from the file's contents, not its extension. The dump summary costs one pass over the image for the banner (about 0.4 s per GB warm);--no-bannerskips it.pakunoda validate <isf.json>— check an ISF file against the Volatility 3 schema.--strictalso fails on warnings. Handed a memory dump it exits 5 and points atpakunoda extract.
Both accept lzma-compressed .json.xz profiles as well as plain .json.
Common flags: --arch selects the target architecture (default auto), -v enables
verbose logging, -q suppresses everything but errors, and --json switches to
machine-readable output for scripting.
Example
$ pakunoda extract my-webserver-new.lime
pakunoda v0.5.0 — Volatility 3 ISF extractor
Dump: my-webserver-new.lime
Arch: auto
Detected arch: x86_64
ISF generated: /home/analyst/cases/my-webserver-new_profile.isf.json
Types: 12043 Symbols: 8587 Enums: 743 Base types: 12
Kernel: 6.12.48+deb13-amd64
Time: 23.71s
Ready to use with Volatility 3:
vol -f my-webserver-new.lime -s /home/analyst/cases linux.pslist
vol -f my-webserver-new.lime -s /home/analyst/cases linux.lsmod
If Vol3 shows errors or empty results, clear its symbol cache:
rm -f ~/.cache/volatility3/identifier.cache
Also ensure no other ISF files with the same kernel exist under the -s directory.
Using the result with Volatility 3
Pass the directory holding the generated ISF file to Volatility 3 as its symbol directory:
vol -f my-webserver-new.lime -s /home/analyst/cases linux.pslist
Volatility 3 caches which ISF file matches which kernel banner. If it reports errors or returns empty results after you generate a new profile, clear that cache:
rm -f ~/.cache/volatility3/identifier.cache
Also make sure no other ISF file for the same kernel sits under the -s directory,
or Volatility 3 may pick the wrong one.
What it needs from the dump
BTF and kallsyms both live in the kernel's .rodata section, so a dump that captured
kernel memory normally contains everything pakunoda needs. BTF is present on kernels
built with CONFIG_DEBUG_INFO_BTF, which covers mainstream distribution kernels from
roughly 5.2 onwards. When BTF is absent — older kernels, or a custom build without it
— pakunoda falls back to identifying the kernel by structure detection and selecting a
donor profile whose layout matches what the dump actually contains.
That donor comes from a local cache of prebuilt ISFs under ~/.cache/pakunoda/, which
is optional and only consulted on the no-BTF path. If you work with pre-BTF kernels
(CentOS 7, Debian 9, older custom builds) and want to build one, see
docs/PROFILE_CACHE.md — it covers what the cache buys you, how
donor selection is graded and recorded in the output, and the exact steps to build a
cache of your own. For modern kernels you can ignore it entirely.
Supported architectures are x86-64, ARM64, and x86-32 (i386/i686). On a PAE i386 kernel the page-table walk is declined rather than approximated, and is reported as a capability gap. Dumps in raw, LiME, and ELF core formats are read directly.
Note on --research
--research enables prototype research algorithms (structural analysis, profile HMMs,
constellation-based reconstruction) that are part of the ongoing research behind the
tool. They are off by default and are not needed for normal extraction — the
default path is the one you want. Use pakunoda extract <dump> --research-list to see
what is available.
Further reading
For reproducing the results in the accompanying paper, see README_ARTIFACT.md.
Licence
Apache-2.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pakunoda-0.9.0.tar.gz.
File metadata
- Download URL: pakunoda-0.9.0.tar.gz
- Upload date:
- Size: 27.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fd928d13600adf7f728313b571f040544c47cc2666fc225dd73b5e44d0d3393
|
|
| MD5 |
7cef7ebb45e3cee02a2533391a39a842
|
|
| BLAKE2b-256 |
71922019e1028ea80cd24cc7300573d5f70aadd9f8a2bfe1189c2ec307e31c0a
|
Provenance
The following attestation bundles were made for pakunoda-0.9.0.tar.gz:
Publisher:
publish.yml on monkeywave/pakunoda
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pakunoda-0.9.0.tar.gz -
Subject digest:
1fd928d13600adf7f728313b571f040544c47cc2666fc225dd73b5e44d0d3393 - Sigstore transparency entry: 2786035364
- Sigstore integration time:
-
Permalink:
monkeywave/pakunoda@3084156bae4a84ba86b20285fb7eda6ab406ad92 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/monkeywave
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3084156bae4a84ba86b20285fb7eda6ab406ad92 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pakunoda-0.9.0-py3-none-any.whl.
File metadata
- Download URL: pakunoda-0.9.0-py3-none-any.whl
- Upload date:
- Size: 971.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2f926d777f173f20ff967859d1104e09dcb57de8e81764d37b9a4c58d8fd8d7
|
|
| MD5 |
0078bacbbba67628fe8c2cd6fda4c906
|
|
| BLAKE2b-256 |
39b6c65eb846327c0fb91603573cfd495159c36e3ffdf50c7411f31e245729f6
|
Provenance
The following attestation bundles were made for pakunoda-0.9.0-py3-none-any.whl:
Publisher:
publish.yml on monkeywave/pakunoda
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pakunoda-0.9.0-py3-none-any.whl -
Subject digest:
d2f926d777f173f20ff967859d1104e09dcb57de8e81764d37b9a4c58d8fd8d7 - Sigstore transparency entry: 2786035417
- Sigstore integration time:
-
Permalink:
monkeywave/pakunoda@3084156bae4a84ba86b20285fb7eda6ab406ad92 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/monkeywave
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3084156bae4a84ba86b20285fb7eda6ab406ad92 -
Trigger Event:
push
-
Statement type: