예제 #1
0
    def verify(self):
        ncaHeader = NcaHeader()
        ncaHeader.open(
            MemoryFile(self.ncaHeader, Type.Crypto.XTS,
                       uhx(Keys.get('header_key'))))

        id = ncaHeader.rightsId[0:16].decode().upper()
        if str(self.titleId) != id:
            raise IndexError('Title IDs do not match!  ' + str(self.titleId) +
                             ' != ' + id)

        decKey = Keys.decryptTitleKey(uhx(self.titleKey), ncaHeader.masterKey)

        pfs0 = Fs.Pfs0(self.sectionHeaderBlock)
        '''
		print('encKey = ' + str(self.titleKey))
		print('decKey = ' + str(hx(decKey)))
		print('master key = ' + str(ncaHeader.masterKey))
		print('ctr = ' + str(hx(pfs0.cryptoCounter)))
		print('offset = ' + str(self.pfs0Offset))
		'''

        mem = MemoryFile(self.pfs0Header,
                         Type.Crypto.CTR,
                         decKey,
                         pfs0.cryptoCounter,
                         offset=self.pfs0Offset)
        magic = mem.read()[0:4]
        if magic != b'PFS0':
            raise LookupError('Title Key is incorrect!')

        return True
예제 #2
0
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)
예제 #3
0
파일: BaseFs.py 프로젝트: jeffangama/nut
    def open(self,
             path=None,
             mode='rb',
             cryptoType=-1,
             cryptoKey=-1,
             cryptoCounter=-1):
        r = super(BaseFs, self).open(path, mode, cryptoType, cryptoKey,
                                     cryptoCounter)

        if self.bktr1Buffer:
            self.bktrRelocation = Bktr.Bktr1(MemoryFile(self.bktr1Buffer),
                                             'rb',
                                             nca=self)

        if self.bktr2Buffer:
            self.bktrSubsection = Bktr.Bktr2(MemoryFile(self.bktr2Buffer),
                                             'rb',
                                             nca=self)
예제 #4
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
예제 #5
0
파일: Rom.py 프로젝트: yukun451/nut
	def __init__(self, buffer, path=None, mode=None, cryptoType=-1, cryptoKey=-1, cryptoCounter=-1):
		super(Rom, self).__init__(buffer, path, mode, cryptoType, cryptoKey, cryptoCounter)
		if buffer:
			self.ivfc = Ivfc(MemoryFile(buffer[0x8:]), 'rb')
			self.magic = buffer[0x8:0xC]

			# Hex.dump(buffer)
			#self.sectionStart = self.ivfc.levels[5].offset
		else:
			self.ivfc = None
예제 #6
0
파일: Rom.py 프로젝트: pka4916/nut
 def __init__(self,
              buffer,
              path=None,
              mode=None,
              cryptoType=-1,
              cryptoKey=-1,
              cryptoCounter=-1):
     super(Rom, self).__init__(buffer, path, mode, cryptoType, cryptoKey,
                               cryptoCounter)
     if buffer:
         self.ivfc = Ivfc(MemoryFile(buffer[0x8:]), 'rb')
         self.magic = buffer[0x8:0xC]
     else:
         self.ivfc = None
예제 #7
0
    def open(self,
             path=None,
             mode='rb',
             cryptoType=-1,
             cryptoKey=-1,
             cryptoCounter=-1):
        r = super(BaseFs, self).open(path, mode, cryptoType, cryptoKey,
                                     cryptoCounter)

        if self.bktr1Buffer:
            try:
                self.bktrRelocation = Bktr.Bktr1(MemoryFile(self.bktr1Buffer),
                                                 'rb',
                                                 nca=self)
            except BaseException as e:
                Print.info('bktr reloc exception: ' + str(e))

        if self.bktr2Buffer:
            try:
                self.bktrSubsection = Bktr.Bktr2(MemoryFile(self.bktr2Buffer),
                                                 'rb',
                                                 nca=self)
            except BaseException as e:
                Print.info('bktr subsection exception: ' + str(e))
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
예제 #9
0
    def verify(self):
        ncaHeader = NcaHeader()
        ncaHeader.open(
            MemoryFile(self.ncaHeader, Type.Crypto.XTS,
                       uhx(Keys.get('header_key'))))

        id = ncaHeader.rightsId[0:16].decode().upper()
        if str(self.titleId) != id:
            raise IndexError('Title IDs do not match!  ' + str(self.titleId) +
                             ' != ' + id)

        decKey = Keys.decryptTitleKey(uhx(self.titleKey), ncaHeader.masterKey)

        pfs0 = Fs.Pfs0(self.sectionHeaderBlock)
        '''
		print('encKey = ' + str(self.titleKey))
		print('decKey = ' + str(hx(decKey)))
		print('master key = ' + str(ncaHeader.masterKey))
		print('ctr = ' + str(hx(pfs0.cryptoCounter)))
		print('offset = ' + str(self.pfs0Offset))
		'''

        if self.sectionHeaderBlock[8:12] == b'IVFC':
            #Hex.dump(self.sectionHeaderBlock)
            #Print.info(hx(self.sectionHeaderBlock[0xc8:0xc8+0x20]).decode('utf-8'))
            mem = MemoryFile(self.pfs0Header,
                             Type.Crypto.CTR,
                             decKey,
                             pfs0.cryptoCounter,
                             offset=self.pfs0Offset)
            data = mem.read()
            #Hex.dump(data)
            #print('hash = %s' % str(_sha256(data)))
            if hx(self.sectionHeaderBlock[0xc8:0xc8 +
                                          0x20]).decode('utf-8') == str(
                                              _sha256(data)):
                return True
            else:
                return False
        else:
            mem = MemoryFile(self.pfs0Header,
                             Type.Crypto.CTR,
                             decKey,
                             pfs0.cryptoCounter,
                             offset=self.pfs0Offset)
            magic = mem.read()[0:4]
            if magic != b'PFS0':
                raise LookupError('Title Key is incorrect!')

        return True
예제 #10
0
def decrypt_nax0(input, output=None, ofolder=None, relative_PATH=False):
    if output == None and ofolder == None:
        raise Exception("User didn't set output")
    NAXKey0, NAXKey1, r_path = get_decryption_keys(input, relative_PATH)
    filename = (r_path.split('/'))[-1]
    with open(input, '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'))))
    if ncaHeader.magic not in [b'NCA3', b'NCA2']:
        raise Exception('Failed to decrypt NCA header: ' + str(self.magic))
    else:
        sz = ncaHeader.size
        print(f'* {r_path} - Decryption Correct')
        print(
            f'* NCA Type is {str(ncaHeader.contentType).replace("Content.","")}'
        )
        print(f'* NCA TitleID is {str(ncaHeader.titleId)}')
        print(f'* NCA size is {str(sq_tools.getSize(sz))}')
        if not str(ncaHeader.contentType) == 'Content.META':
            print(f'* Filename is {filename}')
        else:
            filename = filename.replace('.nca', '.cnmt.nca')
    if output == None:
        output = os.path.join(ofolder, filename)
    t = tqdm(total=sz, unit='B', unit_scale=True, leave=False)
    t.write(f'\n- Decrypting to {output}')
    buffer = 0x4000
    sect = 0
    with open(output, 'wb') as o:
        with open(input, 'rb') as f:
            f.seek(0x4000)
            for data in iter(lambda: f.read(0x4000), ""):
                crypto = aes128.AESXTS(NAXKey0 + NAXKey1,
                                       sector=sect,
                                       sector_size=0x4000)
                o.write(crypto.decrypt(data))
                o.flush()
                if not data:
                    t.close()
                    break
                sect += 1
예제 #11
0
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
예제 #12
0
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
예제 #13
0
파일: Nca.py 프로젝트: yukun451/nut
    def verifyKey(self, userkey):
        if not self.header.hasTitleRights():
            titleKeyDec = Keys.decryptTitleKey(
                file.getTitleKeyBlock().to_bytes(16, byteorder='big'),
                Keys.getMasterKeyIndex(self.masterKey()))
        else:
            encKey = userkey

            titleKeyDec = Keys.decryptTitleKey(
                encKey, Keys.getMasterKeyIndex(self.masterKey()))
            '''
			print('\nTesting {} with:'.format(self))
			print('- Keygeneration {}'.format(self.masterKey()))
			print('- Encrypted key {}'.format(str(hx(encKey))[2:-1]))
			print('- Decrypted key {}'.format(str(hx(titleKeyDec))[2:-1]))
			'''

        decKey = titleKeyDec
        f = self

        if self.header.getRightsId() != 0:
            for fs in self:
                # print(fs.fsType)
                # print(fs.cryptoType)
                if fs.fsType == Type.Fs.PFS0 and fs.cryptoType == Type.Crypto.CTR:
                    f.seek(0)
                    ncaHeader = NcaHeader()
                    ncaHeader.open(
                        MemoryFile(f.read(0x400), Type.Crypto.XTS,
                                   uhx(Keys.get('header_key'))))
                    pfs0 = fs
                    sectionHeaderBlock = fs.buffer

                    #fs.f.setKey(b'\x00' * 16)
                    #print('- Current key {}'.format(str(hx(fs.f.cryptoKey))[2:-1]))

                    fs.seek(0)
                    pfs0Offset = 0  # int.from_bytes(sectionHeaderBlock[0x38:0x40], byteorder='little', signed=False)
                    pfs0Header = fs.read(0x10)

                    # Hex.dump(sectionHeaderBlock)
                    #mem = MemoryFile(pfs0Header, Type.Crypto.CTR, decKey, pfs0.cryptoCounter, offset = pfs0Offset)
                    data = pfs0Header  # mem.read();
                    # Hex.dump(pfs0Header)
                    magic = data[0:4]
                    # print(magic)
                    if magic != b'PFS0':
                        return False
                    else:
                        return True

                if fs.fsType == Type.Fs.ROMFS and fs.cryptoType == Type.Crypto.CTR:
                    f.seek(0)
                    ncaHeader = NcaHeader()
                    ncaHeader.open(
                        MemoryFile(f.read(0x400), Type.Crypto.XTS,
                                   uhx(Keys.get('header_key'))))
                    ncaHeader = f.read(0x400)
                    pfs0 = fs
                    sectionHeaderBlock = fs.buffer

                    levelOffset = int.from_bytes(sectionHeaderBlock[0x18:0x20],
                                                 byteorder='little',
                                                 signed=False)
                    levelSize = int.from_bytes(sectionHeaderBlock[0x20:0x28],
                                               byteorder='little',
                                               signed=False)

                    pfs0Offset = levelOffset
                    f.seek(pfs0Offset + fs.f.offset)
                    pfs0Header = f.read(levelSize)

                    # fs.seek(pfs0Offset)
                    #pfs0Header = fs.read(levelSize)

                    #print(sectionHeaderBlock[8:12] == b'IVFC')
                    if sectionHeaderBlock[8:12] == b'IVFC':
                        # Hex.dump(sectionHeaderBlock)
                        # Print.info(hx(sectionHeaderBlock[0xc8:0xc8+0x20]).decode('utf-8'))
                        mem = MemoryFile(pfs0Header,
                                         Type.Crypto.CTR,
                                         decKey,
                                         pfs0.cryptoCounter,
                                         offset=fs.f.offset)

                        data = mem.read()

                        #Hex.dump(data, 48)
                        #print('hash = %s' % str(sha256(data).hexdigest()))
                        if hx(sectionHeaderBlock[0xc8:0xc8 +
                                                 0x20]).decode('utf-8') == str(
                                                     sha256(data).hexdigest()):
                            return True
                        else:
                            return False
                    else:
                        mem = MemoryFile(pfs0Header,
                                         Type.Crypto.CTR,
                                         decKey,
                                         pfs0.cryptoCounter,
                                         offset=pfs0Offset)
                        data = mem.read()
                        # Hex.dump(data)
                        magic = mem.read()[0:4]
                        # print(magic)
                        if magic != b'PFS0':
                            pass
                        else:
                            return True

                if fs.fsType == Type.Fs.ROMFS and fs.cryptoType == Type.Crypto.BKTR and str(
                        f.header.contentType) == 'Content.PROGRAM':
                    f.seek(0)
                    ncaHeader = NcaHeader()
                    ncaHeader.open(
                        MemoryFile(f.read(0x400), Type.Crypto.XTS,
                                   uhx(Keys.get('header_key'))))
                    ncaHeader = f.read(0x400)
                    pfs0 = fs
                    sectionHeaderBlock = fs.buffer

                    levelOffset = int.from_bytes(sectionHeaderBlock[0x18:0x20],
                                                 byteorder='little',
                                                 signed=False)
                    levelSize = int.from_bytes(sectionHeaderBlock[0x20:0x28],
                                               byteorder='little',
                                               signed=False)

                    pfs0Offset = fs.offset + levelOffset
                    f.seek(pfs0Offset)
                    pfs0Header = f.read(levelSize)

                    if sectionHeaderBlock[8:12] == b'IVFC':
                        for i in range(10):
                            ini = 0x100 + (i * 0x10)
                            fin = 0x110 + (i * 4)
                            test = sectionHeaderBlock[ini:fin]
                            if test == b'BKTR':
                                return True
        return False
예제 #14
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						
예제 #15
0
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						
예제 #16
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
예제 #17
0
def memoryload(filelist,target=False,ender=False):
	for i in range(len(filelist)):
		entry=filelist[i]
		file=entry[0];size=entry[1]
		initpath=entry[2];off1=entry[3]
		endpath=entry[4];off2=entry[5]
		if file.lower()==str(target).lower():
			if initpath==endpath:
				with open(initpath, 'rb') as f:
					f.seek(off1)
					inmemoryfile = io.BytesIO(f.read(size))
					inmemoryfile.seek(0)
					nca = Fs.Nca()
					nca.open(inmemoryfile)
					nca.read_cnmt()
		elif target==False and ender!=False:
			if str(file.lower()).endswith(ender):
				if initpath==endpath:
					with open(initpath, 'rb') as f:
						f.seek(off1)
						inmemoryfile = io.BytesIO(f.read(size))
						inmemoryfile.seek(0)
						ncaHeader = NcaHeader()
						f.seek(off1)
						ncaHeader.open(MemoryFile(f.read(size), Type.Crypto.XTS, uhx(Keys.get('header_key'))))
						# ncaHeader.seek(0x400)
					try:
						nca3=NCA3(inmemoryfile,0,file,ncaHeader.titleKeyDec)
						for _, sec in enumerate(nca3.sections):
							if sec.fs_type == 'RomFS':
								continue
							for buf in sec.decrypt_raw():
								DAT=buf
								Hex.dump(buf)
								# print(d)
								# if file.endswith('.cnmt'):
									# DAT=sec.fs.open(file)
									# for test in DAT:
										# Hex.dump(test)
									# print(DAT)
					except Exception as e:
						print('%s: %s' % (e.__class__.__name__, e))
						# for i in range(4):
							# fs = GetSectionFilesystem(ncaHeader.read(0x200), cryptoKey = ncaHeader.titleKeyDec)
							# Print.info('fs type = ' + hex(fs.fsType))
							# Print.info('fs crypto = ' + hex(fs.cryptoType))
							# 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)))
							# break
						# pfs0=fs
						# sectionHeaderBlock = fs.buffer
						# ncaHeader.seek(fs.offset)
						# pfs0Offset=fs.offset
						# pfs0Header = f.read(0x100)
						# Hex.dump(pfs0Header)
						# mem = MemoryFile(pfs0Header, Type.Crypto.CTR, ncaHeader.titleKeyDec, pfs0.cryptoCounter, offset = pfs0Offset)
						# data=mem.read();
						# data=ncaHeader.read()
						# Hex.dump(data)
						# nca = Fs.Nca()
						# f.seek(off1)
						# nca.open(MemoryFile(f.read(size), Type.Crypto.None, uhx(Keys.get('header_key'))))
						# nca.read_cnmt()
					break