diff --git a/volatility3/framework/symbols/windows/pdb.json b/volatility3/framework/symbols/windows/pdb.json index f87b8db9f..eae0d913e 100644 --- a/volatility3/framework/symbols/windows/pdb.json +++ b/volatility3/framework/symbols/windows/pdb.json @@ -812,6 +812,33 @@ "kind": "struct", "size": 10 }, + "LF_BCLASS": { + "fields": { + "field_attributes": { + "offset": 0, + "type": { + "kind": "base", + "name": "unsigned short" + } + }, + "type_index": { + "offset": 2, + "type": { + "kind": "base", + "name": "unsigned long" + } + }, + "bases": { + "offset": 6, + "type": { + "kind": "base", + "name": "unsigned long" + } + } + }, + "kind": "struct", + "size": 10 + }, "LF_BITFIELD": { "fields": { "underlying_type": { @@ -992,6 +1019,112 @@ "kind": "struct", "size": 8 }, + "LF_METHOD": { + "fields": { + "count": { + "offset": 0, + "type": { + "kind": "base", + "name": "unsigned short" + } + }, + "method_list": { + "offset": 2, + "type": { + "kind": "base", + "name": "unsigned long" + } + }, + "name": { + "offset": 6, + "type": { + "kind": "base", + "name": "string" + } + } + }, + "kind": "struct", + "size": 7 + }, + "LF_METHODLIST": { + "fields": { + "mlist": { + "offset": 0, + "type": { + "kind": "array", + "count": 1, + "subtype": { + "kind": "base", + "name": "unsigned long" + } + } + } + }, + "kind": "struct", + "size": 4 + }, + "LF_MFUNCTION": { + "fields": { + "return_type": { + "offset": 0, + "type": { + "kind": "base", + "name": "unsigned long" + } + }, + "class_type": { + "offset": 4, + "type": { + "kind": "base", + "name": "unsigned long" + } + }, + "this_type": { + "offset": 8, + "type": { + "kind": "base", + "name": "unsigned long" + } + }, + "calling_convention": { + "offset": 12, + "type": { + "kind": "base", + "name": "unsigned char" + } + }, + "attributes": { + "offset": 13, + "type": { + "kind": "base", + "name": "unsigned short" + } + }, + "num_params": { + "offset": 15, + "type": { + "kind": "base", + "name": "unsigned short" + } + }, + "arglist": { + "offset": 17, + "type": { + "kind": "base", + "name": "unsigned long" + } + }, + "adjuster": { + "offset": 21, + "type": { + "kind": "base", + "name": "unsigned long" + } + } + }, + "kind": "struct", + "size": 25 + }, "LF_MODIFIER": { "fields": { "subtype_index": { @@ -1041,6 +1174,26 @@ "kind": "struct", "size": 6 }, + "LF_NESTTYPE": { + "fields": { + "subtype_index": { + "offset": 2, + "type": { + "kind": "base", + "name": "unsigned long" + } + }, + "name": { + "offset": 6, + "type": { + "kind": "base", + "name": "string" + } + } + }, + "kind": "struct", + "size": 10 + }, "LF_POINTER": { "fields": { "subtype_index": { diff --git a/volatility3/framework/symbols/windows/pdbconv.py b/volatility3/framework/symbols/windows/pdbconv.py index b48e8268c..d926e4cd3 100644 --- a/volatility3/framework/symbols/windows/pdbconv.py +++ b/volatility3/framework/symbols/windows/pdbconv.py @@ -363,6 +363,7 @@ class PdbReader: except ValueError: return None + def _read_info_stream(self, stream_number, stream_name, info_list): vollog.debug(f"Reading {stream_name}") info_layer = self._context.layers.get(self._layer_name + "_stream" + str(stream_number), None) @@ -656,7 +657,7 @@ class PdbReader: result = value.size elif leaf_type in [leaf_type.LF_ARRAY, leaf_type.LF_ARRAY_ST, leaf_type.LF_STRIDED_ARRAY]: result = value.size - elif leaf_type in [leaf_type.LF_MODIFIER, leaf_type.LF_ENUM, leaf_type.LF_ARGLIST]: + elif leaf_type in [leaf_type.LF_MODIFIER, leaf_type.LF_ENUM, leaf_type.LF_ARGLIST, leaf_type.LF_NESTTYPE]: result = self.get_size_from_index(value.subtype_index) elif leaf_type in [leaf_type.LF_MEMBER]: result = self.get_size_from_index(value.field_type) @@ -755,7 +756,12 @@ class PdbReader: 'LF_BITFIELD': ('LF_BITFIELD', False, None), 'LF_UDT_SRC_LINE': ('LF_UDT_SRC_LINE', False, None), 'LF_UDT_MOD_SRC_LINE': ('LF_UDT_MOD_SRC_LINE', False, None), - 'LF_BUILDINFO': ('LF_BUILDINFO', False, None) + 'LF_BUILDINFO': ('LF_BUILDINFO', False, None), + 'LF_NESTTYPE': ('LF_NESTTYPE', True, None), + 'LF_BCLASS': ('LF_BCLASS', False, None), + 'LF_METHOD': ('LF_METHOD', True, None), + 'LF_METHODLIST': ('LF_METHODLIST', False, None), + 'LF_MFUNCTION': ('LF_MFUNCTION', False, None), } def consume_type( @@ -829,6 +835,12 @@ class PdbReader: return result for field in fields_struct: _, name, member = field + skip = False + for skip_type in ['LF_NESTTYPE', 'LF_METHOD', 'LF_BCLASS']: + if member.vol.type_name.endswith(skip_type): + skip = True + if skip: + continue result[name] = {"offset": member.offset, "type": self.get_type_from_index(member.field_type)} return result @@ -852,9 +864,9 @@ class PdbReader: if element_type > 0x1000: _, name, toplevel_type = self.types[element_type - 0x1000] # If there's no name, the original size is probably fine as long as we're not indirect (LF_MODIFIER) - if not name and isinstance( - toplevel_type, - interfaces.objects.ObjectInterface) and toplevel_type.vol.type_name.endswith('LF_MODIFIER'): + if not name and isinstance(toplevel_type, interfaces.objects.ObjectInterface) and \ + (toplevel_type.vol.type_name.endswith('LF_MODIFIER') or + toplevel_type.vol.type_name.endswith('LF_NESTTYPE')): # We have check they don't point to a forward reference, so we go round again with the subtype element_type = toplevel_type.subtype_index loop = True