def ParseVolumesInApfsContainer(img, vol_info, container_size, container_start_offset, container_uuid): global mac_info mac_info = macinfo.ApfsMacInfo(mac_info.output_params, mac_info.password, mac_info.dont_decrypt) mac_info.pytsk_image = img # Must be populated mac_info.vol_info = vol_info # Must be populated mac_info.is_apfs = True mac_info.macos_partition_start_offset = container_start_offset # apfs container offset mac_info.apfs_container = ApfsContainer(img, container_size, container_start_offset) # Check if this is 10.15 style System + Data volume? for vol in mac_info.apfs_container.volumes: if vol.role == vol.container.apfs.VolumeRoleType.system.value: log.debug("{} is SYSTEM volume type".format(vol.volume_name)) mac_info.apfs_sys_volume = vol elif vol.role == vol.container.apfs.VolumeRoleType.data.value: log.debug("{} is DATA volume type".format(vol.volume_name)) mac_info.apfs_data_volume = vol try: # start db use_existing_db = False apfs_sqlite_path = os.path.join( mac_info.output_params.output_path, "APFS_Volumes_" + str(container_uuid).upper() + ".db") if os.path.exists(apfs_sqlite_path): # Check if db already exists existing_db = SqliteWriter( ) # open & check if it has the correct data existing_db.OpenSqliteDb(apfs_sqlite_path) apfs_db_info = ApfsDbInfo(existing_db) if apfs_db_info.CheckVerInfo( ) and apfs_db_info.CheckVolInfoAndGetVolEncKey( mac_info.apfs_container.volumes): # all good, db is up to date, use it use_existing_db = True mac_info.apfs_db = existing_db if mac_info.apfs_sys_volume: mac_info.apfs_data_volume.dbo = mac_info.apfs_db mac_info.apfs_sys_volume.dbo = mac_info.apfs_db mac_info.UseCombinedVolume() log.info( 'Found an existing APFS_Volumes.db in the output folder, looks good, will not create a new one!' ) else: # db does not seem up to date, create a new one and read info existing_db.CloseDb() log.info( 'Found an existing APFS_Volumes.db in the output folder, but it is STALE, creating a new one!' ) os.remove(apfs_sqlite_path) if not use_existing_db: apfs_sqlite_path = SqliteWriter.CreateSqliteDb( apfs_sqlite_path) # Will create with next avail file name mac_info.apfs_db = SqliteWriter() mac_info.apfs_db.OpenSqliteDb(apfs_sqlite_path) try: log.info( 'Reading APFS volumes from container, this may take a few minutes ...' ) mac_info.ReadApfsVolumes() apfs_db_info = ApfsDbInfo(mac_info.apfs_db) apfs_db_info.WriteVolInfo(mac_info.apfs_container.volumes) if mac_info.apfs_sys_volume: mac_info.apfs_data_volume.dbo = mac_info.apfs_db mac_info.apfs_sys_volume.dbo = mac_info.apfs_db if not mac_info.CreateCombinedVolume(): return False apfs_db_info.WriteVersionInfo() except: log.exception('Error while reading APFS volumes') return False mac_info.output_params.apfs_db_path = apfs_sqlite_path if mac_info.apfs_db != None: #test, export a file # output_params.export_path = os.path.join(output_params.output_path, "Export") # if not os.path.exists(output_params.export_path): # try: # os.makedirs(output_params.export_path) # except Exception as ex: # log.error("Exception while creating Export folder: " + output_params.export_path + "\n Is the location Writeable?" + # "Is drive full? Perhaps the drive is disconnected? Exception Details: " + str(ex)) # Exit() # export_sqlite_path = SqliteWriter.CreateSqliteDb(os.path.join(output_params.export_path, "Exported_Files_Log.db")) # writer = SqliteWriter(asynchronous=True) # writer.OpenSqliteDb(export_sqlite_path) # column_info = collections.OrderedDict([ ('SourcePath',DataType.TEXT), ('ExportPath',DataType.TEXT), # ('InodeModifiedTime',DataType.DATE),('ModifiedTime',DataType.DATE), # ('CreatedTime',DataType.DATE),('AccessedTime',DataType.DATE) ]) # writer.CreateTable(column_info, 'ExportedFileInfo') # output_params.export_log_sqlite = writer # mac_info.macos_FS = mac_info.apfs_container.volumes[0] # mac_info.apfs_container.volumes[0].dbo = mac_info.apfs_db # mac_info.ExportFile('/kyoto-1976538_1920.jpg', 'test', '') # output_params.export_log_sqlite.CloseDb() #endtest mac_info.apfs_db.CloseDb() mac_info.apfs_db = None return True except Exception as ex: log.info('Sqlite db could not be created at : ' + apfs_sqlite_path) log.exception( 'Exception occurred when trying to create APFS_Volumes Sqlite db') return False
def FindMacOsPartitionInApfsContainer(img, vol_info, container_size, container_start_offset, container_uuid): global mac_info mac_info = macinfo.ApfsMacInfo(mac_info.output_params, mac_info.password, mac_info.dont_decrypt) mac_info.pytsk_image = img # Must be populated mac_info.vol_info = vol_info # Must be populated mac_info.is_apfs = True mac_info.macos_partition_start_offset = container_start_offset # apfs container offset mac_info.apfs_container = ApfsContainer(img, container_size, container_start_offset) # Check if this is 10.15 style System + Data volume? for vol in mac_info.apfs_container.volumes: if vol.role == vol.container.apfs.VolumeRoleType.system.value: log.debug("{} is SYSTEM volume type".format(vol.volume_name)) mac_info.apfs_sys_volume = vol elif vol.role == vol.container.apfs.VolumeRoleType.data.value: log.debug("{} is DATA volume type".format(vol.volume_name)) mac_info.apfs_data_volume = vol try: # start db use_existing_db = False apfs_sqlite_path = os.path.join( mac_info.output_params.output_path, "APFS_Volumes_" + str(container_uuid).upper() + ".db") if os.path.exists(apfs_sqlite_path): # Check if db already exists existing_db = SqliteWriter( ) # open & check if it has the correct data existing_db.OpenSqliteDb(apfs_sqlite_path) apfs_db_info = ApfsDbInfo(existing_db) if apfs_db_info.CheckVerInfo( ) and apfs_db_info.CheckVolInfoAndGetVolEncKey( mac_info.apfs_container.volumes): # all good, db is up to date, use it use_existing_db = True mac_info.apfs_db = existing_db if mac_info.apfs_sys_volume: mac_info.apfs_data_volume.dbo = mac_info.apfs_db mac_info.apfs_sys_volume.dbo = mac_info.apfs_db mac_info.UseCombinedVolume() log.info( 'Found an existing APFS_Volumes.db in the output folder, looks good, will not create a new one!' ) else: # db does not seem up to date, create a new one and read info existing_db.CloseDb() log.info( 'Found an existing APFS_Volumes.db in the output folder, but it is STALE, creating a new one!' ) os.remove(apfs_sqlite_path) if not use_existing_db: apfs_sqlite_path = SqliteWriter.CreateSqliteDb( apfs_sqlite_path) # Will create with next avail file name mac_info.apfs_db = SqliteWriter() mac_info.apfs_db.OpenSqliteDb(apfs_sqlite_path) try: log.info( 'Reading APFS volumes from container, this may take a few minutes ...' ) mac_info.ReadApfsVolumes() apfs_db_info = ApfsDbInfo(mac_info.apfs_db) apfs_db_info.WriteVolInfo(mac_info.apfs_container.volumes) if mac_info.apfs_sys_volume: mac_info.apfs_data_volume.dbo = mac_info.apfs_db mac_info.apfs_sys_volume.dbo = mac_info.apfs_db if not mac_info.CreateCombinedVolume(): return False apfs_db_info.WriteVersionInfo() except: log.exception('Error while reading APFS volumes') return False mac_info.output_params.apfs_db_path = apfs_sqlite_path if mac_info.apfs_sys_volume: # catalina or above if mac_info.apfs_data_volume == None: log.error('Found system volume, but no Data volume!') return False return FindMacOsFiles(mac_info) else: # Search for macOS partition in volumes for vol in mac_info.apfs_container.volumes: if vol.num_blocks_used * vol.container.block_size < 3000000000: # < 3 GB, cannot be a macOS root volume continue mac_info.macos_FS = vol vol.dbo = mac_info.apfs_db if FindMacOsFiles(mac_info): return True # Did not find macOS installation mac_info.macos_FS = None except Exception as ex: log.info('Sqlite db could not be created at : ' + apfs_sqlite_path) log.exception( 'Exception occurred when trying to create APFS_Volumes Sqlite db') return False