Пример #1
0
def gen_multi_file_header(prlist, filelist):
    oflist = []
    osizelist = []
    ototlist = []
    files = []
    totSize = 0
    for i in range(len(prlist)):
        for j in prlist[i][4]:
            el = j[0]
            if el.endswith('.nca'):
                oflist.append(j[0])
                #print(j[0])
                totSize = totSize + j[1]
                #print(j[1])
            ototlist.append(j[0])
    sec_hashlist = list()
    GClist = list()
    # print(filelist)
    for file in oflist:
        for filepath in filelist:
            if filepath.endswith('.nsp') or filepath.endswith('.nsz'):
                try:
                    f = squirrelNSP(filepath)
                    sha, size, gamecard = f.file_hash(file)
                    if sha != False:
                        sec_hashlist.append(sha)
                        osizelist.append(size)
                        GClist.append([file, gamecard])
                    f.flush()
                    f.close()
                except BaseException as e:
                    Print.error('Exception: ' + str(e))
            if filepath.endswith('.xci') or filepath.endswith('.xcz'):
                try:
                    f = squirrelXCI(filepath)
                    sha, size, gamecard = f.file_hash(file)
                    if sha != False:
                        sec_hashlist.append(sha)
                        osizelist.append(size)
                        GClist.append([file, gamecard])
                    f.flush()
                    f.close()
                except BaseException as e:
                    Print.error('Exception: ' + str(e))
    xci_header, game_info, sig_padding, xci_certificate, root_header, upd_header, norm_header, sec_header, rootSize, upd_multiplier, norm_multiplier, sec_multiplier = sq_tools.get_xciheader(
        oflist, osizelist, sec_hashlist)
    totSize = len(xci_header) + len(game_info) + len(sig_padding) + len(
        xci_certificate) + rootSize
    outheader = xci_header
    outheader += game_info
    outheader += sig_padding
    outheader += xci_certificate
    outheader += root_header
    outheader += upd_header
    outheader += norm_header
    outheader += sec_header
    properheadsize = len(outheader)
    return outheader, properheadsize, totSize, oflist
Пример #2
0
def file_verification(filename,hash=False):
	if not os.path.exists(cachefolder):
		os.makedirs(cachefolder)
	tempfolder=os.path.join(cachefolder, 'temp')	
	if not os.path.exists(tempfolder):
		os.makedirs(tempfolder)	
	verdict=False;isrestored=False;cnmt_is_patched=False
	if filename.endswith('.nsp') or filename.endswith('.nsx') or filename.endswith('.nsz') or filename.endswith('.xcz') or filename.endswith('.xci'):
		try:
			if filename.endswith('.nsp') or filename.endswith('.nsx') or filename.endswith('.nsz'):		
				f = squirrelNSP(filename, 'rb')
			elif filename.endswith('.xci') or filename.endswith('.xcz'):	
				f = factory(filename)		
				f.open(filename, 'rb')	
			check,feed=f.verify()
			if filename.endswith('.nsp') or filename.endswith('.nsx') or filename.endswith('.nsz'):					
				verdict,headerlist,feed=f.verify_sig(feed,tempfolder,cnmt='nocheck')
			else:
				verdict,headerlist,feed=f.verify_sig(feed,tempfolder)
			output_type='nsp';multi=False;cnmtcount=0
			if verdict == True:
				isrestored=True
				for i in range(len(headerlist)):
					entry=headerlist[i]
					if str(entry[0]).endswith('.cnmt.nca'):
						cnmtcount+=1
						if cnmt_is_patched==False:
							status=entry[2]
							if status=='patched':
								cnmt_is_patched=True
					if entry[1]!=False:
						if int(entry[-1])==1:
							output_type='xci'
						isrestored=False	
					else:
						pass
				if	isrestored == False:	
					if cnmt_is_patched !=True:
						print('\nFILE VERIFICATION CORRECT.\n -> FILE WAS MODIFIED BUT ORIGIN IS CONFIRMED AS LEGIT\n')
					else:
						print('\nFILE VERIFICATION CORRECT. \n -> FILE WAS MODIFIED AND CNMT PATCHED\n')
				else:
					print("\nFILE VERIFICATION CORRECT. FILE IS SAFE.\n")
			if verdict == False:		
				print("\nFILE VERIFICATION INCORRECT. \n -> UNCONFIRMED ORIGIN FILE HAS BEEN TAMPERED WITH\n")	
			if 	hash==True and verdict==True:
				if filename.endswith('.nsp') or filename.endswith('.nsx') or filename.endswith('.xci'):
					verdict,feed=f.verify_hash_nca(65536,headerlist,verdict,feed)
				elif filename.endswith('.nsz'):
					verdict,feed=f.nsz_hasher(65536,headerlist,verdict,feed)
				elif filename.endswith('.xcz'):	
					verdict,feed=f.xcz_hasher(65536,headerlist,verdict,feed)
			f.flush()
			f.close()					
		except BaseException as e:
			Print.error('Exception: ' + str(e))
	return verdict,isrestored,cnmt_is_patched	
Пример #3
0
def install_conv_st1(filepath, outfolder, keypatch='false'):
    tname = str(os.path.basename(filepath))[:-3] + 'nsp'
    tmpfile = os.path.join(outfolder, tname)
    if filepath.endswith('xci'):
        f = factory(filepath)
        f.open(filepath, 'rb')
    elif filepath.endswith('nsp'):
        f = squirrelNSP(filepath, 'rb')
    f.c_nsp_direct(65536, tmpfile, outfolder, keypatch=keypatch)
    f.flush()
    f.close()
Пример #4
0
def generate_and_transfer_st1(filepath,outfolder,keypatch='false'):
	tname=str(os.path.basename(filepath))[:-3]+'xci'
	tmpfile=os.path.join(outfolder,tname)
	if filepath.endswith('xci') or filepath.endswith('xcz'):
		f = factory(filepath)
		f.open(filepath, 'rb')
	elif filepath.endswith('nsp') or filepath.endswith('nsz'):	
		f = squirrelNSP(filepath, 'rb')	
	f.c_xci_direct(65536,tmpfile,outfolder,metapatch='true',keypatch=keypatch)
	f.flush()
	f.close()	
Пример #5
0
def get_DB_dict(filepath):
	installedsize=0
	if filepath.endswith('xci') or filepath.endswith('xcz'):
		f = factory(filepath)		
		f.open(filepath, 'rb')		
		dict=f.return_DBdict()			
		f.flush()
		f.close()
	elif filepath.endswith('nsp') or filepath.endswith('nsz') or filepath.endswith('nsx'):
		f = squirrelNSP(filepath)			
		dict=f.return_DBdict()		
		f.flush()
		f.close()		
	return dict
Пример #6
0
def calculate_name(filelist, romanize=True, ext='.xci'):
    from Fs import Nsp as squirrelNSP
    from Fs import Xci as squirrelXCI
    import re
    prlist = list()
    for filepath in filelist:
        if filepath.endswith('.nsp'):
            try:
                c = list()
                f = squirrelNSP(filepath)
                contentlist = f.get_content(False, False, True)
                f.flush()
                f.close()
                if len(prlist) == 0:
                    for i in contentlist:
                        prlist.append(i)
                else:
                    for j in range(len(contentlist)):
                        notinlist = False
                        for i in range(len(prlist)):
                            if contentlist[j][1] == prlist[i][1]:
                                if contentlist[j][6] > prlist[i][6]:
                                    del prlist[i]
                                    prlist.append(contentlist[j])
                                    notinlist = False
                                elif contentlist[j][6] == prlist[i][6]:
                                    notinlist = False
                            else:
                                notinlist = True
                        if notinlist == True:
                            prlist.append(contentlist[j])
            except BaseException as e:
                nutPrint.error('Exception: ' + str(e))
        if filepath.endswith('.xci'):
            try:
                c = list()
                f = squirrelXCI(filepath)
                contentlist = f.get_content(False, False, True)
                f.flush()
                f.close()
                if len(prlist) == 0:
                    for i in contentlist:
                        prlist.append(i)
                else:
                    for j in range(len(contentlist)):
                        notinlist = False
                        for i in range(len(prlist)):
                            if contentlist[j][1] == prlist[i][1]:
                                if contentlist[j][6] > prlist[i][6]:
                                    del prlist[i]
                                    prlist.append(contentlist[j])
                                    notinlist = False
                                elif contentlist[j][6] == prlist[i][6]:
                                    notinlist = False
                            else:
                                notinlist = True
                        if notinlist == True:
                            prlist.append(contentlist[j])
            except BaseException as e:
                nutPrint.error('Exception: ' + str(e))
    basecount = 0
    basename = ''
    basever = ''
    baseid = ''
    basefile = ''
    updcount = 0
    updname = ''
    updver = ''
    updid = ''
    updfile = ''
    dlccount = 0
    dlcname = ''
    dlcver = ''
    dlcid = ''
    dlcfile = ''
    ccount = ''
    bctag = ''
    updtag = ''
    dctag = ''
    for i in range(len(prlist)):
        if prlist[i][5] == 'BASE':
            basecount += 1
            if baseid == "":
                basefile = str(prlist[i][0])
                baseid = str(prlist[i][1])
                basever = '[v' + str(prlist[i][6]) + ']'
        if prlist[i][5] == 'UPDATE':
            updcount += 1
            endver = str(prlist[i][6])
            if updid == "":
                updfile = str(prlist[i][0])
                updid = str(prlist[i][1])
                updver = '[v' + str(prlist[i][6]) + ']'
        if prlist[i][5] == 'DLC':
            dlccount += 1
            if dlcid == "":
                dlcfile = str(prlist[i][0])
                dlcid = str(prlist[i][1])
                dlcver = '[v' + str(prlist[i][6]) + ']'
        if basecount != 0:
            bctag = str(basecount) + 'G'
        else:
            bctag = ''
        if updcount != 0:
            if bctag != '':
                updtag = '+' + str(updcount) + 'U'
            else:
                updtag = str(updcount) + 'U'
        else:
            updtag = ''
        if dlccount != 0:
            if bctag != '' or updtag != '':
                dctag = '+' + str(dlccount) + 'D'
            else:
                dctag = str(dlccount) + 'D'
        else:
            dctag = ''
        ccount = '(' + bctag + updtag + dctag + ')'
    if baseid != "":
        if basefile.endswith('.xci'):
            f = squirrelXCI(basefile)
        elif basefile.endswith('.nsp'):
            f = squirrelNSP(basefile)
        ctitl = f.get_title(baseid)
        f.flush()
        f.close()
        if ctitl == 'DLC' or ctitl == '-':
            ctitl = ''
    elif updid != "":
        if updfile.endswith('.xci'):
            f = squirrelXCI(updfile)
        elif updfile.endswith('.nsp'):
            f = squirrelNSP(updfile)
        ctitl = f.get_title(updid)
        f.flush()
        f.close()
        if ctitl == 'DLC' or ctitl == '-':
            ctitl = ''
    elif dlcid != "":
        ctitl = get_title
        if dlcfile.endswith('.xci'):
            f = squirrelXCI(dlcfile)
        elif dlcfile.endswith('.nsp'):
            f = squirrelNSP(dlcfile)
        ctitl = f.get_title(dlcid)
        f.flush()
        f.close()
    else:
        ctitl = 'UNKNOWN'
    baseid = '[' + baseid.upper() + ']'
    updid = '[' + updid.upper() + ']'
    dlcid = '[' + dlcid.upper() + ']'
    if ccount == '(1G)' or ccount == '(1U)' or ccount == '(1D)':
        ccount = ''
    if baseid != "[]":
        if updver != "":
            endname = ctitl + ' ' + baseid + ' ' + updver + ' ' + ccount
        else:
            endname = ctitl + ' ' + baseid + ' ' + basever + ' ' + ccount
    elif updid != "[]":
        endname = ctitl + ' ' + updid + ' ' + updver + ' ' + ccount
    else:
        endname = ctitl + ' ' + dlcid + ' ' + dlcver + ' ' + ccount
    if romanize == True:
        import pykakasi
        kakasi = pykakasi.kakasi()
        kakasi.setMode("H", "a")
        kakasi.setMode("K", "a")
        kakasi.setMode("J", "a")
        kakasi.setMode("s", True)
        kakasi.setMode("E", "a")
        kakasi.setMode("a", None)
        kakasi.setMode("C", False)
        converter = kakasi.getConverter()
        endname = converter.do(endname)
        endname = endname[0].upper() + endname[1:]
    endname = (re.sub(r'[\/\\\:\*\?]+', '', endname))
    endname = re.sub(r'[™©®`~^´ªº¢#£€¥$ƒ±¬½¼♡«»±•²‰œæƳ☆<<>>|]', '', endname)
    endname = re.sub(r'[Ⅰ]', 'I', endname)
    endname = re.sub(r'[Ⅱ]', 'II', endname)
    endname = re.sub(r'[Ⅲ]', 'III', endname)
    endname = re.sub(r'[Ⅳ]', 'IV', endname)
    endname = re.sub(r'[Ⅴ]', 'V', endname)
    endname = re.sub(r'[Ⅵ]', 'VI', endname)
    endname = re.sub(r'[Ⅶ]', 'VII', endname)
    endname = re.sub(r'[Ⅷ]', 'VIII', endname)
    endname = re.sub(r'[Ⅸ]', 'IX', endname)
    endname = re.sub(r'[Ⅹ]', 'X', endname)
    endname = re.sub(r'[Ⅺ]', 'XI', endname)
    endname = re.sub(r'[Ⅻ]', 'XII', endname)
    endname = re.sub(r'[Ⅼ]', 'L', endname)
    endname = re.sub(r'[Ⅽ]', 'C', endname)
    endname = re.sub(r'[Ⅾ]', 'D', endname)
    endname = re.sub(r'[Ⅿ]', 'M', endname)
    endname = re.sub(r'[—]', '-', endname)
    endname = re.sub(r'[√]', 'Root', endname)
    endname = re.sub(r'[àâá@äå]', 'a', endname)
    endname = re.sub(r'[ÀÂÁÄÅ]', 'A', endname)
    endname = re.sub(r'[èêéë]', 'e', endname)
    endname = re.sub(r'[ÈÊÉË]', 'E', endname)
    endname = re.sub(r'[ìîíï]', 'i', endname)
    endname = re.sub(r'[ÌÎÍÏ]', 'I', endname)
    endname = re.sub(r'[òôóöø]', 'o', endname)
    endname = re.sub(r'[ÒÔÓÖØ]', 'O', endname)
    endname = re.sub(r'[ùûúü]', 'u', endname)
    endname = re.sub(r'[ÙÛÚÜ]', 'U', endname)
    endname = re.sub(r'[’]', "'", endname)
    endname = re.sub(r'[“”]', '"', endname)
    endname = re.sub(' {3,}', ' ', endname)
    re.sub(' {2,}', ' ', endname)
    try:
        endname = endname.replace("( ", "(")
        endname = endname.replace(" )", ")")
        endname = endname.replace("[ ", "[")
        endname = endname.replace(" ]", "]")
        endname = endname.replace("[ (", "[(")
        endname = endname.replace(") ]", ")]")
        endname = endname.replace("[]", "")
        endname = endname.replace("()", "")
        endname = endname.replace('" ', '"')
        endname = endname.replace(' "', '"')
        endname = endname.replace(" !", "!")
        endname = endname.replace(" ?", "?")
        endname = endname.replace("  ", " ")
        endname = endname.replace("  ", " ")
        endname = endname.replace('"', '')
        endname = endname.replace(')', ') ')
        endname = endname.replace(']', '] ')
        endname = endname.replace("[ (", "[(")
        endname = endname.replace(") ]", ")]")
        endname = endname.replace("  ", " ")
    except:
        pass
    if endname[-1] == ' ':
        endname = endname[:-1]
    endname = endname + ext
    return endname, prlist
Пример #7
0
def compress(filePath,
             ofolder=None,
             level=17,
             threads=0,
             delta=False,
             ofile=None,
             buffer=65536,
             pos=False,
             nthreads=False):
    isthreaded = False
    if pos != False:
        isthreaded = True
    elif str(pos) == '0':
        isthreaded = True
    else:
        pos = 0
    pos = int(pos)
    files_list = sq_tools.ret_nsp_offsets(filePath)
    files = list()
    filesizes = list()
    if isthreaded == True and nthreads != False:
        tqlist = list()
        for i in range(nthreads):
            tq = tqdm(total=0,
                      unit='B',
                      unit_scale=True,
                      leave=False,
                      position=i)
            tqlist.append(tq)
    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]
        cnmtfile = entry[0]
        if cnmtfile.endswith('.cnmt.nca'):
            f = squirrelNSP(filePath, 'rb')
            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':
                    test1 = str(row['NcaId']) + '.nca'
                    test2 = str(row['NcaId']) + '.ncz'
                    if test1 in fplist or test2 in fplist:
                        # print(str(row['NcaId'])+'.nca')
                        files.append(str(row['NcaId']) + '.nca')
                        filesizes.append(int(row['Size']))
                else:
                    # print(str(row['NcaId'])+'.cnmt.nca')
                    files.append(str(row['NcaId']) + '.cnmt.nca')
                    filesizes.append(int(row['Size']))
    for k in range(len(files_list)):
        entry = files_list[k]
        fp = entry[0]
        sz = int(entry[3])
        if fp.endswith('xml'):
            files.append(fp)
            filesizes.append(sz)
    for k in range(len(files_list)):
        entry = files_list[k]
        fp = entry[0]
        sz = int(entry[3])
        if fp.endswith('.tik'):
            files.append(fp)
            filesizes.append(sz)
    for k in range(len(files_list)):
        entry = files_list[k]
        fp = entry[0]
        sz = int(entry[3])
        if fp.endswith('.cert'):
            files.append(fp)
            filesizes.append(sz)
    nspheader = sq_tools.gen_nsp_header(files, filesizes)
    properheadsize = len(nspheader)

    compressionLevel = int(level)
    container = nutFs.factory(filePath)

    container.open(filePath, 'rb')

    CHUNK_SZ = buffer

    if ofolder is None and ofile is None:
        nszPath = filePath[0:-1] + 'z'
    elif ofolder is not None:
        nszPath = os.path.join(ofolder, os.path.basename(filePath[0:-1] + 'z'))
    elif ofile is not None:
        nszPath = ofile

    tsize = properheadsize
    for sz in filesizes:
        tsize += sz
    if isthreaded == True:
        from colorama import Fore
        colors = Fore.__dict__
        k = 0
        l = pos
        for col in colors:
            if l > len(colors):
                l = l - len(colors)
            color = colors[col]
            if k == (l + 1):
                break
            else:
                k += 1
        t = tqdm(total=tsize,
                 unit='B',
                 unit_scale=True,
                 leave=False,
                 position=pos,
                 bar_format="{l_bar}%s{bar}%s{r_bar}" % (color, Fore.RESET))
    else:
        t = tqdm(total=tsize,
                 unit='B',
                 unit_scale=True,
                 leave=False,
                 position=0)
    # nszPath = os.path.abspath(nszPath)

    nszPath = Path(filePath)
    nszPath = os.path.join(nszPath.parents[0],
                           os.path.basename(filePath[0:-1] + 'z'))

    if isthreaded == False:
        t.write('\n Compressing with level %d and %d threads' %
                (compressionLevel, threads))
        t.write('%s -> %s \n' % (filePath, nszPath))
    newNsp = nutFs.Pfs0.Pfs0Stream(nszPath, headsize=properheadsize)

    for file in files:
        for nspf in container:
            if nspf._path == file:
                if isinstance(
                        nspf, nutFs.Nca.Nca
                ) and nspf.header.contentType == nutFs.Type.Content.DATA and delta == False:
                    if isthreaded == False:
                        t.write('-> Skipping delta fragment')
                    continue

                if isinstance(nspf, nutFs.Nca.Nca) and (
                        nspf.header.contentType == nutFs.Type.Content.PROGRAM
                        or nspf.header.contentType
                        == nutFs.Type.Content.PUBLIC_DATA):
                    if isNcaPacked(nspf):
                        cctx = zstandard.ZstdCompressor(level=compressionLevel,
                                                        threads=threads)

                        newFileName = nspf._path[0:-1] + 'z'

                        f = newNsp.add(newFileName, nspf.size, t, isthreaded)

                        start = f.tell()

                        nspf.seek(0)
                        f.write(nspf.read(ncaHeaderSize))
                        written = ncaHeaderSize

                        compressor = cctx.stream_writer(f)

                        sections = get_sections(nspf)

                        header = b'NCZSECTN'
                        header += len(sections).to_bytes(8, 'little')

                        i = 0
                        for fs in sections:
                            i += 1
                            header += fs.offset.to_bytes(8, 'little')
                            header += fs.size.to_bytes(8, 'little')
                            header += fs.cryptoType.to_bytes(8, 'little')
                            header += b'\x00' * 8
                            header += fs.cryptoKey
                            header += fs.cryptoCounter

                        f.write(header)
                        written += len(header)
                        timestamp = time.time()
                        decompressedBytes = ncaHeaderSize
                        totsize = 0
                        for fs in sections:
                            totsize += fs.size

                        for section in sections:
                            #print('offset: %x\t\tsize: %x\t\ttype: %d\t\tiv%s' % (section.offset, section.size, section.cryptoType, str(hx(section.cryptoCounter))))
                            o = nspf.partition(offset=section.offset,
                                               size=section.size,
                                               n=None,
                                               cryptoType=section.cryptoType,
                                               cryptoKey=section.cryptoKey,
                                               cryptoCounter=bytearray(
                                                   section.cryptoCounter),
                                               autoOpen=True)

                            while not o.eof():
                                buffer = o.read(CHUNK_SZ)
                                t.update(len(buffer))
                                if len(buffer) == 0:
                                    raise IOError('read failed')

                                written += compressor.write(buffer)

                                decompressedBytes += len(buffer)

                        compressor.flush(zstandard.FLUSH_FRAME)

                        elapsed = time.time() - timestamp
                        minutes = elapsed / 60
                        seconds = elapsed % 60

                        speed = 0 if elapsed == 0 else (nspf.size / elapsed)

                        written = f.tell() - start
                        if isthreaded == False:
                            t.write(
                                '\n  * Compressed at %d%% from %s to %s  - %s'
                                % (int(written * 100 / nspf.size),
                                   str(sq_tools.getSize(decompressedBytes)),
                                   str(sq_tools.getSize(written)), nspf._path))
                            t.write(
                                '  * Compressed in %02d:%02d at speed: %.1f MB/s\n'
                                % (minutes, seconds, speed / 1000000.0))
                        newNsp.resize(newFileName, written)
                        continue
                    else:
                        print('not packed!')

                f = newNsp.add(nspf._path, nspf.size, t, isthreaded)
                nspf.seek(0)
                while not nspf.eof():
                    buffer = nspf.read(CHUNK_SZ)
                    t.update(len(buffer))
                    f.write(buffer)
    t.close()
    newNsp.close()
    if isthreaded == True and nthreads != False:
        for i in range(nthreads):
            tqlist[i].close()
Пример #8
0
def get_header_size(filepath):
	properheadsize=0;sz=0
	if filepath.endswith('xci') or filepath.endswith('xcz'):
		files_list=sq_tools.ret_xci_offsets(filepath)
		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]
			cnmtfile=entry[0]
			if cnmtfile.endswith('.cnmt.nca'):
				f=squirrelXCI(filepath)
				titleid,titleversion,base_ID,keygeneration,rightsId,RSV,RGV,ctype,metasdkversion,exesdkversion,hasHtmlManual,Installedsize,DeltaSize,ncadata=f.get_data_from_cnmt(cnmtfile)
				for j in range(len(ncadata)):
					row=ncadata[j]
					# print(row)
					if row['NCAtype']!='Meta':
						test1=str(row['NcaId'])+'.nca';test2=str(row['NcaId'])+'.ncz'
						if test1 in fplist or test2 in fplist:
							# print(str(row['NcaId'])+'.nca')
							files.append(str(row['NcaId'])+'.nca')
							filesizes.append(int(row['Size']))	
							sz+=int(row['Size'])		
					elif row['NCAtype']=='Meta':
						# print(str(row['NcaId'])+'.cnmt.nca')
						files.append(str(row['NcaId'])+'.cnmt.nca')
						filesizes.append(int(row['Size']))	
						sz+=int(row['Size'])
		sec_hashlist=list()
		try:
			for file in files:
				sha,size,gamecard=f.file_hash(file)
				# print(sha)
				if sha != False:
					sec_hashlist.append(sha)	
		except BaseException as e:
			Print.error('Exception: ' + str(e))									
		f.flush()
		f.close()	
		xci_header,game_info,sig_padding,xci_certificate,root_header,upd_header,norm_header,sec_header,rootSize,upd_multiplier,norm_multiplier,sec_multiplier=sq_tools.get_xciheader(files,filesizes,sec_hashlist)			
		outheader=xci_header
		outheader+=game_info
		outheader+=sig_padding
		outheader+=xci_certificate
		outheader+=root_header
		outheader+=upd_header
		outheader+=norm_header
		outheader+=sec_header		
	elif filepath.endswith('nsp') or filepath.endswith('nsz'):
		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])
		for i in range(len(files_list)):
			entry=files_list[i]
			cnmtfile=entry[0]
			if cnmtfile.endswith('.cnmt.nca'):
				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':
						test1=str(row['NcaId'])+'.nca';test2=str(row['NcaId'])+'.ncz'
						if test1 in fplist or test2 in fplist:
							# print(str(row['NcaId'])+'.nca')
							files.append(str(row['NcaId'])+'.nca')
							filesizes.append(int(row['Size']))	
							sz+=int(row['Size'])								
					elif row['NCAtype']=='Meta':
						# print(str(row['NcaId'])+'.cnmt.nca')
						files.append(str(row['NcaId'])+'.cnmt.nca')
						filesizes.append(int(row['Size']))
						sz+=int(row['Size'])												
		f.flush()
		f.close()	
		outheader = sq_tools.gen_nsp_header(files,filesizes)			
	properheadsize=len(outheader)
	return properheadsize,keygeneration,sz
Пример #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					
Пример #10
0
def groupncabyid_and_idoffset(filepath,
                              ofolder,
                              export,
                              buffer=65536,
                              fat='exfat',
                              fx='files',
                              nodecompress=False):
    if filepath.endswith('.nsp') or filepath.endswith(
            '.nsx') or filepath.endswith('.nsz'):
        container = squirrelNSP(filepath, 'rb')
    elif filepath.endswith('.xci') or filepath.endswith('.xcz'):
        container = factory(filepath)
        container.open(filepath, 'rb')
    contentlist = list()
    ncalist = list()
    completefilelist = list()
    for nspF in container.hfs0:
        if str(nspF._path) == "secure":
            for file in nspF:
                completefilelist.append(str(file._path))
    for nspF in container.hfs0:
        if str(nspF._path) == "secure":
            for nca in nspF:
                if type(nca) == Nca:
                    if str(nca.header.contentType) == 'Content.META':
                        crypto1 = nca.header.getCryptoType()
                        crypto2 = nca.header.getCryptoType2()
                        if crypto1 == 2:
                            if crypto1 > crypto2:
                                keygen = nca.header.getCryptoType()
                            else:
                                keygen = nca.header.getCryptoType2()
                        else:
                            keygen = nca.header.getCryptoType2()
                        ncalist = list()
                        for f in nca:
                            for cnmt in f:
                                nca.rewind()
                                f.rewind()
                                cnmt.rewind()
                                titleid = cnmt.readInt64()
                                titleversion = cnmt.read(0x4)
                                cnmt.rewind()
                                cnmt.seek(0xE)
                                offset = cnmt.readInt16()
                                content_entries = cnmt.readInt16()
                                meta_entries = cnmt.readInt16()
                                content_type = str(cnmt._path)
                                content_type = content_type[:-22]
                                titleid2 = str(
                                    hx(titleid.to_bytes(8, byteorder='big')))
                                titleid2 = titleid2[2:-1]
                                cnmt.seek(0x20)
                                if content_type == 'Application':
                                    original_ID = titleid2
                                    cnmt.readInt64()
                                    ttag = ''
                                    CTYPE = 'BASE'
                                elif content_type == 'Patch':
                                    original_ID = cnmt.readInt64()
                                    original_ID = str(
                                        hx(
                                            original_ID.to_bytes(
                                                8, byteorder='big')))
                                    original_ID = original_ID[2:-1]
                                    ttag = ' [UPD]'
                                    CTYPE = 'UPDATE'
                                elif content_type == 'AddOnContent':
                                    original_ID = cnmt.readInt64()
                                    original_ID = str(
                                        hx(
                                            original_ID.to_bytes(
                                                8, byteorder='big')))
                                    original_ID = original_ID[2:-1]
                                    ttag = ' [DLC]'
                                    CTYPE = 'DLC'
                                else:
                                    original_ID = cnmt.readInt64()
                                    original_ID = str(
                                        hx(
                                            original_ID.to_bytes(
                                                8, byteorder='big')))
                                    original_ID = original_ID[2:-1]
                                cnmt.seek(0x20 + offset)
                                for i in range(content_entries):
                                    vhash = cnmt.read(0x20)
                                    NcaId = cnmt.read(0x10)
                                    size = cnmt.read(0x6)
                                    ncatype = cnmt.read(0x1)
                                    idoffset = cnmt.read(0x1)
                                    idoffset = int.from_bytes(
                                        idoffset,
                                        byteorder='little',
                                        signed=True)
                                    #**************************************************************
                                    version = str(
                                        int.from_bytes(titleversion,
                                                       byteorder='little'))
                                    version = '[v' + version + ']'
                                    titleid3 = '[' + titleid2 + ']'
                                    nca_name = str(hx(NcaId))
                                    nca_name = nca_name[2:-1] + '.nca'
                                    ncz_name = nca_name[:-1] + 'z'
                                    if nca_name in completefilelist or ncz_name in completefilelist:
                                        ncalist.append([nca_name, idoffset])
                                nca_meta = str(nca._path)
                                if nca_meta in completefilelist:
                                    ncalist.append([nca_meta, 0])
                                target = str(nca._path)
                                tit_name, editor, ediver, SupLg, regionstr, isdemo = container.inf_get_title(
                                    target, offset, content_entries,
                                    original_ID)
                                tit_name = (re.sub(
                                    r'[\/\\\:\*\?\!\"\<\>\|\.\s™©®()\~]+', ' ',
                                    tit_name))
                                tit_name = tit_name.strip()
                                if tit_name == 'DLC' and (
                                        str(titleid2).endswith('000')
                                        or str(titleid2).endswith('800')):
                                    tit_name = '-'
                                    editor = '-'
                                tid = '[' + titleid2 + ']'
                                filename = tit_name + ' ' + tid + ' ' + version
                                titlerights = titleid2 + str(
                                    '0' * 15) + str(crypto2)
                                contentlist.append([
                                    filename, titleid2, titlerights, keygen,
                                    ncalist, CTYPE, tit_name, tid, version
                                ])
    '''		
	for i in contentlist:
		print("")
		print('Filename: '+i[0])
		print('TitleID: '+i[1])
		print('TitleRights: '+i[2])
		print('Keygen: '+str(i[3]))			
		for j in i[4]:
			print (j)	
	'''
    newcontentlist = []
    counter = 0
    for i in contentlist:
        idoffsets = []
        files = i[4]
        metafile = None
        for j in files:
            if j[0].endswith('.cnmt'):
                metafile = j[0]
                break
        for j in files:
            if j[-1] not in idoffsets:
                idoffsets.append(j[-1])
        for j in idoffsets:
            entry = copy.deepcopy(contentlist[counter])
            newfiles = []
            for k in files:
                if k[-1] == j:
                    newfiles.append(k[0])
            if not metafile in newfiles:
                newfiles.append(metafile)
            filename = entry[-3] + ' ' + (
                entry[-2])[:-2] + str(j) + ' ' + version
            entry[0] = filename
            entry[4] = newfiles
            newcontentlist.append(entry)
        counter += 1

    for nspF in container.hfs0:
        if str(nspF._path) == "secure":
            for file in nspF:
                if type(file) == Ticket or file._path.endswith('.cert'):
                    test = file._path
                    test = test[0:32]
                    for i in newcontentlist:
                        if i[2] == test:
                            i[4].append(file._path)
                elif file._path.endswith('.xml'):
                    test = file._path
                    test = test[0:-4] + '.nca'
                    for i in newcontentlist:
                        if test in i[4]:
                            i[4].append(file._path)

    for i in newcontentlist:
        if export == 'nsp':
            container.cd_spl_nsp(buffer, i[0], ofolder, i[4], fat, fx,
                                 nodecompress)
        if export == 'xci':
            if i[5] != 'BASE':
                container.cd_spl_nsp(buffer, i[0], ofolder, i[4], fat, fx,
                                     nodecompress)
            else:
                container.cd_spl_xci(buffer, i[0], ofolder, i[4], fat, fx,
                                     nodecompress)
        if export == 'both':
            if i[5] != 'BASE':
                container.cd_spl_nsp(buffer, i[0], ofolder, i[4], fat, fx,
                                     nodecompress)
            else:
                container.cd_spl_nsp(buffer, i[0], ofolder, i[4], fat, fx,
                                     nodecompress)
                container.cd_spl_xci(buffer, i[0], ofolder, i[4], fat, fx,
                                     nodecompress)


# def exchange_id_offset(filepath,original_idoffset,new_idoffset):

# def split_multiprogram_by_id(filepath,ofolder,output_format):

# write_cnmt_titleid
# write_cnmt_updateid
Пример #11
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