print('No id1 directory could be found in', id0, file=sys.stderr) sys.exit(2) id1 = id1_list[0] dbs_folder = id1 / 'dbs' dbs_folder.mkdir(exist_ok=True) title_db_path = dbs_folder / 'title.db' import_db_path = dbs_folder / 'import.db' with gzip.open('title.db.gz') as gzfh: db_data = gzfh.read() with title_db_path.open('wb') as fh: with crypto.create_ctr_io(Keyslot.SD, fh, CryptoEngine.sd_path_to_iv('/dbs/title.db')) as cfh: cmac = crypto.create_cmac_object(Keyslot.CMACSDNAND) cmac_data = [b'CTR-9DB0', 0x2.to_bytes(4, 'little'), db_data[0x100:0x200]] cmac.update(sha256(b''.join(cmac_data)).digest()) cfh.write(cmac.digest()) cfh.write(db_data[0x10:]) with import_db_path.open('wb') as fh: with crypto.create_ctr_io(Keyslot.SD, fh, CryptoEngine.sd_path_to_iv('/dbs/import.db')) as cfh: cmac = crypto.create_cmac_object(Keyslot.CMACSDNAND) cmac_data = [b'CTR-9DB0', 0x3.to_bytes(4, 'little'), db_data[0x100:0x200]] cmac.update(sha256(b''.join(cmac_data)).digest()) cfh.write(cmac.digest()) cfh.write(db_data[0x10:])
print('Please remove the rest.', file=sys.stderr) sys.exit(1) elif len(id1_list) < 1: print('No id1 directory could be found in', id0, file=sys.stderr) sys.exit(2) id1 = id1_list[0] title_dir = id1 / 'title' for tmd_path in title_dir.rglob('*.tmd'): tmd_id = int(tmd_path.name[0:8], 16) tmd_path_for_cid = '/' + '/'.join(tmd_path.parts[len(id1.parts):]) with tmd_path.open('rb') as tmd_fh: with crypto.create_ctr_io( Keyslot.SD, tmd_fh, crypto.sd_path_to_iv(tmd_path_for_cid)) as tmd_cfh: try: tmd = TitleMetadataReader.load(tmd_cfh) except Exception as e: print(f'Failed to parse tmd at {tmd_path}') traceback.print_exc() print('Parsing', tmd.title_id) if tmd.title_id.startswith('0004008c'): # DLC puts contents into different folders, the first content always goes in the first one content0_path = tmd_path.parent / '00000000' / ( tmd.chunk_records[0].id + '.app') has_manual = False else: