예제 #1
0
    def setUp(self):
        self.zipper = ZipFile(ZIP_TEMP_FILE)
        self.subfile = ZipSubFile(self.zipper, FILE_NAME)
        self.subfile.open()

        # create a file in memory for comparison
        self.compare = TemporaryFile(prefix='oletools-test-ZipSubFile-',
                                     suffix='.bin')
        self.compare.write(FILE_CONTENTS)
        self.compare.seek(0)  # re-position to start

        self.assertEqual(self.subfile.tell(), 0)
        self.assertEqual(self.compare.tell(), 0)
        if DEBUG:
            print('created comparison file {0!r} in memory'.format(
                self.compare.name))
예제 #2
0
    def setUp(self):
        self.zipper = ZipFile(ZIP_TEMP_FILE)
        self.subfile = ZipSubFile(self.zipper, FILE_NAME)
        self.subfile.open()

        # create a file in memory for comparison
        self.compare = TemporaryFile(prefix='oletools-test-ZipSubFile-',
                                     suffix='.bin')
        self.compare.write(FILE_CONTENTS)
        self.compare.seek(0)   # re-position to start

        self.assertEqual(self.subfile.tell(), 0)
        self.assertEqual(self.compare.tell(), 0)
        if DEBUG:
            print('created comparison file {0!r} in memory'
                  .format(self.compare.name))
예제 #3
0
def find_ole(filename, data):
    """ try to open somehow as zip/ole/rtf/... ; yield None if fail

    If data is given, filename is (mostly) ignored.

    yields embedded ole streams in form of OleFileIO.
    """

    if data is not None:
        # isOleFile and is_ppt can work on data directly but zip need file
        # --> wrap data in a file-like object without copying data
        log.debug('working on data, file is not touched below')
        arg_for_ole = data
        arg_for_zip = FakeFile(data)
    else:
        # we only have a file name
        log.debug('working on file by name')
        arg_for_ole = filename
        arg_for_zip = filename

    ole = None
    try:
        if olefile.isOleFile(arg_for_ole):
            if is_ppt(arg_for_ole):
                log.info('is ppt file: ' + filename)
                for ole in find_ole_in_ppt(arg_for_ole):
                    yield ole
                    ole = None  # is closed in find_ole_in_ppt
            # in any case: check for embedded stuff in non-sectored streams
            log.info('is ole file: ' + filename)
            ole = olefile.OleFileIO(arg_for_ole)
            yield ole
        elif is_zipfile(arg_for_zip):
            log.info('is zip file: ' + filename)
            zipper = ZipFile(arg_for_zip, 'r')
            for subfile in zipper.namelist():
                head = b''
                try:
                    with zipper.open(subfile) as file_handle:
                        head = file_handle.read(len(olefile.MAGIC))
                except RuntimeError:
                    log.error('zip is encrypted: ' + filename)
                    yield None
                    continue

                if head == olefile.MAGIC:
                    log.info('  unzipping ole: ' + subfile)
                    with ZipSubFile(zipper, subfile) as file_handle:
                        try:
                            ole = olefile.OleFileIO(file_handle)
                            yield ole
                        except IOError:
                            log.warning('Error reading data from {0}/{1} or '
                                        'interpreting it as OLE object'.format(
                                            filename, subfile))
                            log.debug('', exc_info=True)
                        finally:
                            if ole is not None:
                                ole.close()
                                ole = None
                else:
                    log.debug('unzip skip: ' + subfile)
        else:
            log.warning(
                'open failed: {0} (or its data) is neither zip nor OLE'.format(
                    filename))
            yield None
    except Exception:
        log.error('Caught exception opening {0}'.format(filename),
                  exc_info=True)
        yield None
    finally:
        if ole is not None:
            ole.close()
예제 #4
0
class TestZipSubFile(unittest.TestCase):
    """ Tests ZipSubFile """

    def setUp(self):
        self.zipper = ZipFile(ZIP_TEMP_FILE)
        self.subfile = ZipSubFile(self.zipper, FILE_NAME)
        self.subfile.open()

        # create a file in memory for comparison
        self.compare = TemporaryFile(prefix='oletools-test-ZipSubFile-',
                                     suffix='.bin')
        self.compare.write(FILE_CONTENTS)
        self.compare.seek(0)   # re-position to start

        self.assertEqual(self.subfile.tell(), 0)
        self.assertEqual(self.compare.tell(), 0)
        if DEBUG:
            print('created comparison file {0!r} in memory'
                  .format(self.compare.name))

    def tearDown(self):
        self.compare.close()
        self.subfile.close()
        self.zipper.close()
        if DEBUG:
            print('\nall files closed')

    def test_read(self):
        """ test reading """
        # read from start
        self.assertEqual(self.subfile.read(4), self.compare.read(4))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # read a bit more
        self.assertEqual(self.subfile.read(4), self.compare.read(4))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # create difference
        self.subfile.read(1)
        self.assertNotEqual(self.subfile.read(4), self.compare.read(4))
        self.compare.read(1)
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # read all the rest
        self.assertEqual(self.subfile.read(), self.compare.read())
        self.assertEqual(self.subfile.tell(), self.compare.tell())

    def test_seek_forward(self):
        """ test seeking forward """
        self.subfile.seek(10)
        self.compare.seek(10)
        self.assertEqual(self.subfile.read(1), self.compare.read(1))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # seek 2 forward
        self.subfile.seek(2, os.SEEK_CUR)
        self.compare.seek(2, os.SEEK_CUR)
        self.assertEqual(self.subfile.read(1), self.compare.read(1))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # seek backward (only implemented case: back to start)
        self.subfile.seek(-self.subfile.tell(), os.SEEK_CUR)
        self.compare.seek(-self.compare.tell(), os.SEEK_CUR)
        self.assertEqual(self.subfile.read(1), self.compare.read(1))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # seek to end
        self.subfile.seek(0, os.SEEK_END)
        self.compare.seek(0, os.SEEK_END)
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # seek back to start
        self.subfile.seek(0)
        self.compare.seek(0)
        self.assertEqual(self.subfile.tell(), self.compare.tell())
        self.assertEqual(self.subfile.tell(), 0)

    def test_check_size(self):
        """ test usual size check: seek to end, tell, seek to start """
        # seek to end
        self.subfile.seek(0, os.SEEK_END)
        self.assertEqual(self.subfile.tell(), len(FILE_CONTENTS))

        # seek back to start
        self.subfile.seek(0)

        # read first few bytes
        self.assertEqual(self.subfile.read(10), FILE_CONTENTS[:10])

    def test_error_read(self):
        """ test correct behaviour if read beyond end (no exception) """
        self.subfile.seek(0, os.SEEK_END)
        self.compare.seek(0, os.SEEK_END)

        self.assertEquals(self.compare.read(10), self.subfile.read(10))
        self.assertEquals(self.compare.tell(), self.subfile.tell())

        self.subfile.seek(0)
        self.compare.seek(0)
        self.subfile.seek(len(FILE_CONTENTS) - 1)
        self.compare.seek(len(FILE_CONTENTS) - 1)
        self.assertEquals(self.compare.read(10), self.subfile.read(10))
        self.assertEquals(self.compare.tell(), self.subfile.tell())

    def test_error_seek(self):
        """ test correct behaviour if seek beyond end (no exception) """
        self.subfile.seek(len(FILE_CONTENTS) + 10)
        self.compare.seek(len(FILE_CONTENTS) + 10)
예제 #5
0
class TestZipSubFile(unittest.TestCase):
    """ Tests ZipSubFile """
    def setUp(self):
        self.zipper = ZipFile(ZIP_TEMP_FILE)
        self.subfile = ZipSubFile(self.zipper, FILE_NAME)
        self.subfile.open()

        # create a file in memory for comparison
        self.compare = TemporaryFile(prefix='oletools-test-ZipSubFile-',
                                     suffix='.bin')
        self.compare.write(FILE_CONTENTS)
        self.compare.seek(0)  # re-position to start

        self.assertEqual(self.subfile.tell(), 0)
        self.assertEqual(self.compare.tell(), 0)
        if DEBUG:
            print('created comparison file {0!r} in memory'.format(
                self.compare.name))

    def tearDown(self):
        self.compare.close()
        self.subfile.close()
        self.zipper.close()
        if DEBUG:
            print('\nall files closed')

    def test_read(self):
        """ test reading """
        # read from start
        self.assertEqual(self.subfile.read(4), self.compare.read(4))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # read a bit more
        self.assertEqual(self.subfile.read(4), self.compare.read(4))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # create difference
        self.subfile.read(1)
        self.assertNotEqual(self.subfile.read(4), self.compare.read(4))
        self.compare.read(1)
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # read all the rest
        self.assertEqual(self.subfile.read(), self.compare.read())
        self.assertEqual(self.subfile.tell(), self.compare.tell())

    def test_seek_forward(self):
        """ test seeking forward """
        self.subfile.seek(10)
        self.compare.seek(10)
        self.assertEqual(self.subfile.read(1), self.compare.read(1))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # seek 2 forward
        self.subfile.seek(2, os.SEEK_CUR)
        self.compare.seek(2, os.SEEK_CUR)
        self.assertEqual(self.subfile.read(1), self.compare.read(1))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # seek backward (only implemented case: back to start)
        self.subfile.seek(-self.subfile.tell(), os.SEEK_CUR)
        self.compare.seek(-self.compare.tell(), os.SEEK_CUR)
        self.assertEqual(self.subfile.read(1), self.compare.read(1))
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # seek to end
        self.subfile.seek(0, os.SEEK_END)
        self.compare.seek(0, os.SEEK_END)
        self.assertEqual(self.subfile.tell(), self.compare.tell())

        # seek back to start
        self.subfile.seek(0)
        self.compare.seek(0)
        self.assertEqual(self.subfile.tell(), self.compare.tell())
        self.assertEqual(self.subfile.tell(), 0)

    def test_check_size(self):
        """ test usual size check: seek to end, tell, seek to start """
        # seek to end
        self.subfile.seek(0, os.SEEK_END)
        self.assertEqual(self.subfile.tell(), len(FILE_CONTENTS))

        # seek back to start
        self.subfile.seek(0)

        # read first few bytes
        self.assertEqual(self.subfile.read(10), FILE_CONTENTS[:10])

    def test_error_read(self):
        """ test correct behaviour if read beyond end (no exception) """
        self.subfile.seek(0, os.SEEK_END)
        self.compare.seek(0, os.SEEK_END)

        self.assertEqual(self.compare.read(10), self.subfile.read(10))
        self.assertEqual(self.compare.tell(), self.subfile.tell())

        self.subfile.seek(0)
        self.compare.seek(0)
        self.subfile.seek(len(FILE_CONTENTS) - 1)
        self.compare.seek(len(FILE_CONTENTS) - 1)
        self.assertEqual(self.compare.read(10), self.subfile.read(10))
        self.assertEqual(self.compare.tell(), self.subfile.tell())

    def test_error_seek(self):
        """ test correct behaviour if seek beyond end (no exception) """
        self.subfile.seek(len(FILE_CONTENTS) + 10)
        self.compare.seek(len(FILE_CONTENTS) + 10)