def _ParseMRUListExEntryValue(self, parser_mediator, key, entry_index, entry_number, values_dict, value_strings, parent_path_segments, codepage=u'cp1252', **unused_kwargs): """Parses the MRUListEx entry value. Args: parser_mediator: a parser mediator object (instance of ParserMediator). key: the Registry key (instance of dfwinreg.WinRegistryKey) that contains the MRUListEx value. entry_index: integer value representing the MRUListEx entry index. entry_number: integer value representing the entry number. values_dict: dictionary object containing values of the key. value_strings: value string dictionary object to append value strings. parent_path_segments: list containing the parent shell item path segments. codepage: optional extended ASCII string codepage. Returns: The path segment of the shell item. """ value = key.GetValueByName(u'{0:d}'.format(entry_number)) path_segment = u'N/A' value_string = u'' if value is None: parser_mediator.ProduceExtractionError( u'Missing MRUListEx entry value: {0:d} in key: {1:s}.'.format( entry_number, key.path)) elif not value.DataIsBinaryData(): parser_mediator.ProduceExtractionError( u'Non-binary MRUListEx entry value: {0:d} in key: {1:s}.'. format(entry_number, key.path)) elif value.data: shell_items_parser = shell_items.ShellItemsParser(key.path) shell_items_parser.ParseByteStream( parser_mediator, value.data, parent_path_segments=parent_path_segments, codepage=codepage) path_segment = shell_items_parser.GetUpperPathSegment() value_string = shell_items_parser.CopyToPath() value_strings[entry_number] = value_string value_string = u'Shell item path: {0:s}'.format(value_string) value_text = u'Index: {0:d} [MRU Value {1:d}]'.format( entry_index + 1, entry_number) values_dict[value_text] = value_string return path_segment
def ParseFileObject(self, parser_context, file_object, file_entry=None, display_name=None): """Parses a Windows Shortcut (LNK) file. The file entry is used to determine the display name if it was not provided. Args: parser_context: A parser context object (instance of ParserContext). file_object: A file-like object. file_entry: Optional file entry object (instance of dfvfs.FileEntry). The default is None. display_name: Optional display name. """ if not display_name and file_entry: display_name = parser_context.GetDisplayName(file_entry) lnk_file = pylnk.file() lnk_file.set_ascii_codepage(parser_context.codepage) try: lnk_file.open_file_object(file_object) except IOError as exception: lnk_file.close() raise errors.UnableToParseFile( u'[{0:s}] unable to parse file {1:s} with error: {2:s}'.format( self.NAME, display_name, exception)) link_target = None if lnk_file.link_target_identifier_data: # TODO: change file_entry.name to display name once it is generated # correctly. if file_entry: display_name = file_entry.name shell_items_parser = shell_items.ShellItemsParser(display_name) shell_items_parser.Parse(parser_context, lnk_file.link_target_identifier_data, codepage=parser_context.codepage) link_target = shell_items_parser.CopyToPath() parser_context.ProduceEvents([ WinLnkLinkEvent(lnk_file.get_file_access_time_as_integer(), eventdata.EventTimestamp.ACCESS_TIME, lnk_file, link_target), WinLnkLinkEvent(lnk_file.get_file_creation_time_as_integer(), eventdata.EventTimestamp.CREATION_TIME, lnk_file, link_target), WinLnkLinkEvent(lnk_file.get_file_modification_time_as_integer(), eventdata.EventTimestamp.MODIFICATION_TIME, lnk_file, link_target) ], parser_name=self.NAME, file_entry=file_entry) # TODO: add support for the distributed link tracker. lnk_file.close()
def ParseFileObject(self, parser_mediator, file_object, display_name=None, **kwargs): """Parses a Windows Shortcut (LNK) file-like object. Args: parser_mediator: A parser mediator object (instance of ParserMediator). file_object: A file-like object. display_name: Optional display name. Raises: UnableToParseFile: when the file cannot be parsed. """ if not display_name: display_name = parser_mediator.GetDisplayName() lnk_file = pylnk.file() lnk_file.set_ascii_codepage(parser_mediator.codepage) try: lnk_file.open_file_object(file_object) except IOError as exception: raise errors.UnableToParseFile( u'[{0:s}] unable to parse file {1:s} with error: {2:s}'.format( self.NAME, display_name, exception)) link_target = None if lnk_file.link_target_identifier_data: # TODO: change file_entry.name to display name once it is generated # correctly. file_entry = parser_mediator.GetFileEntry() display_name = file_entry.name shell_items_parser = shell_items.ShellItemsParser(display_name) shell_items_parser.UpdateChainAndParse( parser_mediator, lnk_file.link_target_identifier_data, None, codepage=parser_mediator.codepage) link_target = shell_items_parser.CopyToPath() parser_mediator.ProduceEvents([ WinLnkLinkEvent(lnk_file.get_file_access_time_as_integer(), eventdata.EventTimestamp.ACCESS_TIME, lnk_file, link_target), WinLnkLinkEvent(lnk_file.get_file_creation_time_as_integer(), eventdata.EventTimestamp.CREATION_TIME, lnk_file, link_target), WinLnkLinkEvent(lnk_file.get_file_modification_time_as_integer(), eventdata.EventTimestamp.MODIFICATION_TIME, lnk_file, link_target) ]) # TODO: add support for the distributed link tracker. lnk_file.close()
def _ParseMRUListExEntryValue( self, parser_mediator, registry_key, entry_index, entry_number, values_dict, value_strings, parent_path_segments, codepage=u'cp1252'): """Parses the MRUListEx entry value. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. registry_key (dfwinreg.WinRegistryKey): Windows Registry key that contains the MRUListEx value. entry_index (int): MRUListEx entry index. entry_number (int): entry number. values_dict (dict[str, object]): values of the key. value_strings (dict[str, str]): value names and strings. parent_path_segments (list[str]): parent shell item path segments. codepage (Optional[str]): extended ASCII string codepage. Returns: str: path segment of the shell item. """ value = registry_key.GetValueByName(u'{0:d}'.format(entry_number)) path_segment = u'N/A' value_string = u'' if value is None: parser_mediator.ProduceExtractionError( u'Missing MRUListEx entry value: {0:d} in key: {1:s}.'.format( entry_number, registry_key.path)) elif not value.DataIsBinaryData(): parser_mediator.ProduceExtractionError( u'Non-binary MRUListEx entry value: {0:d} in key: {1:s}.'.format( entry_number, registry_key.path)) elif value.data: shell_items_parser = shell_items.ShellItemsParser(registry_key.path) shell_items_parser.ParseByteStream( parser_mediator, value.data, parent_path_segments=parent_path_segments, codepage=codepage) path_segment = shell_items_parser.GetUpperPathSegment() value_string = shell_items_parser.CopyToPath() value_strings[entry_number] = value_string value_string = u'Shell item path: {0:s}'.format(value_string) value_text = u'Index: {0:d} [MRU Value {1:d}]'.format( entry_index + 1, entry_number) values_dict[value_text] = value_string return path_segment
def _ParseMRUListExEntryValue(self, parser_context, key, entry_index, entry_number, text_dict, value_strings, parent_value_string, codepage='cp1252', **unused_kwargs): """Parses the MRUListEx entry value. Args: parser_context: A parser context object (instance of ParserContext). key: the Registry key (instance of winreg.WinRegKey) that contains the MRUListEx value. entry_index: integer value representing the MRUListEx entry index. entry_number: integer value representing the entry number. text_dict: text dictionary object to append textual strings. value_string: value string dictionary object to append value strings. parent_value_string: string containing the parent value string. """ value = key.GetValue(u'{0:d}'.format(entry_number)) value_string = u'' if value is None: logging.debug( u'[{0:s}] Missing MRUListEx entry value: {1:d} in key: {2:s}.'. format(self.name, entry_number, key.path)) elif not value.DataIsBinaryData(): logging.debug( (u'[{0:s}] Non-binary MRUListEx entry value: {1:d} in key: ' u'{2:s}.').format(self.name, entry_number, key.path)) elif value.data: shell_items_parser = shell_items.ShellItemsParser(key.path) shell_items_parser.Parse(parser_context, value.data, codepage=codepage) value_string = shell_items_parser.CopyToPath() if parent_value_string: value_string = u', '.join([parent_value_string, value_string]) value_strings[entry_number] = value_string value_string = u'Shell item list: [{0:s}]'.format(value_string) value_text = u'Index: {0:d} [MRU Value {1:d}]'.format( entry_index + 1, entry_number) text_dict[value_text] = value_string
def _ParseMRUListEntryValue(self, parser_mediator, key, entry_index, entry_letter, codepage='cp1252', file_entry=None, parser_chain=None, **unused_kwargs): """Parses the MRUList entry value. Args: parser_mediator: A parser context object (instance of ParserContext). key: the Registry key (instance of winreg.WinRegKey) that contains the MRUList value. entry_index: integer value representing the MRUList entry index. entry_letter: character value representing the entry. codepage: Optional extended ASCII string codepage. The default is cp1252. file_entry: Optional file entry object (instance of dfvfs.FileEntry). The default is None. parser_chain: Optional string containing the parsing chain up to this point. The default is None. Returns: A string containing the value. """ value_string = u'' value = key.GetValue(u'{0:s}'.format(entry_letter)) if value is None: logging.debug( u'[{0:s}] Missing MRUList entry value: {1:s} in key: {2:s}.'. format(self.NAME, entry_letter, key.path)) elif not value.DataIsBinaryData(): logging.debug( (u'[{0:s}] Non-binary MRUList entry value: {1:s} in key: ' u'{2:s}.').format(self.NAME, entry_letter, key.path)) elif value.data: shell_items_parser = shell_items.ShellItemsParser(key.path) shell_items_parser.UpdateChainAndParse(parser_mediator, value.data, None, codepage=codepage) value_string = u'Shell item path: {0:s}'.format( shell_items_parser.CopyToPath()) return value_string
def _ParseMRUListExEntryValue(self, parser_mediator, registry_key, entry_number, parent_path_segments, codepage='cp1252'): """Parses the MRUListEx entry value. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. registry_key (dfwinreg.WinRegistryKey): Windows Registry key that contains the MRUListEx value. entry_number (int): entry number. parent_path_segments (list[str]): parent shell item path segments. codepage (Optional[str]): extended ASCII string codepage. Returns: tuple[str, str]: path and upper path segment of the shell item or None, None if not available. """ value = registry_key.GetValueByName('{0:d}'.format(entry_number)) if value is None: parser_mediator.ProduceExtractionWarning( 'Missing MRUListEx entry value: {0:d} in key: {1:s}.'.format( entry_number, registry_key.path)) return None, None if not value.DataIsBinaryData(): parser_mediator.ProduceExtractionWarning( 'Non-binary MRUListEx entry value: {0:d} in key: {1:s}.'. format(entry_number, registry_key.path)) return None, None path = None upper_path_segment = None if value.data: shell_items_parser = shell_items.ShellItemsParser( registry_key.path) shell_items_parser.ParseByteStream( parser_mediator, value.data, parent_path_segments=parent_path_segments, codepage=codepage) path = shell_items_parser.CopyToPath() upper_path_segment = shell_items_parser.GetUpperPathSegment() return path, upper_path_segment
def _ParseMRUListEntryValue(self, parser_mediator, registry_key, entry_index, entry_letter, codepage=u'cp1252', **kwargs): """Parses the MRUList entry value. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. registry_key (dfwinreg.WinRegistryKey): Windows Registry key that contains the MRUList value. entry_index (int): MRUList entry index. entry_letter (str): character value representing the entry. codepage (Optional[str]): extended ASCII string codepage. Returns: str: MRUList entry value. """ value_string = u'' value = registry_key.GetValueByName(u'{0:s}'.format(entry_letter)) if value is None: logging.debug( u'[{0:s}] Missing MRUList entry value: {1:s} in key: {2:s}.'. format(self.NAME, entry_letter, registry_key.path)) elif not value.DataIsBinaryData(): logging.debug( (u'[{0:s}] Non-binary MRUList entry value: {1:s} in key: ' u'{2:s}.').format(self.NAME, entry_letter, registry_key.path)) elif value.data: shell_items_parser = shell_items.ShellItemsParser( registry_key.path) shell_items_parser.ParseByteStream(parser_mediator, value.data, codepage=codepage) value_string = u'Shell item path: {0:s}'.format( shell_items_parser.CopyToPath()) return value_string
def _ParseMRUListExEntryValue(self, parser_mediator, registry_key, entry_index, entry_number, codepage='cp1252', **kwargs): """Parses the MRUListEx entry value. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. registry_key (dfwinreg.WinRegistryKey): Windows Registry key that contains the MRUListEx value. entry_index (int): MRUListEx entry index. entry_number (int): entry number. codepage (Optional[str]): extended ASCII string codepage. Returns: str: MRUList entry value. """ value_string = '' value = registry_key.GetValueByName('{0:d}'.format(entry_number)) if value is None: parser_mediator.ProduceExtractionWarning( 'missing MRUListEx value: {0:d} in key: {1:s}.'.format( entry_number, registry_key.path)) elif not value.DataIsBinaryData(): logger.debug( ('[{0:s}] Non-binary MRUListEx entry value: {1:d} in key: ' '{2:s}.').format(self.NAME, entry_number, registry_key.path)) elif value.data: shell_items_parser = shell_items.ShellItemsParser( registry_key.path) shell_items_parser.ParseByteStream(parser_mediator, value.data, codepage=codepage) shell_item_path = shell_items_parser.CopyToPath() or 'N/A' value_string = 'Shell item path: {0:s}'.format(shell_item_path) return value_string
def _ParseMRUListExEntryValue(self, parser_mediator, key, entry_index, entry_number, codepage=u'cp1252', **unused_kwargs): """Parses the MRUListEx entry value. Args: parser_mediator: A parser mediator object (instance of ParserMediator). key: the Registry key (instance of winreg.WinRegKey) that contains the MRUListEx value. entry_index: integer value representing the MRUListEx entry index. entry_number: integer value representing the entry number. codepage: Optional extended ASCII string codepage. The default is cp1252. Returns: A string containing the value. """ value_string = u'' value = key.GetValue(u'{0:d}'.format(entry_number)) if value is None: logging.debug( u'[{0:s}] Missing MRUListEx entry value: {1:d} in key: {2:s}.'. format(self.NAME, entry_number, key.path)) elif not value.DataIsBinaryData(): logging.debug( (u'[{0:s}] Non-binary MRUListEx entry value: {1:d} in key: ' u'{2:s}.').format(self.NAME, entry_number, key.path)) elif value.data: shell_items_parser = shell_items.ShellItemsParser(key.path) shell_items_parser.UpdateChainAndParse(parser_mediator, value.data, None, codepage=codepage) value_string = u'Shell item path: {0:s}'.format( shell_items_parser.CopyToPath()) return value_string
def _ParseMRUListExEntryValue( self, parser_mediator, registry_key, entry_index, entry_number, codepage='cp1252', **kwargs): """Parses the MRUListEx entry value. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. registry_key (dfwinreg.WinRegistryKey): Windows Registry key that contains the MRUListEx value. entry_index (int): MRUListEx entry index. entry_number (int): entry number. codepage (Optional[str]): extended ASCII string codepage. Returns: str: MRUList entry value. """ value_string = '' value = registry_key.GetValueByName('{0:d}'.format(entry_number)) if value is None: parser_mediator.ProduceExtractionWarning( 'missing MRUListEx value: {0:d} in key: {1:s}.'.format( entry_number, registry_key.path)) elif not value.DataIsBinaryData(): logger.debug(( '[{0:s}] Non-binary MRUListEx entry value: {1:d} in key: ' '{2:s}.').format(self.NAME, entry_number, registry_key.path)) elif value.data: utf16le_string_map = self._GetDataTypeMap('utf16le_string') context = dtfabric_data_maps.DataTypeMapContext() try: path = self._ReadStructureFromByteStream( value.data, 0, utf16le_string_map, context=context) except (ValueError, errors.ParseError) as exception: parser_mediator.ProduceExtractionWarning(( 'unable to parse MRUListEx entry value: {0:d} with error: ' '{1!s}').format(entry_number, exception)) return value_string path = path.rstrip('\x00') shell_item_list_data = value.data[context.byte_size:] if not shell_item_list_data: parser_mediator.ProduceExtractionWarning(( 'missing shell item in MRUListEx value: {0:d} in key: ' '{1:s}.').format(entry_number, registry_key.path)) value_string = 'Path: {0:s}'.format(path) else: shell_items_parser = shell_items.ShellItemsParser(registry_key.path) shell_items_parser.ParseByteStream( parser_mediator, shell_item_list_data, codepage=codepage) shell_item_path = shell_items_parser.CopyToPath() or 'N/A' value_string = 'Path: {0:s}, Shell item path: {1:s}'.format( path, shell_item_path) return value_string
def ParseFileObject(self, parser_mediator, file_object, display_name=None, **kwargs): """Parses a Windows Shortcut (LNK) file-like object. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. file_object (dfvfs.FileIO): file-like object. display_name (Optional[str]): display name. """ if not display_name: display_name = parser_mediator.GetDisplayName() lnk_file = pylnk.file() lnk_file.set_ascii_codepage(parser_mediator.codepage) try: lnk_file.open_file_object(file_object) except IOError as exception: parser_mediator.ProduceExtractionError( u'unable to open file with error: {0:s}'.format(exception)) return link_target = None if lnk_file.link_target_identifier_data: # TODO: change file_entry.name to display name once it is generated # correctly. display_name = parser_mediator.GetFilename() shell_items_parser = shell_items.ShellItemsParser(display_name) shell_items_parser.ParseByteStream( parser_mediator, lnk_file.link_target_identifier_data, codepage=parser_mediator.codepage) link_target = shell_items_parser.CopyToPath() access_time = lnk_file.get_file_access_time_as_integer() if access_time != 0: date_time = dfdatetime_filetime.Filetime(timestamp=access_time) event = WinLnkLinkEvent(date_time, definitions.TIME_DESCRIPTION_LAST_ACCESS, lnk_file, link_target) parser_mediator.ProduceEvent(event) creation_time = lnk_file.get_file_creation_time_as_integer() if creation_time != 0: date_time = dfdatetime_filetime.Filetime(timestamp=creation_time) event = WinLnkLinkEvent(date_time, definitions.TIME_DESCRIPTION_CREATION, lnk_file, link_target) parser_mediator.ProduceEvent(event) modification_time = lnk_file.get_file_modification_time_as_integer() if modification_time != 0: date_time = dfdatetime_filetime.Filetime( timestamp=modification_time) event = WinLnkLinkEvent(date_time, definitions.TIME_DESCRIPTION_MODIFICATION, lnk_file, link_target) parser_mediator.ProduceEvent(event) if access_time == 0 and creation_time == 0 and modification_time == 0: date_time = dfdatetime_semantic_time.SemanticTime(u'Not set') event = WinLnkLinkEvent(date_time, definitions.TIME_DESCRIPTION_NOT_A_TIME, lnk_file, link_target) parser_mediator.ProduceEvent(event) if lnk_file.droid_file_identifier: try: self._ParseDistributedTrackingIdentifier( parser_mediator, lnk_file.droid_file_identifier, display_name) except (TypeError, ValueError) as exception: parser_mediator.ProduceExtractionError( u'unable to read droid file identifier with error: {0:s}.'. format(exception)) if lnk_file.birth_droid_file_identifier: try: self._ParseDistributedTrackingIdentifier( parser_mediator, lnk_file.birth_droid_file_identifier, display_name) except (TypeError, ValueError) as exception: parser_mediator.ProduceExtractionError( (u'unable to read birth droid file identifier with error: ' u'{0:s}.').format(exception)) lnk_file.close()
def _ParseMRUListExEntryValue( self, parser_context, key, entry_index, entry_number, text_dict, codepage='cp1252', **unused_kwargs): """Parses the MRUListEx entry value. Args: parser_context: A parser context object (instance of ParserContext). key: the Registry key (instance of winreg.WinRegKey) that contains the MRUListEx value. entry_index: integer value representing the MRUListEx entry index. entry_number: integer value representing the entry number. text_dict: text dictionary object to append textual strings. codepage: Optional extended ASCII string codepage. The default is cp1252. """ value_string = u'' value = key.GetValue(u'{0:d}'.format(entry_number)) if value is None: logging.debug( u'[{0:s}] Missing MRUListEx entry value: {1:d} in key: {2:s}.'.format( self.NAME, entry_number, key.path)) elif not value.DataIsBinaryData(): logging.debug(( u'[{0:s}] Non-binary MRUListEx entry value: {1:d} in key: ' u'{2:s}.').format(self.NAME, entry_number, key.path)) elif value.data: value_struct = self._STRING_AND_SHELL_ITEM_LIST_STRUCT.parse(value.data) try: # The struct includes the end-of-string character that we need # to strip off. path = ''.join(value_struct.string).decode('utf16')[:-1] except UnicodeDecodeError as exception: logging.warning(( u'[{0:s}] Unable to decode string MRUListEx entry value: {1:d} ' u'in key: {2:s} with error: {3:s}').format( self.NAME, entry_number, key.path, exception)) path = u'' if path: shell_item_list_data = value.data[value_struct.shell_item_list:] if not shell_item_list_data: logging.debug(( u'[{0:s}] Missing shell item in MRUListEx entry value: {1:d}' u'in key: {2:s}').format(self.NAME, entry_number, key.path)) value_string = u'Path: {0:s}'.format(path) else: shell_items_parser = shell_items.ShellItemsParser(key.path) shell_items_parser.Parse( parser_context, shell_item_list_data, codepage=codepage) value_string = u'Path: {0:s}, Shell item list: [{1:s}]'.format( path, shell_items_parser.CopyToPath()) value_text = u'Index: {0:d} [MRU Value {1:d}]'.format( entry_index + 1, entry_number) text_dict[value_text] = value_string
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 = ExplorerProgramsCacheEventData() event_data.entries = ' '.join([ '{0:d}: {1:s}'.format(index, link_target) for index, link_target in enumerate(link_targets)]) or None event_data.key_path = registry_key.path event_data.known_folder_identifier = known_folder_identifier 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)
def _ParseMRUListExEntryValue(self, parser_mediator, key, entry_index, entry_number, codepage=u'cp1252', **unused_kwargs): """Parses the MRUListEx entry value. Args: parser_mediator: A parser mediator object (instance of ParserMediator). key: the Registry key (instance of dfwinreg.WinRegistryKey) that contains the MRUListEx value. entry_index: integer value representing the MRUListEx entry index. entry_number: integer value representing the entry number. codepage: Optional extended ASCII string codepage. Returns: A string containing the value. """ value_string = u'' value = key.GetValueByName(u'{0:d}'.format(entry_number)) if value is None: logging.debug( u'[{0:s}] Missing MRUListEx entry value: {1:d} in key: {2:s}.'. format(self.NAME, entry_number, key.path)) elif not value.DataIsBinaryData(): logging.debug( (u'[{0:s}] Non-binary MRUListEx entry value: {1:d} in key: ' u'{2:s}.').format(self.NAME, entry_number, key.path)) elif value.data: value_struct = self._STRING_AND_SHELL_ITEM_LIST_STRUCT.parse( value.data) try: # The struct includes the end-of-string character that we need # to strip off. path = b''.join(value_struct.string).decode(u'utf16')[:-1] except UnicodeDecodeError as exception: logging.warning(( u'[{0:s}] Unable to decode string MRUListEx entry value: {1:d} ' u'in key: {2:s} with error: {3:s}').format( self.NAME, entry_number, key.path, exception)) path = u'' if path: shell_item_list_data = value.data[value_struct. shell_item_list:] if not shell_item_list_data: logging.debug(( u'[{0:s}] Missing shell item in MRUListEx entry value: {1:d}' u'in key: {2:s}').format(self.NAME, entry_number, key.path)) value_string = u'Path: {0:s}'.format(path) else: shell_items_parser = shell_items.ShellItemsParser(key.path) shell_items_parser.ParseByteStream(parser_mediator, shell_item_list_data, codepage=codepage) value_string = u'Path: {0:s}, Shell item path: {1:s}'.format( path, shell_items_parser.CopyToPath()) return value_string
def _ParseValueData(self, parser_mediator, registry_key, registry_value): """Extracts event objects from a Explorer ProgramsCache value data. Args: parser_mediator: A parser mediator object (instance of ParserMediator). registry_key: A Windows Registry key (instance of dfwinreg.WinRegistryKey). registry_value: A Windows Registry value (instance of dfwinreg.WinRegistryValue). """ 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.ProduceParseError( u'unable to parse header with error: {0:s}'.format( exception)) return format_version = header_struct.get(u'format_version') if format_version not in [0x01, 0x09, 0x0c, 0x13]: parser_mediator.ProduceParseError( u'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.ProduceParseError(( u'unable to parse sentinel at offset: 0x{0:08x} ' u'with error: {1:s}').format(value_data_offset, exception)) return value_data_offset += self._ENTRY_FOOTER_STRUCT.sizeof() sentinel = entry_footer_struct.get(u'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.ProduceParseError(( u'unable to parse entry header at offset: 0x{0:08x} ' u'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(u'data_size') display_name = u'{0:s} {1:s}'.format( registry_key.path, registry_value.name) shell_items_parser = shell_items.ShellItemsParser(display_name) shell_items_parser.UpdateChainAndParse( parser_mediator, value_data[value_data_offset:], None, 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.ProduceParseError(( u'unable to parse entry footer at offset: 0x{0:08x} ' u'with error: {1:s}').format(value_data_offset, exception)) break value_data_offset += self._ENTRY_FOOTER_STRUCT.sizeof() sentinel = entry_footer_struct.get(u'sentinel') # TODO: recover remaining items. list_name = registry_value.name list_values = u' '.join([ u'{0:d}: {1:s}'.format(index, link_target) for index, link_target in enumerate(link_targets)]) event_object = windows_events.WindowsRegistryListEvent( registry_key.last_written_time, registry_key.path, list_name, list_values, value_name=registry_value.name) parser_mediator.ProduceEvent(event_object)
def _ParseMRUListExEntryValue( self, parser_mediator, registry_key, entry_index, entry_number, codepage='cp1252', **kwargs): """Parses the MRUListEx entry value. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. registry_key (dfwinreg.WinRegistryKey): Windows Registry key that contains the MRUListEx value. entry_index (int): MRUListEx entry index. entry_number (int): entry number. codepage (Optional[str]): extended ASCII string codepage. Returns: str: MRUList entry value. """ value_string = '' value = registry_key.GetValueByName('{0:d}'.format(entry_number)) if value is None: logger.debug( '[{0:s}] Missing MRUListEx entry value: {1:d} in key: {2:s}.'.format( self.NAME, entry_number, registry_key.path)) elif not value.DataIsBinaryData(): logger.debug(( '[{0:s}] Non-binary MRUListEx entry value: {1:d} in key: ' '{2:s}.').format(self.NAME, entry_number, registry_key.path)) elif value.data: value_struct = self._STRING_AND_SHELL_ITEM_LIST_STRUCT.parse(value.data) try: # The struct includes the end-of-string character that we need # to strip off. path = b''.join(value_struct.string).decode('utf16')[:-1] except UnicodeDecodeError as exception: logger.warning(( '[{0:s}] Unable to decode string MRUListEx entry value: {1:d} ' 'in key: {2:s} with error: {3!s}').format( self.NAME, entry_number, registry_key.path, exception)) path = '' if path: shell_item_list_data = value.data[value_struct.shell_item_list:] if not shell_item_list_data: logger.debug(( '[{0:s}] Missing shell item in MRUListEx entry value: {1:d}' 'in key: {2:s}').format( self.NAME, entry_number, registry_key.path)) value_string = 'Path: {0:s}'.format(path) else: shell_items_parser = shell_items.ShellItemsParser(registry_key.path) shell_items_parser.ParseByteStream( parser_mediator, shell_item_list_data, codepage=codepage) value_string = 'Path: {0:s}, Shell item path: {1:s}'.format( path, shell_items_parser.CopyToPath()) return value_string
def ParseFileObject( self, parser_mediator, file_object, display_name=None, **kwargs): """Parses a Windows Shortcut (LNK) file-like object. Args: parser_mediator: A parser mediator object (instance of ParserMediator). file_object: A file-like object. display_name: Optional display name. """ if not display_name: display_name = parser_mediator.GetDisplayName() lnk_file = pylnk.file() lnk_file.set_ascii_codepage(parser_mediator.codepage) try: lnk_file.open_file_object(file_object) except IOError as exception: parser_mediator.ProduceExtractionError( u'unable to open file with error: {0:s}'.format(exception)) return link_target = None if lnk_file.link_target_identifier_data: # TODO: change file_entry.name to display name once it is generated # correctly. display_name = parser_mediator.GetFilename() shell_items_parser = shell_items.ShellItemsParser(display_name) shell_items_parser.ParseByteStream( parser_mediator, lnk_file.link_target_identifier_data, codepage=parser_mediator.codepage) link_target = shell_items_parser.CopyToPath() access_time = lnk_file.get_file_access_time_as_integer() if access_time > 0: parser_mediator.ProduceEvent( WinLnkLinkEvent( access_time, eventdata.EventTimestamp.ACCESS_TIME, lnk_file, link_target)) creation_time = lnk_file.get_file_creation_time_as_integer() if creation_time > 0: parser_mediator.ProduceEvent( WinLnkLinkEvent( creation_time, eventdata.EventTimestamp.CREATION_TIME, lnk_file, link_target)) modification_time = lnk_file.get_file_modification_time_as_integer() if modification_time > 0: parser_mediator.ProduceEvent( WinLnkLinkEvent( modification_time, eventdata.EventTimestamp.MODIFICATION_TIME, lnk_file, link_target)) if access_time == 0 and creation_time == 0 and modification_time == 0: parser_mediator.ProduceEvent( WinLnkLinkEvent( 0, eventdata.EventTimestamp.NOT_A_TIME, lnk_file, link_target)) try: uuid_object = uuid.UUID(lnk_file.droid_file_identifier) if uuid_object.version == 1: event_object = ( windows_events.WindowsDistributedLinkTrackingCreationEvent( uuid_object, display_name)) parser_mediator.ProduceEvent(event_object) except (TypeError, ValueError): pass try: uuid_object = uuid.UUID(lnk_file.birth_droid_file_identifier) if uuid_object.version == 1: event_object = ( windows_events.WindowsDistributedLinkTrackingCreationEvent( uuid_object, display_name)) parser_mediator.ProduceEvent(event_object) except (TypeError, ValueError): pass lnk_file.close()
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)
def ParseFileLNKFile(self, parser_mediator, file_object, display_name): """Parses a Windows Shortcut (LNK) file-like object. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. file_object (dfvfs.FileIO): file-like object. display_name (str): display name. """ lnk_file = pylnk.file() lnk_file.set_ascii_codepage(parser_mediator.codepage) try: lnk_file.open_file_object(file_object) except IOError as exception: parser_mediator.ProduceExtractionWarning( 'unable to open file with error: {0!s}'.format(exception)) return link_target = None if lnk_file.link_target_identifier_data: # pylint: disable=using-constant-test # TODO: change file_entry.name to display name once it is generated # correctly. display_name = parser_mediator.GetFilename() shell_items_parser = shell_items.ShellItemsParser(display_name) shell_items_parser.ParseByteStream( parser_mediator, lnk_file.link_target_identifier_data, codepage=parser_mediator.codepage) link_target = shell_items_parser.CopyToPath() event_data = WinLnkLinkEventData() event_data.birth_droid_file_identifier = ( lnk_file.birth_droid_file_identifier) event_data.birth_droid_volume_identifier = ( lnk_file.birth_droid_volume_identifier) event_data.command_line_arguments = lnk_file.command_line_arguments event_data.description = lnk_file.description event_data.drive_serial_number = lnk_file.drive_serial_number event_data.drive_type = lnk_file.drive_type event_data.droid_file_identifier = lnk_file.droid_file_identifier event_data.droid_volume_identifier = lnk_file.droid_volume_identifier event_data.env_var_location = lnk_file.environment_variables_location event_data.file_attribute_flags = lnk_file.file_attribute_flags event_data.file_size = lnk_file.file_size event_data.icon_location = lnk_file.icon_location event_data.link_target = link_target event_data.local_path = lnk_file.local_path event_data.network_path = lnk_file.network_path event_data.relative_path = lnk_file.relative_path event_data.volume_label = lnk_file.volume_label event_data.working_directory = lnk_file.working_directory access_time = lnk_file.get_file_access_time_as_integer() if access_time != 0: date_time = dfdatetime_filetime.Filetime(timestamp=access_time) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_LAST_ACCESS) parser_mediator.ProduceEventWithEventData(event, event_data) creation_time = lnk_file.get_file_creation_time_as_integer() if creation_time != 0: date_time = dfdatetime_filetime.Filetime(timestamp=creation_time) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_CREATION) parser_mediator.ProduceEventWithEventData(event, event_data) modification_time = lnk_file.get_file_modification_time_as_integer() if modification_time != 0: date_time = dfdatetime_filetime.Filetime( timestamp=modification_time) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_MODIFICATION) parser_mediator.ProduceEventWithEventData(event, event_data) if access_time == 0 and creation_time == 0 and modification_time == 0: date_time = dfdatetime_semantic_time.NotSet() event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_NOT_A_TIME) parser_mediator.ProduceEventWithEventData(event, event_data) if lnk_file.droid_file_identifier: # pylint: disable=using-constant-test try: self._ParseDistributedTrackingIdentifier( parser_mediator, lnk_file.droid_file_identifier, display_name) except (TypeError, ValueError) as exception: parser_mediator.ProduceExtractionWarning( 'unable to read droid file identifier with error: {0!s}.'. format(exception)) if lnk_file.birth_droid_file_identifier: # pylint: disable=using-constant-test try: self._ParseDistributedTrackingIdentifier( parser_mediator, lnk_file.birth_droid_file_identifier, display_name) except (TypeError, ValueError) as exception: parser_mediator.ProduceExtractionWarning( ('unable to read birth droid file identifier with error: ' '{0!s}.').format(exception)) lnk_file.close()