mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-12 20:57:39 +02:00
Merge branch 'volatilityfoundation:develop' into fix/ethread
This commit is contained in:
+11
@@ -27,3 +27,14 @@ config*.json
|
||||
# Pyinstaller files
|
||||
build
|
||||
dist
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
|
||||
# Memory dump files
|
||||
*.dmp
|
||||
*.vmem
|
||||
|
||||
@@ -63,7 +63,7 @@ To determine the string for a particular memory image, use the `banners` plugin.
|
||||
try to locate that exact kernel debugging package for the operating system. Unfortunately each distribution provides
|
||||
its debugging packages under different package names and there are so many that the distribution may not keep all old
|
||||
versions of the debugging symbols, and therefore **it may not be possible to find the right symbols to analyze a linux
|
||||
memory image with volatlity**. With Macs there are far fewer kernels and only one distribution, making it easier to
|
||||
memory image with volatility**. With Macs there are far fewer kernels and only one distribution, making it easier to
|
||||
ensure that the right symbols can be found.
|
||||
|
||||
Once a kernel with debugging symbols/appropriate DWARF file has been located, `dwarf2json <https://github.com/volatilityfoundation/dwarf2json>`_ will convert it into an
|
||||
|
||||
@@ -110,7 +110,7 @@ This means that pointers do not need to be explicitly dereferenced to access und
|
||||
Running plugins
|
||||
---------------
|
||||
|
||||
It's possible to run any plugin by importing it appropriately and passing it to the `display_plugin_ouptut` or `dpo`
|
||||
It's possible to run any plugin by importing it appropriately and passing it to the `display_plugin_output` or `dpo`
|
||||
method. In the following example we'll provide no additional parameters. Volatility will show us which parameters
|
||||
were required:
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ class CommandLine:
|
||||
detail = f"{excp}"
|
||||
caused_by = ["A required python module is not installed (install the module and re-run)"]
|
||||
else:
|
||||
general = "Volatilty encountered an unexpected situation."
|
||||
general = "Volatility encountered an unexpected situation."
|
||||
detail = ""
|
||||
caused_by = [
|
||||
"Please re-run using with -vvv and file a bug with the output", f"at {constants.BUG_URL}"
|
||||
|
||||
@@ -11,7 +11,6 @@ from volatility3.framework.renderers import format_hints
|
||||
from volatility3.framework.symbols import intermed
|
||||
from volatility3.framework.symbols.windows import versions
|
||||
from volatility3.plugins.windows import ssdt
|
||||
from volatility3.plugins.windows import svcscan
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
@@ -28,7 +27,6 @@ class Callbacks(interfaces.plugins.PluginInterface):
|
||||
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
|
||||
architectures = ["Intel32", "Intel64"]),
|
||||
requirements.PluginRequirement(name = 'ssdt', plugin = ssdt.SSDT, version = (1, 0, 0)),
|
||||
requirements.PluginRequirement(name = 'svcscan', plugin = svcscan.SvcScan, version = (1, 0, 0))
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
@@ -111,30 +109,19 @@ class Callbacks(interfaces.plugins.PluginInterface):
|
||||
yield symbol_name, callback.Callback, None
|
||||
|
||||
@classmethod
|
||||
def list_registry_callbacks(cls, context: interfaces.context.ContextInterface, layer_name: str, symbol_table: str,
|
||||
callback_table_name: str) -> Iterable[Tuple[str, int, None]]:
|
||||
"""Lists all registry callbacks.
|
||||
|
||||
Args:
|
||||
context: The context to retrieve required elements (layers, symbol tables) from
|
||||
layer_name: The name of the layer on which to operate
|
||||
symbol_table: The name of the table containing the kernel symbols
|
||||
callback_table_name: The nae of the table containing the callback symbols
|
||||
|
||||
Yields:
|
||||
A name, location and optional detail string
|
||||
def _list_registry_callbacks_legacy(cls, context: interfaces.context.ContextInterface, layer_name: str, symbol_table: str,
|
||||
callback_table_name: str) -> Iterable[Tuple[str, int, None]]:
|
||||
"""
|
||||
Lists all registry callbacks from the old format via the CmpCallBackVector.
|
||||
"""
|
||||
|
||||
kvo = context.layers[layer_name].config['kernel_virtual_offset']
|
||||
ntkrnlmp = context.module(symbol_table, layer_name = layer_name, offset = kvo)
|
||||
full_type_name = callback_table_name + constants.BANG + "_EX_CALLBACK_ROUTINE_BLOCK"
|
||||
|
||||
try:
|
||||
symbol_offset = ntkrnlmp.get_symbol("CmpCallBackVector").address
|
||||
symbol_count_offset = ntkrnlmp.get_symbol("CmpCallBackCount").address
|
||||
except exceptions.SymbolError:
|
||||
vollog.debug("Cannot find CmpCallBackVector or CmpCallBackCount")
|
||||
return
|
||||
symbol_offset = ntkrnlmp.get_symbol("CmpCallBackVector").address
|
||||
symbol_count_offset = ntkrnlmp.get_symbol("CmpCallBackCount").address
|
||||
|
||||
|
||||
callback_count = ntkrnlmp.object(object_type = "unsigned int", offset = symbol_count_offset)
|
||||
|
||||
@@ -155,6 +142,62 @@ class Callbacks(interfaces.plugins.PluginInterface):
|
||||
if callback.Function != 0:
|
||||
yield "CmRegisterCallback", callback.Function, None
|
||||
|
||||
@classmethod
|
||||
def _list_registry_callbacks_new(cls, context: interfaces.context.ContextInterface, layer_name: str, symbol_table: str,
|
||||
callback_table_name: str) -> Iterable[Tuple[str, int, None]]:
|
||||
"""
|
||||
Lists all registry callbacks via the CallbackListHead.
|
||||
"""
|
||||
|
||||
kvo = context.layers[layer_name].config['kernel_virtual_offset']
|
||||
ntkrnlmp = context.module(symbol_table, layer_name = layer_name, offset = kvo)
|
||||
full_type_name = callback_table_name + constants.BANG + "_CM_CALLBACK_ENTRY"
|
||||
|
||||
symbol_offset = ntkrnlmp.get_symbol("CallbackListHead").address
|
||||
symbol_count_offset = ntkrnlmp.get_symbol("CmpCallBackCount").address
|
||||
|
||||
callback_count = ntkrnlmp.object(object_type = "unsigned int", offset = symbol_count_offset)
|
||||
|
||||
if callback_count == 0:
|
||||
return
|
||||
|
||||
callback_list = ntkrnlmp.object(object_type = "_LIST_ENTRY", offset = symbol_offset)
|
||||
for callback in callback_list.to_list(full_type_name, "Link"):
|
||||
yield "CmRegisterCallbackEx", callback.Function, f"Altitude: {callback.Altitude.String}"
|
||||
|
||||
@classmethod
|
||||
def list_registry_callbacks(cls, context: interfaces.context.ContextInterface, layer_name: str, symbol_table: str,
|
||||
callback_table_name: str) -> Iterable[Tuple[str, int, None]]:
|
||||
"""Lists all registry callbacks.
|
||||
|
||||
Args:
|
||||
context: The context to retrieve required elements (layers, symbol tables) from
|
||||
layer_name: The name of the layer on which to operate
|
||||
symbol_table: The name of the table containing the kernel symbols
|
||||
callback_table_name: The nae of the table containing the callback symbols
|
||||
|
||||
Yields:
|
||||
A name, location and optional detail string
|
||||
"""
|
||||
|
||||
kvo = context.layers[layer_name].config['kernel_virtual_offset']
|
||||
ntkrnlmp = context.module(symbol_table, layer_name = layer_name, offset = kvo)
|
||||
|
||||
if ntkrnlmp.has_symbol("CmpCallBackVector") and ntkrnlmp.has_symbol("CmpCallBackCount"):
|
||||
yield from cls._list_registry_callbacks_legacy(context, layer_name, symbol_table, callback_table_name)
|
||||
elif ntkrnlmp.has_symbol("CallbackListHead") and ntkrnlmp.has_symbol("CmpCallBackCount"):
|
||||
yield from cls._list_registry_callbacks_new(context, layer_name, symbol_table, callback_table_name)
|
||||
else:
|
||||
symbols_to_check = ["CmpCallBackVector", "CmpCallBackCount", "CallbackListHead"]
|
||||
vollog.debug("Failed to get registry callbacks!")
|
||||
for symbol_name in symbols_to_check:
|
||||
symbol_status = "does not exist"
|
||||
if ntkrnlmp.has_symbol(symbol_name):
|
||||
symbol_status = "exists"
|
||||
vollog.debug(f"symbol {symbol_name} {symbol_status}.")
|
||||
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def list_bugcheck_reason_callbacks(cls, context: interfaces.context.ContextInterface, layer_name: str,
|
||||
symbol_table: str, callback_table_name: str) -> Iterable[Tuple[str, int, str]]:
|
||||
|
||||
@@ -65,7 +65,7 @@ class DllList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
try:
|
||||
name = dll_entry.FullDllName.get_string()
|
||||
except exceptions.InvalidAddressException:
|
||||
name = 'UnreadbleDLLName'
|
||||
name = 'UnreadableDLLName'
|
||||
|
||||
if layer_name is None:
|
||||
layer_name = dll_entry.vol.layer_name
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned long long": {
|
||||
"kind": "int",
|
||||
"size": 8,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned char": {
|
||||
"kind": "char",
|
||||
"size": 1,
|
||||
@@ -137,6 +143,43 @@
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 64
|
||||
},
|
||||
"_CM_CALLBACK_ENTRY": {
|
||||
"fields": {
|
||||
"Link": {
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"name": "nt_symbols!_LIST_ENTRY"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"Cookie": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long long"
|
||||
},
|
||||
"offset": 24
|
||||
},
|
||||
"Function": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "void"
|
||||
}
|
||||
},
|
||||
"offset": 40
|
||||
},
|
||||
"Altitude": {
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"name": "nt_symbols!_UNICODE_STRING"
|
||||
},
|
||||
"offset": 48
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 64
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned long long": {
|
||||
"kind": "int",
|
||||
"size": 8,
|
||||
"signed": false,
|
||||
"endian": "little"
|
||||
},
|
||||
"unsigned char": {
|
||||
"kind": "char",
|
||||
"size": 1,
|
||||
@@ -137,6 +143,43 @@
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 28
|
||||
},
|
||||
"_CM_CALLBACK_ENTRY": {
|
||||
"fields": {
|
||||
"Link": {
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"name": "nt_symbols!_LIST_ENTRY"
|
||||
},
|
||||
"offset": 0
|
||||
},
|
||||
"Cookie": {
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long long"
|
||||
},
|
||||
"offset": 16
|
||||
},
|
||||
"Function": {
|
||||
"type": {
|
||||
"kind": "pointer",
|
||||
"subtype": {
|
||||
"kind": "base",
|
||||
"name": "void"
|
||||
}
|
||||
},
|
||||
"offset": 28
|
||||
},
|
||||
"Altitude": {
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"name": "nt_symbols!_UNICODE_STRING"
|
||||
},
|
||||
"offset": 32
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 40
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
|
||||
Reference in New Issue
Block a user