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)))
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)))
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")