diff --git a/volatility/framework/layers/crash.py b/volatility/framework/layers/crash.py index 68abc0937..ece32f22e 100644 --- a/volatility/framework/layers/crash.py +++ b/volatility/framework/layers/crash.py @@ -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(' 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 diff --git a/volatility/framework/symbols/windows/crash.json b/volatility/framework/symbols/windows/crash.json index d27d4a27e..026a0c9ca 100644 --- a/volatility/framework/symbols/windows/crash.json +++ b/volatility/framework/symbols/windows/crash.json @@ -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, diff --git a/volatility/framework/symbols/windows/crash64.json b/volatility/framework/symbols/windows/crash64.json new file mode 100644 index 000000000..445992d00 --- /dev/null +++ b/volatility/framework/symbols/windows/crash64.json @@ -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" + } +}