def file_hash(remote, target, files_list=None): if files_list == None: files_list = get_files_from_head(remote, remote.name) else: files_list = files_list target2 = target[:-1] + 'z' indent = 1 gamecard = False tabs = '\t' * indent sha = False sizef = False for i in range(len(files_list)): if str(files_list[i][0]).lower() == str(target).lower() or str( files_list[i][0]).lower() == str(target2).lower(): nca_name = files_list[i][0] off1 = files_list[i][1] off2 = files_list[i][2] sz = files_list[i][3] break hblock = remote.read_at(off1, 0x200) sha = sha256(hblock).hexdigest() if nca_name.endswith('.ncz') or nca_name.endswith('.nca'): ncaHeader = NcaHeader() ncaHeader.open( MemoryFile(remote.read_at(off1, 0x400), Type.Crypto.XTS, uhx(Keys.get('header_key')))) if nca_name.endswith('.ncz'): sizef = ncaHeader.size else: sizef = sz if nca_name.endswith('.ncz'): if ncaHeader.getgamecard() == 1: gamecard = True else: nca_id = ncaHeader.titleId if nca_id.endswith('000') or nca_id.endswith('800'): if str(ncaHeader.contentType) == 'Content.PROGRAM': docheck = True else: if str(ncaHeader.contentType) == 'Content.DATA': docheck = True if docheck == True: 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)) KB1L = ncaHeader.getKB1L() KB1L = crypto.decrypt(KB1L) if sum(KB1L) == 0: gamecard = True return sha, sizef, gamecard
def return_nca_data(file_list): File_DB = {} meta_filename = False meta_filepath = False end = len(file_list) c = 1 for filepath in file_list: try: NAXKey0, NAXKey1, r_path = get_decryption_keys(filepath) filename = (r_path.split('/'))[-1] with open(filepath, 'rb') as f: f.seek(0x4000) data = f.read(0x4000) crypto = aes128.AESXTS(NAXKey0 + NAXKey1, sector_size=0x4000) first_chunk = crypto.decrypt(data) ncaHeader = NcaHeader() ncaHeader.open( MemoryFile(first_chunk, Type.Crypto.XTS, uhx(Keys.get('header_key')))) # print(str(ncaHeader.contentType)) if ncaHeader.magic not in [b'NCA3', b'NCA2']: pass elif str(ncaHeader.contentType) == 'Content.META': if str(ncaHeader.contentType) == 'Content.META': filename = filename.replace('.nca', '.cnmt.nca') # meta_filename=filename # meta_filepath=filepath File_DB[filename] = { 'filepath': filepath, 'NAXKey0': NAXKey0, 'NAXKey1': NAXKey1, 'r_path': r_path, 'content_type': ncaHeader.contentType, 'titleid': ncaHeader.titleId, 'size': ncaHeader.size, 'titlerights': ncaHeader.rightsId, 'crypto1': ncaHeader.getCryptoType(), 'crypto2': ncaHeader.getCryptoType2() } print( f"{filename} - {ncaHeader.titleId} - {str(ncaHeader.contentType)} ({c}/{end})" ) c += 1 ncaHeader.close() except: pass # return meta_filepath,meta_filename,File_DB return File_DB
def gen_xci_parts_spec1(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'] for j in range(len(ncadata)): row=ncadata[j] 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 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 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 data=remote.read_at(off1,nca_size) 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 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 < 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) break 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,properheadsize+written,properheadsize,0,properheadsize,"False")) 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),"False")) 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+2,URL,remote.size,targetsize,off1,off2,token)) break k+=2;l+=1 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:pass return nspname