## File: README.md
# Volatility 3: The volatile memory extraction framework
Volatility is the world's most widely used framework for extracting digital
artifacts from volatile memory (RAM) samples. The extraction techniques are
performed completely independent of the system being investigated but offer
visibility into the runtime state of the system. The framework is intended
to introduce people to the techniques and complexities associated with
extracting digital artifacts from volatile memory samples and provide a
platform for further work into this exciting area of research.
In 2019, the Volatility Foundation released a complete rewrite of the
framework, Volatility 3. The project was intended to address many of the
technical and performance challenges associated with the original
code base that became apparent over the previous 10 years. Another benefit
of the rewrite is that Volatility 3 could be released under a custom
license that was more aligned with the goals of the Volatility community,
the Volatility Software License (VSL). See the
[LICENSE](https://www.volatilityfoundation.org/license/vsl-v1.0) file for
more details.
## Quick Start
1. Install the required dependencies:
```shell
pip install --user -e ".[full]"
```
2. See available options:
```shell
vol -h
```
3. To get more information on a Windows memory sample and to make sure Volatility supports that sample type, run `vol -f windows.info`:
```shell
vol -f /home/user/samples/stuxnet.vmem windows.info
```
4. Run some other plugins. The `-f` or `--single-location` is not strictly required, but most plugins expect a single sample.
Some also require/accept other options. Run `vol -h` for more information on a particular command.
## Installing
Volatility 3 requires Python 3.8.0 or later and is published on the [PyPi registry](https://pypi.org/project/volatility3).
```shell
pip install volatility3
```
If you want to use the latest development version of Volatility 3 we recommend you manually clone this repository and install an editable version of the project.
We recommend you use a virtual environment to keep installed dependencies separate from system packages.
The latest stable version of Volatility will always be the `stable` branch of the GitHub repository. The default branch is `develop`.
```shell
git clone https://github.com/volatilityfoundation/volatility3.git
cd volatility3/
python3 -m venv venv && . venv/bin/activate
pip install -e ".[dev]"
```
## Symbol Tables
Symbol table packs for the various operating systems are available for download at:
[windows.zip](https://github.com/volatilityfoundation/volatility3-test-data/releases/download/v0.0.1/windows.zip)
[mac.zip](https://github.com/volatilityfoundation/volatility3-test-data/releases/download/v0.0.1/mac.zip)
[linux.zip](https://github.com/volatilityfoundation/volatility3-test-data/releases/download/v0.0.1/linux.zip)
The hashes to verify whether any of the symbol pack files have downloaded successfully or have changed can be found at:
[SHA256SUMS](https://raw.githubusercontent.com/volatilityfoundation/volatility3-test-data/refs/tags/v0.0.1/symbols/SHA256SUMS)
[SHA1SUMS](https://raw.githubusercontent.com/volatilityfoundation/volatility3-test-data/refs/tags/v0.0.1/symbols/SHA1SUMS)
[MD5SUMS](https://raw.githubusercontent.com/volatilityfoundation/volatility3-test-data/refs/tags/v0.0.1/symbols/MD5SUMS)
Symbol tables zip files must be placed, as named, into the `volatility3/symbols` directory (or just the symbols directory next to the executable file).
Windows symbols that cannot be found will be queried, downloaded, generated and cached. Mac and Linux symbol tables must be manually produced by a tool such as [dwarf2json](https://github.com/volatilityfoundation/dwarf2json).
Important: The first run of volatility with new symbol files will require the cache to be updated. The symbol packs contain a large number of symbol files and so may take some time to update!
However, this process only needs to be run once on each new symbol file, so assuming the pack stays in the same location will not need to be done again. Please also note it can be interrupted and next run will restart itself.
Please note: These are representative and are complete up to the point of creation for Windows and Mac. Due to the ease of compiling Linux kernels and the inability to uniquely distinguish them, an exhaustive set of Linux symbol tables cannot easily be supplied.
## Documentation
The framework is documented through doc strings and can be built using sphinx.
The latest generated copy of the documentation can be found at:
## Licensing and Copyright
Copyright (C) 2007-2026 Volatility Foundation
All Rights Reserved
## Bugs and Support
If you think you've found a bug, please report it at:
In order to help us solve your issues as quickly as possible,
please include the following information when filing a bug:
- The version of Volatility you're using
- The operating system used to run Volatility
- The version of Python used to run Volatility
- The suspected operating system of the memory sample
- The complete command line you used to run Volatility
For community support, please join us on Slack:
## Contact
For information or requests, contact:
Volatility Foundation
Web:
Blog:
Email: volatility (at) volatilityfoundation (dot) org
Twitter: [@volatility](https://twitter.com/volatility)
---
## File: doc/source/basics.rst
Volatility 3 Basics
===================
Volatility splits memory analysis down to several components. The main ones are:
* Memory layers
* Templates and Objects
* Symbol Tables
Volatility 3 stores all of these within a :py:class:`Context `,
which acts as a container for all the various layers and tables necessary to conduct memory analysis.
Memory layers
-------------
A memory layer is a body of data that can be accessed by requesting data at a specific address. At its lowest level
this data is stored on a phyiscal medium (RAM) and very early computers addressed locations in memory directly. However,
as the size of memory increased and it became more difficult to manage memory most architectures moved to a "paged" model
of memory, where the available memory is cut into specific fixed-sized pages. To help further, programs can ask for any address
and the processor will look up their (virtual) address in a map, to find out where the (physical) address that it lives at is,
in the actual memory of the system.
Volatility can work with these layers as long as it knows the map (so, for example that virtual address `1` looks up at physical
address `9`). The automagic that runs at the start of every volatility session often locates the kernel's memory map, and creates
a kernel virtual layer, which allows for kernel addresses to be looked up and the correct data returned. There can, however, be
several maps, and in general there is a different map for each process (although a portion of the operating system's memory is
usually mapped to the same location across all processes). The maps may take the same address but point to a different part of
physical memory. It also means that two processes could theoretically share memory, both having a virtual address mapped to the
same physical address. See the worked example below for more information.
To translate an address on a layer, call :py:meth:`layer.mapping(offset, length, ignore_errors) ` and it will return a list of chunks without overlap, in order,
for the requested range. If a portion cannot be mapped, an exception will be thrown unless `ignore_errors` is true. Each
chunk will contain the original offset of the chunk, the translated offset, the original size and the translated size of
the chunk, as well as the lower layer the chunk lives within.
Worked example
^^^^^^^^^^^^^^
The operating system and two programs may all appear to have access to all of physical memory, but actually the maps they each have
mean they each see something different:
.. code-block::
:caption: Memory mapping example
Operating system map Physical Memory
1 -> 9 1 - Free
2 -> 3 2 - OS.4, Process 1.4, Process 2.4
3 -> 7 3 - OS.2
4 -> 2 4 - Free
5 - Free
Process 1 map 6 - Process 1.2, Process 2.3
1 -> 12 7 - OS.3
2 -> 6 8 - Process1.3
3 -> 8 9 - OS.1
4 -> 2 10 - Process2.1
11 - Free
Process 2 map 12 - Process1.1
1 -> 10 13 - Free
2 -> 15 14 - Free
3 -> 6 15 - Process2.2
4 -> 2 16 - Free
In this example, part of the operating system is visible across all processes (although not all processes can write to the memory, there
is a permissions model for Intel addressing which is not discussed further here).
In Volatility 3 mappings are represented by a directed graph of layers, whose end nodes are
:py:class:`DataLayers ` and whose internal nodes are :py:class:`TranslationLayers `.
In this way, a raw memory image in the LiME file format and a page file can be combined to form a single Intel virtual
memory layer. When requesting addresses from the Intel layer, it will use the Intel memory mapping algorithm, along
with the address of the directory table base or page table map, to translate that
address into a physical address, which will then either be directed towards the swap layer or the LiME layer. Should it
be directed towards the LiME layer, the LiME file format algorithm will translate the new address to determine where
within the file the data is stored. When the :py:meth:`layer.read() `
method is called, the translation is done automatically and the correct data gathered and combined.
.. note:: Volatility 2 had a similar concept, called address spaces, but these could only stack linearly one on top of another.
The list of layers supported by Volatility can be determined by running the `frameworkinfo` plugin.
Templates and Objects
---------------------
Once we can address contiguous chunks of memory with a means to translate a virtual address (as seen by the programs)
into the actual data used by the processor, we can start pulling out
:py:class:`Objects ` by taking a
:py:class:`~volatility3.framework.interfaces.objects.Template` and constructing
it on the memory layer at a specific offset. A :py:class:`~volatility3.framework.interfaces.objects.Template` contains
all the information you can know about the structure of the object without actually being populated by any data.
As such a :py:class:`~volatility3.framework.interfaces.objects.Template` can tell you the size of a structure and its
members, how far into the structure a particular member lives and potentially what various values in that field would
mean, but not what resides in a particular member.
Using a :py:class:`~volatility3.framework.interfaces.objects.Template` on a memory layer at a particular offset, an
:py:class:`Object ` can be constructed. In Volatility 3, once an
:py:class:`Object ` has been created, the data has been read from the
layer and is not read again. An object allows its members to be interrogated and in particular allows pointers to be
followed, providing easy access to the data contained in the object.
.. note:: Volatility 2 would re-read the data which was useful for live memory forensics but quite inefficient for the
more common static memory analysis typically conducted. Volatility 3 requires that objects be manually reconstructed
if the data may have changed. Volatility 3 also constructs actual Python integers and floats whereas Volatility 2
created proxy objects which would sometimes cause problems with type checking.
Symbol Tables
-------------
Most compiled programs know of their own templates, and define the structure (and location within the program) of these
templates as a :py:class:`Symbol `. A
:py:class:`Symbol ` is often an address and a template and can
be used to refer to either independently. Lookup tables of these symbols are often produced as debugging information
alongside the compilation of the program. Volatility 3 provides access to these through a
:py:class:`SymbolTable `, many of which can be collected
within a :py:class:`~volatility3.framework.contexts.Context` as a :py:class:`SymbolSpace `.
A :py:class:`~volatility3.framework.contexts.Context` can store only one :py:class:`~volatility.framework.symbols.SymbolSpace`
at a time, although a :py:class:`~volatility3.framework.symbols.SymbolSpace` can store as
many :py:class:`~volatility3.framework.symbols.SymbolTable` items as necessary.
Volatility 3 uses the de facto naming convention for symbols of `module!symbol` to refer to them. It reads them from its
own JSON formatted file, which acts as a common intermediary between Windows PDB files, Linux DWARF files, other symbol
formats and the internal Python format that Volatility 3 uses to represent
a :py:class:`~volatility3.framework.interfaces.objects.Template` or
a :py:class:`Symbol `.
.. note:: Volatility 2's name for a :py:class:`~volatility3.framework.symbols.SymbolSpace` was a profile, but it could
not differentiate between symbols from different modules and required special handling for 32-bit programs that
used Wow64 on Windows. This meant that all symbols lived in a single namespace with the possibility of symbol name
collisions. It read the symbols using a format called *vtypes*, written in Python code directly.
This made it less transferable or able to be used by other software.
Plugins
-------
A plugin acts as a means of requesting data from the user interface (and so the user) and then using it to carry out a
specific form of analysis on the :py:class:`Context `
(containing whatever symbol tables and memory layers it may). The means of communication between the user interface and
the library is the configuration tree, which is used by components within the :py:class:`~volatility3.framework.contexts.Context`
to store configurable data. After the plugin has been run, it then returns the results in a specific format known as a
:py:class:`~volatility3.framework.interfaces.renderers.TreeGrid`. This ensures that the data can be handled by consumers of
the library, without knowing exactly what the data is or how it's formatted.
Output Renderers
----------------
User interfaces can choose how best to present the output of the results to their users. The library always responds from
every plugin with a :py:class:`~volatility3.framework.renderers.TreeGrid`, and the user interface can then determine how
best to display it. For the Command Line Interface, that might be via text output as a table, or it might output to an
SQLite database or a CSV file. For a web interface, the best output is probably as JSON where it could be displayed as
a table, or inserted into a database like Elastic Search and trawled using an existing frontend such as Kibana.
The renderers only need to know how to process very basic types (booleans, strings, integers, bytes) and a few additional specific
ones (disassembly and various absent values).
Renderers can also be added to volatility automatically. There is an additional arrow/parquet format renderer available (but requires
the pyarrow dependency to be installed), but this is not shipped with the EXE version because it doubles the size of the executable.
Configuration Tree
------------------
The configuration tree acts as the interface between the calling program and Volatility 3 library. Elements of the
library (such as a :py:class:`Plugin `,
a :py:class:`TranslationLayer `,
an :py:class:`Automagic `, etc.) can use the configuration
tree to inform the calling program of the options they require and/or optionally support, and allows the calling program
to provide that information when the library is then called.
Automagic
---------
There are certain setup tasks that establish the context in a way favorable to a plugin before it runs, removing
several tasks that are repetitive and also easy to get wrong. These are called
:py:class:`Automagic `, since they do things like magically
taking a raw memory image and automatically providing the plugin with an appropriate Intel translation layer and an
accurate symbol table without either the plugin or the calling program having to specify all the necessary details. Automagics are a core component which consumers of the library can call or not at their discretion.
.. note:: Volatility 2 used to do this as well, but it wasn't a particularly modular mechanism, and was used only for
stacking address spaces (rather than identifying profiles), and it couldn't really be disabled/configured easily.
---
## File: doc/source/complex-plugin.rst
Writing more advanced Plugins
=============================
There are several common tasks you might wish to accomplish, there is a recommended means of achieving most of these
which are discussed below.
Writing Reusable Methods
------------------------
Classes which inherit from :py:class:`~volatility3.framework.interfaces.plugins.PluginInterface` all have a :py:meth:`run()` method
which takes no parameters and will return a :py:class:`~volatility3.framework.interfaces.renderers.TreeGrid`. Since most useful
functions are parameterized, to provide parameters to a plugin the `configuration` for the context must be appropriately manipulated.
There is scope for this, in order to run multiple plugins (see `Writing plugins that run other plugins`) but a much simpler method
is to provide a parameterized `classmethod` within the plugin, which will allow the method to yield whatever kind of output it will
generate and take whatever parameters it might need.
As an example, an often used function is listing processes. The code lives within the
:py:class:`~volatility3.plugins.windows.pslist.PsList` plugin but can be used by other plugins by providing the
appropriate parameters (see
:py:meth:`~volatility3.plugins.windows.pslist.PsList.list_processes`).
It is up to the author of a plugin to validate that any required plugins are present and are the appropriate version.
Writing plugins that run other plugins
--------------------------------------
Occasionally plugins will want to process the output from other plugins (for example, the timeliner plugin which runs all other
available plugins that feature a Timeliner interface). This can be achieved with the following example code:
.. code-block:: python
automagics = automagic.choose_automagic(automagic.available(self._context), plugin_class)
plugin = plugins.construct_plugin(self.context, automagics, plugin_class, self.config_path,
self._progress_callback, self.open)
This code will first generate suitable automagics for running against the context. Unfortunately this must be re-run for
each plugin in order to populate the context's configuration correctly based on the plugin's requirements (which may vary
between plugins). Once the automagics have been constructed, the plugin can be instantiated using the helper function
:py:func:`~volatility3.framework.plugins.construct_plugin` providing:
* the base context (containing the configuration and any already loaded layers or symbol tables)
* the plugin class to run
* the configuration path within the context for the plugin
* any callback to determine progress in lengthy operations
* an open method for the plugin to create files during the run
With the constructed plugin, it can either be run by calling its
:py:meth:`~volatility3.framework.interfaces.plugins.PluginInterface.run` method, or any other known method can
be invoked on it.
Writing plugins that output files
---------------------------------
Every plugin can create files, but since the user interface must decide how to actually provide these files to the user,
an abstraction layer is used.
The user interface specifies an open_method (which is actually a class constructor that can double as a python
ContextManager, so it can be used by the python `with` keyword). This is set on the plugin using
`plugin.set_open_method` and can then be called or accessed using `plugin.open(preferred_filename)`. There are no additional options
that can be set on the filename, and a :py:class:`~volatility3.framework.interfaces.plugins.FileHandlerInterface` is the result.
This mimics an `IO[bytes]` object, which closely mimics a standard python file-like object.
As such, code for outputting to a file would be expected to look something like:
.. code-block:: python
with self.open(preferred_filename) as file_handle:
file_handle.write(data)
Since self.open returns a ContextManager the file is closed automatically and thus committed for the UI to process as
necessary. If the file is not closed, the UI may not be able to properly process it and unexpected results may arise.
In certain instances you may receive a file_handle from another plugin's method, in which case the file is unlikely to be
closed to allow the preferred filename to be changed (or data to be added/modified, if necessary).
Writing Scanners
----------------
Scanners are objects that adhere to the :py:class:`~volatility3.framework.interfaces.layers.ScannerInterface`. They are
passed to the :py:meth:`~volatility3.framework.interfaces.layers.TranslationLayerInterface.scan` method on layers which will
divide the provided range of sections (or the entire layer
if none are provided) and call the :py:meth:`~volatility3.framework.interfaces.layers.ScannerInterface`'s call method
with each chunk as a parameter, ensuring a suitable amount of overlap (as defined by the scanner).
The offset of the chunk, within the layer, is also provided as a parameter.
Scanners can technically maintain state, but it is not recommended since the ordering that the chunks are scanned is
not guaranteed. Scanners may be executed in parallel if they mark themselves as `thread_safe` although the threading
technique may be either standard threading or multiprocessing. Note, the only component of the scans which is
parallelized are those that go on within the scan method. As such, any processing carried out on the results yielded
by the scanner will be processed in serial. It should also be noted that generating the addresses to be scanned are
not iterated in parallel (in full, before the scanning occurs), meaning the smaller the sections to scan the quicker the
scan will run.
Empirically it was found that scanners are typically not the most time intensive part of plugins (even those that do
extensive scanning) and so parallelism does not offer significant gains. As such, parallelism is not enabled by default
but interfaces can easily enable parallelism when desired.
Writing / Using Intermediate Symbol Format Files
------------------------------------------------
It can occasionally be useful to create a data file containing the static structures that can create a
:py:class:`~volatility3.framework.interfaces.objects.Template` to be instantiated on a layer.
Volatility has all the machinery necessary to construct these for you from properly formatted JSON data.
The JSON format is documented by the JSON schema files located in the schemas directory. These are versioned using standard .so
library versioning, so they may not increment as expected. Each schema lists an available version that can be used,
which specifies five different sections:
* Base_types - These are the basic type names that will make up the native / primitive types
* User_types - These are the standard definitions of type structures, most will go here
* Symbols - These list offsets that are associated with specific names (and can be associated with specific type names)
* Enums - Enumerations that offer a number of choices
* Metadata - This is information about the generator, when the file was generated and similar
Constructing an appropriate file, the file can be loaded into a symbol table as follows:
.. code-block:: python
table_name = intermed.IntermediateSymbolTable.create(context, config_path, 'sub_path', 'filename')
This code will load a JSON file from one of the standard symbol paths (volatility3/symbols and volatility3/framework/symbols)
under the additional directory sub_path, with a name matching filename.json
(the extension should not be included in the filename).
The `sub_path` parameter acts as a filter, so that similarly named symbol tables for each operating system can be
addressed separately. The top level directories which sub_path filters are also checked as zipfiles to determine
any symbols within them. As such, group of symbol tables can be included in a single zip file. The filename for the
symbol tables should not contain an extension, as extensions for JSON (and compressed JSON files) will be tested to find
a match.
Additional parameters exist, such as `native_types` which can be used to provide pre-populated native types.
Another useful parameter is `table_mapping` which allows for type referenced inside the JSON (such as
`one_table!type_name`) would allow remapping of `one_table` to `another_table` by providing a dictionary as follows:
.. code-block:: python
table_name = intermed.IntermediateSymbolTable.create(context, config_path, 'sub_path', 'filename',
table_mapping = {'one_table': 'another_table'})
The last parameter that can be used is called `class_types` which allows a particular structure to be instantiated on
a class other than :py:class:`~volatility3.framework.objects.StructType`, allowing for additional methods to be defined
and associated with the type.
The table name can then by used to access the constructed table from the context, such as:
.. code-block:: python
context.symbol_space[table_name]
Writing new Translation Layers
------------------------------
Translation layers offer a way for data to be translated from a higher (domain) layer to a lower (range) layer.
The main method that must be overloaded for a translation layer is the `mapping` method. Usually this is a linear
mapping whereby a value at an offset in the domain maps directly to an offset in the range.
Most new layers should inherit from :py:class:`~volatility3.framework.layers.linear.LinearlyMappedLayer` where they
can define a mapping method as follows:
.. code-block:: python
def mapping(self,
offset: int,
length: int,
ignore_errors: bool = False) -> Iterable[Tuple[int, int, int, int, str]]:
This takes a (domain) offset and a length of block, and returns a sorted list of chunks that cover the requested amount
of data. Each chunk contains the following information, in order:
**offset (domain offset)**
requested offset in the domain
**chunk length**
the length of the data in the domain
**mapped offset (range offset)**
where the data lives in the lower layer
**mapped length**
the length of the data in the range
**layer_name**
the layer that this data comes from
An example (and the most common layer encountered in memory forensics) would be an Intel layer, which models the Intel
page mapping system. Based on a series of tables stored within the layer itself, an intel layer can convert a virtual
address to a physical address. It should be noted that intel layers allow multiple virtual addresses to map to the
same physical address (but a single virtual address cannot ever map to more than one physical address).
As a simple example, in a virtual layer which looks like `abracadabra` but maps to a physical layer that looks
like `abcdr`, requesting `mapping(5, 4)` would return:
.. code-block:: python
[(5,1,0,1, 'physical_layer'),
(6,1,3,1, 'physical_layer'),
(7,2,0,2, 'physical_layer')
]
This mapping mechanism allows for great flexibility because chunks making up a virtual layer can come from multiple
different range layers, allowing for swap space to be used to construct the virtual layer, for example. Also, by
defining the mapping method, the read and write methods (which read and write into the domain layer) are defined for you
to write to the lower layers (which in turn can write to layers even lower than that) until eventually they arrive at a
DataLayer, such as a file or a buffer.
This mechanism also allowed for some minor optimization in scanning such a layer, but should further control over the
scanning of layers be needed, please refer to the Layer Scanning page.
Whilst it may seem as though some of the data seems redundant (the length values are always the same) this is not the
case for :py:class:`~volatility3.framework.layers.segmented.NonLinearlySegmentedLayer`. These layers do not guarantee
that each domain address maps directly to a range address, and in fact can carry out processing on the data. These
layers are most commonly encountered as compression or encryption layers (whereby a domain address may map into a
chunk of the range, but not directly). In this instance, the mapping will likely define additional methods that can
take a chunk and process it from its original value into its final value (such as decompressing for read and compressing
for write).
These methods are private to the class, and are used within the standard `read` and `write` methods of a layer.
A non-linear layer's mapping method should return the data required to be able to return the original data. As an
example, a run length encoded layer, whose domain data looks like `aaabbbbbcdddd` could be stored as `3a5b1c4d`.
The mapping method call for `mapping(5,4)` should return all the regions that encompass the data required. The layer
would return the following data:
.. code-block:: python
[(5, 4, 2, 4, 'rle layer')]
It would then define `_decode` and `_encode` methods that could convert from one to the other. In the case of `read(5, 4)`,
the `_decode` method would be provided with the following parameters:
.. code-block:: python
data = "5b1c"
mapped_offset = 2
offset = 5
output_length = 4
This requires that the `_decode` method can unpack the encoding back to `bbbbbc` and also know that the decoded
block starts at 3, so that it can return just `bbbc`, as required. Such layers therefore typically need to keep much
more internal state, to keep track of which offset of encoded data relates to which decoded offset for both the mapping
and `_encode` and `_decode` methods.
If the data processing produces known fixed length values, then it is possible to write an `_encode` method in much the
same way as the decode method. `_encode` is provided with the data to encode, the mapped_offset to write it to the lower
(range) layer, the original offset of the data in the higher (domain) layer and the value of the not yet encoded data
to write. The encoded result, regardless of length will be written over the current image at the mapped_offset. No
other changes or updates to tables, etc are carried out.
`_encode` is much more difficult if the encoded data can be variable length, as it may involve rewriting most, if not
all of the data in the image. Such a situation is not currently supported with this API and it is strongly recommended
to raise NotImplementedError in this method.
Communicating between layers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Layers can ask for information from lower layers using the `layer.metadata` lookup. In the following example,
a LayerStacker automagic that generates the intel TranslationLayer requests whether the base layer knows what the
`page_map_offset` value should be, a CrashDumpLayer would have that information. As such the TranslationLayer would
just lookup the `page_map_offset` value in the `base_layer.metadata` dictionary:
.. code-block:: python
if base_layer.metadata.get('page_layer_offset', None) is not None:
Most layers will return `None`, since this is the default, but the CrashDumpLayer may know what the value should be,
so it therefore populates the `metadata` property. This is defined as a read-only mapping to ensure that every layer
includes data from every underlying layer. As such, CrashDumpLayer would actually specify this value by setting it
in the protected dictionary by `self._direct_metadata['page_map_offset']`.
There is, unfortunately, no easy way to form consensus between what a particular layer may want and what a particular layer
may be able to provide. At the moment, the main information that layers may populate are:
* `os` with values of `Windows`, `Linux`, `Mac` or `unknown`
* `architecture` with values of `Intel32`, `Intel64` or `unknown`
* `pae` a boolean specifying whether the PAE mode is enabled for windows
* `page_map_offset` the value pointing to the intel page_map_offset
Any value can be specified and used by layers but consideration towards ambiguity should be used to ensure that overly
generic names aren't used for something and then best describe something else that may be needed later on.
.. note::
The data stored in metadata is *not* restored when constructed from a configuration, so metadata should only be
used as a temporary means of storing information to be used in constructing later objects and all information
required to recreate an object must be written through the requirements mechanism.
Writing new Templates and Objects
---------------------------------
In most cases, a whole new type of object is unnecessary. It will usually be derived from an
:py:class:`~volatility3.framework.objects.StructType` (which is itself just another name for a
:py:class:`~volatility3.framework.objects.AggregateType`, but it's better to use `StructType` for readability).
This can be used as a class override for a particular symbol table, so that an existing structure can be augmented with
additional methods. An example of this would be:
.. code-block:: python
symbol_table = contexts.symbol_space[symbol_table_name]
symbol_table.set_type_class('', NewStructureClass)
This will mean that when a specific structure is loaded from the symbol_space, it is not constructed as a standard
`StructType`, but instead is instantiated using the NewStructureClass, meaning new methods can be called directly on it.
If the situation really calls for an entirely new object, that isn't covered by one of the existing
:py:class:`~volatility3.framework.objects.PrimitiveObject` objects (such as
:py:class:`~volatility3.framework.objects.Integer`,
:py:class:`~volatility3.framework.objects.Boolean`,
:py:class:`~volatility3.framework.objects.Float`,
:py:class:`~volatility3.framework.objects.Char`,
:py:class:`~volatility3.framework.objects.Bytes`)
or the other builtins (such as
:py:class:`~volatility3.framework.objects.Array`,
:py:class:`~volatility3.framework.objects.Bitfield`,
:py:class:`~volatility3.framework.objects.Enumeration`,
:py:class:`~volatility3.framework.objects.Pointer`,
:py:class:`~volatility3.framework.objects.String`,
:py:class:`~volatility3.framework.objects.Void`) then you can review the following information about defining an entirely
new object.
All objects must inherit from :py:class:`~volatility3.framework.interfaces.objects.ObjectInterface` which defines a
constructor that takes a context, a `type_name`, an :py:class:`~volatility3.framework.interfaces.objects.ObjectInformation`
object and then can accept additional keywords (which will not necessarily be provided if the object is constructed
from a JSON reference).
The :py:class:`~volatility3.framework.interfaces.objects.ObjectInformation` class contains all the basic elements that
define an object, which include:
* layer_name
* offset
* member_name
* parent
* native_layer_name
* size
The layer_name and offset are how volatility reads the data of the object. Since objects can reference other objects
(specifically pointers), and contain values that are used as offsets in a particular layer, there is also the concept
of a native_layer_name. The native_layer_name allows an object to be constructed based on physical data (for instance)
but to reference virtual addresses, or for an object in the kernel virtual layer to reference offsets in a process
virtual layer.
The member_name and parent are optional and are used for when an object is constructed as a member of a structure.
The parent points back to the object that created this one, and member_name is the name of the attribute of the parent
used to get to this object.
Finally, some objects are dynamically sized, and this size parameter allows a constructor to specify how big the object
should be. Note, the size can change throughout the lifespan of the object, and the object will need to ensure that
it compensates for such a change.
Objects must also contain a specific class called `VolTemplateProxy` which must inherit from
:py:class:`~volatility3.framework.interfaces.objects.ObjectInterface`. This is used to access information about
a structure before it has been associated with data and becomes an Object. The
:py:class:`~volatility3.framework.interfaces.objects.ObjectInterface.VolTemplateProxy` class contains a number of
abstract classmethods, which take a :py:class:`~volatility3.framework.interfaces.objects.Template`. The main method
that is likely to need overwriting is the `size` method, which should return the size of the object (for the template
of a dynamically-sized object, this should be a suitable value, and calculated based on the best available information).
For most objects, this can be determined from the JSON data used to construct a normal `Struct` and therefore only needs
to be defined for very specific objects.
---
## File: doc/source/development.rst
Writing Plugins
===============
.. toctree::
simple-plugin
complex-plugin
using-as-a-library
---
## File: doc/source/getting-started-linux-tutorial.rst
Linux Tutorial
==============
This guide will give you a brief overview of how volatility3 works as well as a demonstration of several of the plugins available in the suite.
Acquiring memory
----------------
Volatility3 does not provide the ability to acquire memory. Below is an example of a tool that can be used to acquire memory on Linux systems:
* `AVML - Acquire Volatile Memory for Linux `_
Other tools may exist, but please verify their maintenance status and compatibility with volatility3 before use.
Procedure to create symbol tables for Linux
-------------------------------------------
It is recommended to first check the repository `volatility3-symbols `_ for pre-generated JSON.xz symbol table files.
This repository provides files organized by kernel version for popular Linux distributions such as Debian, Ubuntu, and AlmaLinux.
If you cannot find a suitable symbol table for your kernel version there, please refer to :ref:`symbol-tables:Mac or Linux symbol tables` to create one manually.
After creating the file, place it under the directory ``volatility3/symbols``.
Volatility3 will automatically detect and use symbol tables from this location.
Listing plugins
---------------
Volatility3 currently supports over 40 Linux-specific plugins covering a wide range of forensic analysis needs, such as process enumeration, memory-mapped file inspection, loaded modules, and kernel tracing features.
Some representative plugins include:
- ``linux.pslist``: Lists running processes with their PIDs and PPIDs.
- ``linux.bash``: Recovers bash command history from memory.
- ``linux.lsmod``: Displays loaded kernel modules.
- ``linux.kmsg``: Reads messages from the kernel log buffer.
- ``linux.elfs``: Lists all memory-mapped ELF files.
- ``linux.check_creds``: Checks for suspicious credential structures.
- ``linux.vmayarascan``: Scans process memory using YARA signatures.
For a full list of supported plugins, run the following command:
.. code-block:: shell-session
$ python3 vol.py --help | grep -i linux.
.. note:: You can also filter and inspect available plugins using more sophisticated patterns or tools like ``grep``, ``awk``, or simply explore the source under ``volatility3/framework/plugins/linux``.
Using plugins
-------------
The following is the syntax to run the volatility CLI.
.. code-block:: shell-session
$ python3 vol.py -f
Example
-------
banners
~~~~~~~
In this example we will be using a memory dump from the Insomni'hack teaser 2020 CTF Challenge called Getdents. We will limit the discussion to memory forensics with volatility 3 and not extend it to other parts of the challenge.
Thanks go to `stuxnet `_ for providing this memory dump and `writeup `_.
.. code-block:: shell-session
$ python3 vol.py -f memory.vmem banners
Volatility 3 Framework 2.26.0
Progress: 100.00 PDB scanning finished
Offset Banner
0x141c1390 Linux version 4.15.0-42-generic (buildd@lgw01-amd64-023) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #45-Ubuntu SMP Thu Nov 15 19:32:57 UTC 2018 (Ubuntu 4.15.0-42.45-generic 4.15.18)
0x63a00160 Linux version 4.15.0-72-generic (buildd@lcy01-amd64-026) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 (Ubuntu 4.15.0-72.81-generic 4.15.18)
0x6455c4d4 Linux version 4.15.0-72-generic (buildd@lcy01-amd64-026) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 (Ubuntu 4.15.0-72.81-generic 4.15.18)
0x6e1e055f Linux version 4.15.0-72-generic (buildd@lcy01-amd64-026) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 (Ubuntu 4.15.0-72.81-generic 4.15.18)
0x7fde0010 Linux version 4.15.0-72-generic (buildd@lcy01-amd64-026) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 (Ubuntu 4.15.0-72.81-generic 4.15.18)
The above command helps us identify the kernel version and distribution from the memory dump.
Using this information, follow the instructions in :ref:`getting-started-linux-tutorial:Procedure to create symbol tables for linux` to generate the required ISF file.
Once created, place the file under the ``volatility3/symbols`` directory so that Volatility3 can recognize it automatically.
linux.boottime
~~~~~~~~~~~~~~
This plugin provides the system boot time extracted from memory.
It is useful for establishing a timeline, particularly when analyzing incident response scenarios or determining system uptime.
.. code-block:: shell-session
$ python3 vol.py -f memory.vmem linux.boottime
Volatility 3 Framework 2.26.0
Progress: 100.00 Stacking attempts finished
TIME NS Boot Time
- 2022-02-10 06:50:16.450008 UTC
This timestamp can serve as a reference point for correlating system events, such as process start times, logs, or malicious activity.
linux.pslist
~~~~~~~~~~~~
This plugin lists active processes by walking the task list from memory.
It provides detailed metadata for each process, including identifiers and user/group information.
.. code-block:: shell-session
$ python3 vol.py -f memory.vmem linux.pslist
Volatility 3 Framework 2.26.0
Progress: 100.00 Stacking attempts finished
OFFSET (V) PID TID PPID COMM UID GID EUID EGID CREATION TIME File output
0x8ca6db1aac80 1 1 0 systemd 0 0 0 0 2022-02-10 06:50:16.364213 UTC Disabled
0x8ca6db1a9640 2 2 0 kthreadd 0 0 0 0 2022-02-10 06:50:16.364213 UTC Disabled
0x8ca6db1ac2c0 3 3 2 rcu_gp 0 0 0 0 2022-02-10 06:50:16.372213 UTC Disabled
...
This detailed view allows investigators to correlate user privileges, startup times, and relationships between processes more precisely than before.
linux.pstree
~~~~~~~~~~~~
This plugin presents the process hierarchy as a tree, clearly showing parent-child relationships between processes.
.. code-block:: shell-session
$ python3 vol.py -f memory.vmem linux.pstree
Volatility 3 Framework 2.26.0
Progress: 100.00 Stacking attempts finished
OFFSET (V) PID TID PPID COMM
0x8ca6db1aac80 1 1 0 systemd
* 0x8ca6db3342c0 278 278 1 systemd-journal
* 0x8ca6d005ac80 315 315 1 systemd-udevd
* 0x8ca6d0eac2c0 478 478 1 systemd-resolve
* ...
*** 0x8ca67108c2c0 1507 1507 1438 gdm-x-session
**** 0x8ca671215900 1527 1527 1507 Xorg
**** 0x8ca671210000 1608 1608 1507 gnome-session-b
***** 0x8ca66fba42c0 1765 1765 1608 ssh-agent
It helps identify unusual or suspicious process structures such as orphaned child processes, injected children under legitimate parents, or long chains of shell execution.
The tree view is particularly useful for spotting anomalies in process launch sequences or privilege escalations by inspecting unexpected parent-child relationships.
linux.bash
~~~~~~~~~~
Now to find the commands that were run in the bash shell by using ``linux.bash``.
.. code-block:: shell-session
$ python3 vol.py -f memory.vmem linux.bash
Volatility 3 Framework 2.26.0
Progress: 100.00 Stacking attempts finished
PID Process CommandTime Command
1733 bash 2020-01-16 14:00:36.000000 sudo reboot
1733 bash 2020-01-16 14:00:36.000000 AWAVH��
1733 bash 2020-01-16 14:00:36.000000 sudo apt upgrade
1733 bash 2020-01-16 14:00:36.000000 sudo apt upgrade
1733 bash 2020-01-16 14:00:36.000000 sudo reboot
1733 bash 2020-01-16 14:00:36.000000 uname -a
1733 bash 2020-01-16 14:00:41.000000 chmod +x meterpreter
1733 bash 2020-01-16 14:00:42.000000 sudo ./meterpreter
linux.ip.Addr and linux.ip.Link
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Network configuration is an essential aspect of memory forensics.
Analyzing the network interfaces and their IP assignments can reveal active connections, misconfigured settings, or even artifacts of malicious activity.
Volatility3 provides the following two plugins to examine this information:
**linux.ip.Addr** displays IP-related metadata for each interface, including IPv4/IPv6 addresses, MAC, scope, and interface status.
.. code-block:: shell-session
$ python3 vol.py -f memory.vmem linux.ip.Addr
NetNS Index Interface MAC Promiscuous IP Prefix Scope Type State
4026531992 2 enp0s3 08:00:27:8a:4d:eb False 10.0.2.15 24 global UP
...
**linux.ip.Link** shows lower-level link information such as MTU, Qdisc, and interface flags.
.. code-block:: shell-session
$ python3 vol.py -f memory.vmem linux.ip.Link
NS Interface MAC State MTU Qdisc Qlen Flags
4026531992 enp0s3 08:00:27:8a:4d:eb UP 1500 fq_codel 1000 BROADCAST,LOWER_UP,MULTICAST,UP
Together, these plugins help investigators assess the system’s network exposure and identify anomalies such as multiple network namespaces, unexpected IP addresses, or active interfaces in promiscuous mode.
linux.malfind
~~~~~~~~~~~~~
This plugin scans process memory for suspicious executable regions that may indicate code injection or malicious payloads.
It is particularly useful for detecting fileless malware, injected shellcode, or unpacked runtime payloads that do not correspond to legitimate binary files on disk.
.. code-block:: shell-session
$ python3 vol.py -f memory.vmem linux.malfind
Volatility 3 Framework 2.26.0
Progress: 100.00 Stacking attempts finished
PID Process Start End Path Protection Hexdump Disasm
540 networkd-dispat 0x7f1506482000 0x7f1506483000 Anonymous Mapping rwx
00 00 00 00 00 00 00 00 43 00 00 00 00 00 00 00 ........C.......
4c 8d 15 f9 ff ff ff ff 25 03 00 00 00 0f 1f 00 L.......%.......
...
0x7f1506482000: add byte ptr [rax], al
0x7f1506482002: add byte ptr [rax], al
...
0x7f1506482013: stc
In this output:
- **PID / Process**: Identifies the target process (in this case, `networkd-dispat`, PID 540)
- **Start / End**: The memory address range of the suspicious region
- **Path**: Indicates that the region is an anonymous memory mapping (i.e., not backed by a file)
- **Protection**: The region is marked `rwx` (read-write-execute), which is uncommon for legitimate memory regions
- **Disasm**: Shows the disassembled machine code found in that memory region
**Key indicators to focus on:**
- **Anonymous Mapping + rwx**: Memory that is not backed by a file and has execute permissions is often used for injected code
- **Disassembly patterns**: Repetitive `add` instructions, `nop`, or unusual instruction sequences can be artifacts of shellcode, packer stubs, or JIT-compiled code
- **Process context**: The suspicious memory is found in `networkd-dispat`, a system service — if this service is not expected to have dynamic executable memory regions, it may be compromised
Use this plugin early in an investigation to flag processes for deeper inspection.
Further Exploration and Contribution
------------------------------------
This guide has introduced several key Linux plugins available in Volatility 3 for memory forensics.
However, many more plugins are available, covering topics such as kernel modules, page cache analysis, tracing frameworks, and malware detection.
If you identify gaps in plugin functionality or wish to extend support for a specific analysis use case, you are encouraged to contribute new plugins or enhancements.
Your insights can help shape the future of Linux memory forensics.
---
## File: doc/source/getting-started-mac-tutorial.rst
macOS Tutorial
==============
.. warning::
As of the Volatility 3 parity release, macOS analysis support is no longer actively maintained.
The existing macOS plugins remain available but may not receive future updates or bug fixes.
For more details, see the `official announcement `_.
This guide will give you a brief overview of how volatility3 works as well as a demonstration of several of the plugins available in the suite.
Acquiring memory
----------------
Volatility3 does not provide the ability to acquire memory. The example below is an open source tool. Other commercial tools are also available.
* `osxpmem `_
Procedure to create symbol tables for macOS
--------------------------------------------
To create a symbol table please refer to :ref:`symbol-tables:Mac or Linux symbol tables`.
.. tip:: It may be possible to locate pre-made ISF files from the `download link `_ ,
which is built and maintained by `volatilityfoundation `_.
After creating the file or downloading it from the link, place the file under the directory ``volatility3/symbols/``.
Listing plugins
---------------
The following is a sample of the macOS plugins available for volatility3, it is not complete and more plugins may
be added. For a complete reference, please see the volatility 3 :doc:`list of plugins `.
For plugin requests, please create an issue with a description of the requested plugin.
.. code-block:: shell-session
$ python3 vol.py --help | grep -i mac. | head -n 4
mac.bash.Bash Recovers bash command history from memory.
mac.check_syscall.Check_syscall
mac.check_sysctl.Check_sysctl
mac.check_trap_table.Check_trap_table
.. note:: Here the command is piped to grep and head to provide the start of the list of macOS plugins.
Using plugins
-------------
The following is the syntax to run the volatility CLI.
.. code-block:: shell-session
$ python3 vol.py -f
Example
-------
banners
~~~~~~~
In this example we will be using a memory dump from the Securinets CTF Quals 2019 Challenge called Contact_me. We will limit the discussion to memory forensics with volatility 3 and not extend it to other parts of the challenge.
Thanks go to `stuxnet `_ for providing this memory dump and `writeup `_.
.. code-block:: shell-session
$ python3 vol.py -f contact_me banners.Banners
Volatility 3 Framework 2.4.2
Progress: 100.00 PDB scanning finished
Offset Banner
0x4d2c7d0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64
0xb42b180 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64
0xcda9100 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64
0x1275e7d0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64
0x1284fba4 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64
0x34ad0180 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64
The above command helps us to find the memory dump's Darwin kernel version. Now using the above banner we can search for the needed ISF file.
If an ISF file cannot be found then, follow the instructions on :ref:`getting-started-mac-tutorial:Procedure to create symbol tables for macOS`. After that, place the ISF file under the ``volatility3/symbols`` directory.
mac.pslist
~~~~~~~~~~
.. code-block:: shell-session
$ python3 vol.py -f contact_me mac.pslist.PsList
Volatility 3 Framework 2.4.2
Progress: 100.00 Stacking attempts finished
PID PPID COMM
0 0 kernel_task
1 0 launchd
35 1 UserEventAgent
38 1 kextd
39 1 fseventsd
37 1 uninstalld
45 1 configd
46 1 powerd
52 1 logd
58 1 warmd
.....
``mac.pslist`` helps us to list the processes which are running, their PIDs and PPIDs.
mac.pstree
~~~~~~~~~~
.. code-block:: shell-session
$ python3 vol.py -f contact_me mac.pstree.PsTree
Volatility 3 Framework 2.4.2
Progress: 100.00 Stacking attempts finished
PID PPID COMM
35 1 UserEventAgent
38 1 kextd
39 1 fseventsd
37 1 uninstalld
204 1 softwareupdated
* 449 204 SoftwareUpdateCo
337 1 system_installd
* 455 337 update_dyld_shar
``mac.pstree`` helps us to display the parent-child relationships between processes.
mac.ifconfig
~~~~~~~~~~~~
.. code-block:: shell-session
$ python3 vol.py -f contact_me mac.ifconfig.Ifconfig
Volatility 3 Framework 2.4.2
Progress: 100.00 Stacking attempts finished
Interface IP Address Mac Address Promiscuous
lo0 False
lo0 127.0.0.1 False
lo0 ::1 False
lo0 fe80:1::1 False
gif0 False
stf0 False
en0 00:0C:29:89:8B:F0 00:0C:29:89:8B:F0 False
en0 fe80:4::10fb:c89d:217f:52ae 00:0C:29:89:8B:F0 False
en0 192.168.140.128 00:0C:29:89:8B:F0 False
utun0 False
utun0 fe80:5::2a95:bb15:87e3:977c False
We can use the ``mac.ifconfig`` plugin to get information about the configuration of the network interfaces of the host under investigation.
---
## File: doc/source/getting-started-windows-tutorial.rst
Windows Tutorial
================
This guide provides a brief introduction to how volatility3 works as a demonstration of several of the plugins available in the suite.
Acquiring memory
----------------
Volatility does not provide the ability to acquire memory.
Memory can be acquired using a number of tools, below are some examples but others exist:
* `WinPmem `_
* `FTK Imager `_
Listing Plugins
---------------
The following is a sample of the windows plugins available for volatility3, it is not complete and more plugins may
be added. For a complete reference, please see the volatility 3 :doc:`list of plugins `.
For plugin requests, please create an issue with a description of the requested plugin.
.. code-block:: shell-session
$ python3 vol.py --help | grep windows | head -n 4
windows.bigpools.BigPools
windows.cmdline.CmdLine
windows.crashinfo.Crashinfo
windows.dlllist.DllList
.. note:: Here the command is piped to grep and head to provide the start of a list of the available windows plugins.
Using plugins
-------------
The following is the syntax to run the volatility CLI.
.. code-block:: shell-session
$ python3 vol.py -f plugin_name plugin_option
Example
-------
windows.pslist
~~~~~~~~~~~~~~
In this example we will be using a memory dump from the PragyanCTF'22.
We will limit the discussion to memory forensics with volatility 3 and not extend it to other parts of the challenges.
When using windows plugins in volatility 3, the required ISF file can often be generated from PDB files automatically
downloaded from Microsoft servers, and therefore does not require locating or adding specific ISF files to the volatility 3 symbols directory.
.. code-block:: shell-session
$ python3 vol.py -f MemDump.DMP windows.pslist | head -n 10
Volatility 3 Framework 2.0.1 PDB scanning finished
PID PPID ImageFileName Offset(V) Threads Handles SessionId Wow64 CreateTime ExitTime File output
4 0 System 0xfa8000cbc040 85 492 N/A False 2022-02-07 16:30:12.000000 N/A Disabled
276 4 smss.exe 0xfa8001e04040 2 29 N/A False 2022-02-07 16:30:12.000000 N/A Disabled
352 336 csrss.exe 0xfa8002110b30 9 375 0 False 2022-02-07 16:30:13.000000 N/A Disabled
404 336 wininit.exe 0xfa800219f060 3 74 0 False 2022-02-07 16:30:13.000000 N/A Disabled
412 396 csrss.exe 0xfa80021c5b30 9 224 1 False 2022-02-07 16:30:13.000000 N/A Disabled
468 396 winlogon.exe 0xfa8002284060 5 113 1 False 2022-02-07 16:30:14.000000 N/A Disabled
``windows.pslist`` helps list the processes running while the memory dump was taken.
windows.pstree
~~~~~~~~~~~~~~
.. code-block:: shell-session
$ python3 vol.py -f MemDump.DMP windows.pstree | head -n 20
Volatility 3 Framework 2.0.1 PDB scanning finished
PID PPID ImageFileName Offset(V) Threads Handles SessionId Wow64 CreateTime ExitTime
4 0 System 0xfa8000cbc040 85 492 N/A False 2022-02-07 16:30:12.000000 N/A
* 276 4 smss.exe 0xfa8001e04040 2 29 N/A False 2022-02-07 16:30:12.000000 N/A
352 336 csrss.exe 0xfa8002110b30 9 375 0 False 2022-02-07 16:30:13.000000 N/A
404 336 wininit.exe 0xfa800219f060 3 74 0 False 2022-02-07 16:30:13.000000 N/A
* 504 404 services.exe 0xfa80022ccb30 7 190 0 False 2022-02-07 16:30:14.000000 N/A
** 960 504 svchost.exe 0xfa8001c17b30 39 1003 0 False 2022-02-07 16:30:14.000000 N/A
** 1216 504 svchost.exe 0xfa80026e0b30 18 311 0 False 2022-02-07 16:30:15.000000 N/A
** 1312 504 svchost.exe 0xfa8002740380 19 287 0 False 2022-02-07 16:30:15.000000 N/A
** 1984 504 taskhost.exe 0xfa8002eb1b30 8 129 1 False 2022-02-07 16:30:27.000000 N/A
** 804 504 svchost.exe 0xfa80024ca5f0 20 450 0 False 2022-02-07 16:30:14.000000 N/A
*** 100 804 audiodg.exe 0xfa80025b4b30 6 131 0 False 2022-02-07 16:30:14.000000 N/A
** 1568 504 SearchIndexer. 0xfa800254b480 12 616 0 False 2022-02-07 16:30:32.000000 N/A
** 744 504 svchost.exe 0xfa8002477b30 8 265 0 False 2022-02-07 16:30:14.000000 N/A
** 1096 504 svchost.exe 0xfa800260db30 14 357 0 False 2022-02-07 16:30:14.000000 N/A
** 616 504 svchost.exe 0xfa8002b86ab0 13 314 0 False 2022-02-07 16:32:16.000000 N/A
** 624 504 svchost.exe 0xfa8002410630 10 350 0 False 2022-02-07 16:30:14.000000 N/A
``windows.pstree`` helps to display the parent-child relationships between processes.
.. note:: Here the command is piped to head to provide smaller output, here listing only the first 20.
windows.hashdump
~~~~~~~~~~~~~~~~
.. code-block:: shell-session
$ python3 vol.py -f MemDump.DMP windows.hashdump
Volatility 3 Framework 2.0.3
Progress: 100.00 PDB scanning finished
User rid lmhash nthash
Administrator 500 aad3b435b51404eeaad3b435b51404ee 31d6cfe0d16ae931b73c59d7e0c089c0
Guest 501 aad3b435b51404eeaad3b435b51404ee 31d6cfe0d16ae931b73c59d7e0c089c0
Frank Reynolds 1000 aad3b435b51404eeaad3b435b51404ee a88d1e18706d3aa676e01e5943d15911
HomeGroupUser$ 1002 aad3b435b51404eeaad3b435b51404ee af10ecac6ea817d2bb56e3e5c33ce1cd
Dennis 1003 aad3b435b51404eeaad3b435b51404ee cf96684bbc7877920adaa9663698bf54
``windows.hashdump`` helps to list the hashes of the users in the system.
---
## File: doc/source/glossary.rst
Glossary
========
There are many terms when talking about memory forensics, this list hopes to define the common ones and
provide some commonality on how to refer to particular ideas within the field.
A
-
.. _Address:
An address is another name for an :ref:`offset`, specifically an offset within memory. Offsets can be
both relative or absolute, whereas addresses are almost always absolute.
.. _Address Space:
Address Space
This is the name in volatility 2 for what's referred to as a :ref:`Translation Layer`. It
encompasses all values that can be addresses, usually in reference to addresses in memory.
.. _Alignment:
Alignment
This value is what all data :ref:`offsets` will typically be a multiple of within a :ref:`type`.
.. _Array:
Array
This represents a list of items, which can be accessed by an index, which is zero-based (meaning the first
element has index 0). Items in arrays are almost always the same size (it is not a generic list, as in python)
even if they are :ref:`pointers` to different sized objects.
D
-
.. _Data Layer:
Data Layer
A group of bytes, where each byte can be addressed by a specific offset. Data layers are usually contiguous
chunks of data.
.. _Dereference:
Dereference
The act of taking the value of a pointer, and using it as an offset to another object, as a reference.
.. _Domain:
Domain
The set of input values for a mapping or mathematical function.
I
-
.. _Intermediate Symbol File (ISF):
Intermediate Symbol File (ISF)
They contain kernel structures and specific offsets formatted as JSON. For macOS and Linux analysis, the kernel needs to be added as an ISF file to the volatility 3 symbols directory. For Windows, the required ISF file can often be generated from PDB files automatically downloaded from Microsoft servers, and therefore does not require manual intervention.
M
-
.. _Map:
Map, mapping
A mapping is a relationship between two sets (where elements of the :ref:`Domain` map to elements
of the :ref:`Range`). Mappings can be seen as a mathematical function, and therefore volatility 3
attempts to use mathematical functional notation where possible. Within volatility a mapping is most often
used to refer to the function for translating addresses from a higher layer (domain) to a lower layer (range).
For further information, please see `Function (mathematics) in Wikipedia_`.
.. _Member:
Member
The name of subcomponents of a type, similar to attributes of objects in common programming parlance. These
are usually recorded as :ref:`offset` and :ref:`type` pairs within a :ref:`structure`.
O
-
.. _Object:
Object
This has a specific meaning within computer programming (as in object-oriented programming), but within the world
of Volatility it is used to refer to a type that has been associated with a chunk of data, or a specific instance
of a type. See also :ref:`Type`.
.. _Offset:
Offset
A numeric value that identifies a distance within a group of bytes, to uniquely identify a single byte, or the
start of a run of bytes. An offset is often relative (offset from another object/item) but can be absolute (offset from
the start of a region of data).
P
-
.. _Packed:
Packed
Structures are often :ref:`aligned` meaning that the various members (subtypes) are always aligned at
particular values (usually multiples of 2, 4 or 8). Thus if the data used to represent a particular value has
an odd number of bytes, not a multiple of the chosen number, there will be :ref:`padding` between it and
the next member. In packed structs, no padding is used and the offset of the next member depends on the length of
the previous one.
.. _Padding:
Padding
Data that (usually) contains no useful information. The typical value used for padding is 0 (sometimes called
a null byte). As an example, if a string :ref:`object