ReferenceCONSTRUCTED
Memory forensics cheat sheet: acquisition order and the Volatility 3 plugins that answer real questions
What to capture before you touch anything else, how to check the image is usable, and the Volatility 3 plugins grouped by the question they answer, with what each one cannot tell you.
version 1.0checked 2026-09-21windows · linux6 min read
Before analysis: acquisition
Memory is first in the order of volatility set out in RFC 3227, and it is the one artifact on any list that cannot be collected later. Everything else on the host will still be there after a reboot. This will not.
| Rule | Why |
|---|---|
| Capture before isolating with a tool that kills processes, before running antivirus, before anything that loads a lot of code | Every program you run overwrites free pages, and free pages are where terminated processes and closed connections still are |
| Write to external media or a network share, never the local disk | The write goes through the same page cache you are trying to preserve, and the target disk is evidence |
| Record the tool, version, start and end time, and hash the image when it completes | An image with no provenance is an anecdote |
| On a virtual machine, take a snapshot with memory or suspend and copy the memory file | It is atomic. A live capture of a busy host is smeared across the minutes it took, so structures can disagree with each other |
| Collect the pagefile and hiberfil.sys as well | Pages that were swapped out are not in the capture |
Acquisition tooling: WinPmem, DumpIt or Magnet RAM Capture on Windows; AVML or LiME on Linux. Whatever you choose, test it on your standard build before an incident. A driver that blue-screens the one host you needed is a known way to lose the evidence.
Is the image usable?
vol -f host.raw windows.info # did symbols resolve, and does the build look right
vol -f host.raw windows.pslist | head # do process names and times look sane
vol -f host.raw windows.pstree # does the tree have a System, smss, wininit shape
If windows.info cannot find a kernel, the capture is truncated, smeared beyond
use, or from a build whose symbols Volatility could not download. Check the file
size against the host's installed RAM before anything else.
Windows plugins, by question
What was running?
| Plugin | Answers | Be aware |
|---|---|---|
windows.pslist | Processes from the kernel's active process list | A rootkit that unlinks a process hides it from this |
windows.psscan | Processes found by scanning memory for the structure | Finds unlinked and recently exited processes. A process in psscan but not pslist is terminated or hidden, and the exit time says which |
windows.pstree | Parent and child relationships | The relationships are the finding: Word spawning PowerShell, services.exe with an unexpected child, two lsass.exe |
windows.cmdline | The command line of each process | Read from the process's own memory, so the process can alter it |
windows.envars | Environment variables per process | |
windows.getsids, windows.privileges | Which account a process runs as, and enabled privileges | SeDebugPrivilege enabled in a user's process is worth a question |
Was code injected?
| Plugin | Answers | Be aware |
|---|---|---|
windows.malfind | Memory regions that are executable, writable and not backed by a file on disk | The classic injection heuristic. It has false positives: JIT compilers (.NET, browsers, Java) allocate exactly this. Look for an MZ header or shellcode at the start of the region, and ask whether that process should be doing it |
windows.dlllist | Modules loaded in each process, from the loader's lists | A reflectively loaded DLL is absent here, which is why it is compared with VADs |
windows.vadinfo | Every memory region of a process with its protection and backing file | The detail behind a malfind hit |
windows.ldrmodules | Whether each mapped module appears in all three loader lists | A module mapped but missing from the lists has been unlinked |
windows.hollowprocesses | Processes whose in-memory image differs from the one on disk | Present in recent releases. Check your version with vol -h |
What was it talking to?
| Plugin | Answers | Be aware |
|---|---|---|
windows.netscan | TCP and UDP endpoints found by pool scanning, with owning process and creation time | Includes closed connections still in memory. An absent connection proves nothing: the structures are reused quickly on a busy host |
windows.netstat | Endpoints from the live network structures | Closer to what the host would have reported at that moment |
What persisted, and what is loaded in the kernel?
| Plugin | Answers |
|---|---|
windows.svcscan | Services, including their binary paths and state, from memory rather than from the registry on disk |
windows.registry.hivelist, windows.registry.printkey | Hives in memory and the keys in them. Run keys as they were at capture time, including values that were never flushed to disk |
windows.scheduled_tasks | Scheduled tasks parsed from the registry in memory. Present in recent releases |
windows.modules, windows.modscan, windows.driverscan | Kernel modules by list and by scan. The pslist and psscan comparison again, for drivers |
windows.ssdt, windows.callbacks | System call table entries and kernel callbacks pointing outside known modules |
Credentials and files
| Plugin | Answers | Be aware |
|---|---|---|
windows.hashdump, windows.lsadump, windows.cachedump | Local account hashes, LSA secrets, cached domain credentials | This is credential material. Handle the output as you would the credentials themselves, and know whether your authority covers extracting it |
windows.filescan | File objects in memory, with paths | Finds files that were open, including ones since deleted |
windows.dumpfiles | Extracts cached file contents | Often partial. Hash it, but do not expect the hash to match the on-disk file |
windows.handles | Handles per process: files, keys, mutexes | Mutex names are a durable family indicator |
Carving with rules
vol -f host.raw windows.vadyarascan --yara-file sa_triage_samples.yar
vol -f host.raw yarascan.YaraScan --yara-file rules.yar # whole image, slower
The YARA triage samples in this library work here unchanged.
Linux, briefly
Volatility 3 needs a symbol table (ISF) that matches the exact kernel build.
Generating it with dwarf2json from the matching debug kernel is usually the slow
part, so record uname -a at acquisition time.
| Plugin | Answers |
|---|---|
linux.pslist, linux.psscan, linux.pstree | Processes by list, by scan, and as a tree |
linux.bash | Bash history recovered from process memory, including commands never written to .bash_history |
linux.sockstat | Sockets with owning process |
linux.lsmod, linux.check_modules | Kernel modules, and modules hidden from the list |
linux.check_syscall | System call table entries that have been hooked |
linux.malfind | Suspicious executable mappings |
linux.elfs | ELF images mapped in each process |
What memory cannot tell you
- History. It is one moment. It shows what was running at capture, and fragments of what ran recently.
- Absence. Structures are overwritten continuously. "No connection to that address in netscan" is not "no connection was made".
- Anything, if the capture was smeared badly enough. Contradictions between plugins on a live capture are often the acquisition, not the intrusion.
Plugin names and availability change between Volatility 3 releases. vol -h
lists what your installed version has, and that list is the authority, not this
page.
sources
- Volatility 3 documentation
- Volatility 3 source repository, for the current plugin list
- RFC 3227: Guidelines for Evidence Collection and Archiving (order of volatility)
- NIST SP 800-86: Guide to Integrating Forensic Techniques into Incident Response
- Microsoft AVML, a Linux memory acquisition tool
- MemProcFS, memory as a mounted file system