sync with fa1c03d of jxwegner/volatility3

This commit is contained in:
iMHLv2
2021-03-30 15:27:09 -05:00
parent f3c3e2c4f9
commit f4dee3c5f0
2 changed files with 70 additions and 23 deletions
+37 -23
View File
@@ -1,14 +1,15 @@
# This file is Copyright 2019 Volatility Foundation and licensed under the Volatility Software License 1.0
# This file is Copyright 2021 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
import struct
from typing import Tuple, Optional
from typing import Tuple, Optional, Iterable
from volatility3.framework import constants, exceptions, interfaces
from volatility3.framework.layers import segmented
from volatility3.framework.symbols import intermed
from volatility.framework import constants, exceptions, interfaces
from volatility.framework.layers import segmented
from volatility.framework.symbols import intermed
vollog = logging.getLogger(__name__)
@@ -19,7 +20,6 @@ class WindowsCrashDumpFormatException(exceptions.LayerException):
class WindowsCrashDump32Layer(segmented.SegmentedLayer):
"""A Windows crash format TranslationLayer.
This TranslationLayer supports Microsoft complete memory dump files.
It currently does not support kernel or small memory dump files.
"""
@@ -42,7 +42,11 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
self._context = context
self._config_path = config_path
self._page_size = 0x1000
self._base_layer = self.config["base_layer"]
try:
self._base_layer = self.config["base_layer"]
except KeyError:
self._base_layer = 'base_layer'
self.config['base_layer']='base_layer'
# Create a custom SymbolSpace
self._crash_table_name = intermed.IntermediateSymbolTable.create(context, self._config_path, 'windows',
@@ -71,30 +75,34 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
def _load_segments(self) -> None:
"""Loads up the segments from the meta_layer."""
header = self.context.object(self._crash_table_name + constants.BANG + self.dump_header_name,
offset = 0,
layer_name = self._base_layer)
segments = []
offset = self.headerpages
header = self.context.object(self._crash_table_name + constants.BANG + self.dump_header_name,
offset = 0,
layer_name = self._base_layer)
offset = self.headerpages
header.PhysicalMemoryBlockBuffer.Run.count = header.PhysicalMemoryBlockBuffer.NumberOfRuns
for x in header.PhysicalMemoryBlockBuffer.Run:
segments.append((x.BasePage * 0x1000, offset * 0x1000, x.PageCount * 0x1000, x.PageCount * 0x1000))
# print("Segments {:x} {:x} {:x}".format(x.BasePage * 0x1000,
# offset * 0x1000,
# x.PageCount * 0x1000))
# print("Segments {:x} {:x} {:x}".format(x.BasePage * 0x1000,
# offset * 0x1000,
# x.PageCount * 0x1000))
offset += x.PageCount
if len(segments) == 0:
raise WindowsCrashDumpFormatException(self.name, "No Crash segments defined in {}".format(self._base_layer))
self._segments = segments
@classmethod
def check_header(cls, base_layer: interfaces.layers.DataLayerInterface, offset: int = 0) -> Tuple[int, int]:
# Verify the Window's crash dump file magic
try:
header_data = base_layer.read(offset, cls._magic_struct.size)
except exceptions.InvalidAddressException:
@@ -114,7 +122,6 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
class WindowsCrashDump64Layer(WindowsCrashDump32Layer):
"""A Windows crash format TranslationLayer.
This TranslationLayer supports Microsoft complete memory dump files.
It currently does not support kernel or small memory dump files.
"""
@@ -133,7 +140,6 @@ class WindowsCrashDump64Layer(WindowsCrashDump32Layer):
summary_header = self.context.object(self._crash_table_name + constants.BANG + "_SUMMARY_DUMP64",
offset = 0x2000,
layer_name = self._base_layer)
if self.dump_type == 0x1:
header = self.context.object(self._crash_table_name + constants.BANG + self.dump_header_name,
offset = 0,
@@ -146,16 +152,19 @@ class WindowsCrashDump64Layer(WindowsCrashDump32Layer):
offset += x.PageCount
elif self.dump_type == 0x05:
summary_header.BufferLong.count = (summary_header.BitmapSize + 31) // 32
#Add 0x2000 as some bitmaps are too short by one offset
summary_header.BufferLong.count = (summary_header.BitmapSize + 31) // 32 + 0x2000
previous_bit = 0
start_position = 0
# We cast as an int because we don't want to carry the context around with us for infinite loop reasons
mapped_offset = int(summary_header.HeaderSize)
current_word = None
for bit_position in range(len(summary_header.BufferLong) * 32):
bitmap_len=len(summary_header.BufferLong) * 32
for bit_position in range(bitmap_len):
if (bit_position % 32) == 0:
current_word = summary_header.BufferLong[bit_position // 32]
current_bit = (current_word >> (bit_position % 32)) & 1
if current_bit != previous_bit:
if previous_bit == 0:
# Start
@@ -166,11 +175,15 @@ class WindowsCrashDump64Layer(WindowsCrashDump32Layer):
segments.append((start_position * 0x1000, mapped_offset, length, length))
mapped_offset += length
# Finish it off
if bit_position == (len(summary_header.BufferLong) * 32) - 1 and current_bit == 1:
# Find the last segment in a file which will be at the end or two pages from the end. We multiply by 32 as we want to offset bby words rather than bits
if (bit_position == bitmap_len - 1 or bit_position == bitmap_len - 1 -32*0x2000) and current_bit == 1:
length = (bit_position - start_position) * 0x1000
segments.append((start_position * 0x1000, mapped_offset, length, length))
mapped_offset += length
break
previous_bit = current_bit
else:
@@ -179,7 +192,7 @@ class WindowsCrashDump64Layer(WindowsCrashDump32Layer):
if len(segments) == 0:
raise WindowsCrashDumpFormatException(self.name, "No Crash segments defined in {}".format(self._base_layer))
self._segments = segments
@@ -200,3 +213,4 @@ class WindowsCrashDumpStacker(interfaces.automagic.StackerLayerInterface):
except WindowsCrashDumpFormatException:
pass
return None
@@ -0,0 +1,33 @@
# This file is Copyright 2021 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 volatility.framework import interfaces, renderers
from volatility.framework.configuration import requirements
from volatility.framework.layers import crash
from volatility.framework import exceptions
vollog = logging.getLogger(__name__)
class Crashinfo(interfaces.plugins.PluginInterface):
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
]
def _generator(self, layer):
for offset, length, mapped_offset in layer.mapping(0x0, layer.maximum_address, ignore_errors = True):
yield(0,(offset,length,mapped_offset))
def run(self):
layer = self._context.layers[self.config['primary.memory_layer']]
return renderers.TreeGrid([("StartAddress", int),("FileOffset", int),("Length", int)],self._generator(layer))