Exemple #1
0
    def testGetAttributeNames(self):
        """Tests the GetAttributeNames function."""
        attribute_container = windows_events.WindowsRegistryListEventData()

        expected_attribute_names = [
            'data_type', 'key_path', 'list_name', 'list_values', 'offset',
            'query', 'value_name'
        ]

        attribute_names = sorted(attribute_container.GetAttributeNames())

        self.assertEqual(attribute_names, expected_attribute_names)
Exemple #2
0
    def _ParseValueData(self, parser_mediator, registry_key, registry_value):
        """Extracts event objects from a Explorer ProgramsCache value data.

    Args:
      parser_mediator (ParserMediator): mediates interactions between parsers
          and other components, such as storage and dfvfs.
      registry_key (dfwinreg.WinRegistryKey): Windows Registry key.
      registry_value (dfwinreg.WinRegistryValue): Windows Registry value.
    """
        value_data = registry_value.data
        if len(value_data) < 4:
            return

        try:
            header_struct = self._HEADER_STRUCT.parse(value_data)
        except construct.FieldError as exception:
            parser_mediator.ProduceExtractionError(
                'unable to parse header with error: {0!s}'.format(exception))
            return

        format_version = header_struct.get('format_version')
        if format_version not in (0x01, 0x09, 0x0c, 0x13):
            parser_mediator.ProduceExtractionError(
                'unsupported format version: 0x{0:08x}'.format(format_version))
            return

        if format_version == 0x01:
            value_data_offset = 8

        elif format_version == 0x09:
            value_data_offset = 6

        else:
            # TODO: get known folder identifier?
            value_data_offset = 20

        if format_version == 0x09:
            sentinel = 0
        else:
            try:
                entry_footer_struct = self._ENTRY_FOOTER_STRUCT.parse(
                    value_data[value_data_offset:])
            except construct.FieldError as exception:
                parser_mediator.ProduceExtractionError(
                    ('unable to parse sentinel at offset: 0x{0:08x} '
                     'with error: {1!s}').format(value_data_offset, exception))
                return

            value_data_offset += self._ENTRY_FOOTER_STRUCT.sizeof()

            sentinel = entry_footer_struct.get('sentinel')

        link_targets = []
        while sentinel in (0x00, 0x01):
            try:
                entry_header_struct = self._ENTRY_HEADER_STRUCT.parse(
                    value_data[value_data_offset:])
            except construct.FieldError as exception:
                parser_mediator.ProduceExtractionError(
                    ('unable to parse entry header at offset: 0x{0:08x} '
                     'with error: {1!s}').format(value_data_offset, exception))
                break

            value_data_offset += self._ENTRY_HEADER_STRUCT.sizeof()

            entry_data_size = entry_header_struct.get('data_size')

            display_name = '{0:s} {1:s}'.format(registry_key.path,
                                                registry_value.name)

            shell_items_parser = shell_items.ShellItemsParser(display_name)
            shell_items_parser.ParseByteStream(
                parser_mediator,
                value_data[value_data_offset:],
                codepage=parser_mediator.codepage)

            link_target = shell_items_parser.CopyToPath()
            link_targets.append(link_target)

            value_data_offset += entry_data_size

            try:
                entry_footer_struct = self._ENTRY_FOOTER_STRUCT.parse(
                    value_data[value_data_offset:])
            except construct.FieldError as exception:
                parser_mediator.ProduceExtractionError(
                    ('unable to parse entry footer at offset: 0x{0:08x} '
                     'with error: {1!s}').format(value_data_offset, exception))
                break

            value_data_offset += self._ENTRY_FOOTER_STRUCT.sizeof()

            sentinel = entry_footer_struct.get('sentinel')

        # TODO: recover remaining items.

        event_data = windows_events.WindowsRegistryListEventData()
        event_data.key_path = registry_key.path
        event_data.list_name = registry_value.name
        event_data.list_values = ' '.join([
            '{0:d}: {1:s}'.format(index, link_target)
            for index, link_target in enumerate(link_targets)
        ])
        event_data.value_name = registry_value.name

        event = time_events.DateTimeValuesEvent(
            registry_key.last_written_time,
            definitions.TIME_DESCRIPTION_WRITTEN)
        parser_mediator.ProduceEventWithEventData(event, event_data)
Exemple #3
0
    def _ParseValueData(self, parser_mediator, registry_key, registry_value):
        """Extracts event objects from a Explorer ProgramsCache value data.

    Args:
      parser_mediator (ParserMediator): mediates interactions between parsers
          and other components, such as storage and dfvfs.
      registry_key (dfwinreg.WinRegistryKey): Windows Registry key.
      registry_value (dfwinreg.WinRegistryValue): Windows Registry value.

    Raises:
      ParseError: if the value data could not be parsed.
    """
        value_data = registry_value.data

        value_data_size = len(value_data)
        if value_data_size < 4:
            return

        header_map = self._GetDataTypeMap('programscache_header')

        try:
            header = self._ReadStructureFromByteStream(value_data, 0,
                                                       header_map)
        except (ValueError, errors.ParseError) as exception:
            parser_mediator.ProduceExtractionWarning(
                'unable to parse header value with error: {0!s}'.format(
                    exception))
            return

        if header.format_version not in (1, 9, 12, 19):
            parser_mediator.ProduceExtractionWarning(
                'unsupported format version: {0:d}'.format(
                    header.format_version))
            return

        known_folder_identifier = None
        if header.format_version == 1:
            value_data_offset = 8

        elif header.format_version == 9:
            value_data_offset = 6

        elif header.format_version in (12, 19):
            known_folder_identifier = uuid.UUID(bytes_le=value_data[4:20])
            value_data_offset = 20

        entry_header_map = self._GetDataTypeMap('programscache_entry_header')
        entry_footer_map = self._GetDataTypeMap('programscache_entry_footer')

        sentinel = 0
        if header.format_version != 9:
            try:
                entry_footer = self._ReadStructureFromByteStream(
                    value_data[value_data_offset:], value_data_offset,
                    entry_footer_map)
            except (ValueError, errors.ParseError) as exception:
                parser_mediator.ProduceExtractionWarning(
                    ('unable to parse sentinel at offset: 0x{0:08x} '
                     'with error: {1!s}').format(value_data_offset, exception))
                return

            value_data_offset += entry_footer_map.GetByteSize()

            sentinel = entry_footer.sentinel

        link_targets = []
        while sentinel in (0x00, 0x01):
            if value_data_offset >= value_data_size:
                break

            try:
                entry_header = self._ReadStructureFromByteStream(
                    value_data[value_data_offset:], value_data_offset,
                    entry_header_map)
            except (ValueError, errors.ParseError) as exception:
                parser_mediator.ProduceExtractionWarning(
                    ('unable to parse entry header at offset: 0x{0:08x} '
                     'with error: {1!s}').format(value_data_offset, exception))
                break

            value_data_offset += entry_header_map.GetByteSize()

            display_name = '{0:s} {1:s}'.format(registry_key.path,
                                                registry_value.name)

            shell_items_parser = shell_items.ShellItemsParser(display_name)
            shell_items_parser.ParseByteStream(
                parser_mediator,
                value_data[value_data_offset:],
                codepage=parser_mediator.codepage)

            link_target = shell_items_parser.CopyToPath()
            link_targets.append(link_target)

            value_data_offset += entry_header.data_size

            try:
                entry_footer = self._ReadStructureFromByteStream(
                    value_data[value_data_offset:], value_data_offset,
                    entry_footer_map)
            except (ValueError, errors.ParseError) as exception:
                parser_mediator.ProduceExtractionWarning(
                    ('unable to parse entry footer at offset: 0x{0:08x} '
                     'with error: {1!s}').format(value_data_offset, exception))
                return

            value_data_offset += entry_footer_map.GetByteSize()

            sentinel = entry_footer.sentinel

        # TODO: recover remaining items.

        if known_folder_identifier:
            known_folder_identifier = '{0!s}'.format(known_folder_identifier)

        event_data = windows_events.WindowsRegistryListEventData()
        event_data.key_path = registry_key.path
        event_data.known_folder_identifier = known_folder_identifier
        event_data.list_name = registry_value.name
        event_data.list_values = ' '.join([
            '{0:d}: {1:s}'.format(index, link_target)
            for index, link_target in enumerate(link_targets)
        ])
        event_data.value_name = registry_value.name

        event = time_events.DateTimeValuesEvent(
            registry_key.last_written_time,
            definitions.TIME_DESCRIPTION_WRITTEN)
        parser_mediator.ProduceEventWithEventData(event, event_data)