// What is Volatility?
Volatility is an open-source memory forensics framework written in Python. It analyses raw memory dumps taken from a live system � giving you a snapshot of everything that was in RAM at the time of capture: running processes, open network connections, loaded DLLs, registry hives, injected shellcode, and more.
Memory forensics is often the most valuable part of a malware investigation. Disk artefacts can be wiped or encrypted, but a memory dump captured mid-execution exposes exactly what the malware was doing � including code that never touched the disk.
This guide covers Volatility 3, the current version. Vol3 no longer requires profiles � it automatically identifies the OS and uses symbol tables instead. Commands shown use vol.py but the tool may also be invoked as vol depending on your installation.
| Supported memory sources | Notes |
|---|---|
Raw memory dump (.raw, .mem, .dmp) | Most common � produced by tools like WinPmem, DumpIt, Magnet RAM Capture |
Windows crash dump (.dmp) | Full kernel dumps include all physical memory |
Hibernation file (hiberfil.sys) | Compressed RAM snapshot from Windows hibernation |
VMware snapshot (.vmem + .vmss) | Virtualised environment memory � common in lab scenarios |
VirtualBox snapshot (.sav) | VirtualBox saved state files |
// Getting Started
Volatility 3 requires Python 3.7+ and can be installed via pip or run directly from the source repository.
# Clone the repository
git clone https://github.com/volatilityfoundation/volatility3.git
cd volatility3
# Install dependencies
pip3 install -r requirements.txt
# Verify install
python3 vol.py -h
Basic command structure
All Volatility 3 commands follow the same pattern. The -f flag specifies the memory image, followed by the plugin name.
python3 vol.py -f <memory.dmp> <plugin> [options]
# Example
python3 vol.py -f memdump.raw windows.pslist
Pipe output to a file. Volatility plugins often return hundreds of rows. Always redirect output so you can grep and search at leisure: vol.py -f mem.raw windows.pslist > pslist.txt
Plugin namespaces
| Prefix | Target OS | Example |
|---|---|---|
windows. | Windows | windows.pslist |
linux. | Linux | linux.pslist |
mac. | macOS | mac.pslist |
// Identifying the Image
Before running analysis plugins, confirm what OS and architecture the dump is from. Volatility 3 handles this automatically in most cases, but windows.info gives you a clear summary.
# OS and kernel information
python3 vol.py -f memdump.raw windows.info
This returns the Windows version, build number, architecture, processor count, and base kernel offsets � useful context for the rest of the investigation.
Volatility 2 difference: In Vol2 you had to manually specify --profile=Win10x64_19041. Vol3 replaces this with automatic symbol resolution using ISF (Intermediate Symbol Format) files downloaded on first use.
// Process Analysis
Process analysis is usually the first step in a memory investigation. You want to understand what was running, how processes relate to each other, and whether anything looks out of place.
List running processes
# Walk the EPROCESS linked list � the standard process list
python3 vol.py -f memdump.raw windows.pslist
# Display as a tree showing parent-child relationships
python3 vol.py -f memdump.raw windows.pstree
Scan for hidden processes
# Scan memory for EPROCESS structures directly � finds processes
# unlinked from the list by rootkits
python3 vol.py -f memdump.raw windows.psscan
Compare pslist vs psscan. Any process that appears in psscan but not pslist has been deliberately unlinked from the process list � a strong indicator of a rootkit or advanced malware hiding itself.
Command line arguments
# Show the full command line used to launch each process
python3 vol.py -f memdump.raw windows.cmdline
DLLs loaded per process
# All DLLs loaded by every process
python3 vol.py -f memdump.raw windows.dlllist
# Filter to a specific PID
python3 vol.py -f memdump.raw windows.dlllist --pid 1234
What to look for in processes
| Indicator | Why it matters |
|---|---|
Misspelled system process names (svch0st.exe, lsass_.exe) | Malware masquerading as a legitimate process |
| System processes with unexpected parent PIDs | e.g. lsass.exe spawned by anything other than wininit.exe |
| Multiple instances of processes that should be singular | There should only be one lsass.exe, one csrss.exe per session |
cmd.exe or powershell.exe as a child of an unexpected parent | e.g. spawned from winword.exe � macro execution |
| Processes with no executable path on disk | Fileless malware running entirely in memory |
Process running from Temp, AppData, or unusual paths | Malware rarely runs from System32 |
Expected Windows process hierarchy
| Process | Expected parent | Expected count |
|---|---|---|
smss.exe | System | 1 |
csrss.exe | smss.exe | 1 per session |
wininit.exe | smss.exe | 1 |
winlogon.exe | smss.exe | 1 per session |
lsass.exe | wininit.exe | 1 |
services.exe | wininit.exe | 1 |
svchost.exe | services.exe | Multiple (normal) |
explorer.exe | userinit.exe | 1 per logged-in user |
// Network Connections
Network plugins extract connection state from memory � showing active and recently closed TCP connections and UDP sockets, along with which process owns them.
# Active and recently closed TCP connections
python3 vol.py -f memdump.raw windows.netstat
# Scan memory for network structures (finds more, including closed connections)
python3 vol.py -f memdump.raw windows.netscan
Both plugins return: local address/port, remote address/port, connection state, owning PID, process name, and creation time.
Prefer netscan over netstat. netscan scans physical memory directly and often surfaces connections that have been closed but not yet cleared, giving you a broader picture of network activity at the time of capture.
Suspicious network indicators
| Indicator | Significance |
|---|---|
Outbound connection from lsass.exe, svchost.exe, or system processes | System processes don't make outbound connections � almost certainly malicious |
| Connection to a non-standard port (4444, 1337, 8888, 443 to a non-CDN IP) | Reverse shell or C2 channel |
| Large number of connections to the same external IP | Beaconing or data exfiltration |
| Listening port opened by an unexpected process | Backdoor or bind shell |
| Connection from a process with no on-disk executable | Fileless malware communicating outbound |
// Hunting Malware
These plugins are specifically designed for detecting malicious code in memory � injected shellcode, hollowed processes, and hooked functions.
malfind � injected code detection
malfind scans Virtual Address Descriptor (VAD) entries for memory regions that are executable, not backed by a file on disk, and contain code-like content. This is the primary way to find shellcode injection and process hollowing.
# Scan all processes for suspicious memory regions
python3 vol.py -f memdump.raw windows.malfind
# Limit to a specific process
python3 vol.py -f memdump.raw windows.malfind --pid 1234
# Dump suspicious regions to disk for further analysis
python3 vol.py -f memdump.raw windows.malfind --dump
malfind produces false positives. Legitimate software like browsers and .NET runtimes frequently JIT-compile code into anonymous RWX memory regions. Always verify hits manually � look for MZ headers, shellcode patterns, or recognisable C2 signatures in the hex output before concluding injection.
Handles � open object references
# All open handles for a process (files, registry keys, mutexes, threads)
python3 vol.py -f memdump.raw windows.handles --pid 1234
Malware often uses named mutexes as an infection marker to avoid re-infecting the same host. Unique or randomly named mutexes in suspicious processes are worth noting.
Services
# Enumerate Windows services from memory
python3 vol.py -f memdump.raw windows.svcscan
Suspicious memory region flags
| VAD Protection | Meaning | Suspicion level |
|---|---|---|
PAGE_EXECUTE_READWRITE | Memory is readable, writable, and executable simultaneously | High � legitimate code is rarely RWX |
PAGE_EXECUTE_READ | Readable and executable but not writable | Normal for mapped DLLs |
PAGE_NOACCESS | Reserved memory with no access | Low on its own |
vadinfo � virtual address descriptor details
# Show VAD tree for a specific process
python3 vol.py -f memdump.raw windows.vadinfo --pid 1234
// Registry & Files
Registry hives are mapped into memory during runtime. Volatility can read them directly from the dump without needing the on-disk hive files.
List registry hives
# List all registry hives loaded in memory
python3 vol.py -f memdump.raw windows.registry.hivelist
Print a registry key
# Read a specific key � useful for checking persistence locations
python3 vol.py -f memdump.raw windows.registry.printkey \
--key "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
# Read a user-specific Run key
python3 vol.py -f memdump.raw windows.registry.printkey \
--key "SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
Common persistence registry keys
| Registry key | What malware does with it |
|---|---|
...\CurrentVersion\Run | Execute on every user login � most common persistence mechanism |
...\CurrentVersion\RunOnce | Execute once on next login then delete the entry |
...\CurrentVersion\RunServices | Legacy service autostart |
SYSTEM\CurrentControlSet\Services | Malicious driver or service installation |
SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon | Modify Shell or Userinit values for persistence |
File objects in memory
# Scan memory for FILE_OBJECT structures � finds open and recently closed files
python3 vol.py -f memdump.raw windows.filescan
# Filter output to find a specific file
python3 vol.py -f memdump.raw windows.filescan | grep -i "\.exe\|\.dll\|\.bat\|temp"
// Dumping Artefacts
Once you've identified suspicious processes, files, or memory regions, you can extract them from the dump for further analysis in tools like PE Studio, Ghidra, or a sandbox.
Dump a process executable
# Dump the executable image of a process from memory
python3 vol.py -f memdump.raw windows.procdump --pid 1234 --dump-dir ./output/
Dump all process memory
# Dump the full memory map of a process (includes heap, stack, injected code)
python3 vol.py -f memdump.raw windows.memmap --pid 1234 --dump
Dump files from memory
# Dump a file by its virtual offset (from filescan output)
python3 vol.py -f memdump.raw windows.dumpfiles --virtaddr 0xXXXXXXXX
# Find exe files then dump by virtual address
python3 vol.py -f memdump.raw windows.filescan | grep -i "\.exe"
# Then use the virtual address from the output above with --virtaddr
Handle dumped files as live malware. Any executable extracted from a malware capture should be treated as active. Open in an isolated VM or submit to a sandbox (Any.run, VirusTotal) rather than executing on your analysis machine.
Full plugin reference
| Plugin | What it does |
|---|---|
windows.info | OS version, architecture, kernel base address |
windows.pslist | Active processes via EPROCESS linked list |
windows.pstree | Process tree showing parent-child relationships |
windows.psscan | Scan for EPROCESS structures � finds hidden processes |
windows.cmdline | Command line arguments per process |
windows.dlllist | Loaded DLLs per process |
windows.handles | Open handles (files, keys, mutexes) per process |
windows.netscan | Network connections and sockets |
windows.netstat | Active TCP/UDP connections |
windows.malfind | Injected code and suspicious memory regions |
windows.vadinfo | Virtual address descriptor details per process |
windows.svcscan | Windows services from memory |
windows.registry.hivelist | Registry hives loaded in memory |
windows.registry.printkey | Print contents of a registry key |
windows.filescan | FILE_OBJECT structures � open and cached files |
windows.procdump | Dump process executable from memory |
windows.memmap | Full memory map of a process |
windows.dumpfiles | Extract cached files from memory |
// Tips & Best Practices
Start with pslist, pstree, and netscan. These three plugins give you the broadest initial picture � what was running, how it was structured, and what it was communicating with. Build your investigation from what stands out here.
Always compare pslist and psscan. Discrepancies between the two are one of the most reliable indicators of a rootkit or process-hiding technique. A process in psscan but not pslist is hiding.
Capture memory as early as possible. RAM is volatile � processes terminate, connections close, and injected code gets paged out. The sooner you capture memory after an incident is detected, the more evidence you'll recover.
Correlate with disk artefacts. Memory forensics is most powerful when combined with disk analysis (Autopsy) and network logs (Wireshark/Sentinel). A process you find in memory can be cross-referenced against prefetch files, event logs, and network captures for a complete picture.
Check hashes of dumped files. After extracting a suspicious executable with procdump, run the file hash through VirusTotal and your threat intel platform before spending time on manual analysis. It may already be a known sample.