def parseTOC(self):
        # Go to the table of contents
        self.fPtr.seek(self.tableOfContentsPos, os.SEEK_SET)

        self.tocList = []
        parsedLen = 0

        # Parse table of contents
        while parsedLen < self.tableOfContentsSize:
            (entrySize, ) = struct.unpack('!i', self.fPtr.read(4))
            nameLen = struct.calcsize('!iiiiBc')

            (entryPos, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name) = \
            struct.unpack( \
                '!iiiBc{}s'.format(entrySize - nameLen), \
                self.fPtr.read(entrySize - 4))
            
            name = name.decode('utf-8').rstrip('\0')
            if len(name) == 0:
                name = str(uniquename())
                print('[!] Warning: Found an unamed file in CArchive. Using random name {}'.format(name))
                
            self.tocList.append( \
                                CTOCEntry(                      \
                                    self.overlayPos + entryPos, \
                                    cmprsdDataSize,             \
                                    uncmprsdDataSize,           \
                                    cmprsFlag,                  \
                                    typeCmprsData,              \
                                    name                        \
                                ))

            parsedLen += entrySize
        print('[*] Found {} files in CArchive'.format(len(self.tocList)))
Exemple #2
0
    def parseTOC(self):
        # Go to the table of contents
        self.fPtr.seek(self.tableOfContentsPos, os.SEEK_SET)

        self.tocList = []
        parsedLen = 0

        # Parse table of contents
        while parsedLen < self.tableOfContentsSize:
            (entrySize, ) = struct.unpack('!i', self.fPtr.read(4))
            nameLen = struct.calcsize('!iiiiBc')

            (entryPos, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name) = \
            struct.unpack( \
                '!iiiBc{0}s'.format(entrySize - nameLen), \
                self.fPtr.read(entrySize - 4))

            name = name.decode('utf-8').rstrip('\0')
            if len(name) == 0:
                name = str(uniquename())
                print('[!] Warning: Found an unamed file in CArchive. Using random name {0}'.format(name))

            self.tocList.append( \
                                CTOCEntry(                      \
                                    entryPos, \
                                    cmprsdDataSize,             \
                                    uncmprsdDataSize,           \
                                    cmprsFlag,                  \
                                    typeCmprsData,              \
                                    name                        \
                                ))

            parsedLen += entrySize
        print('[*] Found {0} files in CArchive'.format(len(self.tocList)))
Exemple #3
0
    def parse_toc(self):
        # Read CArchive cookie
        if self.pyinstaller_version == 2.0 or self.pyinstaller_version == "unknown":
            try:
                (
                    magic,
                    self.length_of_package,
                    self.toc_offset,
                    self.toc_size,
                    self.python_version,
                ) = struct.unpack(
                    "!8siiii",
                    self.archive_contents[self.magic_index:self.magic_index +
                                          self.PYINST20_COOKIE_SIZE],
                )
            except:
                pass
            else:
                self.pyinstaller_version = 2.0
        if self.pyinstaller_version == 2.1 or self.pyinstaller_version == "unknown":
            try:
                (
                    magic,
                    self.length_of_package,
                    self.toc_offset,
                    self.toc_size,
                    self.python_version,
                    self.python_dynamic_lib,
                ) = struct.unpack(
                    "!8siiii64s",
                    self.archive_contents[self.magic_index:self.magic_index +
                                          self.PYINST21_COOKIE_SIZE],
                )
            except:
                pass
            else:
                self.pyinstaller_version = 2.1
                if self.python_dynamic_lib:
                    self.python_dynamic_lib = self.python_dynamic_lib.decode(
                        "ascii").rstrip("\x00")

        if self.pyinstaller_version == "unknown":
            logger.warning(
                "[!] Could not parse CArchive because PyInstaller version is unknown."
            )
            return

        self.python_version = float(self.python_version) / 10
        logger.info(
            f"[*] This CArchive was built with Python {self.python_version}")
        logger.debug(f"[*] CArchive Package Size: {self.length_of_package}")
        logger.debug(f"[*] CArchive Python Version: {self.python_version}")
        if self.pyinstaller_version == 2.1:
            logger.debug(
                f"[*] CArchive Python Dynamic Library Name: {self.python_dynamic_lib}"
            )

        self.toc = []
        toc_bytes = self.archive_contents[self.toc_offset:self.toc_offset +
                                          self.toc_size]
        while toc_bytes:
            (entry_size, ) = struct.unpack("!i", toc_bytes[0:4])
            name_length = entry_size - self.CTOCEntry.ENTRYLEN
            (
                entry_offset,
                compressed_data_size,
                uncompressed_data_size,
                compression_flag,
                type_code,
                name,
            ) = struct.unpack(f"!iiiBB{name_length}s", toc_bytes[4:entry_size])

            name = name.decode("utf-8").rstrip("\0")
            if name == "":
                name = str(uniquename())
                logger.debug(
                    f"[!] Warning: Found an unnamed file in CArchive. Using random name {name}"
                )

            type_code = chr(type_code)
            self.toc.append(
                self.CTOCEntry(
                    entry_offset,
                    compressed_data_size,
                    uncompressed_data_size,
                    compression_flag,
                    type_code,
                    name,
                ))

            toc_bytes = toc_bytes[entry_size:]
        logger.debug(
            f"[*] Found {len(self.toc)} entries in this PyInstaller CArchive")