def get_cnmt_data(path=None,TD=None,filter=None,target=None,file=None): if path==None and file==None: return False if file != None: remote=file type='file' remote.rewind() elif path.startswith('http'): url=path remote=Public.location(url);readable=remote.readable if not readable: return False type='file' else: if path=='pick': account=Private.token_picker() TD=Private.TD_picker(account) return test=path.split(".+") if TD=='pick': TD=Private.TD_picker(path) if len(test)>1 or path.endswith('/') or path.endswith('\\'): type="folder" else: ID,name,type,size,md5,remote=Private.get_Data(path,TD=TD,Print=False) if type!='file': # print('Path is a folder') Private.folderpicker(path,TD=TD,filter=filter,mode='get_cnmt_data') return else: files_list=get_files_from_head(remote,remote.name) # print(files_list) for i in range(len(files_list)): if (files_list[i][0]).endswith('.cnmt.nca'): nca_name=files_list[i][0] off1=files_list[i][1] off2=files_list[i][2] sz=files_list[i][3] if target==None: break # print(nca_name) # print(target) if str(nca_name).lower()==str(target).lower(): break remote.seek(off1,off2) buf=int(sz) try: nca=Nca() nca.open(MemoryFile(remote.read(buf))) nca.rewind() cnmt=io.BytesIO(nca.return_cnmt()) titleid,titleversion,base_ID,keygeneration,rightsId,RSV,RGV,ctype,metasdkversion,exesdkversion,hasHtmlManual,Installedsize,DeltaSize,ncadata=cnmt_data(cnmt,nca,nca_name) d={} d['titleid']=titleid;d['version']=titleversion;d['baseid']=base_ID;d['keygeneration']=keygeneration;d['rightsId']=rightsId; d['rsv']=RSV;d['rgv']=RGV;d['ctype']=ctype;d['metasdkversion']=metasdkversion;d['exesdkversion']=exesdkversion; d['hasHtmlManual']=hasHtmlManual;d['Installedsize']=Installedsize;d['DeltaSize']=DeltaSize;d['ncadata']=ncadata; # print(d) return d,files_list,remote except IOError as e: print(e, file=sys.stderr)
def get_nsx_name(dic=None, filepath=None): if dic == None: NAXKey0, NAXKey1, r_path = get_decryption_keys(filepath) elif dic != None: NAXKey0 = dic['NAXKey0'] NAXKey1 == dic['NAXKey1'] r_path = dic['r_path'] filepath = dic['filepath'] else: return False nca_name = (r_path.split('/'))[-1] = (r_path.split('/'))[-1] with open(filepath, 'rb') as f: f.seek(0x4000) data = f.read() crypto = aes128.AESXTS(NAXKey0 + NAXKey1, sector_size=0x4000) nca = Nca() nca.open(MemoryFile(crypto.decrypt(data))) nca.rewind() nca._path = nca_name result = nca.get_langueblock(roman=False) title_name = result[0] return title_name
def get_cnmt_data(dic=None, filepath=None): if dic == None: NAXKey0, NAXKey1, r_path = get_decryption_keys(filepath) elif dic != None: NAXKey0 = dic['NAXKey0'] NAXKey1 = dic['NAXKey1'] r_path = dic['r_path'] filepath = dic['filepath'] else: return False nca_name = (r_path.split('/'))[-1] = (r_path.split('/'))[-1] with open(filepath, 'rb') as f: f.seek(0x4000) data = f.read() crypto = aes128.AESXTS(NAXKey0 + NAXKey1, sector_size=0x4000) nca = Nca() nca.open(MemoryFile(crypto.decrypt(data))) nca.rewind() nca_name = nca_name.replace('.nca', '.cnmt.nca') nca._path = nca_name cnmt = io.BytesIO(nca.return_cnmt()) cnmt_dict = cnmt_data(cnmt, nca, nca_name) return cnmt_dict
def gen_xci_parts_spec0(filepath=None,remote=None,target_cnmt=None,cachefolder=None,keypatch=False,files_list=None): if filepath=="": filepath=None if remote=="": remote=None if remote==None: test=filepath.split('|');TD=None if len(test)<2: filepath=test[0] lib,TD,libpath=get_library_from_path(remote_lib_file,filepath) else: filepath=test[0] TD=test[1] if str(TD).upper()=="NONE": TD=None ID,name,type,size,md5,remote=DrivePrivate.get_Data(filepath,TD=TD,Print=False) if keypatch!=False: try: keypatch=int(keypatch) except: keypatch=False if cachefolder==None: cachefolder=os.path.join(ztools_dir, '_mtp_cache_') if not os.path.exists(cachefolder): os.makedirs(cachefolder) else: for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) if files_list==None: files_list=DriveTools.get_files_from_head(remote,remote.name) files=list();filesizes=list() fplist=list() for k in range(len(files_list)): entry=files_list[k] fplist.append(entry[0]) if target_cnmt==None: for i in range(len(files_list)): entry=files_list[i] cnmtfile=entry[0] if cnmtfile.endswith('.cnmt.nca'): target_cnmt=cnmtfile break for i in range(len(files_list)): entry=files_list[i] cnmtfile=entry[0] if cnmtfile.endswith('.cnmt.nca') and target_cnmt==cnmtfile: metadict,d1,d2=DriveTools.get_cnmt_data(target=cnmtfile,file=remote) ncadata=metadict['ncadata'] content_type=metadict['ctype'] if content_type!="DLC": for j in range(len(ncadata)): row=ncadata[j] if row['NCAtype']!='Meta' and row['NCAtype']!='Program' and row['NCAtype']!='DeltaFragment': test1=str(row['NcaId'])+'.nca';test2=str(row['NcaId'])+'.ncz' if test1 in fplist: files.append(str(row['NcaId'])+'.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId'])+'.ncz') for k in range(len(files_list)): entry=files_list[k] if entry[0]==test2: filesizes.append(int(entry[3])) break for j in range(len(ncadata)): row=ncadata[j] if row['NCAtype']=='Meta': # print(str(row['NcaId'])+'.cnmt.nca') files.append(str(row['NcaId'])+'.cnmt.nca') filesizes.append(int(row['Size'])) for j in range(len(ncadata)): row=ncadata[j] # print(row) if row['NCAtype']=='Program': test1=str(row['NcaId'])+'.nca';test2=str(row['NcaId'])+'.ncz' if test1 in fplist: files.append(str(row['NcaId'])+'.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId'])+'.ncz') for k in range(len(files_list)): entry=files_list[k] if entry[0]==test2: filesizes.append(int(entry[3])) break else: for j in range(len(ncadata)): row=ncadata[j] if row['NCAtype']!='Meta' and row['NCAtype']!='Data': test1=str(row['NcaId'])+'.nca';test2=str(row['NcaId'])+'.ncz' if test1 in fplist: files.append(str(row['NcaId'])+'.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId'])+'.ncz') for k in range(len(files_list)): entry=files_list[k] if entry[0]==test2: filesizes.append(int(entry[3])) break for j in range(len(ncadata)): row=ncadata[j] if row['NCAtype']=='Meta': # print(str(row['NcaId'])+'.cnmt.nca') files.append(str(row['NcaId'])+'.cnmt.nca') filesizes.append(int(row['Size'])) for j in range(len(ncadata)): row=ncadata[j] # print(row) if row['NCAtype']=='Data': test1=str(row['NcaId'])+'.nca';test2=str(row['NcaId'])+'.ncz' if test1 in fplist: files.append(str(row['NcaId'])+'.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId'])+'.ncz') for k in range(len(files_list)): entry=files_list[k] if entry[0]==test2: filesizes.append(int(entry[3])) break break remote.rewind() outheader = sq_tools.gen_nsp_header(files,filesizes) properheadsize=len(outheader) # print(properheadsize) # print(bucketsize) i=0;sum=properheadsize; outfile=os.path.join(cachefolder, "0") outf = open(outfile, 'w+b') outf.write(outheader) written=0 nca_program='' for fi in files: if fi.endswith('nca') or fi.endswith('ncz') : for i in range(len(files_list)): if str(files_list[i][0]).lower() == str(fi).lower(): nca_name=files_list[i][0] off1=files_list[i][1] off2=files_list[i][2] nca_size=files_list[i][3] break ncaHeader = NcaHeader() ncaHeader.open(MemoryFile(remote.read_at(off1,0x400), FsType.Crypto.XTS, uhx(Keys.get('header_key')))) crypto1=ncaHeader.getCryptoType() crypto2=ncaHeader.getCryptoType2() if crypto2>crypto1: masterKeyRev=crypto2 if crypto2<=crypto1: masterKeyRev=crypto1 crypto = aes128.AESECB(Keys.keyAreaKey(Keys.getMasterKeyIndex(masterKeyRev), ncaHeader.keyIndex)) hcrypto = aes128.AESXTS(uhx(Keys.get('header_key'))) gc_flag='00'*0x01 crypto1=ncaHeader.getCryptoType() crypto2=ncaHeader.getCryptoType2() if ncaHeader.getRightsId() != 0: ncaHeader.rewind() if crypto2>crypto1: masterKeyRev=crypto2 if crypto2<=crypto1: masterKeyRev=crypto1 rightsId=metadict['rightsId'] titleKeyDec = DriveTools.get_titlekey(remote,rightsId,masterKeyRev,files_list=files_list) encKeyBlock = crypto.encrypt(titleKeyDec * 4) if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < ncaHeader.getCryptoType2(): encKeyBlock,crypto1,crypto2=get_new_cryptoblock(ncaHeader,keypatch,encKeyBlock,t) t.close() if ncaHeader.getRightsId() == 0: ncaHeader.rewind() encKeyBlock = ncaHeader.getKeyBlock() if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < ncaHeader.getCryptoType2(): encKeyBlock,crypto1,crypto2=get_new_cryptoblock(ncaHeader,keypatch,encKeyBlock,t) t.close() ncaHeader.rewind() i=0 newheader=get_newheader(MemoryFile(remote.read_at(off1,0xC00)),encKeyBlock,crypto1,crypto2,hcrypto,gc_flag) outf.write(newheader) written+=len(newheader) if content_type!="DLC": if (str(ncaHeader.contentType) != 'Content.PROGRAM'): nca = Nca() nca.open(MemoryFile(remote.read_at(off1,nca_size))) nca.seek(0xC00) data=nca.read() outf.write(data) written+=len(data) # print(nca_name) # print(len(newheader)+len(data)) else: nca_program=nca_name # print(nca_name) # print(len(newheader)) else: if (str(ncaHeader.contentType) != 'Content.PUBLIC_DATA'): nca = Nca() nca.open(MemoryFile(remote.read_at(off1,nca_size))) nca.seek(0xC00) data=nca.read() outf.write(data) written+=len(data) # print(nca_name) # print(len(newheader)+len(data)) else: nca_program=nca_name # print(nca_name) # print(len(newheader)) else:pass outf.flush() outf.close() tfile=os.path.join(cachefolder, "remote_files.csv") with open(tfile,'w') as csvfile: csvfile.write("{}|{}|{}|{}|{}|{}|{}\n".format("step","filepath","size","targetsize","off1","off2","token")) csvfile.write("{}|{}|{}|{}|{}|{}|{}\n".format(0,outfile,os.path.getsize(outfile),os.path.getsize(outfile),0,os.path.getsize(outfile),"False")) k=0; for j in files_list: if j[0]==nca_program: # print(j[0]) off1=j[1]+0xC00 off2=j[2] targetsize=j[3]-0xC00 URL='https://www.googleapis.com/drive/v3/files/'+remote.ID+'?alt=media' token=remote.access_token csvfile.write("{}|{}|{}|{}|{}|{}|{}\n".format(k+1,URL,remote.size,targetsize,off1,off2,token)) k+=1 break nspname="test.nsp" try: g=remote.name g0=[pos for pos, char in enumerate(g) if char == '['] g0=(g[0:g0[0]]).strip() titleid=metadict['titleid'] titleversion=metadict['version'] ctype=metadict['ctype'] nspname=f"{g0} [{titleid}] [v{titleversion}] [{ctype}].nsp" except BaseException as e: Print.error('Exception: ' + str(e)) pass return nspname
def nacp_data(file,ncadata,files_list): ncaname=None;dict={} for entry in ncadata: if str(entry['NCAtype']).lower()=='control': ncaname=entry['NcaId']+'.nca' break if ncaname!=None: for i in range(len(files_list)): if files_list[i][0]==ncaname: nca_name=files_list[i][0] off1=files_list[i][1] off2=files_list[i][2] sz=files_list[i][3] break file.seek(off1,off2) buf=int(sz) nca=Nca() nca.open(MemoryFile(file.read(buf))) nca.rewind() f=io.BytesIO(nca.ret_nacp());f.seek(0) nacp = Nacp() dict['RegionalNames'],dict['RegionalEditors']=nacp.get_NameandPub(f.read(0x300*15)) f.seek(0x3000) dict['ISBN']=nacp.get_Isbn(f.read(0x24)) f.seek(0x3025) dict['StartupUserAccount']=nacp.get_StartupUserAccount(readInt8(f,'little')) dict['UserAccountSwitchLock']=nacp.get_UserAccountSwitchLock(readInt8(f,'little')) dict['AddOnContentRegistrationType']=nacp.get_AddOnContentRegistrationType(readInt8(f,'little')) dict['ctype']=nacp.get_ContentType(readInt8(f,'little')) dict['ParentalControl']=nacp.get_ParentalControl(readInt8(f,'little')) dict['ScreenshotsEnabled']=nacp.get_Screenshot(readInt8(f,'little')) dict['VideocaptureEnabled']=nacp.get_VideoCapture(readInt8(f,'little')) dict['dataLossConfirmation']=nacp.get_dataLossConfirmation(readInt8(f,'little')) dict['PlayLogPolicy']=nacp.get_PlayLogPolicy(readInt8(f,'little')) dict['PresenceGroupId']=nacp.get_PresenceGroupId(readInt64(f,'little')) f.seek(0x3040) dict['AgeRatings']=nacp.get_RatingAge(f.read(0x20)) f.seek(0x3060) try: dict['BuildNumber']=nacp.get_DisplayVersion(f.read(0xF)) f.seek(0x3070) dict['AddOnContentBaseId']=nacp.get_AddOnContentBaseId(readInt64(f,'little')) f.seek(0x3078) dict['SaveDataOwnerId']=nacp.get_SaveDataOwnerId(readInt64(f,'little')) f.seek(0x3080) dict['UserAccountSaveDataSize']=nacp.get_UserAccountSaveDataSize(readInt64(f,'little')) f.seek(0x3088) dict['UserAccountSaveDataJournalSize']=nacp.get_UserAccountSaveDataJournalSize(readInt64(f,'little')) f.seek(0x3090) dict['DeviceSaveDataSize']=nacp.get_DeviceSaveDataSize(readInt64(f,'little')) f.seek(0x3098) dict['DeviceSaveDataJournalSize']=nacp.get_DeviceSaveDataJournalSize(readInt64(f,'little')) f.seek(0x30A0) dict['BcatDeliveryCacheStorageSize']=nacp.get_BcatDeliveryCacheStorageSize(readInt64(f,'little')) f.seek(0x30A8) dict['ApplicationErrorCodeCategory']=nacp.get_ApplicationErrorCodeCategory(f.read(0x07)) f.seek(0x30B0) dict['LocalCommunicationId']=nacp.get_LocalCommunicationId(readInt64(f,'little')) f.seek(0x30F0) dict['LogoType']=nacp.get_LogoType(readInt8(f,'little')) dict['LogoHandling']=nacp.get_LogoHandling(readInt8(f,'little')) dict['RuntimeAddOnContentInstall']=nacp.get_RuntimeAddOnContentInstall(readInt8(f,'little')) dict['CrashReport']=nacp.get_CrashReport(readInt8(f,'little')) dict['Hdcp']=nacp.get_Hdcp(readInt8(f,'little')) dict['SeedForPseudoDeviceId']=nacp.get_SeedForPseudoDeviceId(readInt64(f,'little')) f.seek(0x3100) dict['BcatPassphrase']=nacp.get_BcatPassphrase(f.read(0x40)) f.seek(0x3148) dict['UserAccountSaveDataSizeMax']=nacp.par_UserAccountSaveDataSizeMax(readInt64(f,'little')) f.seek(0x3150) dict['UserAccountSaveDataJournalSizeMax']=nacp.par_UserAccountSaveDataJournalSizeMax(readInt64(f,'little')) f.seek(0x3158) dict['DeviceSaveDataSizeMax']=nacp.get_DeviceSaveDataSizeMax(readInt64(f,'little')) f.seek(0x3160) dict['DeviceSaveDataJournalSizeMax']=nacp.get_DeviceSaveDataJournalSizeMax(readInt64(f,'little')) f.seek(0x3168) dict['TemporaryStorageSize']=nacp.get_TemporaryStorageSize(readInt64(f,'little')) dict['CacheStorageSize']=nacp.get_CacheStorageSize(readInt64(f,'little')) f.seek(0x3178) dict['CacheStorageJournalSize']=nacp.get_CacheStorageJournalSize(readInt64(f,'little')) dict['CacheStorageDataAndJournalSizeMax']=nacp.get_CacheStorageDataAndJournalSizeMax(readInt64(f,'little')) f.seek(0x3188) dict['CacheStorageIndexMax']=nacp.get_CacheStorageIndexMax(readInt64(f,'little')) dict['PlayLogQueryableApplicationId']=nacp.get_PlayLogQueryableApplicationId(readInt64(f,'little')) f.seek(0x3210) dict['PlayLogQueryCapability']=nacp.get_PlayLogQueryCapability(readInt8(f,'little')) dict['Repair']=nacp.get_Repair(readInt8(f,'little')) dict['ProgramIndex']=nacp.get_ProgramIndex(readInt8(f,'little')) dict['RequiredNetworkServiceLicenseOnLaunch']=nacp.get_RequiredNetworkServiceLicenseOnLaunch(readInt8(f,'little')) except:pass return dict
def gen_nsp_parts_spec1(filepath,target_cnmt=None,cachefolder=None,keypatch=False): if keypatch!=False: try: keypatch=int(keypatch) except: keypatch=False if cachefolder==None: cachefolder=os.path.join(ztools_dir, '_mtp_cache_') if not os.path.exists(cachefolder): os.makedirs(cachefolder) else: for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) files_list=sq_tools.ret_nsp_offsets(filepath) files=list();filesizes=list() fplist=list() for k in range(len(files_list)): entry=files_list[k] fplist.append(entry[0]) if target_cnmt==None: for i in range(len(files_list)): entry=files_list[i] cnmtfile=entry[0] if cnmtfile.endswith('.cnmt.nca'): target_cnmt=cnmtfile break for i in range(len(files_list)): entry=files_list[i] cnmtfile=entry[0] if cnmtfile.endswith('.cnmt.nca') and target_cnmt==cnmtfile: f=squirrelNSP(filepath) titleid,titleversion,base_ID,keygeneration,rightsId,RSV,RGV,ctype,metasdkversion,exesdkversion,hasHtmlManual,Installedsize,DeltaSize,ncadata=f.get_data_from_cnmt(cnmtfile) f.flush() f.close() for j in range(len(ncadata)): row=ncadata[j] # print(row) if row['NCAtype']!='Meta' and row['NCAtype']!='Program': test1=str(row['NcaId'])+'.nca';test2=str(row['NcaId'])+'.ncz' if test1 in fplist: files.append(str(row['NcaId'])+'.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId'])+'.ncz') for k in range(len(files_list)): entry=files_list[k] if entry[0]==test2: filesizes.append(int(entry[3])) break for j in range(len(ncadata)): row=ncadata[j] if row['NCAtype']=='Meta': # print(str(row['NcaId'])+'.cnmt.nca') files.append(str(row['NcaId'])+'.cnmt.nca') filesizes.append(int(row['Size'])) for j in range(len(ncadata)): row=ncadata[j] # print(row) if row['NCAtype']=='Program': test1=str(row['NcaId'])+'.nca';test2=str(row['NcaId'])+'.ncz' if test1 in fplist: files.append(str(row['NcaId'])+'.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId'])+'.ncz') for k in range(len(files_list)): entry=files_list[k] if entry[0]==test2: filesizes.append(int(entry[3])) break break f.flush() f.close() outheader = sq_tools.gen_nsp_header(files,filesizes) properheadsize=len(outheader) # print(properheadsize) # print(bucketsize) i=0;sum=properheadsize; nsp=squirrelNSP(filepath) outfile=os.path.join(cachefolder, "0") outf = open(outfile, 'w+b') outf.write(outheader) written=0 for fi in files: for nca in nsp: if nca._path==fi: nca=Nca(nca) crypto1=nca.header.getCryptoType() crypto2=nca.header.getCryptoType2() if crypto2>crypto1: masterKeyRev=crypto2 if crypto2<=crypto1: masterKeyRev=crypto1 crypto = aes128.AESECB(Keys.keyAreaKey(Keys.getMasterKeyIndex(masterKeyRev), nca.header.keyIndex)) hcrypto = aes128.AESXTS(uhx(Keys.get('header_key'))) gc_flag='00'*0x01 crypto1=nca.header.getCryptoType() crypto2=nca.header.getCryptoType2() if nca.header.getRightsId() != 0: nca.rewind() if crypto2>crypto1: masterKeyRev=crypto2 if crypto2<=crypto1: masterKeyRev=crypto1 from mtp_tools import get_nca_ticket check,titleKey=get_nca_ticket(filepath,fi) if check==False: sys.exit("Can't verify titleckey") titleKeyDec = Keys.decryptTitleKey(titleKey, Keys.getMasterKeyIndex(int(masterKeyRev))) encKeyBlock = crypto.encrypt(titleKeyDec * 4) if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2(): encKeyBlock,crypto1,crypto2=squirrelNSP.get_new_cryptoblock(squirrelNSP,nca,keypatch,encKeyBlock,t) t.close() if nca.header.getRightsId() == 0: nca.rewind() encKeyBlock = nca.header.getKeyBlock() if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2(): encKeyBlock,crypto1,crypto2=squirrelNSP.get_new_cryptoblock(squirrelNSP,nca,keypatch,encKeyBlock,t) t.close() nca.rewind() i=0 newheader=nsp.get_newheader(nca,encKeyBlock,crypto1,crypto2,hcrypto,gc_flag) outf.write(newheader) written+=len(newheader) nca.seek(0xC00) break else:pass
def gen_xci_parts_spec1(filepath, target_cnmt=None, cachefolder=None, keypatch=False): if keypatch != False: try: keypatch = int(keypatch) except: keypatch = False if cachefolder == None: cachefolder = os.path.join(ztools_dir, '_mtp_cache_') if not os.path.exists(cachefolder): os.makedirs(cachefolder) else: for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) files_list = sq_tools.ret_xci_offsets(filepath) files = list() filesizes = list() fplist = list() for k in range(len(files_list)): entry = files_list[k] fplist.append(entry[0]) if target_cnmt == None: for i in range(len(files_list)): entry = files_list[i] cnmtfile = entry[0] if cnmtfile.endswith('.cnmt.nca'): target_cnmt = cnmtfile break for i in range(len(files_list)): entry = files_list[i] cnmtfile = entry[0] if cnmtfile.endswith('.cnmt.nca') and target_cnmt == cnmtfile: f = squirrelXCI(filepath) titleid, titleversion, base_ID, keygeneration, rightsId, RSV, RGV, ctype, metasdkversion, exesdkversion, hasHtmlManual, Installedsize, DeltaSize, ncadata = f.get_data_from_cnmt( cnmtfile) f.flush() f.close() for j in range(len(ncadata)): row = ncadata[j] # print(row) if row['NCAtype'] != 'Meta' and row['NCAtype'] != 'Program': test1 = str(row['NcaId']) + '.nca' test2 = str(row['NcaId']) + '.ncz' if test1 in fplist: files.append(str(row['NcaId']) + '.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId']) + '.ncz') for k in range(len(files_list)): entry = files_list[k] if entry[0] == test2: filesizes.append(int(entry[3])) break for j in range(len(ncadata)): row = ncadata[j] if row['NCAtype'] == 'Meta': # print(str(row['NcaId'])+'.cnmt.nca') files.append(str(row['NcaId']) + '.cnmt.nca') filesizes.append(int(row['Size'])) for j in range(len(ncadata)): row = ncadata[j] # print(row) if row['NCAtype'] == 'Program': test1 = str(row['NcaId']) + '.nca' test2 = str(row['NcaId']) + '.ncz' if test1 in fplist: files.append(str(row['NcaId']) + '.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId']) + '.ncz') for k in range(len(files_list)): entry = files_list[k] if entry[0] == test2: filesizes.append(int(entry[3])) break break f.flush() f.close() outheader = sq_tools.gen_nsp_header(files, filesizes) properheadsize = len(outheader) # print(properheadsize) # print(bucketsize) i = 0 sum = properheadsize xci = squirrelXCI(filepath) outfile = os.path.join(cachefolder, "0") outf = open(outfile, 'w+b') outf.write(outheader) written = 0 for fi in files: for nspF in xci.hfs0: if str(nspF._path) == "secure": for nca in nspF: if nca._path == fi: nca = Nca(nca) crypto1 = nca.header.getCryptoType() crypto2 = nca.header.getCryptoType2() if crypto2 > crypto1: masterKeyRev = crypto2 if crypto2 <= crypto1: masterKeyRev = crypto1 crypto = aes128.AESECB( Keys.keyAreaKey( Keys.getMasterKeyIndex(masterKeyRev), nca.header.keyIndex)) hcrypto = aes128.AESXTS(uhx(Keys.get('header_key'))) gc_flag = '00' * 0x01 crypto1 = nca.header.getCryptoType() crypto2 = nca.header.getCryptoType2() if nca.header.getRightsId() != 0: nca.rewind() if crypto2 > crypto1: masterKeyRev = crypto2 if crypto2 <= crypto1: masterKeyRev = crypto1 from mtp_tools import get_nca_ticket check, titleKey = get_nca_ticket(filepath, fi) if check == False: sys.exit("Can't verify titleckey") titleKeyDec = Keys.decryptTitleKey( titleKey, Keys.getMasterKeyIndex(int(masterKeyRev))) encKeyBlock = crypto.encrypt(titleKeyDec * 4) if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2(): encKeyBlock, crypto1, crypto2 = squirrelXCI.get_new_cryptoblock( squirrelXCI, nca, keypatch, encKeyBlock, t) t.close() if nca.header.getRightsId() == 0: nca.rewind() encKeyBlock = nca.header.getKeyBlock() if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2(): encKeyBlock, crypto1, crypto2 = squirrelXCI.get_new_cryptoblock( squirrelXCI, nca, keypatch, encKeyBlock, t) t.close() nca.rewind() i = 0 newheader = xci.get_newheader(nca, encKeyBlock, crypto1, crypto2, hcrypto, gc_flag) outf.write(newheader) written += len(newheader) nca.seek(0xC00) break else: pass xci.flush() xci.close() outf.flush() outf.close() tfile = os.path.join(cachefolder, "files.csv") with open(tfile, 'w') as csvfile: csvfile.write("{}|{}|{}|{}|{}|{}\n".format("step", "filepath", "size", "targetsize", "off1", "off2")) csvfile.write("{}|{}|{}|{}|{}|{}\n".format(0, outfile, properheadsize + written, properheadsize, 0, properheadsize)) k = 0 l = 0 for fi in files: for j in files_list: if j[0] == fi: csvfile.write("{}|{}|{}|{}|{}|{}\n".format( k + 1, outfile, properheadsize + written, 0xC00, (properheadsize + l * 0xC00), (properheadsize + (l * 0xC00) + 0xC00))) off1 = j[1] + 0xC00 off2 = j[2] targetsize = j[3] - 0xC00 csvfile.write("{}|{}|{}|{}|{}|{}\n".format( k + 2, filepath, (os.path.getsize(filepath)), targetsize, off1, off2)) break k += 2 l += 1 nspname = "test.nsp" try: g = os.path.basename(filepath) g0 = [pos for pos, char in enumerate(g) if char == '['] g0 = (g[0:g0[0]]).strip() nspname = f"{g0} [{titleid}] [v{titleversion}] [{ctype}].nsp" except: pass return nspname
def gen_xci_parts_spec0(filepath, target_cnmt=None, cachefolder=None, keypatch=False, export_type='csv'): if cachefolder == None: cachefolder = os.path.join(ztools_dir, '_mtp_cache_') if not os.path.exists(cachefolder): os.makedirs(cachefolder) else: for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) program_name = None files_list = sq_tools.ret_xci_offsets(filepath) files = list() filesizes = list() fplist = list() for k in range(len(files_list)): entry = files_list[k] fplist.append(entry[0]) if target_cnmt == None: for i in range(len(files_list)): entry = files_list[i] cnmtfile = entry[0] if cnmtfile.endswith('.cnmt.nca'): target_cnmt = cnmtfile break for i in range(len(files_list)): entry = files_list[i] cnmtfile = entry[0] if cnmtfile.endswith('.cnmt.nca') and target_cnmt == cnmtfile: f = squirrelXCI(filepath) titleid, titleversion, base_ID, keygeneration, rightsId, RSV, RGV, ctype, metasdkversion, exesdkversion, hasHtmlManual, Installedsize, DeltaSize, ncadata = f.get_data_from_cnmt( cnmtfile) f.flush() f.close() for j in range(len(ncadata)): row = ncadata[j] # print(row) if row['NCAtype'] != 'Meta' and row['NCAtype'] != 'Program': test1 = str(row['NcaId']) + '.nca' test2 = str(row['NcaId']) + '.ncz' if test1 in fplist or test2 in fplist: # print(str(row['NcaId'])+'.nca') if test1 in fplist: files.append(str(row['NcaId']) + '.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId']) + '.ncz') for k in range(len(files_list)): entry = files_list[k] if entry[0] == test2: filesizes.append(int(entry[3])) break for j in range(len(ncadata)): row = ncadata[j] if row['NCAtype'] == 'Meta': # print(str(row['NcaId'])+'.cnmt.nca') files.append(str(row['NcaId']) + '.cnmt.nca') filesizes.append(int(row['Size'])) for j in range(len(ncadata)): row = ncadata[j] # print(row) if row['NCAtype'] == 'Program': test1 = str(row['NcaId']) + '.nca' test2 = str(row['NcaId']) + '.ncz' if test1 in fplist or test2 in fplist: # print(str(row['NcaId'])+'.nca') if test1 in fplist: files.append(str(row['NcaId']) + '.nca') filesizes.append(int(row['Size'])) elif test2 in fplist: files.append(str(row['NcaId']) + '.ncz') for k in range(len(files_list)): entry = files_list[k] if entry[0] == test2: filesizes.append(int(entry[3])) break break f.flush() f.close() outheader = sq_tools.gen_nsp_header(files, filesizes) properheadsize = len(outheader) # print(properheadsize) # print(bucketsize) i = 0 sum = properheadsize for file in files: # print(file) # print(filesizes[i]) if i < (len(files) - 1): sum += filesizes[i] i += 1 # print(sum) # print(sum/bucketsize) multiplier = math.ceil(sum / bucketsize) # print(multiplier) remainder = bucketsize * multiplier - sum # print(bucketsize*multiplier) xci = squirrelXCI(filepath) outfile = os.path.join(cachefolder, "0") written = 0 outf = open(outfile, 'w+b') outf.write(outheader) written += len(outheader) movoffset = 0 for fi in files: for nspF in xci.hfs0: if str(nspF._path) == "secure": for nca in nspF: if nca._path == fi: nca = Nca(nca) crypto1 = nca.header.getCryptoType() crypto2 = nca.header.getCryptoType2() if crypto2 > crypto1: masterKeyRev = crypto2 if crypto2 <= crypto1: masterKeyRev = crypto1 crypto = aes128.AESECB( Keys.keyAreaKey( Keys.getMasterKeyIndex(masterKeyRev), nca.header.keyIndex)) hcrypto = aes128.AESXTS(uhx(Keys.get('header_key'))) gc_flag = '00' * 0x01 crypto1 = nca.header.getCryptoType() crypto2 = nca.header.getCryptoType2() if nca.header.getRightsId() != 0: nca.rewind() if crypto2 > crypto1: masterKeyRev = crypto2 if crypto2 <= crypto1: masterKeyRev = crypto1 from mtp_tools import get_nca_ticket check, titleKey = get_nca_ticket(filepath, fi) if check == False: sys.exit("Can't verify titleckey") titleKeyDec = Keys.decryptTitleKey( titleKey, Keys.getMasterKeyIndex(int(masterKeyRev))) encKeyBlock = crypto.encrypt(titleKeyDec * 4) if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2(): encKeyBlock, crypto1, crypto2 = squirrelXCI.get_new_cryptoblock( squirrelXCI, nca, keypatch, encKeyBlock, t) t.close() if nca.header.getRightsId() == 0: nca.rewind() encKeyBlock = nca.header.getKeyBlock() if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2(): encKeyBlock, crypto1, crypto2 = squirrelXCI.get_new_cryptoblock( squirrelXCI, nca, keypatch, encKeyBlock, t) t.close() nca.rewind() i = 0 newheader = xci.get_newheader(nca, encKeyBlock, crypto1, crypto2, hcrypto, gc_flag) outf.write(newheader) written += len(newheader) nca.seek(0xC00) movoffset += 0xC00 if (str(nca.header.contentType) != 'Content.PROGRAM'): data = nca.read() nca.close() outf.write(data) written += len(data) break else: pass xci.flush() xci.close() outf.close() if export_type == 'json': files_json = os.path.join(cachefolder, "files.json") d = {} d['0'] = { "step": 0, "filepath": outfile, "size": (written), "targetsize": (written), "off1": 0, "off2": (written) } for j in files_list: if j[0] == files[-1]: off1 = j[1] + 0xC00 off2 = j[2] targetsize = j[3] - 0xC00 d['1'] = { "step": 1, "filepath": filepath, "size": (os.path.getsize(filepath)), "targetsize": targetsize, "off1": off1, "off2": off2 } app_json = json.dumps(d, indent=1) with open(files_json, 'w') as json_file: json_file.write(app_json) # print(os.path.getsize(filepath)) else: for j in files_list: if j[0] == files[-1]: off1 = j[1] + 0xC00 off2 = j[2] targetsize = j[3] - 0xC00 tfile = os.path.join(cachefolder, "files.csv") i = 0 while True: with open(tfile, 'w') as csvfile: if i == 0: csvfile.write("{}|{}|{}|{}|{}|{}\n".format( "step", "filepath", "size", "targetsize", "off1", "off2")) i += 1 if i == 1: csvfile.write("{}|{}|{}|{}|{}|{}\n".format( 0, outfile, os.path.getsize(outfile), os.path.getsize(outfile), 0, os.path.getsize(outfile))) i += 1 if i == 2: csvfile.write("{}|{}|{}|{}|{}|{}".format( 1, filepath, (os.path.getsize(filepath)), targetsize, off1, off2)) i += 1 break nspname = "test.nsp" try: g = os.path.basename(filepath) g0 = [pos for pos, char in enumerate(g) if char == '['] g0 = (g[0:g0[0]]).strip() nspname = f"{g0} [{titleid}] [v{titleversion}] [{ctype}].nsp" except: pass return nspname
def gen_mxci_parts(input_files, cachefolder=None, keypatch=False): from listmanager import calculate_name if keypatch != False: try: keypatch = int(keypatch) except: keypatch = False if cachefolder == None: cachefolder = os.path.join(ztools_dir, '_mtp_cache_') if not os.path.exists(cachefolder): os.makedirs(cachefolder) else: for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) end_name, prlist = calculate_name(input_files, romanize=True, ext='.xci') print(f"Calculated name {end_name}") outheader, properheadsize, sz, files = gen_multi_file_header( prlist, input_files) properheadsize = len(outheader) outfile = os.path.join(cachefolder, "0") outf = open(outfile, 'w+b') outf.write(outheader) # print(properheadsize) # print(bucketsize) i = 0 sum = properheadsize for fi in files: for filepath in input_files: if filepath.endswith('xci'): xci = squirrelXCI(filepath) written = 0 for nspF in xci.hfs0: if str(nspF._path) == "secure": for nca in nspF: if nca._path == fi: nca = Nca(nca) crypto1 = nca.header.getCryptoType() crypto2 = nca.header.getCryptoType2() if crypto2 > crypto1: masterKeyRev = crypto2 if crypto2 <= crypto1: masterKeyRev = crypto1 crypto = aes128.AESECB( Keys.keyAreaKey( Keys.getMasterKeyIndex(masterKeyRev), nca.header.keyIndex)) hcrypto = aes128.AESXTS( uhx(Keys.get('header_key'))) gc_flag = '00' * 0x01 crypto1 = nca.header.getCryptoType() crypto2 = nca.header.getCryptoType2() if nca.header.getRightsId() != 0: nca.rewind() if crypto2 > crypto1: masterKeyRev = crypto2 if crypto2 <= crypto1: masterKeyRev = crypto1 from mtp_tools import get_nca_ticket check, titleKey = get_nca_ticket( filepath, fi) if check == False: sys.exit("Can't verify titleckey") titleKeyDec = Keys.decryptTitleKey( titleKey, Keys.getMasterKeyIndex( int(masterKeyRev))) encKeyBlock = crypto.encrypt(titleKeyDec * 4) if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2( ): encKeyBlock, crypto1, crypto2 = squirrelXCI.get_new_cryptoblock( squirrelXCI, nca, keypatch, encKeyBlock, t) t.close() if nca.header.getRightsId() == 0: nca.rewind() encKeyBlock = nca.header.getKeyBlock() if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2( ): encKeyBlock, crypto1, crypto2 = squirrelXCI.get_new_cryptoblock( squirrelXCI, nca, keypatch, encKeyBlock, t) t.close() nca.rewind() i = 0 newheader = xci.get_newheader( nca, encKeyBlock, crypto1, crypto2, hcrypto, gc_flag) outf.write(newheader) written += len(newheader) nca.seek(0xC00) break else: pass xci.flush() xci.close() elif filepath.endswith('nsp'): nsp = squirrelNSP(filepath) written = 0 for nca in nsp: if nca._path == fi: nca = Nca(nca) crypto1 = nca.header.getCryptoType() crypto2 = nca.header.getCryptoType2() if crypto2 > crypto1: masterKeyRev = crypto2 if crypto2 <= crypto1: masterKeyRev = crypto1 crypto = aes128.AESECB( Keys.keyAreaKey( Keys.getMasterKeyIndex(masterKeyRev), nca.header.keyIndex)) hcrypto = aes128.AESXTS(uhx(Keys.get('header_key'))) gc_flag = '00' * 0x01 crypto1 = nca.header.getCryptoType() crypto2 = nca.header.getCryptoType2() if nca.header.getRightsId() != 0: nca.rewind() if crypto2 > crypto1: masterKeyRev = crypto2 if crypto2 <= crypto1: masterKeyRev = crypto1 from mtp_tools import get_nca_ticket check, titleKey = get_nca_ticket(filepath, fi) if check == False: sys.exit("Can't verify titleckey") titleKeyDec = Keys.decryptTitleKey( titleKey, Keys.getMasterKeyIndex(int(masterKeyRev))) encKeyBlock = crypto.encrypt(titleKeyDec * 4) if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2(): encKeyBlock, crypto1, crypto2 = squirrelNSP.get_new_cryptoblock( squirrelNSP, nca, keypatch, encKeyBlock, t) t.close() if nca.header.getRightsId() == 0: nca.rewind() encKeyBlock = nca.header.getKeyBlock() if str(keypatch) != "False": t = tqdm(total=False, unit='B', unit_scale=False, leave=False) if keypatch < nca.header.getCryptoType2(): encKeyBlock, crypto1, crypto2 = squirrelNSP.get_new_cryptoblock( squirrelNSP, nca, keypatch, encKeyBlock, t) t.close() nca.rewind() i = 0 newheader = nsp.get_newheader(nca, encKeyBlock, crypto1, crypto2, hcrypto, gc_flag) outf.write(newheader) written += len(newheader) nca.seek(0xC00) break else: pass nsp.flush() nsp.close() outf.flush() outf.close() tfile = os.path.join(cachefolder, "files.csv") with open(tfile, 'w') as csvfile: csvfile.write("{}|{}|{}|{}|{}|{}\n".format("step", "filepath", "size", "targetsize", "off1", "off2")) csvfile.write("{}|{}|{}|{}|{}|{}\n".format(0, outfile, properheadsize + written, properheadsize, 0, properheadsize)) k = 0 l = 0 for fi in files: for filepath in input_files: if filepath.endswith('xci'): files_list = sq_tools.ret_xci_offsets(filepath) elif filepath.endswith('nsp'): files_list = sq_tools.ret_nsp_offsets(filepath) for j in files_list: if j[0] == fi: csvfile.write("{}|{}|{}|{}|{}|{}\n".format( k + 1, outfile, properheadsize + written, 0xC00, (properheadsize + l * 0xC00), (properheadsize + (l * 0xC00) + 0xC00))) off1 = j[1] + 0xC00 off2 = j[2] targetsize = j[3] - 0xC00 csvfile.write("{}|{}|{}|{}|{}|{}\n".format( k + 2, filepath, (os.path.getsize(filepath)), targetsize, off1, off2)) break k += 2 l += 1 return end_name