예제 #1
0
 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)
예제 #2
0
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)
예제 #3
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)