mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-06 17:57:38 +02:00
Automagic: Remove unused old code
This commit is contained in:
@@ -37,141 +37,6 @@ from volatility3.framework.layers import intel
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# class DtbTest:
|
||||
# """This class generically contains the tests for a page based on a set of
|
||||
# class parameters.
|
||||
#
|
||||
# When constructed it contains all the information necessary to
|
||||
# extract a specific index from a page and determine whether it points
|
||||
# back to that page's offset.
|
||||
# """
|
||||
#
|
||||
# def __init__(self, layer_type: Type[layers.intel.Intel], ptr_struct: str, ptr_reference: List[int],
|
||||
# mask: int) -> None:
|
||||
# self.layer_type = layer_type
|
||||
# self.ptr_struct = ptr_struct
|
||||
# self.ptr_size = struct.calcsize(ptr_struct)
|
||||
# self.ptr_reference = ptr_reference
|
||||
# self.mask = mask
|
||||
# self.page_size: int = layer_type.page_size
|
||||
#
|
||||
# def _unpack(self, value: bytes) -> int:
|
||||
# return struct.unpack("<" + self.ptr_struct, value)[0]
|
||||
#
|
||||
# def __call__(self, data: bytes, data_offset: int, page_offset: int) -> Optional[Tuple[int, Any]]:
|
||||
# """Tests a specific page in a chunk of data to see if it contains a
|
||||
# self-referential pointer.
|
||||
#
|
||||
# Args:
|
||||
# data: The chunk of data that contains the page to be scanned
|
||||
# data_offset: Where, within the layer, the chunk of data lives
|
||||
# page_offset: Where, within the data, the page to be scanned starts
|
||||
#
|
||||
# Returns:
|
||||
# A valid DTB within this page (and an additional parameter for data)
|
||||
# """
|
||||
# for ptr_reference in self.ptr_reference:
|
||||
# value = data[page_offset + (ptr_reference * self.ptr_size):page_offset +
|
||||
# ((ptr_reference + 1) * self.ptr_size)]
|
||||
# try:
|
||||
# ptr = self._unpack(value)
|
||||
# except struct.error:
|
||||
# return None
|
||||
# # The value *must* be present (bit 0) since it's a mapped page
|
||||
# # It's almost always writable (bit 1)
|
||||
# # It's occasionally Super, but not reliably so, haven't checked when/why not
|
||||
# # The top 3-bits are usually ignore (which in practice means 0
|
||||
# # Need to find out why the middle 3-bits are usually 6 (0110)
|
||||
# if ptr != 0 and (ptr & self.mask == data_offset + page_offset) & (ptr & 0xFF1 == 0x61):
|
||||
# dtb = (ptr & self.mask)
|
||||
# return self.second_pass(dtb, data, data_offset)
|
||||
# return None
|
||||
#
|
||||
# def second_pass(self, dtb: int, data: bytes, data_offset: int) -> Optional[Tuple[int, Any]]:
|
||||
# """Re-reads over the whole page to validate other records based on the
|
||||
# number of pages marked user vs super.
|
||||
#
|
||||
# Args:
|
||||
# dtb: The identified dtb that needs validating
|
||||
# data: The chunk of data that contains the dtb to be validated
|
||||
# data_offset: Where, within the layer, the chunk of data lives
|
||||
#
|
||||
# Returns:
|
||||
# A valid DTB within this page
|
||||
# """
|
||||
# page = data[dtb - data_offset:dtb - data_offset + self.page_size]
|
||||
# usr_count, sup_count = 0, 0
|
||||
# for i in range(0, self.page_size, self.ptr_size):
|
||||
# val = self._unpack(page[i:i + self.ptr_size])
|
||||
# if val & 0x1:
|
||||
# sup_count += 0 if (val & 0x4) else 1
|
||||
# usr_count += 1 if (val & 0x4) else 0
|
||||
# # print(hex(dtb), usr_count, sup_count, usr_count + sup_count)
|
||||
# # We sometimes find bogus DTBs at 0x16000 with a very low sup_count and 0 usr_count
|
||||
# # I have a winxpsp2-x64 image with identical usr/sup counts at 0x16000 and 0x24c00 as well as the actual 0x3c3000
|
||||
# if usr_count or sup_count > 5:
|
||||
# return dtb, None
|
||||
# return None
|
||||
#
|
||||
#
|
||||
# class DtbTest32bit(DtbTest):
|
||||
#
|
||||
# def __init__(self) -> None:
|
||||
# super().__init__(layer_type = layers.intel.WindowsIntel,
|
||||
# ptr_struct = "I",
|
||||
# ptr_reference = [0x300],
|
||||
# mask = 0xFFFFF000)
|
||||
#
|
||||
#
|
||||
# class DtbTest64bit(DtbTest):
|
||||
#
|
||||
# def __init__(self) -> None:
|
||||
# super().__init__(layer_type = layers.intel.WindowsIntel32e,
|
||||
# ptr_struct = "Q",
|
||||
# ptr_reference = range(0x1E0, 0x1FF),
|
||||
# mask = 0x3FFFFFFFFFF000)
|
||||
#
|
||||
# # As of Windows-10 RS1+, the ptr_reference is randomized:
|
||||
# # https://blahcat.github.io/2020/06/15/playing_with_self_reference_pml4_entry/
|
||||
# # So far, we've only seen examples between 0x1e0 and 0x1ff
|
||||
#
|
||||
#
|
||||
# class DtbTestPae(DtbTest):
|
||||
#
|
||||
# def __init__(self) -> None:
|
||||
# super().__init__(layer_type = layers.intel.WindowsIntelPAE,
|
||||
# ptr_struct = "Q",
|
||||
# ptr_reference = [0x3],
|
||||
# mask = 0x3FFFFFFFFFF000)
|
||||
#
|
||||
# def second_pass(self, dtb: int, data: bytes, data_offset: int) -> Optional[Tuple[int, Any]]:
|
||||
# """PAE top level directory tables contains four entries and the self-
|
||||
# referential pointer occurs in the second level of tables (so as not to
|
||||
# use up a full quarter of the space). This is very high in the space,
|
||||
# and occurs in the fourht (last quarter) second-level table. The
|
||||
# second-level tables appear always to come sequentially directly after
|
||||
# the real dtb. The value for the real DTB is therefore four page
|
||||
# earlier (and the fourth entry should point back to the `dtb` parameter
|
||||
# this function was originally passed.
|
||||
#
|
||||
# Args:
|
||||
# dtb: The identified self-referential pointer that needs validating
|
||||
# data: The chunk of data that contains the dtb to be validated
|
||||
# data_offset: Where, within the layer, the chunk of data lives
|
||||
#
|
||||
# Returns:
|
||||
# Returns the actual DTB of the PAE space
|
||||
# """
|
||||
# dtb -= 0x4000
|
||||
# # If we're not in something that the overlap would pick up
|
||||
# if dtb - data_offset >= 0:
|
||||
# pointers = data[dtb - data_offset + (3 * self.ptr_size):dtb - data_offset + (4 * self.ptr_size)]
|
||||
# val = self._unpack(pointers)
|
||||
# if (val & self.mask == dtb + 0x4000) and (val & 0xFFF == 0x001):
|
||||
# return dtb, None
|
||||
# return None
|
||||
#
|
||||
|
||||
class DtbSelfReferential:
|
||||
"""A generic DTB test which looks for a self-referential pointer at *any*
|
||||
index within the page."""
|
||||
@@ -258,63 +123,6 @@ class PageMapScanner(interfaces.layers.ScannerInterface):
|
||||
yield (test, result[0])
|
||||
|
||||
|
||||
# class WintelHelper(interfaces.automagic.AutomagicInterface):
|
||||
# """Windows DTB finder based on self-referential pointers.
|
||||
#
|
||||
# This class adheres to the :class:`~volatility3.framework.interfaces.automagic.AutomagicInterface` interface
|
||||
# and both determines the directory table base of an intel layer if one hasn't been specified, and constructs
|
||||
# the intel layer if necessary (for example when reconstructing a pre-existing configuration).
|
||||
#
|
||||
# It will scan for existing TranslationLayers that do not have a DTB using the :class:`PageMapScanner`
|
||||
# """
|
||||
# priority = 20
|
||||
# tests = [DtbTest64bit(), DtbTest32bit(), DtbTestPae()]
|
||||
#
|
||||
# def __call__(self,
|
||||
# context: interfaces.context.ContextInterface,
|
||||
# config_path: str,
|
||||
# requirement: interfaces.configuration.RequirementInterface,
|
||||
# progress_callback: constants.ProgressCallback = None) -> None:
|
||||
# useful = []
|
||||
# sub_config_path = interfaces.configuration.path_join(config_path, requirement.name)
|
||||
# if (isinstance(requirement, requirements.TranslationLayerRequirement)
|
||||
# and requirement.requirements.get("class", False) and requirement.unsatisfied(context, config_path)):
|
||||
# class_req = requirement.requirements["class"]
|
||||
#
|
||||
# for test in self.tests:
|
||||
# if (test.layer_type.__module__ + "." + test.layer_type.__name__ == class_req.config_value(
|
||||
# context, sub_config_path)):
|
||||
# useful.append(test)
|
||||
#
|
||||
# # Determine if a class has been chosen
|
||||
# # Once an appropriate class has been chosen, attempt to determine the page_map_offset value
|
||||
# if ("memory_layer" in requirement.requirements
|
||||
# and not requirement.requirements["memory_layer"].unsatisfied(context, sub_config_path)):
|
||||
# # Only bother getting the DTB if we don't already have one
|
||||
# page_map_offset_path = interfaces.configuration.path_join(sub_config_path, "page_map_offset")
|
||||
# if not context.config.get(page_map_offset_path, None):
|
||||
# physical_layer_name = requirement.requirements["memory_layer"].config_value(
|
||||
# context, sub_config_path)
|
||||
# if not isinstance(physical_layer_name, str):
|
||||
# raise TypeError(f"Physical layer name is not a string: {sub_config_path}")
|
||||
# physical_layer = context.layers[physical_layer_name]
|
||||
# # Check lower layer metadata first
|
||||
# if physical_layer.metadata.get('page_map_offset', None):
|
||||
# context.config[page_map_offset_path] = physical_layer.metadata['page_map_offset']
|
||||
# else:
|
||||
# hits = physical_layer.scan(context, PageMapScanner(useful), progress_callback)
|
||||
# for test, dtb in hits:
|
||||
# context.config[page_map_offset_path] = dtb
|
||||
# break
|
||||
# else:
|
||||
# return None
|
||||
# if isinstance(requirement, interfaces.configuration.ConstructableRequirementInterface):
|
||||
# requirement.construct(context, config_path)
|
||||
# else:
|
||||
# for subreq in requirement.requirements.values():
|
||||
# self(context, sub_config_path, subreq)
|
||||
|
||||
|
||||
class WindowsIntelStacker(interfaces.automagic.StackerLayerInterface):
|
||||
stack_order = 40
|
||||
exclusion_list = ['mac', 'linux']
|
||||
@@ -362,23 +170,7 @@ class WindowsIntelStacker(interfaces.automagic.StackerLayerInterface):
|
||||
config_path, "page_map_offset")] = base_layer.metadata['page_map_offset']
|
||||
layer = layer_type(context, config_path = config_path, name = new_layer_name, metadata = {'os': 'Windows'})
|
||||
|
||||
# # Check for the self-referential pointer
|
||||
# if layer is None:
|
||||
# hits = base_layer.scan(context, PageMapScanner(), progress_callback = progress_callback)
|
||||
# layer = None
|
||||
# config_path = None
|
||||
# for test, dtb in hits:
|
||||
# new_layer_name = context.layers.free_layer_name("IntelLayer")
|
||||
# config_path = interfaces.configuration.path_join("IntelHelper", new_layer_name)
|
||||
# context.config[interfaces.configuration.path_join(config_path, "memory_layer")] = layer_name
|
||||
# context.config[interfaces.configuration.path_join(config_path, "page_map_offset")] = dtb
|
||||
# layer = test.layer_type(context,
|
||||
# config_path = config_path,
|
||||
# name = new_layer_name,
|
||||
# metadata = {'os': 'Windows'})
|
||||
# break
|
||||
|
||||
# Fall back to a heuristic for finding the Windows DTB
|
||||
# Self Referential finder
|
||||
if layer is None:
|
||||
vollog.debug("Self-referential pointer not in well-known location, moving to recent windows heuristic")
|
||||
# There is a very high chance that the DTB will live in this narrow segment, assuming we couldn't find it previously
|
||||
|
||||
Reference in New Issue
Block a user