Windows Memory Forensics: Extracting Processes, Drivers, and Objects

 


By this stage of an investigation, examiners typically possess candidate processes, modules (DLLs), kernel drivers, and discrete memory ranges that warrant deeper examination; each of these artifacts is subject to extraction.


Additional specialized recovery capabilities are also available for other memory-resident items. Although residual data, process heaps, file-system caches, and kernel objects frequently retain evidence of prior system activity, it must be emphasized that not every artifact of interest remains fully resident or complete—individual pages may have been swapped out, overwritten, or never mapped into physical memory. Extraction success is further conditioned by the specific Windows version under examination, the integrity and completeness of the acquired memory image, and the capabilities of the analysis framework employed. Consequently, recovered artifacts—particularly large files or registry hives—may be partial and often require subsequent reconstruction.


Within these constraints, examiners can still pursue extraction of cached copies of previously opened documents, portions of the NTFS Master File Table when present in the file-system cache, enumerations of running Windows services, and memory-resident registry hives. These capabilities, among others, form an integral part of a rigorous memory-forensic examination.


Extraction of memory-resident objects within MemProcFS is realized by presenting recovered artifacts as discrete files and directories inside a mounted virtual filesystem, thereby permitting conventional copy or in-situ examination operations. The principal analytical challenge resides in the accurate identification of the appropriate hierarchical path for each object class. Process-centric artifacts are accessible under either the name-qualified directory M:\name\<process>-<pid>\ or the PID-qualified directory M:\pid\<pid>\; these two views are maintained as cross-linked mirrors containing identical content.


Once a process directory has been entered, the following specialized subdirectories furnish access to discrete categories of memory objects:


  • vmemd exposes individual virtual-address ranges constructed principally from Virtual Address Descriptors (VADs) and, where divergent, from Page Table Entries (PTEs). This view is particularly valuable when isolating discrete memory sections previously flagged by detection plugins such as FindEvil.
  • heaps enumerates private process heaps—both classic NT heaps and segment heaps on supported Windows builds—constituting the primary repositories of application-specific data.
  • minidump\minidump.dmp supplies a unified, best-effort process dump encompassing both executable code and data regions.
  • modules\<module name>\pefile.dll (together with the parallel reconstruction paths under files\modules and files\vads) yields reconstructed Portable Executable images of the process image and its loaded dynamic-link libraries.
  • Kernel drivers are reachable via the System process (M:\name\System-4\modules\... or equivalent).
  • Cached files appear under M:\forensic\files.
  • Specialty artifacts are located at the paths listed for the MFT (M:\forensic\ntfs), registry hives (M:\registry), and services/tasks (M:\sys\services, M:\sys\tasks).


All of these objects can be copied out of the mounted drive or examined in place with ordinary tools. It must be stressed that all reconstruction is inherently best-effort. Pages that were never resident in physical memory, were paged out, subject to compression, or subsequently overwritten appear as zero-padded or entirely absent regions. Consequently, large files, complete registry hives, or fully intact module images are frequently recovered only in partial form and ordinarily require subsequent validation, cross-correlation, or secondary reconstruction. Completeness and fidelity are further conditioned by the precise Windows build represented in the memory image, the integrity and temporal consistency of the acquisition itself, and whether forensic-mode analysis has been activated for certain specialized extractions (for example, comprehensive NTFS/MFT processing). Within these well-recognized constraints, the paths described nevertheless afford rapid, file-oriented access to the preponderance of forensically pertinent memory-resident objects.



A distinctive capability of MemProcFS lies in its virtualization of memory-resident objects within a hierarchical folder structure that extends to the underlying contents of physical and virtual memory, each exposed as discrete files. Consequently, extraction of executables, dynamic-link libraries, and kernel drivers is reduced to a conventional file-copy operation into a working directory; in the majority of analytical scenarios, even this step proves unnecessary, as the virtual files may be operated upon in situ. Practical examples include opening a memory section directly in a hexadecimal editor, extracting strings from a reconstructed executable, submitting a file or its cryptographic hash to VirusTotal, or loading a DLL into a disassembler.


When subjecting artifacts to antivirus or endpoint-detection engines, it is prudent to first create a local copy, thereby avoiding potential quarantine or deletion of the virtual file by security software. Although MemProcFS objects are predominantly presented as read-only, the creation of an independent working copy eliminates unnecessary interaction friction. Should a third-party tool fail to open a MemProcFS virtual file, an effective diagnostic step is to copy the object to a conventional local filesystem and reattempt the operation.


Information pertaining to executables, DLLs, and drivers is distributed across multiple locations within the MemProcFS hierarchy. The file pefile.dll constitutes the closest available reconstruction of a Portable Executable (PE) image; because modules undergo relocation, section realignment, and other runtime modifications upon loading, these reconstructions are never bit-for-bit identical to their on-disk counterparts. The pefile.dll artifact resides under the modules sub-directory of the process to which the module belongs; each process directory enumerates both its primary executable and all loaded DLLs in this manner.


Absence of a process of interest under M:\name or M:\pid may indicate that the process has already terminated. By default, MemProcFS omits folders for exited processes, as residual data within them is frequently incomplete or corrupted. Enabling the configuration flag contained in M:\config\config_process_show_terminated.txt (setting its value to 1) forces construction of these folders, albeit with the explicit caveat that the recovered content may be fragmentary.


Kernel drivers are predominantly accessible via the modules hierarchy of the System process (PID 4), the inaugural process instantiated at boot and the execution context under which the majority of kernel-mode code, including drivers, operates. Each driver folder contains a corresponding pefile.dll representing its reconstructed image. A limited subset of graphics-related drivers (Win32k) appears under CSRSS.exe processes; such instances are rarely of primary investigative interest.


While MemProcFS substantially simplifies the extraction of numerous classes of memory objects, both it and Volatility furnish complementary capabilities and distinct data sets; the selection of the tool or the parallel employment of both remains contingent upon the specific analytic requirements of the examination.


The terminal phase of any structured memory-analysis workflow consists of the extraction of candidate processes, kernel drivers, and ancillary objects from the memory image so that they may be subjected to complementary forms of examination. This step underscores a fundamental principle of digital forensics: comprehensive understanding of a compromise and of the associated malware is rarely achievable through memory analysis alone. While memory forensics frequently yields a near-complete picture of the intrusion vector and of the malware’s in-memory behavior, definitive characterization of indicators of compromise and of the malware’s full operational logic ordinarily requires subsequent dynamic and static analysis. Once investigative effort has been narrowed to a discrete set of artifacts, those artifacts must be recovered from the memory image.


Multiple recovery modalities exist and produce correspondingly different results. An examiner may elect to obtain a reconstructed executable suitable for sandbox execution, to recover memory-mapped DLLs and other files, or to dump discrete memory sections suspected of harboring injected code. All of these options, among others, are supported within the Volatility framework. Volatility furnishes an extensive suite of extraction capabilities. The principal acquisition plugins of enduring relevance are summarized in the table below.


Objective

Volatility 2

Volatility 3

Dump DLLs mapped into a process

dlldump

windows.dlllist --dump

Dump kernel drivers/modules

moddump

windows.modules --dump

Dump a process's executable image

procdump

windows.pslist --dump

(windows.psscan --dump for unlinked/terminated processes)

Dump all resident addressable memory of a process

memdump

windows.memmap --dump --pid

Enumerate _FILE_OBJECT structures

filescan

windows.filescan

Extract cached file content

dumpfiles

windows.dumpfiles

Carve MFT FILE records

mftparser

windows.mftscan.MFTScan

(also .ADS and .ResidentData)

Recover AppCompatCache (ShimCache)

shimcachemem

(Mandiant third-party plugin)

windows.shimcachemem

Recover console command history

cmdscan

windows.cmdscan

Recover console input and output

consoles

windows.consoles

Recover service records

svcscan

windows.svcscan

(also windows.svclist, windows.svcdiff)


A notable architectural shift occurred between the two major versions: Volatility 3 deprecated the majority of the earlier stand-alone dumping utilities and instead embedded dumping functionality within many of the standard analysis plugins through the introduction of the --dump parameter. windows.dumpfiles is the exception and remains a dedicated plugin. Proficiency with both Volatility 2 and Volatility 3 remains essential, because extraction success is not uniform; circumstances arise in which one version recovers data that the other cannot. Consequently, failure of an extraction attempt under Volatility 3 should prompt an immediate retry with the earlier version.


Volatility’s extensive history of community-contributed plugins further expands the available toolkit. Although this post cannot exhaustively catalogue every specialty plugin, the methodological foundation established herein enables independent exploration and mastery of additional modules. Some of these specialized plugins have not been—and may never be—ported to Volatility 3, reinforcing the continuing utility of dual-version competence.


Process and module extraction

  • dlldump/windows.dlllist enumerate modules from the PEB loader lists, which are user-mode data that malware can unlink. Reflectively loaded or injected code never appears there. Cross-check with ldrmodules, vadinfo and malfind.
  • moddump/windows.modules walk PsLoadedModuleList, so unlinked or hidden drivers are missed. Cross-view with modscan and driverscan.
  • procdump/windows.pslist walk ActiveProcessLinks, so hidden or exited processes are missed. Use psscan for those. The pslist --dump in Vol3 is the same list-walking limitation.
  • memdump/windows.memmap capture only resident pages. Paged-out memory is absent. In Vol3 the dump is a concatenation of mapped pages, so file offsets do not equal virtual addresses. Use the plugin's virtual/physical/file-offset mapping to relate them. Without --pid, Vol3 dumps every process.
  • For injected sections specifically, malfind and vadinfo with dump options are usually the better tools than a whole-process dump.

File and filesystem artifacts

  • filescan pool-scans for _FILE_OBJECT structures. It surfaces closed and orphaned objects still in pool residue, not just open handles.
  • dumpfiles rebuilds files from the cache and section object pointers (data, image and shared-cache-map). It recovers only what is resident. Expect sparse, partial or zero-filled results, and treat them as fragments rather than complete files.
  • mftparser/windows.mftscan signature-scan for FILE records and parse them. They do not extract the $MFT as a file, and you get only the fragments that happen to be in RAM. Their value is:
    • $STANDARD_INFORMATION vs. $FILE_NAME timestamps, for timestomping detection.
    • Small resident $DATA, such as scripts.
    • Records for volumes or files no longer accessible.
    • Body-file output (Vol2) for timelining.
    Corroborate against the on-disk $MFT where available.

Execution and persistence artifacts

  • shimcachemem reads AppCompatCache from kernel memory (the ahcache.sys AVL tree). The registry copy under the SYSTEM hive is written only at shutdown or reboot, so the memory copy captures entries the registry lacks. Compare the two to isolate activity since the last flush. Note the limits of the data:
    • The timestamp is the file's last-modified time, not an execution time.
    • Presence does not by itself prove execution.
    • The cache has a maximum entry count and evicts old entries.
    • Corroborate with Prefetch, Amcache, BAM and similar sources.
    • Vol3 has separate code paths for XP, 2003 to 7, and 8+. Validate on your target build.
  • cmdscan recovers command-history buffers, and consoles recovers the screen buffer, including command output. Both reconstruct only console-hosted interactive sessions.
    • They miss commands run without a console, such as WMI, services and scheduled tasks.
    • History buffers are size-limited (defaults are small) and per-process.
    • Console-host internals change across Windows builds, which is a common reason Vol2 fails on newer Windows 10/11 images. Verify Vol3 support for your build, including newer terminal hosts.
  • svcscan scans services.exe process memory for service record structures. It does not carve registry keys. It reports service name, type, state, PID and binary path. Vol2 -v and Vol3's output also pull registry-derived binary/ServiceDll info. For the registry view, use printkey on ControlSet\Services and diff the two. Vol3's svclist (list walking) and svcdiff are designed for this kind of cross-view.


As practical proficiency is developed, examination should commence with the plugins enumerated above and thereafter expand through systematic review of the complete plugin inventories obtained via vol.py -h and vol2.py -h. All recovered artifacts remain subject to the inherent limitations of memory reconstruction: pages may be absent, zero-padded, or partially corrupted, and the fidelity of any dump is conditioned by the quality of the original acquisition and by the specific Windows build under examination.


Handling extracted artifacts

  • A memory-resident image is not a disk file. Relocations, resolved imports, section alignment, unpacking state, and zero-filled paged-out regions mean its hash will not match the on-disk binary. Hash and document both.
  • Record provenance. Note the image hash, Volatility version, profile or symbol table, full command line, and output hashes for each artifact.
  • Treat outputs as live malware. Work in an isolated environment. AV on the analysis host may quarantine or alter dumps.
  • Cross-view before concluding. Absence from a list-walking plugin is not absence from memory.


A common point of confusion among practitioners transitioning from Volatility 2 concerns the apparent removal of the dedicated dumping plugins. Those capabilities have not been eliminated; rather, they have been consolidated into the corresponding analysis plugins in Volatility 3 and are invoked through the additional parameter --dump. The presence of this option in a plugin’s help output confirms that the plugin supports extraction of memory-resident objects. A complementary global option, -o, designates the destination directory for recovered artifacts (the functional equivalent of Volatility 2’s --dump-dir=). This parameter is especially critical when extracting drivers or DLLs, operations that can otherwise generate large volumes of files without straightforward filtering.



Parameter ordering is strictly enforced in Volatility 3 (in contrast to the more permissive syntax of version 2's optparse-based CLI). The -o is a global option and must precede the plugin name; plugin-specific options such as --pid and --dump are bound to the plugin and must follow it. Getting this backward produces an "unrecognized argument" error rather than silently working.


Executable Extraction

The windows.pslist --dump parameter recovers process images from the memory image for subsequent examination. By default, it walks the PsActiveProcessHead doubly-linked list and dumps every _EPROCESS entry it finds; supplying one or more PIDs via --pid (space-separated) restricts extraction to selected process identifiers. Because pslist is a list-walking plugin, it inherits that technique's blind spot: a process unlinked from PsActiveProcessHead—whether by termination cleanup or deliberate rootkit tampering—will not appear, and therefore cannot be dumped this way. windows.psscan --dump covers that gap. psscan locates _EPROCESS structures by pool-tag scanning rather than list traversal, so it recovers terminated and unlinked processes at the cost of occasionally surfacing stale or partially overwritten pool residue. The corresponding Volatility 2 plugin was procdump, which supported extraction by process identifier (-p), physical offset of the _EPROCESS structure (-o offset), the Vol2-era way of reaching a hidden or unlinked process, filling the same role psscan fills in Vol3, or regular-expression name matching (-n name_regex).


vol.py -f wcry.raw -o output-folder windows.pslist.PsList --dump
vol2.py -f wcry.raw --profile=<profile> procdump --dump-dir=output-folder


DLL Extraction

The windows.dlllist plugin, invoked with --dump, recovers DLLs associated with one or more processes. Run without qualification, it dumps every DLL from every process in the image, which is rarely what an examiner wants—scoping to specific process IDs with --pid is the sensible default working practice. Because DLLs are routinely shared across many processes (common system libraries in particular), extracting from multiple processes will produce duplicate copies of the same module; dedupe by hash before triage if volume becomes an issue.


The Volatility 2 counterpart was dlldump, which permitted selection by PID (-p), base address (-b), or regular-expression matching (-r). Given that many DLLs are shared across processes, extraction from multiple targets commonly yields duplicate files. The Volatility 2 equivalent, dlldump, supported three selectors: -p/--pid for a specific process, -b/--base for a DLL's base address in process memory (useful for extracting reflectively loaded or hidden DLLs that never made it into the PEB loader list), and -r/--regex for name-based filtering (with -i/--ignore-case as a modifier). A separate -o/--offset targeted the physical offset of a hidden _EPROCESS, distinct from --base.


vol.py -f wcry.raw -o output-folder windows.dlllist.DllList --pid 1940 --dump
vol2.py -f wcry.raw --profile=<profile> dlldump --dump-dir=output-folder -p 1940


Driver Extraction

Once potentially malicious kernel drivers have been identified, their recovery for further static or dynamic analysis is a logical next step. The windows.modules --dump option performs this extraction. By default, it dumps every driver in PsLoadedModuleList, so supplying -o for an output directory is essential—unscoped, this produces one file per loaded driver. windows.modules, like pslist, walks a list—PsLoadedModuleList—and inherits the same weakness: a driver unlinked from that list by a rootkit, or one that has since unloaded, will not appear. windows.modscan --dump addresses this by pool-tag scanning for _LDR_DATA_TABLE_ENTRY structures independent of list membership, recovering unlinked and previously unloaded drivers at the cost of losing load-order information (scan results have no relationship to load sequence, unlike the list-walking plugin's output).



The Volatility 2 equivalent, moddump, took -b/--base for a driver's base address and -r/--regex for name-based filtering; it has no PID option, since drivers aren't scoped to a process. Note that Volatility 2's moddump originally exposed --offset for this purpose before it was renamed to --base, specifically to avoid colliding with other plugins that use --offset to mean something else (an _EPROCESS offset, for instance).


vol.py -f wcry.raw -o output-folder windows.modules.Modules --dump
vol2.py -f wcry.raw --profile=<profile> moddump --dump-dir=output-folder


It must be emphasized that successful recovery is never guaranteed. Individual pages or entire objects may have been paged out of physical memory, resulting in extraction failure or the production of only partial, zero-padded results—this applies uniformly across list-walking and scanning plugins and across both framework versions. Incorporating the pagefile alongside the memory image substantially improves recovery odds and is the standard mitigation for this limitation, a topic that merits its own dedicated treatment. All reconstructed objects remain subject to the inherent constraints of memory forensics: relocation, runtime modification, and incomplete residency mean that recovered images are best-effort approximations rather than bit-for-bit replicas of their on-disk counterparts.


File extraction from a memory image is comparatively straightforward—locate the object, dump it, done. Extracting process memory is not, because process address space is not one thing. It splits into two broad categories, and the extraction tool you choose determines which of them you actually get.



Code is the portion of process memory that approximates the original on-disk executable and its statically or dynamically loaded modules. windows.pslist --dump in Volatility 3 and the reconstructed pefile.dll under M:\<process>\modules\<module_name>\ in MemProcFS both produce this view. It's the correct target for IOC generation and for reverse engineering, since it's the closest available proxy to the compiled binary. Pull the reconstructed executable from a PowerShell process and you should find Microsoft's own code; depending on the extraction tool, you may also pull in mapped code from loaded DLLs and, in the case of kernel-mode extraction, drivers.


Data regions, by contrast, typically occupy a far larger portion of the address space and encompass the majority of private memory allocations. This is where command-line buffers, typed console input, and—in the case of a PowerShell process specifically—loaded scripts and module content tend to surface. It's also where a malware sample's domain generation algorithm output is likely to reside, which can point an investigator toward a C2 infrastructure pattern before any network artifact confirms it. The gap between a code-only dump and a full data-inclusive dump can be substantial—several hundred megabytes is not unusual for a single process—because heap, stack, and other private memory regions dwarf the code sections in volume. Different tools recover differing subsets of process memory according to whether heap, stack, and other private allocations are included. Volatility’s extraction semantics are comparatively well-defined:


  • windows.pslist --dump (Vol3)—the successor to Vol2's procdump—reconstructs a close approximation of the on-disk executable. Code only.
  • windows.memmap --dump (Vol3)—the successor to Vol2's memdump—walks the process VAD tree and extracts every memory-resident page into a single file. This captures code and data indiscriminately. The output can be large, but it's the right target for string searching precisely because nothing is filtered out—provided the pages are resident. Paged-out regions are absent regardless of which plugin you run.
  • MemProcFS pefile.dll—The same best-effort reconstructed-executable concept as pslist --dump, generated per loaded module under the process's modules directory. Code only, and explicitly best-effort. The pefile.dll file recreates the executable image, while memory.vmem represents the entire theoretical process address space. In practice, the latter can attain extreme sizes (illustrated here as a 4 GB sparse file), the majority of which consists of zero-filled regions; such files are impractical for most string-searching tools. Fragments not resident in memory are zero-padded, and runtime-mutated PE structures (the import table in particular) may not reconstruct cleanly. The most usable MemProcFS artifact for initial string analysis is currently the minidump.dmp file.
  • MemProcFS minidump.dmp—a WinDbg-compatible minidump located in the process's minidump directory. It bundles stack, heap, executable, and loaded-DLL memory into one practical, tool-compatible file, but it is not exhaustive: private memory outside what the minidump format captures is left out. Treat it as a strong first-pass artifact, not a substitute for a full dump. For anything requiring completeness—full string searching, or confirming that a region the minidump excluded doesn't contain the artifact you're after—windows.memmap --dump is the more comprehensive choice, at the cost of file size and search time.


String searching is one of the most broadly applicable techniques in digital forensics—equally relevant to memory analysis, malware reverse engineering, and unallocated-space review on a disk image. A large share of the evidentiary value in any of these datasets surfaces as plain or wide-character text: IP addresses, domain names, file paths, network traffic fragments, C2 protocol strings, usernames, and credentials. The same workflow applies whether the input is a single extracted process dump, a page file, or a full memory image.


GNU strings, present by default on Linux forensic platforms such as Tsurugi Linux and SIFT Workstation, extracts printable ASCII and Unicode character sequences from any binary stream. Two flags matter for forensic use specifically:


  • -a (--all)—scans the entire file rather than restricting to recognized object-file sections. Without it, coverage against a raw memory or disk image can be silently incomplete.
  • -t d—prefixes each result with its byte offset in decimal, letting you pivot back into the source data to establish context around a hit of interest.


Because Windows stores most of its internal string data as UTF-16LE, a single ASCII-mode pass will miss the majority of it. Standard practice is therefore two passes—one default (ASCII), one with -e l (16-bit little-endian)—concatenated into a single working file:


strings -a -t d file > strings.txt
strings -a -t d -e l file >> strings.txt
sort strings.txt > sorted_strings.txt


Note that the sort step reorders by the text of each line—starting with the offset digits—not numerically by byte position. That's generally fine, since the goal here is usually to cluster similar strings for review, and the offset embedded in each line remains valid for pivoting back to the source regardless of where that line lands in the sorted file. If preserving physical ordering matters for your workflow, use sort -n instead.


Also worth knowing: GNU strings defaults to a 4-character minimum sequence length (-n 4). Shorter artifacts of interest won't appear unless that minimum is lowered—at the cost of a noisier result set. Once a strings file exists, grep is the standard tool for pattern matching against it—efficient even at scale and available natively on any *nix forensic platform. The real skill lies less in the tool and more in the keyword list: a living document that expands and contracts as the investigation develops leads.


  • -f <file> — matches against a list of patterns (one per line) rather than a single term, letting a full keyword list run in one pass.
  • -i — case-insensitive matching, since grep is case-sensitive by default.
  • -F — treats the pattern as a literal string rather than a regular expression. This matters specifically for IOCs like IP addresses and domains: a . in an unescaped regex matches any character, not a literal period, so 192.168.1.1 as a bare regex will also match strings that are not the address you are looking for. -F avoids that ambiguity when the keyword list is literal text rather than intentional regex patterns.


Regular-expression fluency pays off here but is not a prerequisite—prebuilt IOC-matching regexes (IP addresses, email formats, Bitcoin addresses, and similar) are widely available, along with tutorials for building custom patterns as an investigation's keyword list matures.


grep -i search_term sorted_strings.txt
grep -F -f iocs.txt sorted_strings.txt


Several practical caveats must be observed. Recovered strings are frequently incomplete or fragmented because of paging, compression, or partial residency; offsets are relative only to the file under examination and may require additional translation when working with reconstructed or sparse artifacts. False positives are common, rendering contextual review essential. Beyond basic ASCII and little-endian Unicode, alternative encodings (UTF-8, UTF-16BE, etc.) may be present and will not be captured by the commands above. On very large images, the intermediate string files can become unwieldy, and more specialized tools (bulk_extractor, YARA, or commercial forensic string engines) may offer superior performance or encoding coverage. Within these constraints, systematic string extraction and searching nevertheless make a foundational and highly productive component of memory and malware analysis.


bstrings.exe, authored by Eric Zimmerman, offers a forensic-oriented alternative to the standard Linux strings utility. Formerly Windows-exclusive, it was ported to .NET 6, which both improved throughput and extended it to Linux—it ships on current SIFT builds and is invoked directly as bstrings from the command line.


Two capabilities distinguish it from strings/grep: it extracts ASCII and Unicode strings in a single pass rather than requiring two separate runs, and it can filter results at extraction time rather than requiring a downstream grep pass. Filtering is available three ways—a literal string match, a list of terms supplied from a file, or a regular expression—and the tool ships with a library of pre-built regex patterns for common forensic targets: IP addresses, registry key paths, file paths, and URLs among them. Run bstrings -p to list the exact set and naming convention shipped with your installed version, since canned pattern names are not perfectly predictable across releases. Illustrative command-line invocations include:


bstrings -f file -m 8              # strings of length 8 or greater
bstrings -f file --ls search_term  # literal match on search_term
bstrings -f file --lr ipv4         # built-in regex match, e.g. IPv4 addresses


Windows 10+ Memory Compression: A Forensic Obstacle

Starting with Windows 10, the memory manager applies compression in two related contexts: infrequently used pages held in RAM are moved into an in-memory compression store (tracked internally via a dedicated system process), and data destined for the on-disk pagefile is compressed before it is written, reducing both memory footprint and the frequency of costly hard page faults.


The forensic consequence is direct: any tool that cannot decompress these regions will simply under-report. A scanning plugin that relies on signature matching against raw bytes will miss whatever is sitting in a compressed state, producing a result set that looks complete but is not. Both Volatility 3 and MemProcFS advertise support for decompressing these regions, though the maturity of that support is a moving target between releases and tools—worth confirming against current documentation rather than treating as fixed. MemProcFS, running natively on the live or imaged Windows OS rather than parsing structures externally, has at various points had an edge here—a point in favor of preferring its Windows build when compression handling is a priority for a given engagement.


Compression also degrades plain string extraction, since compressed bytes do not resemble readable text regardless of encoding. This matters less when working through a tool like MemProcFS that decompresses on access before exposing an object and matters a great deal when searching across a raw memory image or pagefile directly. For that scenario, Maxim Suhanov's winmem_decompress.py scans page-aligned data for compressed regions and emits the decompressed bytes. Although computationally intensive, the script routinely recovers in excess of 150 % additional content relative to the original image (i.e., its output is not a valid memory image) — The resulting output cannot be re-ingested by a memory forensics framework for structured analysis — its intended use is for string searching, carving, and YARA scanning, and has been observed to recover substantially more usable data than scanning the compressed original directly.



A common application of this is running page_brute.py—a YARA-based scanner that walks pagefile.sys in fixed-size blocks and flags matches against a ruleset—against pagefile content. On a Windows 10+ system, this technique loses much of its effectiveness against compressed regions unless winmem_decompress.py (or an equivalent) is run first to expose the underlying data for scanning.


All string-extraction and decompression techniques remain subject to residual constraints: incomplete residency, residual zero-padding, encoding variants outside the tool’s detection scope, and the possibility of false positives. Consequently, recovered strings must always be interpreted in context, and the choice of extraction or decompression method should be calibrated to the specific investigative objectives and the Windows build under examination.



Although Volatility offers powerful structured analysis capabilities, much of the evidentiary value in a memory investigation still comes down to string searching against extracted objects. A malicious or otherwise suspicious process is the natural place to focus that effort, and in this case the process itself was the direct target.


Process enumeration against the acquired memory image (wcry.raw) identified PID 740, image name @WanaDecryptor@, with parent PID 1940. This process name is a well-known artifact of the WannaCry (WCry/WannaCrypt) ransomware family—specifically its payment and decryption-instructions GUI, which is displayed to the victim once encryption has completed. The process's create time, 2017-05-12 21:22:22 UTC, falls within the known window of the May 2017 WannaCry global outbreak.


With the process identified, its resident memory was extracted directly: windows.memmap.Memmap --pid 740 --dump pulled two 4 KB pages from PID 740 into a single output file, pid.740.dmp. A strings file was then generated from that dump using bstrings (bstrings -f pid.740.dmp -o strings.txt).


The strings output was searched for "Bitcoin," the payment mechanism associated with WannaCry's ransom demand. A single grep pass with generous surrounding context (grep -B 15 -A 15 Bitcoin strings.txt) recovered the bulk of the embedded ransom messaging in one hit: the payment deadline structure—a price increase after three days and a stated point after seven days beyond which recovery is claimed to be impossible—along with repeated references to Bitcoin as the sole accepted payment method. This content is consistent with the widely documented WannaCry ransom note that circulated during the 2017 outbreak and corroborates the process-name identification made in the enumeration step: the report now has two independent indicators—the @WanaDecryptor@ image name and memory-resident ransom-note content—pointing to the same conclusion.


A small number of fragments in the surrounding output did not resolve to coherent ransom-note prose. These are best attributed to GUI rendering data or to the boundary between the two non-contiguous memory pages recovered, rather than treated as additional evidentiary content, and were not relied upon in reaching the conclusions above. No complete Bitcoin wallet address was clearly recoverable from this particular extraction; confirming the specific WannaCry variant or attempting blockchain pivoting from the payment address would require either a broader memory capture of this process or comparison against WannaCry's small set of publicly documented hardcoded addresses.


The technique demonstrated here is a general one worth carrying into future cases: once a malicious process is identified, targeted extraction of its resident memory followed by a keyword-anchored grep pass—rather than an unfocused review of the full strings output—can recover the relevant evidentiary content efficiently, provided the analyst has an IOC (here, "Bitcoin") to anchor the search on.


Windows memory architecture is built on virtual, paged memory—a substantial share of what a process considers "active" memory may, at any given moment, actually reside on disk rather than in RAM. Page files remain heavily used even on systems with abundant physical RAM, since Windows pages out infrequently-accessed data regardless of available capacity. Historically, this has made page files (pagefile.sys in particular) an awkward secondary artifact: without the paging structures that give it context, a page file is effectively a large blob of formerly resident data best approached through simple string searching or file carving.



The latest generation of memory forensics tooling changes that by integrating page file content directly with a memory image's paging structures, allowing paged-out data to be resolved back into its original virtual-memory context. Rekall—a fork of the original Volatility project—was the first to introduce this capability. Volatility 3 and MemProcFS have since added their own support. Of the two, testing indicates MemProcFS currently provides the more mature implementation: including pagefile.sys measurably improves both scanner-based detections (in capabilities like MemProcFS's FindEvil) and the completeness of memory objects available for extraction. Volatility 3's pagefile integration is present and functional at the framework level, but testing to date hasn't shown the same volume of additional recovered artifacts—this is reasonably attributed to the feature's relative immaturity rather than a fundamental limitation and is worth re-testing as the framework matures.


Practical benefits of including pagefile data

  • Fewer extraction failures across processes, DLLs, and drivers, since more of a target object's pages are resolvable.
  • Better odds of recovering a complete, analyzable copy of injected code—a meaningful benefit given that some malware families deliberately page themselves out as an evasion technique specifically to reduce their footprint in the resident memory an examiner would normally scan.
  • Improved yield from scanning-based recovery techniques generally—signature scans, structure carving, and similar approaches all operate over more total data when the page file is included, which translates to better recovery of artifacts like beacon/C2 traffic remnants, MFT entries, and registry hive fragments that may no longer be resident in RAM alone.


This capability should change acquisition priorities going forward, not just analysis technique—page files are worth collecting alongside the memory image as standard practice rather than as an afterthought. On modern Windows systems, this should include swapfile.sys (used by Universal Windows Platform applications) in addition to the traditional pagefile.sys; MemProcFS ingests each by index (-pagefile0, -pagefile1, etc.), with the specific index-to-file mapping determined by the target system's actual page file configuration rather than a fixed convention.


One caveat worth building into the collection procedure: page file content is transient by nature, changing continuously on a live system. To avoid reconstructing an inconsistent view of memory, the page file(s) should be acquired at the same time as, or as close in time as possible to, the memory image itself—a stale page file paired with a memory image from a different point in time can introduce more uncertainty than it resolves.


Windows caches an unusually broad range of file content in memory—not only items the OS keeps resident for I/O efficiency (registry hives, Prefetch files, the $MFT), but memory-mapped executables and DLLs, and effectively any file type recently accessed, from Office documents to log files. This extends even to files opened from removable media or from within encrypted containers. The tracking mechanism is consistent regardless of file type or source: each cached item is represented in memory by a _FILE_OBJECT structure, and processes reference these through two structural paths—their handle table and, for memory-mapped files specifically, their VAD (virtual address descriptor) tree. Memory analysis tooling that can enumerate handle tables and VAD trees can use that metadata to reconstruct and extract the underlying cached content.


MemProcFS exposes this capability directly through its virtual filesystem, presenting cached objects as individual files that can be examined in place or copied out for further analysis. For each process, a files directory offers three independent recovery paths:


  • handles—recovers cached files discovered by walking the process's open handle table for handles that point to _FILE_OBJECT structures.
  • modules—recovers .exe, .dll, and .sys files by reconstructing them from PEB entries and PE header data.
  • vads—attempt reconstruction using VAD tree mappings, which is particularly effective for memory-mapped files.


Because each method reaches the underlying data through a different structural route, they don't always succeed or fail together—a file no longer visible via one path may still be recoverable through another, which is worth checking systematically rather than treating a single method's result as final. All three should be understood as best-effort reconstruction: MemProcFS's own documentation is explicit that recovered content may be incomplete, corrupted, or missing entirely depending on what was actually resident at capture time.



This recovery walkthrough comes from a system infected with SolarMarker (also known as Jupyter malware). Certain variants of this family package their payload as a .msi (Microsoft Installer) file rather than a standalone executable, specifically to evade host-based security tooling and sandboxes tuned to flag conventional executables—a technique that, notably, continues to work in practice.


The initial lead came from process enumeration: msiexec.exe, PID 6192 was present in the process list—inherently worth investigating, since software installation activity is a common indicator during a malware investigation regardless of whether the majority of .msi activity on any given system turns out to be legitimate. A prior review of that process's open file handles surfaced a reference to \Windows\flash_installer.msi. Adobe Flash has been end-of-life for years, but its name remains a common social-engineering lure—making this handle immediately worth pursuing.


To recover the file itself, the files\handles directory for PID 6192 was examined in MemProcFS. The suspicious .msi was still resident and available for direct extraction, named ffffa002b614aef0-flash_installer.msi—the hexadecimal prefix representing the memory address of the underlying _FILE_OBJECT, useful for cross-referencing this recovery against other tools' output at the same address. Notably, the file was over 120 MB—a deliberate evasion tactic rather than an incidental detail: the payload is bundled with legitimate software (and even digitally signed) to appear benign, and the inflated size specifically exploits the fact that some security products skip scanning unusually large files for performance reasons.


From here, the next step is straightforward: copy the recovered .msi to an isolated working directory and begin static and dynamic malware analysis. This case illustrates the practical value of MemProcFS's direct-object-access model—the path from process list anomaly to a fully recovered malware sample required only a handle lookup and a file copy, with no separate parsing or reconstruction step required.


Volatility offers its own pair of plugins for locating and extracting cached files from a memory image, built on the same _FILE_OBJECT structures MemProcFS relies on.


windows.dumpfiles extracts cached file content by walking _FILE_OBJECT references reachable from process handle tables and VAD entries. Run without qualification, it will attempt to extract every recoverable file object in the image—executables, DLLs, registry hives, .dat databases, and ordinary data files (text, PDF, Office documents) alike. In practice, this produces a large volume of output, much of it irrelevant to the investigation at hand. Scoping to a specific process with --pid is the standard way to narrow this down when the process of interest is already known.


windows.filescan takes a different approach: rather than walking handle tables and VAD entries, it pool-scans directly for _FILE_OBJECT signatures in memory. This makes it a natural complement to dumpfiles rather than a redundant alternative—because dumpfiles' default recovery path depends on a live handle or VAD reference, it will miss file objects that have been closed or deliberately unlinked by malicious tampering. filescan surfaces those regardless. It's also the correct tool for NTFS metadata structures like $MFT and $LogFile: these aren't referenced through a typical process handle or VAD entry, so dumpfiles' default enumeration passes over them entirely.


The two plugins are designed to work in sequence. When filescan surfaces a file object of interest, record its reported virtual offset, then feed that offset directly to dumpfiles via --virtaddr (or --physaddr, if the offset reported was physical) to attempt targeted extraction.



As with every other extraction technique covered so far, there are no completeness guarantees here. A _FILE_OBJECT existing in memory doesn't mean its content is currently mapped or cached—the underlying data may be paged out or only partially resident, in which case the plugin pads the missing regions with zeros. Extraction attempts frequently produce corrupt or unusable output as a result. Registry hives are a common example: they're often present in memory, but an extracted copy will frequently fail to open in a standard registry viewer because required structures are missing. Tools built to work with partial registry data—MemProcFS's registry view and Volatility's own windows.registry.printkey—sidestep this by parsing and exposing only what's actually available rather than requiring a complete hive. Even a failed extraction can carry investigative value: confirming that a known-malicious file once existed on a system — even without a usable copy of its content — is often sufficient to treat the host as compromised and proceed with triage accordingly.


The same functionality exists in Volatility 2 as dumpfiles and filescan. Volatility 2's dumpfiles supports extraction by offset (-Q) or by a regular expression matched against the filename (-r, with -i for case-insensitive matching)—mirroring the --virtaddr/--pid targeting available in Volatility 3. As with the other Volatility 2 dump plugins, the output location is set with --dump-dir=.


If the direct, per-process cached-file access MemProcFS provides through handles, modules, and vads was impressive, its forensic mode extends that same idea system-wide. When forensic mode is enabled (via the -forensic startup option), MemProcFS performs a batch pass across the entire memory image, gathering every potentially recoverable _FILE_OBJECT it can find—regardless of which process referenced it—and exposes the result as a reconstructed filesystem.


In the earlier msiexec.exe/SolarMarker example, we were looking for any pertinent files tied to the msiexec.exe process, specifically, .msi files which could indicate what was installed on the system. An alternative solution would be to search the M:\forensic\csv\files.csv file for file names or file types of interest. Items of interest can then be accessed via the virtualized file system present in M:\forensic\files\ROOT. Because this reconstructed view mounts through the same Dokany-based virtual filesystem as the rest of MemProcFS, browsing and extraction can happen directly in Windows File Explorer—files can be copied elsewhere or, depending on type, opened immediately in a hex editor, image viewer, or the Microsoft Office suite, without an intermediate export step.



The same completeness caveat that applies throughout memory forensics applies here too: nothing is guaranteed. A recovered file may have been partially paged out at capture time, and corrupted or incomplete results are common. Favour viewers and parsers that tolerate malformed input over ones that fail outright on the first inconsistency.


The practical value of this feature is broad. As one example, recovering a deleted Prefetch file that is still resident in memory works exactly the same way—either copy the reconstructed file out and hand it to a standard Prefetch parser, or point the parser directly at the file's location within the mounted virtual filesystem. MemProcFS also ships a dedicated Prefetch module within forensic mode that parses recovered Prefetch data automatically, so it's worth checking that output first—it may already have surfaced execution counts and timestamps for the artifact in question before any manual extraction is needed.



The forensic\files module covered previously recovers cached _FILE_OBJECT content—necessarily a subset of everything that exists on disk, limited to whatever happened to be memory-resident at capture time. To examine the complete filesystem structure rather than just what is cached, MemProcFS's forensic\ntfs module takes a different approach: it locates the NTFS Master File Table ($MFT) in memory and virtualizes its contents, letting an analyst browse the filesystem's structure much as they would on the live system.


The same underlying $MFT data also drives timeline reconstruction. forensic\timeline maintains a set of chronological timelines in text form, and forensic\csv holds the same data as CSV exports suited to direct use in a tool like Timeline Explorer for filtering and pivoting. Of these, timeline_ntfs.csv specifically covers filesystem creation and modification activity; the remaining timeline files in the same directory cover other categories of in-memory artifact (process, registry, network activity, and others) rather than filesystem events.



In the continuing SolarMarker investigation covered earlier—specifically, the PowerShell transcript recovered from conhost.exe memory, which referenced a distinctive folder: C:\Users\Admin\AppData\Roaming\MiCrOsoFt\NsaCWeSQcZlTKFVOHq. forensic\ntfs makes following up on that lead straightforward—navigating to M:\forensic\ntfs\_\Users under the mounted virtual filesystem surfaced the folder directly, confirming it still existed and contained well over a hundred randomly named files. This pattern—a large volume of decoy files concealing a small number of genuinely malicious ones—is a recognized SolarMarker characteristic, seemingly intended to slow down or discourage manual review, and it reads as distinctly suspicious on sight even before any file content is examined.


A limitation worth flagging explicitly: file content under forensic\ntfs is rarely available, because this module's data is sourced entirely from the $MFT itself rather than from cached file content elsewhere in memory. The one exception is a resident file—a file small enough that NTFS stores its data directly inside the MFT record rather than in separate allocated clusters, generally somewhere under roughly 600–700 bytes depending on the specific record's other attributes. Outside that narrow case, expect metadata (names, timestamps, structure) here, not content. When content matters and isn't available through forensic\ntfs, the earlier-covered forensic\files recovery path is the logical next step to check.


The corresponding timeline view of the same folder supplies precise creation and modification timestamps for both the directory and its constituent files. Practical applications of this capability are numerous: inspection of tool-deployment directories, staging locations used for data exfiltration, cloud-synchronization folders, and the Prefetch directory—where creation and last-modification times of Prefetch files themselves furnish reliable first- and last-execution timestamps.


All such reconstructions remain subject to the inherent constraints of memory forensics. $MFT records may themselves be incomplete or partially paged out; resident file content is limited to very small objects; and timestamps, while valuable, must be interpreted in light of possible clock skew, anti-forensic manipulation, or residual corruption. Within these limitations, the virtualized NTFS and timeline views nevertheless constitute a powerful and efficient means of reconstructing file-system activity from memory alone.


Much as forensic\ntfs reconstructs the filesystem from the $MFT, MemProcFS's M:\registry folder provides equivalent access to memory-resident registry data—browsable directly through Windows File Explorer or exportable as reconstructed hive files for use with other tools.


Reconstructed hives are found under M:\registry\hive_files. As with most memory-derived reconstructions covered so far, expect these to often be partial and corrupted, since unavailable pages are zero-padded rather than skipped—a state that prevents many standard registry viewers from opening them cleanly. When that happens, the more productive path is usually to skip the export step entirely and navigate directly to the hive and key of interest under M:\registry\by-hive, checking whether the specific value data needed is available in place—MemProcFS's virtual filesystem model makes this fast, since browsing a key does not require the whole hive to parse successfully.



In continuing the earlier SolarMarker investigation: the PowerShell transcript recovered from conhost.exe memory pointed to an unusually named registry key, HKCU\Software\Classes\jxbflnlzzotwmagpb\shell\open. HKCU ordinarily implies the current user's NTUSER.DAT hive—but the specific subpath here is the tell that this actually belongs to a different hive entirely, the UsrClass.dat hive. On a running system, HKCU\Software\Classes is a virtualized view backed by the user's UsrClass.dat hive rather than NTUSER.DAT. Locating the correct hive under M:\registry\by-hive, the unusually named key and its subkeys were reachable directly, with MemProcFS rendering each value's contents as an individual text file. The command subkey's default value appeared as (Default).txt—opening it revealed an encoded PowerShell script hidden inside the registry. This was the malware's persistence mechanism: storing itself in the registry rather than on disk specifically to stay "file-less" and evade host-based detection tooling built around scanning files rather than registry content.


Volatility offers several registry-focused plugins covering similar ground—windows.registry.hivelist, windows.registry.hivescan, windows.registry.printkey, and windows.registry.userassist among them—but none provide the same fluid, browse-and-open workflow MemProcFS's virtual filesystem model does for navigating and interacting with registry content directly.


Services and scheduled tasks remain two of the most heavily abused mechanisms for code execution, persistence, and lateral movement—a large share of intrusions rely on one or both. Because both are ultimately configured through the Windows registry, and registry data is itself recoverable from memory, extracting this information comes down to having a tool that can locate and parse the relevant registry structures.


MemProcFS surfaces this data in two complementary forms. M:\sys\services and M:\sys\tasks virtualizes each service and scheduled task into its own folder and summary text file, browsable directly. For bulk review and filtering, the same data is also available as CSV exports under M:\forensic\csv, ready to open in a spreadsheet tool or Timeline Explorer.


The service view is particularly valuable because it covers both user-mode services and loaded kernel drivers together, making it a strong starting point for spotting advanced techniques like rootkits that register as a driver-backed service. Filtering on start type is a productive first pass—SERVICE_AUTO_START in particular is a common persistence indicator, since it guarantees execution on every boot without further attacker interaction. Both the services and tasks views provide the full executable path and any arguments, making path- and filename-based anomaly hunting straightforward, and both include additional columns beyond what a summary view shows—timestamps among them.


One habit worth building into every review: check the User field. The overwhelming majority of legitimate services and tasks run under built-in system accounts (SYSTEM, LOCAL SERVICE, NETWORK SERVICE). A service or task running under an ordinary user account context is a meaningful outlier worth extra scrutiny—attackers frequently register persistence mechanisms under a compromised user's context specifically because it blends in less conspicuously with a security team scanning only for SYSTEM-level anomalies or because it was the only context available to them post-compromise.


Volatility's windows.svcscan recovers comparable service information from a memory image, but it's worth being precise about the mechanism, since it differs meaningfully from MemProcFS's registry-sourced view: svcscan locates _SERVICE_RECORD structures by scanning services.exe process memory directly, rather than parsing the registry's service configuration keys. It does pull in some registry-derived detail (service DLL paths, for instance) as part of its output, but its core view reflects live in-memory service state rather than registry configuration. For a registry-equivalent view comparable to what MemProcFS's sys\services presents, windows.registry.printkey against the relevant ControlSet00x\Services key is the closer match. Running both and comparing results is a useful technique in its own right—a discrepancy between the two views (a service present in the registry but absent from the in-memory scan, or vice versa) can itself be an indicator of tampering.


The idea of live memory analysis—analyzing a system for malicious artifacts while it's still running—would have been controversial just a few years ago. Defenders accustomed to pulling the plug before any analysis began legitimately questioned how forensic validity could be maintained if tools were running on the very system being investigated. The practice of capturing a memory image before analysis became standard partly for this reason. That concern has proven largely unfounded in practice. The system impact of live memory analysis is measurable but minimal—and the benefits are substantial:


  • Faster triage capability—no acquisition delay; analysis can begin immediately.
  • More complete view of memory—live analysis naturally includes the page file, which may not be captured alongside a static image.
  • System API integration—the ability to query and compare live WMI, registry, and other OS-level data alongside memory state.
  • More accurate heuristics—some detection logic benefits from access to live process and system state rather than static artifacts alone.
  • Cryptographic validation—digital signatures on process executables, DLLs, and drivers can be verified against current system trust stores.
  • Hash-based comparison—process memory can be compared against "known good" baseline hashes via allowlists or threat intelligence.
  • Distributed collection and processing—live hunting can be scaled across many systems simultaneously.
  • Indicator searches—pre-defined IOC signatures can be deployed network-wide for rapid detection.


Physical access vs. API-based collection

Live memory analysis can be accomplished in two ways. Physical memory access—reading RAM directly through hardware interfaces rather than relying on OS API calls, open handles, or debuggers—provides comparable effectiveness to analyzing a static image, including against advanced malware and rootkits. But this comes at a performance cost, which is why some tools default to API-based collection instead, trading some coverage for scalability. Everything in computing involves tradeoffs; the choice depends on the investigation's constraints. Several specialized tools make live memory analysis practical.


Single-system tools

Jared Atkinson's Get-InjectedThread PowerShell script iterates through every running thread on a system and flags those exhibiting signs of code injection—a surprisingly effective technique for detecting classic injection, reflective DLL injection, and some advanced variations. The script is available standalone and as part of the Kansa framework for scaled collection across multiple systems. Hollows Hunter and Moneta are purpose-built tools for detecting more exotic attack techniques: process hollowing (replacing a process's legitimate code with malware), process doppelganging (a variant using Windows transactional filesystem APIs), reflective code injection, and hooking. Both tools identify many false positives—the volume of noise is high enough that expert analysis is required to distinguish signal from false alarms, making them best suited for hands-on investigation rather than automated large-scale screening.


Network-scale hunting

For hunting across many systems, several open-source and commercial options exist. The Velociraptor project has been in active development for years and includes live memory audit capabilities, enabling scalable hunting and collection of memory artifacts via Windows API calls alongside YARA scanning. MemProcFS Remoting provides network-scale memory forensics by leveraging the PCILeech and WinPMEM projects, giving analysts the full MemProcFS virtual filesystem view over the network rather than requiring local access to the target machine. Commercial EDR suites commonly include equivalent or superior capabilities for live memory investigation, and several members of the Volatility core team have developed commercial tools supporting scalable memory forensics workflows.


Live memory analysis remains a developing discipline, but the trend is clear: as system RAM continues to grow (particularly on servers), the move from postmortem static image analysis toward live, active hunting is nearly inevitable. The question is no longer whether live memory analysis is valid, but how to integrate it effectively into incident response workflows where speed and scale matter.


Indicators of Compromise: Building and Deploying IOC Signatures

Once malicious activity has been identified and analyzed, an examiner builds an Indicator of Compromise (IOC)—a formal, machine-parseable definition of how to detect that specific activity in the future. In memory forensics, an IOC might target a process name, command-line argument, DLL load path, TCP/UDP port, unlinked or hidden DLL, API hook, or a byte-sequence pattern. Once defined and tested, the IOC becomes reusable—subsequent investigations of new systems can be scanned against it automatically, flagging matching artifacts without requiring the examiner to manually re-hunt the same malware signature over and over.


Building an IOC taxonomy is foundational to any incident response team's long-term efficiency. As malware is discovered in the enterprise, it should be analyzed, and signatures should be created representing its behavioral and structural markers. Those signatures can then be deployed network-wide for rapid identification of similar malware in the future.


Takahiro Haruyama's openioc_scan plugin brings OpenIOC format support to Volatility 2, mapping OpenIOC 1.1 indicator definitions to their Volatility plugin equivalents. This allows an investigator to apply existing or custom-built IOCs to a memory image through the same abstraction layer. PyIOCe, a Python-based graphical IOC editor, includes native support for Volatility-specific indicator terms, making it a practical tool for building Volatility-compatible IOCs if the OpenIOC format is your chosen standard—though note that the project has been archived since 2019 and is no longer under active development.


In practice, many teams favor YARA signatures over the formality of OpenIOC format, drawn to their relative simplicity and flexibility. YARA rules work particularly well for memory scanning because they can target byte-sequence patterns, strings, file sections, and metadata all in one concise notation. All major memory-forensics platforms now support YARA natively: Volatility (both windows.yarascan for kernel memory and windows.vadyarascan for process-scoped scanning), MemProcFS, GRR, and Velociraptor all integrate YARA rule scanning.




windows.vadyarascan scans process Virtual Address Descriptors against a provided YARA ruleset. When a rule matches, it reports the process PID, the matched memory location, and crucially, the VAD offsets—the memory locations where the match occurred—which can then be extracted and further analyzed. The same scan can be restricted to specific processes (faster, more targeted) or run across the entire image for comprehensive coverage.


YARA scanning extends beyond process memory. page_brute.py, a community tool designed specifically for this purpose, allows YARA rules to be run against Windows page files—an artifact historically underutilized precisely because few tools existed to analyze it in a structured way. Running YARA signatures against a pagefile can surface paged-out malware, remnants of deleted processes, or stolen credentials—all of which would escape a memory-only scan.



Post a Comment

Previous Post Next Post