def parse_string(structure: interfaces.objects.ObjectInterface, parse_as_pascal: bool = False, size: int = 0) -> str: """Consumes either a c-string or a pascal string depending on the leaf_type.""" if not parse_as_pascal: 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 str(name)
def array_of_pointers( array: interfaces.objects.ObjectInterface, count: int, subtype: Union[str, interfaces.objects.Template], context: interfaces.context.ContextInterface ) -> interfaces.objects.ObjectInterface: """Takes an object, and recasts it as an array of pointers to subtype.""" symbol_table = array.vol.type_name.split(constants.BANG)[0] if isinstance(subtype, str) and context is not None: subtype = context.symbol_space.get_type(subtype) if not isinstance(subtype, interfaces.objects.Template) or subtype is None: raise TypeError( "Subtype must be a valid template (or string name of an object template)" ) subtype_pointer = context.symbol_space.get_type(symbol_table + constants.BANG + "pointer") subtype_pointer.update_vol(subtype=subtype) return array.cast("array", count=count, subtype=subtype_pointer)
def _get_subkeys_recursive( self, hive: RegistryHive, node: interfaces.objects.ObjectInterface ) -> Iterable[interfaces.objects.ObjectInterface]: """Recursively descend a node returning subkeys.""" # The keylist appears to include 4 bytes of key name after each value # We can either double the list and only use the even items, or # We could change the array type to a struct with both parts try: signature = node.cast('string', max_length=2, encoding='latin-1') except (exceptions.InvalidAddressException, RegistryFormatException): return listjump = None if signature == 'ri': listjump = 1 elif signature == 'lh' or signature == 'lf': listjump = 2 elif node.vol.type_name.endswith(constants.BANG + "_CM_KEY_NODE"): yield node else: vollog.debug( "Unexpected node type encountered when traversing subkeys: {}, signature: {}" .format(node.vol.type_name, signature)) if listjump: node.List.count = node.Count * listjump for subnode_offset in node.List[::listjump]: if (subnode_offset & 0x7fffffff) > hive.maximum_address: vollog.log( constants.LOGLEVEL_VVV, "Node found with address outside the valid Hive size: {}" .format(hex(subnode_offset))) else: try: subnode = hive.get_node(subnode_offset) except (exceptions.InvalidAddressException, RegistryFormatException): vollog.log( constants.LOGLEVEL_VVV, "Failed to get node at {}, skipping".format( hex(subnode_offset))) continue yield from self._get_subkeys_recursive(hive, subnode)