def testUt16StreamCopyToString(self): """Test copying an UTF-16 formatted byte stream to a string.""" path = os.path.join('test_data', 'PING.EXE-B29F6629.pf') with open(path, 'rb') as fh: byte_stream = fh.read() # Read a null char terminated string. self.assertEquals( binary.Ut16StreamCopyToString(byte_stream[0x10:]), 'PING.EXE') # Read a fixed size string. expected_string = u'\\DEVICE\\HARDDISKVOLUME' string = binary.Ut16StreamCopyToString(byte_stream[0x27f8:], byte_stream_size=44) self.assertEquals(string, expected_string) expected_string = u'\\DEVICE\\HARDDISKVOLUME1' string = binary.Ut16StreamCopyToString(byte_stream[0x27f8:], byte_stream_size=46) self.assertEquals(string, expected_string) # Read another null char terminated string. expected_string = ( u'\\DEVICE\\HARDDISKVOLUME1\\WINDOWS\\SYSTEM32\\NTDLL.DLL') string = binary.Ut16StreamCopyToString(byte_stream[7236:]) self.assertEquals(string, expected_string)
def __init__(self, timestamp, timestamp_description, file_header, file_information, mapped_files, path, volume_serial_numbers, volume_device_paths): """Initializes the event. Args: timestamp: The FILETIME timestamp value. timestamp_description: The usage string for the timestamp value. file_header: The file header construct object. file_information: The file information construct object. mapped_files: The list of mapped filenames. path: A path to the executable. volume_serial_numbers: A list of volume serial number strings. volume_device_paths: A list of volume device path strings. """ super(WinPrefetchExecutionEvent, self).__init__(timestamp, timestamp_description) self.offset = 0 self.version = file_header.get('version', None) self.executable = binary.Ut16StreamCopyToString( file_header.get('executable', '')) self.prefetch_hash = file_header.get('prefetch_hash', None) self.run_count = file_information.get('run_count', None) self.mapped_files = mapped_files self.path = path self.number_of_volumes = file_information.get('number_of_volumes', 0) self.volume_serial_numbers = volume_serial_numbers self.volume_device_paths = volume_device_paths
def __init__(self, timestamp, timestamp_description, entry_offset, dest_list_entry): """Initializes the event object. Args: timestamp: The FILETIME value for the timestamp. timestamp_description: The usage string for the timestamp value. entry_offset: The offset of the DestList entry relative to the start of the DestList stream. dest_list_entry: The DestList entry (instance of construct.Struct). """ super(AutomaticDestinationsDestListEntryEvent, self).__init__(timestamp, timestamp_description) self.offset = entry_offset self.entry_number = dest_list_entry.entry_number self.hostname = binary.ByteStreamCopyToString(dest_list_entry.hostname, codepage=u'ascii') self.path = binary.Ut16StreamCopyToString(dest_list_entry.path) self.pin_status = dest_list_entry.pin_status self.droid_volume_identifier = binary.ByteStreamCopyToGuid( dest_list_entry.droid_volume_identifier) self.droid_file_identifier = binary.ByteStreamCopyToGuid( dest_list_entry.droid_file_identifier) self.birth_droid_volume_identifier = binary.ByteStreamCopyToGuid( dest_list_entry.birth_droid_volume_identifier) self.birth_droid_file_identifier = binary.ByteStreamCopyToGuid( dest_list_entry.birth_droid_file_identifier)
def ParseCachedEntry(self, format_type, value_data, cached_entry_offset, cached_entry_size): """Parses a cached entry. Args: format_type: integer value that contains the format type. value_data: a binary string containing the value data. cached_entry_offset: integer value that contains the offset of the cached entry data relative to the start of the value data. cached_entry_size: integer value that contains the cached entry data size. Returns: A cached entry object (instance of AppCompatCacheCachedEntry). Raises: RuntimeError: if the format type is not supported. """ if format_type not in [ self.FORMAT_TYPE_XP, self.FORMAT_TYPE_2003, self.FORMAT_TYPE_VISTA, self.FORMAT_TYPE_7, self.FORMAT_TYPE_8 ]: raise RuntimeError( u'Unsupported format type: {0:d}'.format(format_type)) cached_entry_data = value_data[ cached_entry_offset:cached_entry_offset + cached_entry_size] cached_entry_struct = None if format_type == self.FORMAT_TYPE_XP: if cached_entry_size == self._CACHED_ENTRY_XP_32BIT_STRUCT.sizeof( ): cached_entry_struct = self._CACHED_ENTRY_XP_32BIT_STRUCT.parse( cached_entry_data) elif format_type == self.FORMAT_TYPE_2003: if cached_entry_size == self._CACHED_ENTRY_2003_32BIT_STRUCT.sizeof( ): cached_entry_struct = self._CACHED_ENTRY_2003_32BIT_STRUCT.parse( cached_entry_data) elif cached_entry_size == self._CACHED_ENTRY_2003_64BIT_STRUCT.sizeof( ): cached_entry_struct = self._CACHED_ENTRY_2003_64BIT_STRUCT.parse( cached_entry_data) elif format_type == self.FORMAT_TYPE_VISTA: if cached_entry_size == self._CACHED_ENTRY_VISTA_32BIT_STRUCT.sizeof( ): cached_entry_struct = self._CACHED_ENTRY_VISTA_32BIT_STRUCT.parse( cached_entry_data) elif cached_entry_size == self._CACHED_ENTRY_VISTA_64BIT_STRUCT.sizeof( ): cached_entry_struct = self._CACHED_ENTRY_VISTA_64BIT_STRUCT.parse( cached_entry_data) elif format_type == self.FORMAT_TYPE_7: if cached_entry_size == self._CACHED_ENTRY_7_32BIT_STRUCT.sizeof(): cached_entry_struct = self._CACHED_ENTRY_7_32BIT_STRUCT.parse( cached_entry_data) elif cached_entry_size == self._CACHED_ENTRY_7_64BIT_STRUCT.sizeof( ): cached_entry_struct = self._CACHED_ENTRY_7_64BIT_STRUCT.parse( cached_entry_data) elif format_type == self.FORMAT_TYPE_8: if cached_entry_data[0:4] not in [ self._CACHED_ENTRY_SIGNATURE_8_0, self._CACHED_ENTRY_SIGNATURE_8_1 ]: raise RuntimeError(u'Unsupported cache entry signature') if cached_entry_size == self._CACHED_ENTRY_HEADER_8_STRUCT.sizeof( ): cached_entry_struct = self._CACHED_ENTRY_HEADER_8_STRUCT.parse( cached_entry_data) cached_entry_data_size = cached_entry_struct.get( 'cached_entry_data_size') cached_entry_size = 12 + cached_entry_data_size cached_entry_data = value_data[ cached_entry_offset:cached_entry_offset + cached_entry_size] if not cached_entry_struct: raise RuntimeError(u'Unsupported cache entry size: {0:d}'.format( cached_entry_size)) cached_entry_object = AppCompatCacheCachedEntry() cached_entry_object.cached_entry_size = cached_entry_size path_offset = 0 data_size = 0 if format_type == self.FORMAT_TYPE_XP: string_size = 0 for string_index in xrange(0, 528, 2): if (ord(cached_entry_data[string_index]) == 0 and ord(cached_entry_data[string_index + 1]) == 0): break string_size += 2 cached_entry_object.path = binary.Ut16StreamCopyToString( cached_entry_data[0:string_size]) elif format_type in [ self.FORMAT_TYPE_2003, self.FORMAT_TYPE_VISTA, self.FORMAT_TYPE_7 ]: path_size = cached_entry_struct.get('path_size') path_offset = cached_entry_struct.get('path_offset') elif format_type == self.FORMAT_TYPE_8: path_size = cached_entry_struct.get('path_size') cached_entry_data_offset = 14 + path_size cached_entry_object.path = binary.Ut16StreamCopyToString( cached_entry_data[14:cached_entry_data_offset]) remaining_data = cached_entry_data[cached_entry_data_offset:] cached_entry_object.insertion_flags = construct.ULInt32( 'insertion_flags').parse(remaining_data[0:4]) cached_entry_object.shim_flags = construct.ULInt32( 'shim_flags').parse(remaining_data[4:8]) if cached_entry_data[0:4] == self._CACHED_ENTRY_SIGNATURE_8_0: cached_entry_data_offset += 8 elif cached_entry_data[0:4] == self._CACHED_ENTRY_SIGNATURE_8_1: cached_entry_data_offset += 10 remaining_data = cached_entry_data[cached_entry_data_offset:] if format_type in [ self.FORMAT_TYPE_XP, self.FORMAT_TYPE_2003, self.FORMAT_TYPE_VISTA, self.FORMAT_TYPE_7 ]: cached_entry_object.last_modification_time = cached_entry_struct.get( 'last_modification_time') elif format_type == self.FORMAT_TYPE_8: cached_entry_object.last_modification_time = construct.ULInt64( 'last_modification_time').parse(remaining_data[0:8]) if format_type in [self.FORMAT_TYPE_XP, self.FORMAT_TYPE_2003]: cached_entry_object.file_size = cached_entry_struct.get( 'file_size') elif format_type in [self.FORMAT_TYPE_VISTA, self.FORMAT_TYPE_7]: cached_entry_object.insertion_flags = cached_entry_struct.get( 'insertion_flags') cached_entry_object.shim_flags = cached_entry_struct.get( 'shim_flags') if format_type == self.FORMAT_TYPE_XP: cached_entry_object.last_update_time = cached_entry_struct.get( 'last_update_time') if format_type == self.FORMAT_TYPE_7: data_offset = cached_entry_struct.get('data_offset') data_size = cached_entry_struct.get('data_size') elif format_type == self.FORMAT_TYPE_8: data_offset = cached_entry_offset + cached_entry_data_offset + 12 data_size = construct.ULInt32('data_size').parse( remaining_data[8:12]) if path_offset > 0 and path_size > 0: path_size += path_offset cached_entry_object.path = binary.Ut16StreamCopyToString( value_data[path_offset:path_size]) if data_size > 0: data_size += data_offset cached_entry_object.data = value_data[data_offset:data_size] return cached_entry_object
def Parse(self, file_entry): """Extracts events from a Windows Prefetch file. Args: file_entry: A file entry object (instance of dfvfs.FileEntry). Yields: Event objects (instances of EventObject) of the extracted events. """ file_object = file_entry.GetFileObject() file_header = self._ParseFileHeader(file_object) format_version = file_header.get('version', None) if format_version not in [17, 23, 26]: raise errors.UnableToParseFile( u'Unsupported format version: {0:d}'.format(format_version)) file_information = self._ParseFileInformation(file_object, format_version) mapped_files = self._ParseFilenames(file_object, file_information) executable = binary.Ut16StreamCopyToString( file_header.get('executable', u'')) volume_serial_numbers = [] volume_device_paths = [] prefetch_events = [] path = u'' for volume_information in self._ParseVolumesInformationSection( file_object, format_version, file_information): volume_serial_number = volume_information.get('serial_number', 0) volume_device_path = self._ParseVolumeDevicePath( file_object, file_information, volume_information) volume_serial_numbers.append(volume_serial_number) volume_device_paths.append(volume_device_path) timestamp = volume_information.get('creation_time', 0) if timestamp: prefetch_events.append( (timestamp, eventdata.EventTimestamp.CREATION_TIME)) for mapped_file in mapped_files: if (mapped_file.startswith(volume_device_path) and mapped_file.endswith(executable)): _, _, path = mapped_file.partition(volume_device_path) for prefetch_timestamp, prefetch_description in prefetch_events: yield WinPrefetchExecutionEvent(prefetch_timestamp, prefetch_description, file_header, file_information, mapped_files, path, volume_serial_numbers, volume_device_paths) timestamp = file_information.get('last_run_time', 0) if timestamp: yield WinPrefetchExecutionEvent( timestamp, eventdata.EventTimestamp.LAST_RUNTIME, file_header, file_information, mapped_files, path, volume_serial_numbers, volume_device_paths) # Check for the 7 older last run time values available in v26. if format_version == 26: for last_run_time_index in range(1, 8): last_run_time_identifier = 'last_run_time{0:d}'.format( last_run_time_index) timestamp = file_information.get(last_run_time_identifier, 0) if timestamp: yield WinPrefetchExecutionEvent( timestamp, u'Previous {0:s}'.format( eventdata.EventTimestamp.LAST_RUNTIME), file_header, file_information, mapped_files, path, volume_serial_numbers, volume_device_paths) file_object.close()
def Parse(self, parser_context, file_entry): """Extracts events from a Windows Prefetch file. Args: parser_context: A parser context object (instance of ParserContext). file_entry: A file entry object (instance of dfvfs.FileEntry). Yields: Event objects (instances of EventObject) of the extracted events. """ file_object = file_entry.GetFileObject() file_header = self._ParseFileHeader(file_object) format_version = file_header.get('version', None) if format_version not in [17, 23, 26]: raise errors.UnableToParseFile( u'Unsupported format version: {0:d}'.format(format_version)) file_information = self._ParseFileInformation(file_object, format_version) metrics_array = self._ParseMetricsArray( file_object, format_version, file_information) filename_strings = self._ParseFilenameStrings(file_object, file_information) if len(metrics_array) != len(filename_strings): logging.debug( u'Mismatch in number of metrics and filename strings array entries.') executable = binary.Ut16StreamCopyToString( file_header.get('executable', u'')) volume_serial_numbers = [] volume_device_paths = [] path = u'' for volume_information in self._ParseVolumesInformationSection( file_object, format_version, file_information): volume_serial_number = volume_information.get('serial_number', 0) volume_device_path = self._ParseVolumeDevicePath( file_object, file_information, volume_information) volume_serial_numbers.append(volume_serial_number) volume_device_paths.append(volume_device_path) timestamp = volume_information.get('creation_time', 0) if timestamp: event_object = windows_events.WindowsVolumeCreationEvent( timestamp, volume_device_path, volume_serial_number, file_entry.name) parser_context.ProduceEvent( event_object, parser_name=self.NAME, file_entry=file_entry) for filename in filename_strings.itervalues(): if (filename.startswith(volume_device_path) and filename.endswith(executable)): _, _, path = filename.partition(volume_device_path) mapped_files = [] for metrics_array_entry in metrics_array: file_reference = metrics_array_entry.get('file_reference', 0) filename_string_offset = metrics_array_entry.get( 'filename_string_offset', 0) filename = filename_strings.get(filename_string_offset, u'') if not filename: logging.debug(u'Missing filename string for offset: {0:d}.'.format( filename_string_offset)) continue if file_reference: mapped_file_string = ( u'{0:s} [MFT entry: {1:d}, sequence: {2:d}]').format( filename, file_reference & 0xffffffffffffL, file_reference >> 48) else: mapped_file_string = filename mapped_files.append(mapped_file_string) timestamp = file_information.get('last_run_time', 0) if timestamp: event_object = WinPrefetchExecutionEvent( timestamp, eventdata.EventTimestamp.LAST_RUNTIME, file_header, file_information, mapped_files, path, volume_serial_numbers, volume_device_paths) parser_context.ProduceEvent( event_object, parser_name=self.NAME, file_entry=file_entry) # Check for the 7 older last run time values available in v26. if format_version == 26: for last_run_time_index in range(1, 8): last_run_time_identifier = 'last_run_time{0:d}'.format( last_run_time_index) timestamp = file_information.get(last_run_time_identifier, 0) if timestamp: event_object = WinPrefetchExecutionEvent( timestamp, u'Previous {0:s}'.format(eventdata.EventTimestamp.LAST_RUNTIME), file_header, file_information, mapped_files, path, volume_serial_numbers, volume_device_paths) parser_context.ProduceEvent( event_object, parser_name=self.NAME, file_entry=file_entry) file_object.close()
def ParseFileObject(self, parser_mediator, file_object, **kwargs): """Parses a Windows Prefetch file-like object. Args: parser_mediator: A parser mediator object (instance of ParserMediator). file_object: A file-like object. Raises: UnableToParseFile: when the file cannot be parsed. """ file_object.seek(0, os.SEEK_SET) file_header = self._ParseFileHeader(file_object) format_version = file_header.get(u'version', None) if format_version not in [17, 23, 26]: raise errors.UnableToParseFile( u'Unsupported format version: {0:d}'.format(format_version)) file_information = self._ParseFileInformation(file_object, format_version) metrics_array = self._ParseMetricsArray( file_object, format_version, file_information) try: filename_strings = self._ParseFilenameStrings( file_object, file_information) except UnicodeDecodeError as exception: file_name = parser_mediator.GetDisplayName() logging.warning(( u'[{0:s}] Unable to parse filename information from file {1:s} ' u'with error: {2:s}').format( parser_mediator.GetParserChain(), file_name, exception)) filename_strings = {} if len(metrics_array) != len(filename_strings): logging.debug( u'Mismatch in number of metrics and filename strings array entries.') executable = binary.Ut16StreamCopyToString( file_header.get(u'executable', u'')) volume_serial_numbers = [] volume_device_paths = [] path = u'' for volume_information in self._ParseVolumesInformationSection( file_object, format_version, file_information): volume_serial_number = volume_information.get(u'serial_number', 0) volume_device_path = self._ParseVolumeDevicePath( file_object, file_information, volume_information) volume_serial_numbers.append(volume_serial_number) volume_device_paths.append(volume_device_path) timestamp = volume_information.get(u'creation_time', 0) if timestamp: event_object = windows_events.WindowsVolumeCreationEvent( timestamp, volume_device_path, volume_serial_number, parser_mediator.GetFileEntry().name) parser_mediator.ProduceEvent(event_object) for filename in filename_strings.itervalues(): if not filename: continue if (filename.startswith(volume_device_path) and filename.endswith(executable)): _, _, path = filename.partition(volume_device_path) mapped_files = [] for metrics_array_entry in metrics_array: file_reference = metrics_array_entry.get(u'file_reference', 0) filename_string_offset = metrics_array_entry.get( u'filename_string_offset', 0) filename = filename_strings.get(filename_string_offset, u'') if not filename: logging.debug(u'Missing filename string for offset: {0:d}.'.format( filename_string_offset)) continue if file_reference: mapped_file_string = ( u'{0:s} [MFT entry: {1:d}, sequence: {2:d}]').format( filename, file_reference & 0xffffffffffffL, file_reference >> 48) else: mapped_file_string = filename mapped_files.append(mapped_file_string) timestamp = file_information.get(u'last_run_time', 0) if timestamp: event_object = WinPrefetchExecutionEvent( timestamp, eventdata.EventTimestamp.LAST_RUNTIME, file_header, file_information, mapped_files, path, volume_serial_numbers, volume_device_paths) parser_mediator.ProduceEvent(event_object) # Check for the 7 older last run time values available in v26. if format_version == 26: for last_run_time_index in range(1, 8): last_run_time_identifier = u'last_run_time{0:d}'.format( last_run_time_index) timestamp = file_information.get(last_run_time_identifier, 0) if timestamp: event_object = WinPrefetchExecutionEvent( timestamp, u'Previous {0:s}'.format(eventdata.EventTimestamp.LAST_RUNTIME), file_header, file_information, mapped_files, path, volume_serial_numbers, volume_device_paths) parser_mediator.ProduceEvent(event_object)