Beispiel #1
0
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						
Beispiel #2
0
def read_buildid(path=None,
                 TD=None,
                 filter=None,
                 file=None,
                 cnmtdict=None,
                 files_list=None,
                 dectkey=None):
    ModuleId = ''
    BuildID8 = ''
    BuildID16 = ''
    iscorrect = False
    sdkversion = '-'
    sectionFilesystems = []
    if file != None and cnmtdict != None and files_list != None:
        remote = file
    else:
        cnmtdict, files_list, remote = get_cnmt_data(path, TD, filter)
    ctype = cnmtdict['ctype']
    if ctype != 'DLC':
        ncadata = cnmtdict['ncadata']
        for entry in ncadata:
            if str(entry['NCAtype']).lower() == 'program':
                ncaname = entry['NcaId'] + '.nca'
                break
        for i in range(len(files_list)):
            if (files_list[i][0]) == ncaname:
                name = files_list[i][0]
                off1 = files_list[i][1]
                off2 = files_list[i][2]
                sz = files_list[i][3]
                break
        remote.seek(off1, off2)
        ncaHeader = NcaHeader()
        ncaHeader.open(
            MemoryFile(remote.read(0xC00), Type.Crypto.XTS,
                       uhx(Keys.get('header_key'))))
        ncaHeader.rewind()
        if ncaHeader.getRightsId() == 0:
            decKey = ncaHeader.titleKeyDec
        elif dectkey != None:
            # print(dectkey)
            decKey = bytes.fromhex(dectkey)
        try:
            sdkversion = get_sdkversion_from_head(ncaHeader)
        except:
            sdkversion = '-'
        try:
            ncaHeader.seek(0x400)
            for i in range(4):
                hdr = ncaHeader.read(0x200)
                section = BaseFs(hdr, cryptoKey=ncaHeader.titleKeyDec)
                fs = GetSectionFilesystem(hdr, cryptoKey=-1)
                if fs.fsType:
                    fs.offset = ncaHeader.sectionTables[i].offset
                    sectionFilesystems.append(fs)
                    # Print.info('fs type = ' + hex(fs.fsType))
                    # Print.info('fs crypto = ' + hex(fs.cryptoType))
                    # Print.info('fs cryptocounter = ' + str(fs.cryptoCounter))
                    # Print.info('st end offset = ' + str(ncaHeader.sectionTables[i].endOffset - ncaHeader.sectionTables[i].offset))
                    # Print.info('fs offset = ' + hex(ncaHeader.sectionTables[i].offset))
                    # Print.info('fs section start = ' + hex(fs.sectionStart))
                    # Print.info('titleKey = ' + str(hx(ncaHeader.titleKeyDec)))
            for fs in sectionFilesystems:
                if fs.fsType == Type.Fs.PFS0 and fs.cryptoType == Type.Crypto.CTR:
                    # print(fs.fsType)
                    # print(fs.cryptoType)
                    # print(fs.buffer)
                    pfs0 = fs
                    sectionHeaderBlock = fs.buffer
                    pfs0Offset = fs.offset + fs.sectionStart
                    skoff = off1 + pfs0Offset
                    # pfs0Offset=off1+fs.offset+0xC00+ncaHeader.get_htable_offset()
                    remote.seek(skoff, off2)
                    # print(str(fs.cryptoCounter))
                    pfs0Header = remote.read(0x10 * 30)
                    # print(hex(pfs0Offset))
                    # print(hex(fs.sectionStart))
                    # Hex.dump(pfs0Header)
                    off = fs.offset + fs.sectionStart
                    mem = MemoryFile(pfs0Header,
                                     Type.Crypto.CTR,
                                     decKey,
                                     pfs0.cryptoCounter,
                                     offset=pfs0Offset)
                    data = mem.read()
                    # Hex.dump(data)
                    head = data[0:4]
                    n_files = (data[4:8])
                    n_files = int.from_bytes(n_files, byteorder='little')
                    st_size = (data[8:12])
                    st_size = int.from_bytes(st_size, byteorder='little')
                    junk = (data[12:16])
                    offset = (0x10 + n_files * 0x18)
                    stringTable = (data[offset:offset + st_size])
                    stringEndOffset = st_size
                    headerSize = 0x10 + 0x18 * n_files + st_size
                    # print(head)
                    # print(str(n_files))
                    # print(str(st_size))
                    # print(str((stringTable)))
                    files_list = list()
                    for i in range(n_files):
                        i = n_files - i - 1
                        pos = 0x10 + i * 0x18
                        offset = data[pos:pos + 8]
                        offset = int.from_bytes(offset, byteorder='little')
                        size = data[pos + 8:pos + 16]
                        size = int.from_bytes(size, byteorder='little')
                        nameOffset = data[pos + 16:pos + 20]  # just the offset
                        nameOffset = int.from_bytes(nameOffset,
                                                    byteorder='little')
                        name = stringTable[nameOffset:stringEndOffset].decode(
                            'utf-8').rstrip(' \t\r\n\0')
                        stringEndOffset = nameOffset
                        # junk2 = data[pos+20:pos+24] # junk data
                        # print(name)
                        # print(offset)
                        # print(size)
                        files_list.append([name, offset, size])
                    files_list.reverse()
                    # print(files_list)
                    for i in range(len(files_list)):
                        if files_list[i][0] == 'main':
                            foff = files_list[i][1] + pfs0Offset + headerSize
                            skoff2 = files_list[i][1] + skoff + headerSize
                            remote.seek(skoff2, off2)
                            np = remote.read(0x60)
                            mem = MemoryFile(np,
                                             Type.Crypto.CTR,
                                             decKey,
                                             pfs0.cryptoCounter,
                                             offset=foff)
                            magic = mem.read(0x4)
                            # print(magic)
                            if magic == b'NSO0':
                                mem.seek(0x40)
                                data = mem.read(0x20)
                                ModuleId = (str(hx(data)).upper())[2:-1]
                                BuildID8 = (str(hx(data[:8])).upper())[2:-1]
                                BuildID16 = (str(hx(data[:16])).upper())[2:-1]
                                iscorrect = True
                            break
                break
        except:
            pass
    if iscorrect == False:
        ModuleId = ''
        BuildID8 = ''
        BuildID16 = ''
    # print(ModuleId);print(BuildID8);print(BuildID16)
    return ModuleId, BuildID8, BuildID16, sdkversion