Layers: Initial crashdump64 implementation

This commit is contained in:
Mike Auty
2020-09-23 20:28:23 +01:00
committed by ikelos
parent 8baf13d3e3
commit 31e251e108
3 changed files with 586 additions and 42 deletions
+87 -24
View File
@@ -10,7 +10,7 @@ from volatility.framework.layers import segmented
from volatility.framework.symbols import intermed
class WindowsCrashDump32FormatException(exceptions.LayerException):
class WindowsCrashDumpFormatException(exceptions.LayerException):
"""Thrown when an error occurs with the underlying Crash file format."""
@@ -25,6 +25,11 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
SIGNATURE = 0x45474150
VALIDDUMP = 0x504d5544
crashdump_json = 'crash'
supported_dumptypes = [0x01]
dump_header_name = '_DUMP_HEADER'
_magic_struct = struct.Struct('<II')
headerpages = 1
@@ -37,14 +42,15 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
self._base_layer = self.config["base_layer"]
# Create a custom SymbolSpace
self._crash_table_name = intermed.IntermediateSymbolTable.create(context, self._config_path, 'windows', 'crash')
self._crash_table_name = intermed.IntermediateSymbolTable.create(context, self._config_path, 'windows',
self.crashdump_json)
# Check Header
hdr_layer = self._context.layers[self._base_layer]
hdr_offset = 0
self._check_header(hdr_layer, hdr_offset)
self.check_header(hdr_layer, hdr_offset)
# Need to create a header object
self.header = self.context.object(self._crash_table_name + constants.BANG + "_DMP_HEADER",
self.header = self.context.object(self._crash_table_name + constants.BANG + self.dump_header_name,
offset = hdr_offset,
layer_name = self._base_layer)
@@ -52,9 +58,9 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
self.dtb = self.header.DirectoryTableBase
# Verify that it is a supported format
if self.header.DumpType != 0x1:
raise WindowsCrashDump32FormatException(self.name,
"unsupported dump format 0x{:x}".format(self.header.DumpType))
if self.header.DumpType not in self.supported_dumptypes:
raise WindowsCrashDumpFormatException(self.name,
"unsupported dump format 0x{:x}".format(self.header.DumpType))
super().__init__(context, config_path, name)
@@ -73,33 +79,88 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
offset += x.PageCount
if len(segments) == 0:
raise WindowsCrashDump32FormatException(self.name,
"No Crash segments defined in {}".format(self._base_layer))
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]:
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:
raise WindowsCrashDump32FormatException(base_layer.name,
"Crashdump header not found at offset {}".format(offset))
raise WindowsCrashDumpFormatException(base_layer.name,
"Crashdump header not found at offset {}".format(offset))
(signature, validdump) = cls._magic_struct.unpack(header_data)
if signature != cls.SIGNATURE:
raise WindowsCrashDump32FormatException(
raise WindowsCrashDumpFormatException(
base_layer.name, "Bad signature 0x{:x} at file offset 0x{:x}".format(signature, offset))
if validdump != cls.VALIDDUMP:
raise WindowsCrashDump32FormatException(
raise WindowsCrashDumpFormatException(
base_layer.name, "Invalid dump 0x{:x} at file offset 0x{:x}".format(validdump, offset))
return (signature, validdump)
return signature, validdump
class WindowsCrashDump32Stacker(interfaces.automagic.StackerLayerInterface):
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.
"""
VALIDDUMP = 0x34365544
crashdump_json = 'crash64'
dump_header_name = '_DUMP_HEADER64'
supported_dumptypes = [0x05]
def _load_segments(self) -> None:
"""Loads up the segments from the meta_layer."""
segments = []
summary_header = self.context.object(self._crash_table_name + constants.BANG + "_SUMMARY_DUMP64",
offset = 0x2000,
layer_name = self._base_layer)
summary_header.BufferLong.count = (summary_header.BitmapSize + 31) // 32
previous_bit = 0
start_position = 0
mapped_offset = summary_header.HeaderSize
current_word = None
for bit_position in range(len(summary_header.BufferLong) * 32):
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
start_position = bit_position
else:
# Finish
length = (bit_position - start_position) * 0x1000
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:
length = (bit_position - start_position) * 0x1000
segments.append((start_position * 0x1000, mapped_offset, length, length))
mapped_offset += length
previous_bit = current_bit
if len(segments) == 0:
raise WindowsCrashDumpFormatException(self.name,
"No Crash segments defined in {}".format(self._base_layer))
self._segments = segments
class WindowsCrashDumpStacker(interfaces.automagic.StackerLayerInterface):
stack_order = 11
@classmethod
@@ -107,10 +168,12 @@ class WindowsCrashDump32Stacker(interfaces.automagic.StackerLayerInterface):
context: interfaces.context.ContextInterface,
layer_name: str,
progress_callback: constants.ProgressCallback = None) -> Optional[interfaces.layers.DataLayerInterface]:
try:
WindowsCrashDump32Layer._check_header(context.layers[layer_name])
except WindowsCrashDump32FormatException:
return None
new_name = context.layers.free_layer_name("WindowsCrashDump32Layer")
context.config[interfaces.configuration.path_join(new_name, "base_layer")] = layer_name
return WindowsCrashDump32Layer(context, new_name, new_name)
for layer in [WindowsCrashDump32Layer, WindowsCrashDump64Layer]:
try:
layer.check_header(context.layers[layer_name])
new_name = context.layers.free_layer_name(layer.__name__)
context.config[interfaces.configuration.path_join(new_name, "base_layer")] = layer_name
return layer(context, new_name, new_name)
except WindowsCrashDumpFormatException:
pass
return None
+18 -18
View File
@@ -2,7 +2,7 @@
"symbols": {
},
"user_types": {
"_DMP_HEADER": {
"_DUMP_HEADER": {
"fields": {
"Signature": {
"offset": 0,
@@ -14,7 +14,7 @@
"name": "unsigned char"
}
}
},
},
"ValidDump": {
"offset": 4,
"type": {
@@ -56,35 +56,35 @@
},
"PsLoadedModuleList": {
"offset": 24,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"PsActiveProcessHead": {
"offset": 28,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"MachineImageType": {
"offset": 32,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"NumberProcessors": {
"offset": 36,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"BugCheckCode": {
"offset": 40,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
@@ -124,7 +124,7 @@
"kind": "base",
"name": "unsigned char"
}
},
},
"VersionUser2": {
"offset": 94,
"type": {
@@ -135,7 +135,7 @@
"name": "unsigned char"
}
}
},
},
"KdDebuggerDataBlock": {
"offset": 96,
"type": {
@@ -170,7 +170,7 @@
},
"Comment": {
"offset": 2080,
"type": {
"type": {
"count": 128,
"kind": "array",
"subtype": {
@@ -202,42 +202,42 @@
},
"ProductType": {
"offset": 3988,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"SuiteMask": {
"offset": 3992,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"WriterStatus": {
"offset": 3996,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"RequiredDumpSpace": {
"offset": 4000,
"type": {
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"SystemUpTime": {
"offset": 4024,
"type": {
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"SystemTime": {
"offset": 4032,
"type": {
"type": {
"kind": "base",
"name": "unsigned long long"
}
@@ -275,10 +275,10 @@
},
"ExceptionRecord": {
"offset": 8,
"type": {
"type": {
"kind": "base",
"name": "unsigned long"
}
}
},
"ExceptionAddress": {
"offset": 12,
@@ -0,0 +1,481 @@
{
"symbols": {
},
"user_types": {
"_DUMP_HEADER64": {
"fields": {
"Signature": {
"offset": 0,
"type": {
"count": 4,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned char"
}
}
},
"ValidDump": {
"offset": 4,
"type": {
"count": 4,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned char"
}
}
},
"MajorVersion": {
"offset": 8,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"MinorVersion": {
"offset": 12,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"DirectoryTableBase": {
"offset": 16,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"PfnDataBase": {
"offset": 24,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"PsLoadedModuleList": {
"offset": 32,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"PsActiveProcessHead": {
"offset": 40,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"MachineImageType": {
"offset": 44,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"NumberProcessors": {
"offset": 48,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"BugCheckCode": {
"offset": 60,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"BugCheckCodeParameter": {
"offset": 64,
"type": {
"count": 4,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned long long"
}
}
},
"VersionUser": {
"offset": 96,
"type": {
"count": 32,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned char"
}
}
},
"KdDebuggerDataBlock": {
"offset": 128,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"PhysicalMemoryBlockBuffer": {
"offset": 136,
"type": {
"kind": "struct",
"name": "_PHYSICAL_MEMORY_DESCRIPTOR64"
}
},
"ContextRecord": {
"offset": 840,
"type": {
"count": 3000,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned char"
}
}
},
"Exception": {
"offset": 3840,
"type": {
"kind": "struct",
"name": "_EXCEPTION_RECORD64"
}
},
"DumpType": {
"offset": 3992,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"RequiredDumpSpace": {
"offset": 4000,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"SystemUpTime": {
"offset": 4008,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"Comment": {
"offset": 4016,
"type": {
"count": 128,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned char"
}
}
},
"SystemTime": {
"offset": 4144,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"MiniDumpFields": {
"offset": 4152,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"SecondaryDataState": {
"offset": 4156,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"ProductType": {
"offset": 4160,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"SuiteMask": {
"offset": 4164,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"WriterStatus": {
"offset": 4168,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"Unused1": {
"offset": 4172,
"type": {
"kind": "base",
"name": "unsigned char"
}
},
"KdSecondaryVersion": {
"offset": 4173,
"type": {
"kind": "base",
"name": "unsigned char"
}
},
"Unused2": {
"offset": 4174,
"type": {
"kind": "base",
"name": "unsigned char"
}
}
},
"kind": "struct",
"size": 8192
},
"_SUMMARY_DUMP64": {
"fields": {
"Signature": {
"offset": 0,
"type": {
"count": 4,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned char"
}
}
},
"ValidDump": {
"offset": 4,
"type": {
"count": 4,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned char"
}
}
},
"DumpOptions": {
"offset": 8,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"HeaderSize": {
"offset": 32,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"BitmapSize": {
"offset": 40,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"Pages": {
"offset": 48,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"BufferLong": {
"offset": 56,
"type": {
"kind": "array",
"count": 1,
"subtype": {
"kind": "base",
"name": "unsigned long"
}
}
},
"BufferChar": {
"offset": 56,
"type": {
"kind": "array",
"count": 1,
"subtype": {
"kind": "base",
"name": "unsigned char"
}
}
}
},
"kind": "struct",
"size": 56
},
"_EXCEPTION_RECORD64": {
"fields": {
"ExceptionCode": {
"offset": 0,
"type": {
"kind": "base",
"name": "long"
}
},
"ExceptionFlags": {
"offset": 4,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"ExceptionRecord": {
"offset": 8,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"ExceptionAddress": {
"offset": 16,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"NumberParameters": {
"offset": 24,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"ExceptionInformation": {
"offset": 32,
"type": {
"count": 15,
"kind": "array",
"subtype": {
"kind": "base",
"name": "unsigned long long"
}
}
}
},
"kind": "struct",
"size": 152
},
"_PHYSICAL_MEMORY_DESCRIPTOR64": {
"fields": {
"NumberOfPages": {
"offset": 4,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"NumberOfRuns": {
"offset": 0,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"Run": {
"offset": 12,
"type": {
"count": 1,
"kind": "array",
"subtype": {
"kind": "struct",
"name": "_PHYSICAL_MEMORY_RUN64"
}
}
}
},
"kind": "struct",
"size": 20
},
"_PHYSICAL_MEMORY_RUN64": {
"fields": {
"BasePage": {
"offset": 0,
"type": {
"kind": "base",
"name": "unsigned long long"
}
},
"PageCount": {
"offset": 8,
"type": {
"kind": "base",
"name": "unsigned long long"
}
}
},
"kind": "struct",
"size": 16
}
},
"enums": {
},
"base_types": {
"unsigned char": {
"endian": "little",
"kind": "char",
"signed": false,
"size": 1
},
"unsigned short": {
"endian": "little",
"kind": "int",
"signed": false,
"size": 2
},
"long": {
"endian": "little",
"kind": "int",
"signed": true,
"size": 4
},
"char": {
"endian": "little",
"kind": "char",
"signed": true,
"size": 1
},
"unsigned long": {
"endian": "little",
"kind": "int",
"signed": false,
"size": 4
},
"long long": {
"endian": "little",
"kind": "int",
"signed": true,
"size": 8
},
"unsigned long long": {
"endian": "little",
"kind": "int",
"signed": false,
"size": 8
}
},
"metadata": {
"producer": {
"version": "0.0.1",
"name": "ikelos-by-hand",
"datetime": "2020-09-10T00:20:00"
},
"format": "6.2.0"
}
}