Exemple #1
0
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