Beispiel #1
0
def rebuild_nsp(ifolder,
                ofolder,
                buffer=65536,
                delta=False,
                xml_gen=False,
                export='nsp'):
    extlist = ['nsp', 'nsz']
    files = listmanager.folder_to_list(ifolder, extlist)
    from Fs import Nsp
    import decompressor
    total = len(files)
    for filepath in files:
        if filepath.endswith('nsp'):
            basename = os.path.basename(os.path.abspath(filepath))
            endfile = os.path.join(ofolder, basename)
            print('Processing: ' + filepath)
            f = Nsp(filepath)
            f.rebuild(buffer, endfile, delta, False, xml_gen)
            f.flush()
            f.close()
        elif filepath.endswith('nsz'):
            basename = os.path.basename(os.path.abspath(filepath))
            endname = basename[:-1] + 'p'
            endname = os.path.join(ofolder, endname)
            decompressor.decompress_nsz(filepath, endname, buffer, delta,
                                        xml_gen)
        total -= 1
        print("**********************************************************")
        print(('Still {} files to process').format(str(total)))
        print("**********************************************************")
Beispiel #2
0
def decompressWorker(q, output, totalStatus):
	while not q.empty():
		try:
			path = q.get(block=False)
			totalStatus.add(1)

			path = NszDecompressor.decompress(path, output)
			if path:
				i = Nsp(path)
				i.move()

		except queue.Empty as e:
			return
		except BaseException as e:
			Print.info('DECOMPRESS WORKER EXCEPTION: ' + str(e))
			traceback.print_exc(file=sys.stdout)
Beispiel #3
0
def getName(titleId, version, key=None, path=None):
	initTitles()
	initFiles()
	titleId = titleId.upper()
	nsp = Nsp()

	if path:
		nsp.setPath(os.path.basename(path))

	nsp.titleId = titleId
	nsp.version = version
	nsp.hasValidTicket = True

	if path:
		filename, ext = os.path.splitext(path)
	else:
		ext = '.nsp'

	return os.path.join(Config.paths.nspOut, os.path.basename(nsp.fileName() or ('Untitled [%s][v%d]%s' % (titleId, int(version or 0), ext))))
def get_key_fromdict(fp):
	if fp.endswith('.nsp') or fp.endswith('.nsx'):
		files_list=sq_tools.ret_nsp_offsets(fp)
		files=list();filesizes=list()
		fplist=list()
		for k in range(len(files_list)):
			entry=files_list[k]
			fplist.append(entry[0])
		for i in range(len(files_list)):
			entry=files_list[i]
			filepath=entry[0]
			if filepath.endswith('.cnmt.nca'):
				f=Nsp(fp,'rb')
				titleid,titleversion,base_ID,keygeneration,rightsId,RSV,RGV,ctype,metasdkversion,exesdkversion,hasHtmlManual,Installedsize,DeltaSize,ncadata=f.get_data_from_cnmt(filepath)
				titlekey,dectkey=f.db_get_titlekey(rightsId,keygeneration)
				f.flush()
				f.close()
				# print(titlekey);print(rightsId)				
				return titlekey
Beispiel #5
0
def main():
    global err
    try:

        if len(argv) > 1:
            args = ParseArguments.parse()
        else:
            from gui.NSZ_GUI import GUI
            args = GUI().run()
            if args == None:
                Print.info("Done!")
                return

        if args.output:
            outfolderToPharse = args.output
            if not outfolderToPharse.endswith(
                    '/') and not outfolderToPharse.endswith('\\'):
                outfolderToPharse += "/"
            if not Path(outfolderToPharse).is_dir():
                Print.error(
                    'Error: Output directory "{0}" does not exist!'.format(
                        args.output))
                return
        outfolder = Path(outfolderToPharse).resolve() if args.output else Path(
            '.').resolve()

        Print.info('')
        Print.info('             NSZ v3.0   ,;:;;,')
        Print.info('                       ;;;;;')
        Print.info('               .=\',    ;:;;:,')
        Print.info('              /_\', "=. \';:;:;')
        Print.info('              @=:__,  \,;:;:\'')
        Print.info('                _(\.=  ;:;;\'')
        Print.info('               `"_(  _/="`')
        Print.info('                `"\'')
        Print.info('')

        barManager = enlighten.get_manager()
        poolManager = Manager()
        statusReport = poolManager.list()
        readyForWork = Counter(0)
        pleaseNoPrint = Counter(0)
        pleaseKillYourself = Counter(0)
        pool = []
        work = poolManager.Queue()
        amountOfTastkQueued = Counter(0)

        if args.titlekeys:
            extractTitlekeys(args.file)

        if args.extract:
            for f_str in args.file:
                for filePath in expandFiles(Path(f_str)):
                    filePath_str = str(filePath)
                    Print.info('Extracting "{0}" to {1}'.format(
                        filePath_str, outfolder))
                    f = factory(filePath)
                    f.open(filePath_str, 'rb')
                    dir = outfolder.joinpath(filePath.stem)
                    f.unpack(dir, args.extractregex)
                    f.close()
        if args.create:
            Print.info('Creating "{0}"'.format(args.create))
            nsp = Nsp.Nsp(None, None)
            nsp.path = args.create
            nsp.pack(args.file)
        if args.C:
            targetDictNsz = CreateTargetDict(outfolder, args.parseCnmt, ".nsz")
            targetDictXcz = CreateTargetDict(outfolder, args.parseCnmt, ".xcz")
            sourceFileToDelete = []
            for f_str in args.file:
                for filePath in expandFiles(Path(f_str)):
                    if not isUncompressedGame(filePath):
                        continue
                    try:
                        if filePath.suffix == '.nsp':
                            if not AllowedToWriteOutfile(
                                    filePath, ".nsz", targetDictNsz,
                                    args.rm_old_version, args.overwrite,
                                    args.parseCnmt):
                                continue
                        elif filePath.suffix == '.xci':
                            if not AllowedToWriteOutfile(
                                    filePath, ".xcz", targetDictXcz,
                                    args.rm_old_version, args.overwrite,
                                    args.parseCnmt):
                                continue
                        compress(filePath, outfolder, args, work,
                                 amountOfTastkQueued)
                        if args.rm_source:
                            sourceFileToDelete.append(filePath)
                    except KeyboardInterrupt:
                        raise
                    except BaseException as e:
                        Print.error('Error when compressing file: %s' %
                                    filePath)
                        err.append({
                            "filename": filePath,
                            "error": format_exc()
                        })
                        print_exc()

            bars = []
            compressedSubBars = []
            BAR_FMT = u'{desc}{desc_pad}{percentage:3.0f}%|{bar}| {count:{len_total}d}/{total:d} {unit} [{elapsed}<{eta}, {rate:.2f}{unit_pad}{unit}/s]'
            parallelTasks = min(args.multi, amountOfTastkQueued.value())
            if parallelTasks < 0:
                parallelTasks = 4
            for i in range(parallelTasks):
                statusReport.append([0, 0, 100])
                p = Process(target=solidCompressTask,
                            args=(work, statusReport, readyForWork,
                                  pleaseNoPrint, pleaseKillYourself, i))
                p.start()
                pool.append(p)
            for i in range(parallelTasks):
                bar = barManager.counter(total=100,
                                         desc='Compressing',
                                         unit='MiB',
                                         color='cyan',
                                         bar_format=BAR_FMT)
                compressedSubBars.append(bar.add_subcounter('green'))
                bars.append(bar)
            sleep(0.02)
            while readyForWork.value() < parallelTasks:
                sleep(0.2)
                if pleaseNoPrint.value() > 0:
                    continue
                pleaseNoPrint.increment()
                for i in range(parallelTasks):
                    compressedRead, compressedWritten, total = statusReport[i]
                    if bars[i].total != total:
                        bars[i].total = total // 1048576
                    bars[i].count = compressedRead // 1048576
                    compressedSubBars[i].count = compressedWritten // 1048576
                    bars[i].refresh()
                pleaseNoPrint.decrement()
            pleaseKillYourself.increment()
            for i in range(readyForWork.value()):
                work.put(None)

            while readyForWork.value() > 0:
                sleep(0.02)

            for i in range(parallelTasks):
                bars[i].close(clear=True)
            #barManager.stop() #We aren’t using stop because of it printing garbage to the console.

            for filePath in sourceFileToDelete:
                delete_source_file(filePath)

        if args.D:
            targetDictNsz = CreateTargetDict(outfolder, args.parseCnmt, ".nsp")
            targetDictXcz = CreateTargetDict(outfolder, args.parseCnmt, ".xci")
            for f_str in args.file:
                for filePath in expandFiles(Path(f_str)):
                    if not isCompressedGame(
                            filePath) and not isCompressedGameFile(filePath):
                        continue
                    try:
                        if filePath.suffix == '.nsz':
                            if not AllowedToWriteOutfile(
                                    filePath, ".nsp", targetDictNsz,
                                    args.rm_old_version, args.overwrite,
                                    args.parseCnmt):
                                continue
                        elif filePath.suffix == '.xcz':
                            if not AllowedToWriteOutfile(
                                    filePath, ".xci", targetDictXcz,
                                    args.rm_old_version, args.overwrite,
                                    args.parseCnmt):
                                continue
                        elif filePath.suffix == '.ncz':
                            outfile = changeExtension(
                                outfolder.joinpath(filePath.name), ".nca")
                            if not args.overwrite and outfile.is_file():
                                Print.info('{0} with the same file name already exists in the output directory.\n'\
                                'If you want to overwrite it use the -w parameter!'.format(outfile.name))
                                continue
                        decompress(filePath, outfolder)
                        if args.rm_source:
                            delete_source_file(filePath)
                    except KeyboardInterrupt:
                        raise
                    except BaseException as e:
                        Print.error(
                            'Error when decompressing file: {0}'.format(
                                filePath))
                        err.append({
                            "filename": filePath,
                            "error": format_exc()
                        })
                        print_exc()

        if args.info:
            for f_str in args.file:
                for filePath in expandFiles(Path(f_str)):
                    filePath_str = str(filePath)
                    Print.info(filePath_str)
                    f = factory(filePath)
                    f.open(filePath_str, 'r+b')
                    f.printInfo(args.depth + 1)
                    f.close()
        if args.verify and not args.C and not args.D:
            for f_str in args.file:
                for filePath in expandFiles(Path(f_str)):
                    try:
                        if isGame(filePath):
                            Print.info("[VERIFY {0}] {1}".format(
                                getExtensionName(filePath), filePath.name))
                            verify(filePath, False)
                    except KeyboardInterrupt:
                        raise
                    except BaseException as e:
                        Print.error(
                            'Error when verifying file: {0}'.format(filePath))
                        err.append({
                            "filename": filePath,
                            "error": format_exc()
                        })
                        print_exc()

        if len(argv) == 1:
            pass
    except KeyboardInterrupt:
        Print.info('Keyboard exception')
    except BaseException as e:
        Print.info('nut exception: {0}'.format(str(e)))
        raise
    if err:
        Print.info(
            '\n\033[93m\033[1mSummary of errors which occurred while processing files:'
        )

        for e in err:
            Print.info('\033[0mError when processing {0}'.format(
                e["filename"]))
            Print.info(e["error"])

    Print.info('Done!')
def decompress_nsz(input,output,buffer = 65536,delta=False,xml_gen=False):
	f = Nsp(input, 'r+b')
	f.decompress_direct(output,buffer,delta,xml_gen)
	f.flush()
	f.close()
def nsz_hasher(input,buffer = 65536):	
	f = Nsp(input, 'r+b')
	f.nsz_hasher(buffer)
	f.flush()
	f.close()	
	
def verify_nsz(input,buffer = 65536):	
	f = Nsp(input, 'r+b')
	f.verify_nsz(buffer)
	f.flush()
	f.close()
Beispiel #9
0
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					
Beispiel #10
0
def decompress_nsz(input, output, buffer=65536):
    f = Nsp(input, 'r+b')
    f.decompress_direct(output, buffer)
    f.flush()
    f.close()
Beispiel #11
0
def main():
    global err
    try:
        parser = ArgumentParser()
        parser.add_argument('file', nargs='*')
        parser.add_argument('-C', action="store_true", help='Compress NSP')
        parser.add_argument('-D', action="store_true", help='Decompress NSZ')
        parser.add_argument('-l',
                            '--level',
                            type=int,
                            default=18,
                            help='Compression Level')
        parser.add_argument(
            '-B',
            '--block',
            action="store_true",
            default=False,
            help=
            'Uses highly multithreaded block compression with random read access allowing compressed games to be played without decompression in the future however this comes with a low compression ratio cost. Current title installers do not support this yet.'
        )
        parser.add_argument(
            '-s',
            '--bs',
            type=int,
            default=20,
            help=
            'Block Size for random read access 2^x while x between 14 and 32. Default is 20 => 1 MB. Current title installers do not support this yet.'
        )
        parser.add_argument(
            '-V',
            '--verify',
            action="store_true",
            default=False,
            help=
            'Verifies files after compression raising an unhandled exception on hash mismatch and verify existing NSP and NSZ files when given as parameter'
        )
        parser.add_argument(
            '-p',
            '--parseCnmt',
            action="store_true",
            default=False,
            help=
            'Extract TitleId/Version from Cnmt if this information cannot be obtained from the filename. Required for skipping/overwriting existing files and --rm-old-version to work properly if some not every file is named properly. Supported filenames: *TitleID*[vVersion]*'
        )
        parser.add_argument(
            '-t',
            '--threads',
            type=int,
            default=-1,
            help=
            'Number of threads to compress with. Numbers < 1 corresponds to the number of logical CPU cores.'
        )
        parser.add_argument('-o',
                            '--output',
                            nargs='?',
                            help='Directory to save the output NSZ files')
        parser.add_argument(
            '-w',
            '--overwrite',
            action="store_true",
            default=False,
            help=
            'Continues even if there already is a file with the same name or title id inside the output directory'
        )
        parser.add_argument('-r',
                            '--rm-old-version',
                            action="store_true",
                            default=False,
                            help='Removes older version if found')
        parser.add_argument('-i',
                            '--info',
                            help='Show info about title or file')
        parser.add_argument('--depth',
                            type=int,
                            default=1,
                            help='Max depth for file info and extraction')
        parser.add_argument('-x',
                            '--extract',
                            nargs='+',
                            help='extract / unpack a NSP')
        parser.add_argument('-c', '--create', help='create / pack a NSP')
        parser.add_argument(
            '--rm-source',
            action='store_true',
            default=False,
            help=
            'Deletes source file/s after compressing/decompressing. It\'s recommended to only use this in combination with --verify'
        )

        args = parser.parse_args()
        outfolder = str(Path(args.output)) if args.output else str(Path('.'))

        Print.info('')
        Print.info('             NSZ v2.1   ,;:;;,')
        Print.info('                       ;;;;;')
        Print.info('               .=\',    ;:;;:,')
        Print.info('              /_\', "=. \';:;:;')
        Print.info('              @=:__,  \,;:;:\'')
        Print.info('                _(\.=  ;:;;\'')
        Print.info('               `"_(  _/="`')
        Print.info('                `"\'')
        Print.info('')
        if args.extract:
            for filePath in args.extract:
                f = factory(filePath)
                f.open(filePath, 'rb')
                dir = Path(Path(filePath).name).suffix[0]
                f.unpack(dir)
                f.close()
        if args.create:
            Print.info('creating ' + args.create)
            nsp = Nsp.Nsp(None, None)
            nsp.path = args.create
            nsp.pack(args.file)
        if args.C:
            targetDict = CreateTargetDict(outfolder, args.parseCnmt, ".nsz")
            for i in args.file:
                for filePath in expandFiles(i):
                    try:
                        if filePath.endswith('.nsp'):
                            if not AllowedToWriteOutfile(
                                    filePath, ".nsz", targetDict,
                                    args.rm_old_version, args.overwrite,
                                    args.parseCnmt):
                                continue
                            compress(filePath, args)

                            if args.rm_source:
                                delete_source_file(filePath)
                    except KeyboardInterrupt:
                        raise
                    except BaseException as e:
                        Print.error('Error when compressing file: %s' %
                                    filePath)
                        err.append({
                            "filename": filePath,
                            "error": format_exc()
                        })
                        print_exc()

        if args.D:
            targetDict = CreateTargetDict(outfolder, args.parseCnmt, ".nsp")

            for i in args.file:
                for filePath in expandFiles(i):
                    try:
                        if filePath.endswith('.nsz'):
                            if not AllowedToWriteOutfile(
                                    filePath, ".nsp", targetDict,
                                    args.rm_old_version, args.overwrite,
                                    args.parseCnmt):
                                continue
                            decompress(filePath, args.output)
                            if args.rm_source:
                                delete_source_file(filePath)
                    except KeyboardInterrupt:
                        raise
                    except BaseException as e:
                        Print.error('Error when decompressing file: %s' %
                                    filePath)
                        err.append({
                            "filename": filePath,
                            "error": format_exc()
                        })
                        print_exc()

        if args.info:
            f = factory(args.info)
            f.open(args.info, 'r+b')
            f.printInfo(args.depth + 1)
        if args.verify and not args.C and not args.D:
            for i in args.file:
                for filePath in expandFiles(i):
                    try:
                        if filePath.endswith('.nsp') or filePath.endswith(
                                '.nsz'):
                            if filePath.endswith('.nsp'):
                                print("[VERIFY NSP] {0}".format(i))
                            if filePath.endswith('.nsz'):
                                print("[VERIFY NSZ] {0}".format(i))
                            verify(filePath, False)
                    except KeyboardInterrupt:
                        raise
                    except BaseException as e:
                        Print.error('Error when verifying file: %s' % filePath)
                        err.append({
                            "filename": filePath,
                            "error": format_exc()
                        })
                        print_exc()

        if len(argv) == 1:
            pass
    except KeyboardInterrupt:
        Print.info('Keyboard exception')
    except BaseException as e:
        Print.info('nut exception: ' + str(e))
        raise
    if err:
        Print.info('\033[93m\033[1mErrors:')

        for e in err:
            Print.info('\033[0mError when processing %s' % e["filename"])
            Print.info(e["error"])

    Print.info('Done!')
Beispiel #12
0
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