Beispiel #1
0
    def key_iterator(
        cls,
        hive: RegistryHive,
        node_path: Sequence[objects.StructType] = None,
        recurse: bool = False
    ) -> Iterable[Tuple[int, bool, datetime.datetime, str, bool,
                        interfaces.objects.ObjectInterface]]:
        """Walks through a set of nodes from a given node (last one in
        node_path). Avoids loops by not traversing into nodes already present
        in the node_path.

        Args:
            hive: The registry hive to walk
            node_path: The list of nodes that make up the
            recurse: Traverse down the node tree or stay only on the same level

        Yields:
            A tuple of results (depth, is_key, last write time, path, volatile, and the node).
        """
        if not node_path:
            node_path = [hive.get_node(hive.root_cell_offset)]
        if not isinstance(node_path, list) or len(node_path) < 1:
            vollog.warning(
                "Hive walker was not passed a valid node_path (or None)")
            return
        node = node_path[-1]
        key_path_items = [hive] + node_path[1:]
        key_path = '\\'.join([k.get_name() for k in key_path_items])
        if node.vol.type_name.endswith(constants.BANG + '_CELL_DATA'):
            raise RegistryFormatException(
                hive.name, "Encountered _CELL_DATA instead of _CM_KEY_NODE")
        last_write_time = conversion.wintime_to_datetime(
            node.LastWriteTime.QuadPart)

        for key_node in node.get_subkeys():
            result = (len(node_path), True, last_write_time, key_path,
                      key_node.get_volatile(), key_node)
            yield result

            if recurse:
                if key_node.vol.offset not in [
                        x.vol.offset for x in node_path
                ]:
                    try:
                        sub_node_name = key_node.get_name()
                    except exceptions.InvalidAddressException as excp:
                        vollog.debug(excp)
                        continue

                    yield from cls.key_iterator(hive,
                                                node_path + [key_node],
                                                recurse=recurse)

        for value_node in node.get_values():
            result = (len(node_path), False, last_write_time, key_path,
                      node.get_volatile(), value_node)
            yield result
Beispiel #2
0
    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)