Automagic: Remove unused old code

This commit is contained in:
Mike Auty
2021-09-02 23:01:26 +01:00
parent 4b56ee4c73
commit d17ad710f2
+1 -209
View File
@@ -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