Merge pull request #540 from volatilityfoundation/feature/pdbconv-vs19

Feature/pdbconv vs19
This commit is contained in:
ikelos
2021-08-02 11:02:12 +01:00
committed by GitHub
2 changed files with 111 additions and 76 deletions
@@ -1295,6 +1295,54 @@
"kind": "struct",
"size": 18
},
"LF_STRUCTURE_VS19": {
"fields": {
"properties": {
"offset": 0,
"type": {
"kind": "struct",
"name": "Type_Properties"
}
},
"fields": {
"offset": 4,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"derived_from": {
"offset": 8,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"vtable_shape": {
"offset": 12,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"size": {
"offset": 18,
"type": {
"kind": "base",
"name": "unsigned short"
}
},
"name": {
"offset": 20,
"type": {
"kind": "base",
"name": "string"
}
}
},
"kind": "struct",
"size": 20
},
"LF_UDT_SRC_LINE": {
"fields": {
"udt": {
@@ -1626,6 +1674,8 @@
"LF_STRING_ID": 5637,
"LF_UDT_SRC_LINE": 5638,
"LF_UDT_MOD_SRC_LINE": 5639,
"LF_CLASS_VS19": 5640,
"LF_STRUCTURE_VS19": 5641,
"LF_CHAR": 32768,
"LF_SHORT": 32769,
"LF_USHORT": 32770,
@@ -269,7 +269,8 @@ class PdbReader:
if not progress_callback:
progress_callback = lambda x, y: None
self._progress_callback = progress_callback
self.types: List[Tuple[interfaces.objects.ObjectInterface, Optional[str], interfaces.objects.ObjectInterface]] = [
self.types: List[
Tuple[interfaces.objects.ObjectInterface, Optional[str], interfaces.objects.ObjectInterface]] = [
]
self.bases: Dict[str, Any] = {}
self.user_types: Dict[str, Any] = {}
@@ -362,7 +363,6 @@ 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)
@@ -650,7 +650,7 @@ class PdbReader:
leaf_type, name, value = self.types[index - 0x1000]
if leaf_type in [
leaf_type.LF_UNION, leaf_type.LF_CLASS, leaf_type.LF_CLASS_ST, leaf_type.LF_STRUCTURE,
leaf_type.LF_STRUCTURE_ST, leaf_type.LF_INTERFACE
leaf_type.LF_STRUCTURE_ST, leaf_type.LF_INTERFACE, leaf_type.LF_CLASS_VS19, leaf_type.LF_STRUCTURE_VS19
]:
if not value.properties.forward_reference:
result = value.size
@@ -695,7 +695,7 @@ class PdbReader:
leaf_type, name, value = self.types[index]
if leaf_type in [
leaf_type.LF_CLASS, leaf_type.LF_CLASS_ST, leaf_type.LF_STRUCTURE, leaf_type.LF_STRUCTURE_ST,
leaf_type.LF_INTERFACE
leaf_type.LF_INTERFACE, leaf_type.LF_CLASS_VS19, leaf_type.LF_STRUCTURE_VS19
]:
if not value.properties.forward_reference and name:
self.user_types[name] = {
@@ -728,6 +728,36 @@ class PdbReader:
# Re-run through for ForwardSizeReferences
self.user_types = self.replace_forward_references(self.user_types, type_references)
type_handlers = {
# Leaf_type: ('Structure', has_name, value_attribute)
'LF_CLASS': ('LF_STRUCTURE', True, 'size'),
'LF_CLASS_ST': ('LF_STRUCTURE', True, 'size'),
'LF_STRUCTURE': ('LF_STRUCTURE', True, 'size'),
'LF_STRUCTURE_ST': ('LF_STRUCTURE', True, 'size'),
'LF_INTERFACE': ('LF_STRUCTURE', True, 'size'),
'LF_CLASS_VS19': ('LF_STRUCTURE_VS19', True, 'size'),
'LF_STRUCTURE_VS19': ('LF_STRUCTURE_VS19', True, 'size'),
'LF_MEMBER': ('LF_MEMBER', True, 'offset'),
'LF_MEMBER_ST': ('LF_MEMBER', True, 'offset'),
'LF_ARRAY': ('LF_ARRAY', True, 'size'),
'LF_ARRAY_ST': ('LF_ARRAY', True, 'size'),
'LF_STRIDED_ARRAY': ('LF_ARRAY', True, 'size'),
'LF_ENUMERATE': ('LF_ENUMERATE', True, 'value'),
'LF_ARGLIST': ('LF_ENUM', True, None),
'LF_ENUM': ('LF_ENUM', True, None),
'LF_UNION': ('LF_UNION', True, None),
'LF_STRING_ID': ('LF_STRING_ID', True, None),
'LF_FUNC_ID': ('LF_FUNC_ID', True, None),
'LF_MODIFIER': ('LF_MODIFIER', False, None),
'LF_POINTER': ('LF_POINTER', False, None),
'LF_PROCEDURE': ('LF_PROCEDURE', False, None),
'LF_FIELDLIST': ('LF_FIELDLIST', False, None),
'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)
}
def consume_type(
self, module: interfaces.context.ModuleInterface, offset: int, length: int
) -> Tuple[Tuple[Optional[interfaces.objects.ObjectInterface], Optional[str], Union[
@@ -740,61 +770,10 @@ class PdbReader:
consumed = leaf_type.vol.base_type.size
remaining = length - consumed
if leaf_type in [
leaf_type.LF_CLASS, leaf_type.LF_CLASS_ST, leaf_type.LF_STRUCTURE, leaf_type.LF_STRUCTURE_ST,
leaf_type.LF_INTERFACE
]:
structure = module.object(object_type = "LF_STRUCTURE", offset = offset + consumed)
name_offset = structure.name.vol.offset - structure.vol.offset
name, value, excess = self.determine_extended_value(leaf_type, structure.size, module,
remaining - name_offset)
structure.size = value
structure.name = name
consumed += remaining
result = leaf_type, name, structure
elif leaf_type in [leaf_type.LF_MEMBER, leaf_type.LF_MEMBER_ST]:
member = module.object(object_type = "LF_MEMBER", offset = offset + consumed)
name_offset = member.name.vol.offset - member.vol.offset
name, value, excess = self.determine_extended_value(leaf_type, member.offset, module,
remaining - name_offset)
member.offset = value
member.name = name
result = leaf_type, name, member
consumed += member.vol.size + len(name) + 1 + excess
elif leaf_type in [leaf_type.LF_ARRAY, leaf_type.LF_ARRAY_ST, leaf_type.LF_STRIDED_ARRAY]:
array = module.object(object_type = "LF_ARRAY", offset = offset + consumed)
name_offset = array.name.vol.offset - array.vol.offset
name, value, excess = self.determine_extended_value(leaf_type, array.size, module, remaining - name_offset)
array.size = value
array.name = name
result = leaf_type, name, array
consumed += remaining
elif leaf_type in [leaf_type.LF_ENUMERATE]:
enum = module.object(object_type = 'LF_ENUMERATE', offset = offset + consumed)
name_offset = enum.name.vol.offset - enum.vol.offset
name, value, excess = self.determine_extended_value(leaf_type, enum.value, module, remaining - name_offset)
enum.value = value
enum.name = name
result = leaf_type, name, enum
consumed += enum.vol.size + len(name) + 1 + excess
elif leaf_type in [leaf_type.LF_ARGLIST, leaf_type.LF_ENUM]:
enum = module.object(object_type = "LF_ENUM", offset = offset + consumed)
name_offset = enum.name.vol.offset - enum.vol.offset
name = self.parse_string(enum.name, leaf_type < leaf_type.LF_ST_MAX, size = remaining - name_offset)
enum.name = name
result = leaf_type, name, enum
consumed += remaining
elif leaf_type in [leaf_type.LF_UNION]:
union = module.object(object_type = "LF_UNION", offset = offset + consumed)
name_offset = union.name.vol.offset - union.vol.offset
name = self.parse_string(union.name, leaf_type < leaf_type.LF_ST_MAX, size = remaining - name_offset)
result = leaf_type, name, union
consumed += remaining
elif leaf_type in [leaf_type.LF_MODIFIER, leaf_type.LF_POINTER, leaf_type.LF_PROCEDURE]:
obj = module.object(object_type = leaf_type.lookup(), offset = offset + consumed)
result = leaf_type, None, obj
consumed += remaining
elif leaf_type in [leaf_type.LF_FIELDLIST]:
type_handler, has_name, value_attribute = self.type_handlers.get(leaf_type.lookup(),
('LF_UNKNOWN', False, None))
if type_handler in ['LF_FIELDLIST']:
sub_length = remaining
sub_offset = offset + consumed
fields = []
@@ -806,23 +785,29 @@ class PdbReader:
consumed += sub_consumed
fields.append(subfield)
result = leaf_type, None, fields
elif leaf_type in [leaf_type.LF_BITFIELD]:
bitfield = module.object(object_type = "LF_BITFIELD", offset = offset + consumed)
result = leaf_type, None, bitfield
consumed += remaining
elif leaf_type in [leaf_type.LF_STRING_ID, leaf_type.LF_FUNC_ID]:
string_id = module.object(object_type = leaf_type.lookup(), offset = offset + consumed)
name_offset = string_id.name.vol.offset - string_id.vol.offset
name = self.parse_string(string_id.name, leaf_type < leaf_type.LF_ST_MAX, size = remaining - name_offset)
result = leaf_type, name, string_id
elif leaf_type in [leaf_type.LF_UDT_SRC_LINE, leaf_type.LF_UDT_MOD_SRC_LINE]:
src_line = module.object(object_type = leaf_type.lookup(), offset = offset + consumed)
result = leaf_type, None, src_line
elif leaf_type in [leaf_type.LF_BUILDINFO]:
buildinfo = module.object(object_type = leaf_type.lookup(), offset = offset + consumed)
buildinfo.arguments.count = buildinfo.count
consumed += buildinfo.arguments.vol.size
result = leaf_type, None, buildinfo
elif type_handler in ['LF_BUILDINFO']:
parsed_obj = module.object(object_type = type_handler, offset = offset + consumed)
parsed_obj.arguments.count = parsed_obj.count
consumed += parsed_obj.arguments.vol.size
result = leaf_type, None, parsed_obj
elif type_handler in self.type_handlers:
parsed_obj = module.object(object_type = type_handler, offset = offset + consumed)
current_consumed = remaining
if has_name:
name_offset = parsed_obj.name.vol.offset - parsed_obj.vol.offset
if value_attribute:
name, value, excess = self.determine_extended_value(leaf_type, getattr(parsed_obj, value_attribute),
module, remaining - name_offset)
setattr(parsed_obj, value_attribute, value)
current_consumed = parsed_obj.vol.size + len(name) + 1 + excess
else:
name = self.parse_string(parsed_obj.name, leaf_type < leaf_type.LF_ST_MAX,
size = remaining - name_offset)
parsed_obj.name = name
else:
name = None
result = leaf_type, name, parsed_obj
consumed += current_consumed
else:
raise TypeError(f"Unhandled leaf_type: {leaf_type}")