def testReadUTF16Stream(self): """Test reading an UTF-16 stream from a file-like object.""" test_file_path = self._GetTestFilePath(['PING.EXE-B29F6629.pf']) with open(test_file_path, 'rb') as file_object: # Read a null char terminated string. file_object.seek(0x10) self.assertEqual(binary.ReadUTF16Stream(file_object), 'PING.EXE') # Read a fixed size string. file_object.seek(0x27f8) expected_string = '\\DEVICE\\HARDDISKVOLUME' string = binary.ReadUTF16Stream(file_object, byte_size=44) self.assertEqual(string, expected_string) file_object.seek(0x27f8) expected_string = '\\DEVICE\\HARDDISKVOLUME1' string = binary.ReadUTF16Stream(file_object, byte_size=46) self.assertEqual(string, expected_string) # Read another null char terminated string. file_object.seek(7236) self.assertEqual( binary.ReadUTF16Stream(file_object), '\\DEVICE\\HARDDISKVOLUME1\\WINDOWS\\SYSTEM32\\NTDLL.DLL')
def _ReadFilename(self, parser_mediator, file_object, format_version): """Reads the filename. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. file_object (FileIO): file-like object. format_version (int): format version. Returns: str: filename """ if format_version == 1: return binary.ReadUTF16Stream(file_object) try: filename_struct = self._FILENAME_V2_STRUCT.parse_stream( file_object) except (IOError, construct.FieldError) as exception: parser_mediator.ProduceExtractionError( u'unable to parse filename with error: {0:s}'.format( exception)) return return binary.ReadUTF16(filename_struct.string)
def ParseFileObject(self, parser_mediator, file_object, **kwargs): """Parses a Windows RecycleBin $Ixx 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. """ try: magic_header = self.MAGIC_STRUCT.parse_stream(file_object) except (construct.FieldError, IOError) as exception: raise errors.UnableToParseFile( u'Unable to parse $Ixxx file with error: {0:s}'.format( exception)) if magic_header != 1: raise errors.UnableToParseFile( u'Not an $Ixxx file, wrong magic header.') # We may have to rely on filenames since this header is very generic. # TODO: Rethink this and potentially make a better test. filename = parser_mediator.GetFilename() if not filename.startswith(u'$I'): raise errors.UnableToParseFile( u'Not an $Ixxx file, filename doesn\'t start with $I.') record = self.RECORD_STRUCT.parse_stream(file_object) filename_utf = binary.ReadUTF16Stream(file_object) filetime = record.get(u'filetime', 0) # TODO: handle missing timestamp. event_object = WinRecycleEvent(filetime, u'', filename_utf, record, 0) parser_mediator.ProduceEvent(event_object)
def ParseFileObject(self, parser_mediator, file_object, **kwargs): """Parses a Windows RecycleBin $Ixx 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. """ # We may have to rely on filenames since this header is very generic. # TODO: Rethink this and potentially make a better test. filename = parser_mediator.GetFilename() if not filename.startswith(u'$I'): return try: header_struct = self._FILE_HEADER_STRUCT.parse_stream(file_object) except (IOError, construct.FieldError) as exception: parser_mediator.ProduceExtractionError( u'unable to parse file header with error: {0:s}'.format( exception)) return if header_struct.format_version not in (1, 2): parser_mediator.ProduceExtractionError( u'unsupported format version: {0:d}.'.format( header_struct.format_version)) return filename = None if header_struct.format_version == 1: filename = binary.ReadUTF16Stream(file_object) else: try: filename_struct = self._FILENAME_V2_STRUCT.parse_stream( file_object) filename = binary.ReadUTF16(filename_struct.string) except (IOError, construct.FieldError) as exception: parser_mediator.ProduceExtractionError( u'unable to parse filename with error: {0:s}'.format( exception)) return event = WinRecycleEvent(header_struct.deletion_time, filename, header_struct.file_size) parser_mediator.ProduceEvent(event)
def _ParseVolumeDevicePath(self, file_object, file_information, volume_information): """Parses the volume device path. This function expects the current offset of the file-like object to point as the end of the volume information structure. Args: file_object: A file-like object to read data from. file_information: The file information construct object. volume_information: The volume information construct object. Returns: A Unicode string containing the device path or None if not available. """ volumes_information_offset = file_information.get( u'volumes_information_offset', 0) device_path = None if volumes_information_offset > 0: device_path_offset = volume_information.get( u'device_path_offset', 0) device_path_size = 2 * volume_information.get( u'device_path_number_of_characters', 0) if device_path_offset >= 36 and device_path_size > 0: device_path_offset += volumes_information_offset current_offset = file_object.tell() file_object.seek(device_path_offset, os.SEEK_SET) device_path = binary.ReadUTF16Stream( file_object, byte_size=device_path_size) file_object.seek(current_offset, os.SEEK_SET) return device_path