How to Analyze Memory Dumps with Volatility 3 for Incident Response

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
A compromised machine that has been running malware for hours contains forensic evidence that will not survive a reboot and may not exist on disk at all. Fileless malware executes entirely from memory; process injection hides malicious code inside legitimate processes; encryption keys for files and communications exist transiently in RAM. Memory forensics captures this evidence.
Volatility 3 (the Python 3 rewrite of the original Volatility framework) is the standard tool for this analysis. It works on memory images from any acquisition tool and includes over 100 plugins covering Windows, Linux, and macOS analysis.
Memory Acquisition
Tools for acquiring memory from Windows (live system):
# WinPmem (recommended for most use cases: open source):
# Download: https://github.com/Velocidex/WinPmem
winpmem_mini_x64_rc2.exe -o C:\Temp\memory.raw
# Acquires physical memory to a raw image file
# Takes 5-15 minutes for a 16GB system
# Magnet RAM Capture (free, GUI):
# https://www.magnetforensics.com/resources/magnet-ram-capture/
# Download and run: point output to investigation drive
# Belkasoft RAM Capturer:
# Works even if some forensic tools are blocked by security software
# FTK Imager (Lite, free):
# File > Capture Memory → select destination
# For Velociraptor: capture memory remotely:
# Artifact: Windows.Memory.Acquisition
# Streams the memory image to the Velociraptor server without local storage
Acquire on Linux:
# Using avml (Azure VM memory acquisition):
sudo avml /tmp/memory.lime
# Using LiME kernel module:
insmod lime.ko "path=/tmp/memory.lime format=lime"
# avml is simpler: pre-compiled binary, works on most modern kernels
# Download: https://github.com/microsoft/avml
Install Volatility 3:
git clone https://github.com/volatilityfoundation/volatility3
cd volatility3
pip install -r requirements.txt
# Optional: install additional requirements for specific plugins
pip install yara-python capstone pycryptodome
# Verify:
python3 vol.py -h
Process Analysis: Finding Hidden and Injected Processes
Step 1: List all processes (pslist):
# List processes from the Windows kernel EPROCESS doubly-linked list:
python3 vol.py -f memory.raw windows.pslist
# Key output columns:
# PID PPID ImageFileName Offset(V) Threads Handles SessionId CreateTime
# 4 0 System 0xfa80... 95 472 None 2026-05-14...
# 1234 4 svchost.exe 0xfa81... 12 200 0 2026-05-14...
# Look for:
# - svchost.exe with unexpected parent (should be services.exe PID ~700-800)
# - processes with no parent (orphaned)
# - processes named suspiciously like system processes but wrong path
Step 2: Cross-reference with psscan (find hidden processes):
# Scan memory for EPROCESS structures (finds rootkit-hidden processes):
python3 vol.py -f memory.raw windows.psscan
# Compare pslist vs psscan:
python3 vol.py -f memory.raw windows.pslist --pid-filter > pslist.txt
python3 vol.py -f memory.raw windows.psscan > psscan.txt
# Processes in psscan but NOT in pslist = hidden by rootkit
Step 3: Check process executable paths:
# Show the DLL path for each process (reveals processes running from unusual locations):
python3 vol.py -f memory.raw windows.dlllist
# Or check just the image path:
python3 vol.py -f memory.raw windows.cmdline
# Output: PID Process Args
# 1234 svchost.exe C:\Windows\System32\svchost.exe -k netsvcs
# 5678 svchost.exe C:\Temp\svchost.exe -k ← WRONG PATH
Step 4: Detect parent-child anomalies:
# View process tree:
python3 vol.py -f memory.raw windows.pstree
# Legitimate: winlogon.exe → userinit.exe → explorer.exe
# Anomalous: explorer.exe → cmd.exe → powershell.exe → curl.exe
# Anomalous: svchost.exe → cmd.exe (svchost should not spawn cmd)
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
Process Injection Detection with malfind
Identify injected shellcode with malfind:
# malfind scans all process memory for regions that are:
# 1. Executable (PAGE_EXECUTE_* protection)
# 2. NOT backed by a file on disk (anonymous memory region)
# 3. Contain PE headers or shellcode signatures
python3 vol.py -f memory.raw windows.malfind
# Output includes:
# PID Process Address Length Protection Data
# 1234 explorer 0x12340000 4096 PAGE_EXECUTE_READWRITE
# 4d 5a 90 00 03 00 00 00 MZ...... ← PE header = injected DLL
# 5678 notepad 0xabcd0000 1024 PAGE_EXECUTE_READWRITE
# fc 48 83 e4 f0 e8 cc... ← x64 shellcode pattern
# Extract the injected region for further analysis:
python3 vol.py -f memory.raw windows.malfind --dump --pid 1234
# Creates: pid.1234.vad.0x12340000-0x12340fff.dmp
# Analyze the extracted shellcode:
file pid.1234.vad.0x12340000-0x12340fff.dmp
# If PE: run through capa, ClamAV, or Detect-It-Easy
# If shellcode: run through scdbg or run in sandbox
Hash injected regions against VirusTotal:
# Get SHA256 of each dumped VAD region:
for f in *.dmp; do
hash=$(sha256sum "$f" | cut -d' ' -f1)
echo "$f: $hash"
done > dumped_hashes.txt
# Submit to VT via API:
pip install vt-py
python3 -c "
import vt, sys
client = vt.Client('YOUR_VT_API_KEY')
for line in open('dumped_hashes.txt'):
fname, sha256 = line.strip().split(': ')
try:
file = client.get_object(f'/files/{sha256}')
print(f'{fname}: {file.last_analysis_stats}')
except:
print(f'{fname}: NOT FOUND in VT')
client.close()
"
Network, Credentials, and Registry Extraction
Extract network connections at time of capture:
# Show all active network connections and listening ports:
python3 vol.py -f memory.raw windows.netstat
# Output: PID Proto LocalAddr:Port ForeignAddr:Port State Process
# 1234 TCP 0.0.0.0:443 0.0.0.0:0 LISTEN svchost.exe
# 5678 TCP 10.0.0.100:49522 203.0.113.1:443 ESTAB svchost.exe
# The foreign IP of an ESTABLISHED connection is often the C2 server
# Note: windows.netstat shows connections AT THE TIME OF CAPTURE
# Connections terminated before acquisition will not appear
Extract registry hives from memory:
# List registry hives loaded in memory:
python3 vol.py -f memory.raw windows.registry.hivelist
# Shows: Offset FileFullPath
# 0xfa8... \REGISTRY\MACHINE\SYSTEM
# 0xfb2... \REGISTRY\MACHINE\SOFTWARE
# 0xfc1... \REGISTRY\USER\S-1-5-21-...
# Print a specific registry key from memory:
python3 vol.py -f memory.raw windows.registry.printkey \
--key "Software\Microsoft\Windows\CurrentVersion\Run"
# Shows persistence keys for all loaded hives
Extract cached credentials from memory (LSA secrets, hashes):
# WARNING: Only run on evidence you own, in authorized IR
# Dump NTLM hashes from SAM (similar to mimikatz sekurlsa::logonpasswords):
python3 vol.py -f memory.raw windows.hashdump
# Output: User:RID:LMHash:NTHash:::
# Extract LSA secrets:
python3 vol.py -f memory.raw windows.lsadump
# Extract cached domain credentials:
python3 vol.py -f memory.raw windows.cachedump
# These outputs are NTLM hashes: check if matches known breach databases
# or crack with hashcat -m 1000 (NTLM mode)
YARA scan the memory image:
# Scan memory with YARA rules (e.g., Mandiant's flare-rules or Neo23x0's signatures):
python3 vol.py -f memory.raw windows.vadyarascan --yara-rules malware.yar
# Or scan with a YARA rule string:
python3 vol.py -f memory.raw windows.vadyarascan \
--yara-rule 'rule CobaltStrike { strings: $cs = {FC 48 83 E4 F0 E8 C8 00 00 00} condition: $cs }'
# Identifies specific malware families by their in-memory signatures
The bottom line
Volatility 3 memory forensics triage follows four steps: process analysis (windows.pslist + windows.psscan to find hidden processes, windows.cmdline for execution paths), injection detection (windows.malfind for executable non-file-backed memory regions containing PE headers or shellcode), network analysis (windows.netstat for active connections at capture time: the C2 IP is often visible), and credential extraction (windows.hashdump for NTLM hashes). Acquire memory with WinPmem or Magnet RAM Capture before any other IR action on a live system: memory is volatile and lost on reboot or shutdown.
Frequently asked questions
What is Volatility 3 used for in incident response?
Volatility 3 analyzes RAM images from compromised machines to find evidence that does not persist to disk: fileless malware executing entirely from memory, injected shellcode inside legitimate processes (windows.malfind), active network connections at time of capture (windows.netstat: often shows C2 IP), decrypted credentials and encryption keys, and hidden processes that rootkits have unlinked from the kernel process list (windows.psscan vs windows.pslist comparison).
What is the most important Volatility 3 plugin for finding malware?
windows.malfind is the primary injected malware detector: it finds memory regions that are executable but not backed by a file on disk with PAGE_EXECUTE_READWRITE protection (the hallmark of injected shellcode and reflectively loaded DLLs). Combined with windows.psscan (finds rootkit-hidden processes), windows.cmdline (reveals processes running from unusual paths), and windows.netstat (shows active C2 connections), these four plugins cover the most common attacker tradecraft visible in memory.
How do I capture a Windows memory dump for Volatility analysis?
Three methods for capturing a Windows memory dump: WinPmem (free, open-source): run 'winpmem_mini_x64.exe -o memory.dmp' as admin to create a raw memory image. Magnet RAM Capture (free): GUI tool that creates a .raw memory image compatible with Volatility. Process Hacker's memory dump for single-process analysis (insufficient for full-system forensics). For remote acquisition on enrolled endpoints, Microsoft Defender for Endpoint's Live Response console supports memory acquisition via custom tooling. Always capture memory before rebooting or shutting down: memory is volatile and all forensic artifacts disappear at power-off. The memory image must include the page file (pagefile.sys) for complete analysis — use WinPmem with the page file inclusion option.
How does Volatility 3 differ from Volatility 2?
Volatility 3 (released 2020) is a major rewrite with several important changes: no more profile requirement — Volatility 3 uses symbol tables (ISF files) that it can download automatically based on the memory image's kernel version, eliminating the most common beginner error in Volatility 2 ('no suitable address space found'). Plugin syntax changed: commands now use dot notation (windows.pslist instead of pslist), and most plugins run against a specific OS (windows.*, linux.*, mac.*). Volatility 3 is significantly faster due to parallel processing. Volatility 2 had more plugins for older Windows versions and Mac/Linux; Volatility 3 is still catching up in breadth but is the current maintained codebase. New investigations should use Volatility 3; legacy investigations with older memory images may require Volatility 2.
What Volatility 3 commands should I run first when analyzing a suspicious memory image?
Standard first-pass Volatility 3 triage for Windows: run windows.pslist (process list with parent-child relationships), windows.psscan (cross-checks process list against raw pool scanning -- differences indicate rootkit-hidden processes), windows.netstat (active network connections with process attribution), windows.cmdline (command line arguments for all processes -- reveals suspicious commands), and windows.malfind (injected code regions). Compare windows.pslist and windows.psscan outputs: processes appearing in psscan but not pslist are rootkit-hidden. Check network connections for processes making outbound connections that have no legitimate reason (svchost.exe to an unusual IP, cmd.exe to port 443). This five-plugin pass takes 5-10 minutes and covers the majority of common malware indicators.
How does Volatility 3 Linux analysis differ from Windows analysis and how do you handle kernel symbol mismatches?
Linux memory analysis with Volatility 3 requires a matching kernel symbol table (ISF file) for the specific kernel version running on the compromised system. Generate it using dwarf2json on a system with the same kernel version: 'dwarf2json linux --elf /usr/lib/debug/boot/vmlinux-$(uname -r) > linux-symbols.json'. Linux plugins follow the same pattern as Windows: linux.pslist lists processes, linux.psaux shows command arguments, linux.netstat shows network connections, linux.bash extracts bash command history from memory. A key practical challenge: cloud instances often run custom kernels (AWS Nitro, GCP custom kernels) where public symbol table repositories will not match -- in that case, the dwarf2json approach on an identical instance type is the only reliable path. For containerized environments (Docker/Kubernetes), acquire the host's memory: containers share the host kernel, so host memory analysis exposes all container processes. The Volatility3-Linux-Symbols project on GitHub provides pre-built symbol tables for common Ubuntu, Debian, and CentOS kernel versions as a starting point.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
