mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-29 11:19:40 +02:00
issue #186 - add bigpools plugin
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
# This file is Copyright 2019 Volatility Foundation and licensed under the Volatility Software License 1.0
|
||||
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
|
||||
#
|
||||
|
||||
import logging
|
||||
from typing import List, Optional, Tuple, Iterator
|
||||
|
||||
from volatility.framework import interfaces, renderers, exceptions, symbols
|
||||
from volatility.framework.configuration import requirements
|
||||
from volatility.framework.renderers import format_hints
|
||||
from volatility.framework.interfaces import configuration
|
||||
from volatility.framework.symbols import intermed
|
||||
from volatility.framework.symbols.windows import extensions
|
||||
from volatility.plugins.windows import poolscanner
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BigPools(interfaces.plugins.PluginInterface):
|
||||
"""List big page pools."""
|
||||
|
||||
_version = (1, 0, 0)
|
||||
|
||||
is_vista_or_later = poolscanner.os_distinguisher(version_check = lambda x: x >= (6, 0),
|
||||
fallback_checks = [("KdCopyDataBlock", None, True)])
|
||||
|
||||
is_win10 = poolscanner.os_distinguisher(version_check=lambda x: (10, 0) <= x,
|
||||
fallback_checks=[("ObHeaderCookie", None, True),
|
||||
("_HANDLE_TABLE", "HandleCount", False)])
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
|
||||
# Since we're calling the plugin, make sure we have the plugin's requirements
|
||||
return [
|
||||
requirements.TranslationLayerRequirement(name = 'primary',
|
||||
description = 'Memory layer for the kernel',
|
||||
architectures = ["Intel32", "Intel64"]),
|
||||
requirements.SymbolTableRequirement(name = "nt_symbols", description = "Windows kernel symbols"),
|
||||
requirements.StringRequirement(name='tags',
|
||||
description="Comma separated list of pool tags to filter pools returned",
|
||||
optional=True,
|
||||
default=None)
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def list_big_pools(cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
layer_name: str,
|
||||
symbol_table: str,
|
||||
tags: Optional[list] = None):
|
||||
"""Returns the big page pool objects from the kernel PoolBigPageTable array.
|
||||
|
||||
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
|
||||
tags: An optional list of pool tags to filter big page pool tags by
|
||||
|
||||
Yields:
|
||||
A big page pool object
|
||||
"""
|
||||
kvo = context.layers[layer_name].config['kernel_virtual_offset']
|
||||
ntkrnlmp = context.module(symbol_table, layer_name=layer_name, offset=kvo)
|
||||
|
||||
big_page_table_offset = ntkrnlmp.get_symbol("PoolBigPageTable").address
|
||||
big_page_table = ntkrnlmp.object(object_type="unsigned long long",
|
||||
offset=big_page_table_offset)
|
||||
|
||||
big_page_table_size_offset = ntkrnlmp.get_symbol("PoolBigPageTableSize").address
|
||||
big_page_table_size = ntkrnlmp.object(object_type="unsigned long",
|
||||
offset=big_page_table_size_offset)
|
||||
|
||||
try:
|
||||
big_page_table_type = ntkrnlmp.get_type("_POOL_TRACKER_BIG_PAGED")
|
||||
except exceptions.SymbolError:
|
||||
# We have to manually load a symbol table
|
||||
is_vista_or_later = cls.is_vista_or_later(context, symbol_table)
|
||||
is_win10 = cls.is_win10(context, symbol_table)
|
||||
if is_win10:
|
||||
big_pools_json_filename = "bigpools-win10"
|
||||
elif is_vista_or_later:
|
||||
big_pools_json_filename = "bigpools-vista"
|
||||
else:
|
||||
big_pools_json_filename = "bigpools"
|
||||
|
||||
if symbols.symbol_table_is_64bit(context, symbol_table):
|
||||
big_pools_json_filename += "-x64"
|
||||
else:
|
||||
big_pools_json_filename += "-x86"
|
||||
|
||||
new_table_name = intermed.IntermediateSymbolTable.create(
|
||||
context=context,
|
||||
config_path=configuration.path_join(context.symbol_space[symbol_table].config_path, "bigpools"),
|
||||
sub_path="windows",
|
||||
filename=big_pools_json_filename,
|
||||
table_mapping={'nt_symbols': symbol_table},
|
||||
class_types={'_POOL_TRACKER_BIG_PAGES': extensions.pool.POOL_TRACKER_BIG_PAGES})
|
||||
module = context.module(new_table_name, layer_name, offset=0)
|
||||
big_page_table_type = module.get_type("_POOL_TRACKER_BIG_PAGES")
|
||||
|
||||
big_pools = ntkrnlmp.object(object_type="array",
|
||||
offset=big_page_table,
|
||||
subtype=big_page_table_type,
|
||||
count=big_page_table_size,
|
||||
absolute=True)
|
||||
|
||||
for big_pool in big_pools:
|
||||
if big_pool.is_valid():
|
||||
if tags is None or big_pool.get_key() in tags:
|
||||
yield big_pool
|
||||
|
||||
def _generator(self) -> Iterator[Tuple[int, Tuple[int, str]]]: #, str, int]]]:
|
||||
if self.config.get("tags"):
|
||||
tags = [tag for tag in self.config["tags"].split(',')]
|
||||
else:
|
||||
tags = None
|
||||
|
||||
for big_pool in self.list_big_pools(context = self.context,
|
||||
layer_name = self.config["primary"],
|
||||
symbol_table = self.config["nt_symbols"],
|
||||
tags = tags):
|
||||
|
||||
num_bytes = big_pool.get_number_of_bytes()
|
||||
if not isinstance(num_bytes, interfaces.renderers.BaseAbsentValue):
|
||||
num_bytes = format_hints.Hex(num_bytes)
|
||||
|
||||
yield (0, (format_hints.Hex(big_pool.Va),
|
||||
big_pool.get_key(),
|
||||
big_pool.get_pool_type(),
|
||||
num_bytes))
|
||||
|
||||
def run(self):
|
||||
return renderers.TreeGrid([
|
||||
('Allocation', format_hints.Hex),
|
||||
('Tag', str),
|
||||
('PoolType', str),
|
||||
('NumberOfBytes', format_hints.Hex),
|
||||
], self._generator())
|
||||
@@ -33,6 +33,7 @@ class WindowsKernelIntermedSymbols(intermed.IntermediateSymbolTable):
|
||||
self.set_type_class('_KMUTANT', extensions.KMUTANT)
|
||||
self.set_type_class('_DRIVER_OBJECT', extensions.DRIVER_OBJECT)
|
||||
self.set_type_class('_OBJECT_SYMBOLIC_LINK', extensions.OBJECT_SYMBOLIC_LINK)
|
||||
self.set_type_class('_POOL_TRACKER_BIG_PAGES', pool.POOL_TRACKER_BIG_PAGES)
|
||||
|
||||
# This doesn't exist in very specific versions of windows
|
||||
try:
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "dlassalle-by-hand",
|
||||
"datetime": "2020-04-30T14:30:00.000000"
|
||||
},
|
||||
"format": "6.2.0"
|
||||
},
|
||||
"user_types": {
|
||||
"_POOL_TRACKER_BIG_PAGES": {
|
||||
"fields": {
|
||||
"Va": {
|
||||
"offset": 0,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long long"
|
||||
}
|
||||
},
|
||||
"Key": {
|
||||
"offset": 8,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"PoolType": {
|
||||
"offset": 12,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"NumberOfBytes": {
|
||||
"offset": 16,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 24
|
||||
}
|
||||
},
|
||||
"symbols": {
|
||||
},
|
||||
"enums": {
|
||||
"_POOL_TYPE": {
|
||||
"base": "unsigned long",
|
||||
"constants": {
|
||||
"NonPagedPoolBase": 0,
|
||||
"PagedPool": 1,
|
||||
"NonPagedPoolBaseMustSucceed": 2,
|
||||
"DontUseThisType": 3,
|
||||
"NonPagedPoolBaseCacheAligned": 4,
|
||||
"PagedPoolCacheAligned": 5,
|
||||
"NonPagedPoolBaseCacheAlignedMustS": 6,
|
||||
"MaxPoolType": 7,
|
||||
"NonPagedPoolMustSucceedSession": 34,
|
||||
"DontUseThisTypeSession": 35,
|
||||
"NonPagedPoolSession": 32,
|
||||
"NonPagedPoolNx": 512,
|
||||
"NonPagedPoolSessionNx": 544,
|
||||
"NonPagedPoolNxCacheAligned": 516,
|
||||
"PagedPoolSession": 33,
|
||||
"NonPagedPoolCacheAlignedMustSSession": 38,
|
||||
"PagedPoolCacheAlignedSession": 37,
|
||||
"NonPagedPoolCacheAlignedSession": 36
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 8
|
||||
},
|
||||
"unsigned long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "dlassalle-by-hand",
|
||||
"datetime": "2020-04-30T14:30:00.000000"
|
||||
},
|
||||
"format": "6.2.0"
|
||||
},
|
||||
"user_types": {
|
||||
"_POOL_TRACKER_BIG_PAGES": {
|
||||
"fields": {
|
||||
"Va": {
|
||||
"offset": 0,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"Key": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"PoolType": {
|
||||
"offset": 8,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"NumberOfBytes": {
|
||||
"offset": 12,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
}
|
||||
},
|
||||
"symbols": {
|
||||
},
|
||||
"enums": {
|
||||
"_POOL_TYPE": {
|
||||
"base": "unsigned long",
|
||||
"constants": {
|
||||
"NonPagedPoolBase": 0,
|
||||
"PagedPool": 1,
|
||||
"NonPagedPoolBaseMustSucceed": 2,
|
||||
"DontUseThisType": 3,
|
||||
"NonPagedPoolBaseCacheAligned": 4,
|
||||
"PagedPoolCacheAligned": 5,
|
||||
"NonPagedPoolBaseCacheAlignedMustS": 6,
|
||||
"MaxPoolType": 7,
|
||||
"NonPagedPoolMustSucceedSession": 34,
|
||||
"DontUseThisTypeSession": 35,
|
||||
"NonPagedPoolSession": 32,
|
||||
"NonPagedPoolNx": 512,
|
||||
"NonPagedPoolSessionNx": 544,
|
||||
"NonPagedPoolNxCacheAligned": 516,
|
||||
"PagedPoolSession": 33,
|
||||
"NonPagedPoolCacheAlignedMustSSession": 38,
|
||||
"PagedPoolCacheAlignedSession": 37,
|
||||
"NonPagedPoolCacheAlignedSession": 36
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
{
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "dlassalle-by-hand",
|
||||
"datetime": "2020-04-30T14:30:00.000000"
|
||||
},
|
||||
"format": "6.2.0"
|
||||
},
|
||||
"user_types": {
|
||||
"_POOL_TRACKER_BIG_PAGES": {
|
||||
"fields": {
|
||||
"Va": {
|
||||
"offset": 0,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long long"
|
||||
}
|
||||
},
|
||||
"Key": {
|
||||
"offset": 8,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"Pattern": {
|
||||
"offset": 12,
|
||||
"type": {
|
||||
"bit_length": 8,
|
||||
"bit_position": 0,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PoolType": {
|
||||
"offset": 12,
|
||||
"type": {
|
||||
"bit_length": 8,
|
||||
"bit_position": 8,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "_POOL_TYPE"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SlushSize": {
|
||||
"offset": 12,
|
||||
"type": {
|
||||
"bit_length": 12,
|
||||
"bit_position": 20,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NumberOfBytes": {
|
||||
"offset": 16,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 24
|
||||
}
|
||||
},
|
||||
"symbols": {
|
||||
},
|
||||
"enums": {
|
||||
"_POOL_TYPE": {
|
||||
"base": "unsigned long",
|
||||
"constants": {
|
||||
"NonPagedPoolBase": 0,
|
||||
"PagedPool": 1,
|
||||
"NonPagedPoolBaseMustSucceed": 2,
|
||||
"DontUseThisType": 3,
|
||||
"NonPagedPoolBaseCacheAligned": 4,
|
||||
"PagedPoolCacheAligned": 5,
|
||||
"NonPagedPoolBaseCacheAlignedMustS": 6,
|
||||
"MaxPoolType": 7,
|
||||
"NonPagedPoolMustSucceedSession": 34,
|
||||
"DontUseThisTypeSession": 35,
|
||||
"NonPagedPoolSession": 32,
|
||||
"NonPagedPoolNx": 512,
|
||||
"NonPagedPoolSessionNx": 544,
|
||||
"NonPagedPoolNxCacheAligned": 516,
|
||||
"PagedPoolSession": 33,
|
||||
"NonPagedPoolCacheAlignedMustSSession": 38,
|
||||
"PagedPoolCacheAlignedSession": 37,
|
||||
"NonPagedPoolCacheAlignedSession": 36
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 8
|
||||
},
|
||||
"unsigned long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 4
|
||||
},
|
||||
"unsigned char": {
|
||||
"endian": "little",
|
||||
"kind": "char",
|
||||
"signed": false,
|
||||
"size": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "dlassalle-by-hand",
|
||||
"datetime": "2020-04-30T14:30:00.000000"
|
||||
},
|
||||
"format": "6.2.0"
|
||||
},
|
||||
"user_types": {
|
||||
"_POOL_TRACKER_BIG_PAGES": {
|
||||
"fields": {
|
||||
"Va": {
|
||||
"offset": 0,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"Key": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"Pattern": {
|
||||
"offset": 8,
|
||||
"type": {
|
||||
"bit_length": 8,
|
||||
"bit_position": 0,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PoolType": {
|
||||
"offset": 8,
|
||||
"type": {
|
||||
"bit_length": 8,
|
||||
"bit_position": 8,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"name": "_POOL_TYPE"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SlushSize": {
|
||||
"offset": 8,
|
||||
"type": {
|
||||
"bit_length": 12,
|
||||
"bit_position": 20,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NumberOfBytes": {
|
||||
"offset": 12,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
}
|
||||
},
|
||||
"symbols": {
|
||||
},
|
||||
"enums": {
|
||||
"_POOL_TYPE": {
|
||||
"base": "unsigned long",
|
||||
"constants": {
|
||||
"NonPagedPoolBase": 0,
|
||||
"PagedPool": 1,
|
||||
"NonPagedPoolBaseMustSucceed": 2,
|
||||
"DontUseThisType": 3,
|
||||
"NonPagedPoolBaseCacheAligned": 4,
|
||||
"PagedPoolCacheAligned": 5,
|
||||
"NonPagedPoolBaseCacheAlignedMustS": 6,
|
||||
"MaxPoolType": 7,
|
||||
"NonPagedPoolMustSucceedSession": 34,
|
||||
"DontUseThisTypeSession": 35,
|
||||
"NonPagedPoolSession": 32,
|
||||
"NonPagedPoolNx": 512,
|
||||
"NonPagedPoolSessionNx": 544,
|
||||
"NonPagedPoolNxCacheAligned": 516,
|
||||
"PagedPoolSession": 33,
|
||||
"NonPagedPoolCacheAlignedMustSSession": 38,
|
||||
"PagedPoolCacheAlignedSession": 37,
|
||||
"NonPagedPoolCacheAlignedSession": 36
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "dlassalle-by-hand",
|
||||
"datetime": "2020-04-30T14:30:00.000000"
|
||||
},
|
||||
"format": "6.2.0"
|
||||
},
|
||||
"user_types": {
|
||||
"_POOL_TRACKER_BIG_PAGES": {
|
||||
"fields": {
|
||||
"Va": {
|
||||
"offset": 0,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long long"
|
||||
}
|
||||
},
|
||||
"Key": {
|
||||
"offset": 8,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 12
|
||||
}
|
||||
},
|
||||
"symbols": {
|
||||
},
|
||||
"enums": {
|
||||
"_POOL_TYPE": {
|
||||
"base": "unsigned long",
|
||||
"constants": {
|
||||
"NonPagedPool": 0,
|
||||
"PagedPool": 1,
|
||||
"NonPagedPoolMustSucceed": 2,
|
||||
"DontUseThisType": 3,
|
||||
"NonPagedPoolCacheAligned": 4,
|
||||
"PagedPoolAligned": 5,
|
||||
"NonPagedPoolCacheAlignedMustS": 6,
|
||||
"MaxPoolType": 7,
|
||||
"NonPagedPoolMustSucceedSession": 34,
|
||||
"DontUseThisTypeSession": 35,
|
||||
"NonPagedPoolSession": 32,
|
||||
"PagedPoolSession": 33,
|
||||
"NonPagedPoolCacheAlignedMustSSession": 38,
|
||||
"PagedPoolCacheAlignedSession": 37,
|
||||
"NonPagedPoolCacheAlignedSession": 36
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 8
|
||||
},
|
||||
"unsigned long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"metadata": {
|
||||
"producer": {
|
||||
"version": "0.0.1",
|
||||
"name": "dlassalle-by-hand",
|
||||
"datetime": "2020-04-30T14:30:00.000000"
|
||||
},
|
||||
"format": "6.2.0"
|
||||
},
|
||||
"user_types": {
|
||||
"_POOL_TRACKER_BIG_PAGES": {
|
||||
"fields": {
|
||||
"Va": {
|
||||
"offset": 0,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"Key": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 8
|
||||
}
|
||||
},
|
||||
"symbols": {
|
||||
},
|
||||
"enums": {
|
||||
"_POOL_TYPE": {
|
||||
"base": "unsigned long",
|
||||
"constants": {
|
||||
"NonPagedPool": 0,
|
||||
"PagedPool": 1,
|
||||
"NonPagedPoolMustSucceed": 2,
|
||||
"DontUseThisType": 3,
|
||||
"NonPagedPoolCacheAligned": 4,
|
||||
"PagedPoolAligned": 5,
|
||||
"NonPagedPoolCacheAlignedMustS": 6,
|
||||
"MaxPoolType": 7,
|
||||
"NonPagedPoolMustSucceedSession": 34,
|
||||
"DontUseThisTypeSession": 35,
|
||||
"NonPagedPoolSession": 32,
|
||||
"PagedPoolSession": 33,
|
||||
"NonPagedPoolCacheAlignedMustSSession": 38,
|
||||
"PagedPoolCacheAlignedSession": 37,
|
||||
"NonPagedPoolCacheAlignedSession": 36
|
||||
},
|
||||
"size": 4
|
||||
}
|
||||
},
|
||||
"base_types": {
|
||||
"unsigned long": {
|
||||
"endian": "little",
|
||||
"kind": "int",
|
||||
"signed": false,
|
||||
"size": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import functools
|
||||
import struct
|
||||
from typing import Optional, Tuple, List, Dict
|
||||
from typing import Optional, Tuple, List, Dict, Union
|
||||
|
||||
from volatility.framework import objects, interfaces, constants, symbols, exceptions
|
||||
from volatility.framework import objects, interfaces, constants, symbols, exceptions, renderers
|
||||
from volatility.framework.renderers import conversion
|
||||
|
||||
|
||||
@@ -166,6 +166,50 @@ class POOL_HEADER(objects.StructType):
|
||||
return headers, sizes
|
||||
|
||||
|
||||
class POOL_TRACKER_BIG_PAGES(objects.StructType):
|
||||
"""A kernel big page pool tracker."""
|
||||
|
||||
pool_type_lookup = {}
|
||||
|
||||
def _generate_pool_type_lookup(self):
|
||||
# Enumeration._generate_inverse_choices() raises ValueError because multiple enum names map to the same
|
||||
# value in the kernel _POOL_TYPE so create a custom mapping here and take the first match
|
||||
symbol_table_name = self.vol.type_name.split(constants.BANG)[0]
|
||||
pool_type_enum = self._context.symbol_space.get_enumeration(symbol_table_name + constants.BANG + "_POOL_TYPE")
|
||||
for k, v in pool_type_enum.choices.items():
|
||||
if v not in self.pool_type_lookup:
|
||||
self.pool_type_lookup[v] = k
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
return self.Key > 0
|
||||
# return self.Va > 0x1
|
||||
|
||||
def get_key(self) -> str:
|
||||
"""Returns the Key value as a 4 character string"""
|
||||
tag_bytes = objects.convert_value_to_data(self.Key,
|
||||
int,
|
||||
objects.DataFormatInfo(4, "little", False))
|
||||
return "".join([chr(x) if 32 < x < 127 else '' for x in tag_bytes])
|
||||
|
||||
def get_pool_type(self) -> Union[str, interfaces.renderers.BaseAbsentValue]:
|
||||
"""Returns the enum name for the PoolType value on applicable systems"""
|
||||
# Not applicable until Vista
|
||||
if hasattr(self, 'PoolType'):
|
||||
if not self.pool_type_lookup:
|
||||
self._generate_pool_type_lookup()
|
||||
return self.pool_type_lookup.get(self.PoolType, "Unknown choice {}".format(self.PoolType))
|
||||
else:
|
||||
return renderers.NotApplicableValue()
|
||||
|
||||
def get_number_of_bytes(self) -> Union[int, interfaces.renderers.BaseAbsentValue]:
|
||||
"""Returns the NumberOfBytes value on applicable systems"""
|
||||
# Not applicable until Vista
|
||||
try:
|
||||
return self.NumberOfBytes
|
||||
except AttributeError:
|
||||
return renderers.NotApplicableValue()
|
||||
|
||||
|
||||
class ExecutiveObject(interfaces.objects.ObjectInterface):
|
||||
"""This is used as a "mixin" that provides all kernel executive objects
|
||||
with a means of finding their own object header."""
|
||||
|
||||
Reference in New Issue
Block a user