Forensics Intermediate Memory Forensics / Malware Analysis / DFIR

Volatility � Memory Forensics

A practical guide to analysing memory dumps with Volatility 3 � covering process analysis, network connections, malware hunting, and artefact extraction.

20 min read Hands-on Blue Team / DFIR

// 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 sourcesNotes
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.

bash
# 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.

bash
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

PrefixTarget OSExample
windows.Windowswindows.pslist
linux.Linuxlinux.pslist
mac.macOSmac.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.

bash
# 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

bash
# 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

bash
# 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

bash
# Show the full command line used to launch each process
python3 vol.py -f memdump.raw windows.cmdline

DLLs loaded per process

bash
# 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

IndicatorWhy it matters
Misspelled system process names (svch0st.exe, lsass_.exe)Malware masquerading as a legitimate process
System processes with unexpected parent PIDse.g. lsass.exe spawned by anything other than wininit.exe
Multiple instances of processes that should be singularThere should only be one lsass.exe, one csrss.exe per session
cmd.exe or powershell.exe as a child of an unexpected parente.g. spawned from winword.exe � macro execution
Processes with no executable path on diskFileless malware running entirely in memory
Process running from Temp, AppData, or unusual pathsMalware rarely runs from System32

Expected Windows process hierarchy

ProcessExpected parentExpected count
smss.exeSystem1
csrss.exesmss.exe1 per session
wininit.exesmss.exe1
winlogon.exesmss.exe1 per session
lsass.exewininit.exe1
services.exewininit.exe1
svchost.exeservices.exeMultiple (normal)
explorer.exeuserinit.exe1 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.

bash
# 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

IndicatorSignificance
Outbound connection from lsass.exe, svchost.exe, or system processesSystem 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 IPBeaconing or data exfiltration
Listening port opened by an unexpected processBackdoor or bind shell
Connection from a process with no on-disk executableFileless 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.

bash
# 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

bash
# 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

bash
# Enumerate Windows services from memory
python3 vol.py -f memdump.raw windows.svcscan

Suspicious memory region flags

VAD ProtectionMeaningSuspicion level
PAGE_EXECUTE_READWRITEMemory is readable, writable, and executable simultaneouslyHigh � legitimate code is rarely RWX
PAGE_EXECUTE_READReadable and executable but not writableNormal for mapped DLLs
PAGE_NOACCESSReserved memory with no accessLow on its own

vadinfo � virtual address descriptor details

bash
# 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

bash
# List all registry hives loaded in memory
python3 vol.py -f memdump.raw windows.registry.hivelist

Print a registry key

bash
# 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 keyWhat malware does with it
...\CurrentVersion\RunExecute on every user login � most common persistence mechanism
...\CurrentVersion\RunOnceExecute once on next login then delete the entry
...\CurrentVersion\RunServicesLegacy service autostart
SYSTEM\CurrentControlSet\ServicesMalicious driver or service installation
SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinlogonModify Shell or Userinit values for persistence

File objects in memory

bash
# 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

bash
# 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

bash
# 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

bash
# 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

PluginWhat it does
windows.infoOS version, architecture, kernel base address
windows.pslistActive processes via EPROCESS linked list
windows.pstreeProcess tree showing parent-child relationships
windows.psscanScan for EPROCESS structures � finds hidden processes
windows.cmdlineCommand line arguments per process
windows.dlllistLoaded DLLs per process
windows.handlesOpen handles (files, keys, mutexes) per process
windows.netscanNetwork connections and sockets
windows.netstatActive TCP/UDP connections
windows.malfindInjected code and suspicious memory regions
windows.vadinfoVirtual address descriptor details per process
windows.svcscanWindows services from memory
windows.registry.hivelistRegistry hives loaded in memory
windows.registry.printkeyPrint contents of a registry key
windows.filescanFILE_OBJECT structures � open and cached files
windows.procdumpDump process executable from memory
windows.memmapFull memory map of a process
windows.dumpfilesExtract 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.