Beispiel #1
0
    def testSeek(self):
        """Tests the seek function."""
        file_object = io.BytesIO(self._FILE_DATA)
        test_range = data_range.DataRange(file_object,
                                          data_offset=32,
                                          data_size=64)

        test_range.seek(0, os.SEEK_SET)
        offset = test_range.get_offset()
        self.assertEqual(offset, 0)

        test_range.seek(0, os.SEEK_END)
        offset = test_range.get_offset()
        self.assertEqual(offset, 64)

        test_range.seek(-32, os.SEEK_CUR)
        offset = test_range.get_offset()
        self.assertEqual(offset, 32)

        test_range.seek(128, os.SEEK_SET)
        offset = test_range.get_offset()
        self.assertEqual(offset, 128)

        with self.assertRaises(IOError):
            test_range.seek(0, -1)

        with self.assertRaises(IOError):
            test_range.seek(-256, os.SEEK_CUR)

        test_range.data_size = -1

        with self.assertRaises(IOError):
            test_range.seek(0, os.SEEK_SET)

        test_range.data_offset = 64
Beispiel #2
0
    def testRead(self):
        """Tests the read function."""
        file_object = io.BytesIO(self._FILE_DATA)
        test_range = data_range.DataRange(file_object,
                                          data_offset=32,
                                          data_size=64)

        byte_stream = test_range.read(size=1)
        self.assertEqual(byte_stream, b'\x20')

        byte_stream = test_range.read()
        self.assertEqual(len(byte_stream), 63)

        byte_stream = test_range.read()
        self.assertEqual(byte_stream, b'')

        test_range.data_offset = -1

        with self.assertRaises(IOError):
            test_range.read()

        test_range.data_offset = 32

        test_range.data_size = -1

        with self.assertRaises(IOError):
            test_range.read()

        test_range.data_offset = 64
Beispiel #3
0
    def testTell(self):
        """Tests the tell function."""
        file_object = io.BytesIO(self._FILE_DATA)
        test_range = data_range.DataRange(file_object,
                                          data_offset=32,
                                          data_size=64)

        offset = test_range.tell()
        self.assertEqual(offset, 0)
Beispiel #4
0
    def testSeekable(self):
        """Tests the seekable function."""
        file_object = io.BytesIO(self._FILE_DATA)
        test_range = data_range.DataRange(file_object,
                                          data_offset=32,
                                          data_size=64)

        result = test_range.seekable()
        self.assertTrue(result)
Beispiel #5
0
    def testGetSize(self):
        """Tests the get_size function."""
        file_object = io.BytesIO(self._FILE_DATA)
        test_range = data_range.DataRange(file_object,
                                          data_offset=32,
                                          data_size=64)

        size = test_range.get_size()
        self.assertEqual(size, 64)
Beispiel #6
0
  def _ReadLNKFiles(self, file_object):
    """Reads the LNK files.

    Args:
      file_object (file): file-like object.

    Raises:
      ParseError: if the LNK files cannot be read.
    """
    file_offset = file_object.tell()
    remaining_file_size = self._file_size - file_offset
    data_type_map = self._GetDataTypeMap('custom_entry_header')

    # The Custom Destination file does not have a unique signature in
    # the file header that is why we use the first LNK class identifier (GUID)
    # as a signature.
    first_guid_checked = False
    while remaining_file_size > 4:
      try:
        entry_header, _ = self._ReadStructureFromFileObject(
            file_object, file_offset, data_type_map, 'entry header')

      except errors.ParseError as exception:
        error_message = (
            'Unable to parse file entry header at offset: 0x{0:08x} '
            'with error: {1:s}').format(file_offset, exception)

        if not first_guid_checked:
          raise errors.ParseError(error_message)

        logging.warning(error_message)
        break

      if entry_header.guid != self._LNK_GUID:
        error_message = 'Invalid entry header at offset: 0x{0:08x}.'.format(
            file_offset)

        if not first_guid_checked:
          raise errors.ParseError(error_message)

        file_object.seek(-16, os.SEEK_CUR)
        self._ReadFileFooter(file_object)

        file_object.seek(-4, os.SEEK_CUR)
        break

      first_guid_checked = True
      file_offset += 16
      remaining_file_size -= 16

      lnk_file_object = data_range.DataRange(
          file_object, data_offset=file_offset, data_size=remaining_file_size)

      lnk_file_entry = self._ReadLNKFile(lnk_file_object)
      if lnk_file_entry:
        self.entries.append(lnk_file_entry)

      file_offset += lnk_file_entry.data_size
      remaining_file_size -= lnk_file_entry.data_size

      file_object.seek(file_offset, os.SEEK_SET)
Beispiel #7
0
    def HashFileEntries(self):
        """Hashes the file entries stored in the CPIO archive file."""
        stat_object = os.stat(self._path)

        file_object = open(self._path, 'rb')

        file_offset = 0
        file_size = stat_object.st_size

        # initrd files can consist of an uncompressed and compressed cpio archive.
        # Keeping the functionality in this script for now, but this likely
        # needs to be in a separate initrd hashing script.
        while file_offset < stat_object.st_size:
            file_object.seek(file_offset, os.SEEK_SET)
            signature_data = file_object.read(6)

            file_type = None
            if len(signature_data) > 2:
                if (signature_data[:2]
                        in (self._CPIO_SIGNATURE_BINARY_BIG_ENDIAN,
                            self._CPIO_SIGNATURE_BINARY_LITTLE_ENDIAN)
                        or signature_data
                        in (self._CPIO_SIGNATURE_PORTABLE_ASCII,
                            self._CPIO_SIGNATURE_NEW_ASCII,
                            self._CPIO_SIGNATURE_NEW_ASCII_WITH_CHECKSUM)):
                    file_type = 'cpio'
                elif signature_data[:2] == self._GZIP_SIGNATURE:
                    file_type = 'gzip'
                elif signature_data[:2] == self._BZIP_SIGNATURE:
                    file_type = 'bzip'
                elif signature_data == self._XZ_SIGNATURE:
                    file_type = 'xz'

            if not file_type:
                self._output_writer.WriteText(
                    'Unsupported file type at offset: 0x{0:08x}.\n'.format(
                        file_offset))
                return

            if file_type == 'cpio':
                file_object.seek(file_offset, os.SEEK_SET)
                cpio_file_object = file_object
            elif file_type in ('bzip', 'gzip', 'xz'):
                compressed_data_size = file_size - file_offset
                compressed_data_file_object = data_range.DataRange(
                    file_object,
                    data_offset=file_offset,
                    data_size=compressed_data_size)

                if file_type == 'bzip':
                    cpio_file_object = bz2.BZ2File(compressed_data_file_object)
                elif file_type == 'gzip':
                    cpio_file_object = gzip.GzipFile(
                        fileobj=compressed_data_file_object)  # pylint: disable=no-member
                elif file_type == 'xz' and lzma:
                    cpio_file_object = lzma.LZMAFile(
                        compressed_data_file_object)

            cpio_archive_file = cpio.CPIOArchiveFile(debug=self._debug)
            cpio_archive_file.ReadFileObject(cpio_file_object)

            for file_entry in sorted(cpio_archive_file.GetFileEntries()):
                if file_entry.data_size == 0:
                    continue

                sha256_context = hashlib.sha256()
                file_data = file_entry.read(4096)
                while file_data:
                    sha256_context.update(file_data)
                    file_data = file_entry.read(4096)

                self._output_writer.WriteText('{0:s}\t{1:s}\n'.format(
                    sha256_context.hexdigest(), file_entry.path))

            file_offset += cpio_archive_file.size

            padding_size = file_offset % 16
            if padding_size > 0:
                file_offset += 16 - padding_size

            cpio_archive_file.Close()