mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-07 10:17:38 +02:00
Further work on the returning types.
This commit is contained in:
@@ -2,6 +2,26 @@
|
||||
"symbols": {
|
||||
},
|
||||
"user_types": {
|
||||
"pascal_string": {
|
||||
"fields": {
|
||||
"length": {
|
||||
"offset": 0,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned char"
|
||||
}
|
||||
},
|
||||
"string": {
|
||||
"offset": 1,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 2
|
||||
},
|
||||
"SI_PERSIST": {
|
||||
"fields": {
|
||||
"StreamInfoSize": {
|
||||
@@ -259,10 +279,24 @@
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"offset": 16,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"offset": 18,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 16
|
||||
"size": 18
|
||||
},
|
||||
"LF_MEMBER": {
|
||||
"fields": {
|
||||
@@ -356,11 +390,11 @@
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"constant": {
|
||||
"pointer_type": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 1,
|
||||
"bit_position": 7,
|
||||
"bit_length": 5,
|
||||
"bit_position": 0,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
@@ -368,7 +402,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"reference": {
|
||||
"mode": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 3,
|
||||
@@ -380,11 +414,59 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"pointer_type": {
|
||||
"flat32": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 5,
|
||||
"bit_position": 0,
|
||||
"bit_length": 1,
|
||||
"bit_position": 8,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"volatile": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 1,
|
||||
"bit_position": 9,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"constant": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 1,
|
||||
"bit_position": 10,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"unaligned": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 1,
|
||||
"bit_position": 11,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"restricted": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 1,
|
||||
"bit_position": 12,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
@@ -403,10 +485,80 @@
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"mocom": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 1,
|
||||
"bit_position": 19,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lref": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 1,
|
||||
"bit_position": 20,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"rref": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"bit_length": 1,
|
||||
"bit_position": 21,
|
||||
"kind": "bitfield",
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 8
|
||||
"size": 6
|
||||
},
|
||||
"LF_PROCEDURE": {
|
||||
"fields": {
|
||||
"return_type": {
|
||||
"offset": 0,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"offset": 4,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"parameter_count": {
|
||||
"offset": 6,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned short"
|
||||
}
|
||||
},
|
||||
"argument_list": {
|
||||
"offset": 8,
|
||||
"type": {
|
||||
"kind": "base",
|
||||
"name": "unsigned long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "struct",
|
||||
"size": 12
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
|
||||
@@ -74,11 +74,11 @@ class PdbReader:
|
||||
length_len = module.get_type(length_type).size
|
||||
while tpi_layer.maximum_address - offset > 0:
|
||||
length = module.object(type_name = length_type, offset = offset)
|
||||
if not isinstance(length, int):
|
||||
raise ValueError("Non-integer length provided")
|
||||
offset += length_len
|
||||
output, consumed = self.consume_type(module, offset, length)
|
||||
types.update(output)
|
||||
# if consumed != length:
|
||||
# raise ValueError("Bytes unconsumed")
|
||||
offset += length
|
||||
# Since types can only refer to earlier types, assigning the name at this point is fine
|
||||
|
||||
@@ -87,54 +87,67 @@ class PdbReader:
|
||||
|
||||
return header
|
||||
|
||||
def consume_type(self, module: interfaces.context.ModuleInterface, offset: int,
|
||||
length: int) -> Tuple[Dict[str, Dict], int]:
|
||||
def consume_type(self, module: interfaces.context.ModuleInterface, offset: int, length: int,
|
||||
no_output = False) -> Tuple[Dict[str, Dict], int]:
|
||||
"""Returns the dictionary for the type, and the number of bytes consumed"""
|
||||
LeafType = self.context.object(
|
||||
leaf_type = self.context.object(
|
||||
module.get_enumeration("LEAF_TYPE"), layer_name = module._layer_name, offset = offset)
|
||||
consumed = LeafType.vol.base_type.size
|
||||
consumed = leaf_type.vol.base_type.size
|
||||
offset += consumed
|
||||
length -= consumed
|
||||
|
||||
if LeafType in [
|
||||
LeafType.LF_CLASS, LeafType.LF_CLASS_ST, LeafType.LF_STRUCTURE, LeafType.LF_STRUCTURE_ST,
|
||||
LeafType.LF_INTERFACE
|
||||
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(type_name = "LF_STRUCTURE", offset = offset)
|
||||
consumed = structure.vol.size
|
||||
elif LeafType in [LeafType.LF_MEMBER, LeafType.LF_MEMBER_ST]:
|
||||
name = self.parse_string(leaf_type, structure.name, size = length - structure.vol.size - consumed)
|
||||
consumed = length
|
||||
elif leaf_type in [leaf_type.LF_MEMBER, leaf_type.LF_MEMBER_ST]:
|
||||
member = module.object(type_name = "LF_MEMBER", offset = offset)
|
||||
name = member.name.cast("string", max_length = 256, encoding = "latin-1")
|
||||
consumed += member.vol.size + len(name) + 1
|
||||
elif LeafType in [LeafType.LF_MODIFIER]:
|
||||
modifier = module.object(type_name = "LF_MODIFIER", offset = offset)
|
||||
consumed += modifier.vol.size
|
||||
name = self.parse_string(leaf_type, member.name, size = length - member.vol.size - consumed)
|
||||
consumed = length
|
||||
elif leaf_type in [leaf_type.LF_MODIFIER, leaf_type.LF_POINTER, leaf_type.LF_PROCEDURE]:
|
||||
# TODO: Subresolve sub-types
|
||||
obj = module.object(type_name = leaf_type.lookup(), offset = offset)
|
||||
consumed = length
|
||||
# Lookup and return the modified type
|
||||
elif LeafType in [LeafType.LF_POINTER]:
|
||||
pointer = module.object(type_name = "LF_POINTER", offset = offset)
|
||||
consumed += pointer.vol.size
|
||||
elif LeafType in [LeafType.LF_FIELDLIST]:
|
||||
sub_length = length
|
||||
elif leaf_type in [leaf_type.LF_FIELDLIST]:
|
||||
sub_length = length - consumed
|
||||
sub_offset = offset
|
||||
field = []
|
||||
while length > consumed:
|
||||
subfield, sub_consumed = self.consume_type(module, sub_offset, sub_length)
|
||||
subfield, sub_consumed = self.consume_type(module, sub_offset, sub_length, True)
|
||||
sub_length -= sub_consumed
|
||||
sub_offset += sub_consumed
|
||||
consumed += sub_consumed
|
||||
field.append(subfield)
|
||||
pass
|
||||
elif LeafType in [LeafType.LF_ARGLIST]:
|
||||
pass
|
||||
elif leaf_type in [leaf_type.LF_BITFIELD]:
|
||||
consumed = length
|
||||
elif leaf_type in [leaf_type.LF_ARRAY, leaf_type.LF_ARRAY_ST, leaf_type.LF_STRIDED_ARRAY]:
|
||||
consumed = length
|
||||
elif leaf_type in [leaf_type.LF_ARGLIST, leaf_type.LF_ENUMERATE, leaf_type.LF_ENUM, leaf_type.LF_UNION]:
|
||||
consumed = length
|
||||
else:
|
||||
raise ValueError("Unhandled leaf_type: {}".format(LeafType))
|
||||
raise ValueError("Unhandled leaf_type: {}".format(leaf_type))
|
||||
|
||||
# if consumed != length:
|
||||
# import pdb
|
||||
# pdb.set_trace()
|
||||
if consumed != length:
|
||||
print("CONSUMED != length", hex(consumed), hex(length), leaf_type.lookup())
|
||||
|
||||
print("LEAF_TYPE", LeafType.lookup())
|
||||
return {"leaf_type": LeafType}, consumed
|
||||
if not no_output:
|
||||
print(leaf_type.lookup())
|
||||
return {"leaf_type": leaf_type}, consumed
|
||||
|
||||
def parse_string(self,
|
||||
leaf_type: interfaces.objects.ObjectInterface,
|
||||
structure: interfaces.objects.ObjectInterface,
|
||||
size = 0) -> str:
|
||||
if leaf_type > leaf_type.LF_ST_MAX:
|
||||
name = structure.cast("string", max_length = size, encoding = "latin-1")
|
||||
else:
|
||||
name = structure.cast("pascal_string")
|
||||
name = name.string.cast("string", max_length = name.length, encoding = "latin-1")
|
||||
return name
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@@ -154,6 +167,6 @@ if __name__ == '__main__':
|
||||
# x = ctx.object('pdb1!BIG_MSF_HDR', reader.pdb_layer_name, 0)
|
||||
header = reader.read_tpi_stream()
|
||||
|
||||
import pdb
|
||||
|
||||
pdb.set_trace()
|
||||
# import pdb
|
||||
#
|
||||
# pdb.set_trace()
|
||||
|
||||
Reference in New Issue
Block a user