From 80972723d62799bc5cb737d04e255eb1f8df6709 Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Thu, 4 Jul 2019 00:29:31 +0200 Subject: [PATCH 01/13] Correct gen placeholder --- py/ztools/Fs/Nsp.py | 44 ++++++++++++++++++++++++++++++------------- py/ztools/squirrel.py | 11 +++++++---- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/py/ztools/Fs/Nsp.py b/py/ztools/Fs/Nsp.py index c81ab53b..44e56a2e 100644 --- a/py/ztools/Fs/Nsp.py +++ b/py/ztools/Fs/Nsp.py @@ -5203,7 +5203,7 @@ def get_content(self,ofolder,vkeypatch,delta): return contentlist - def get_content_placeholder(self): + def get_content_placeholder(self,ofolder): contentlist=list() ncalist=list() completefilelist=list() @@ -5212,7 +5212,9 @@ def get_content_placeholder(self): if str(file.header.contentType) != 'Content.META' and str(file.header.contentType) != 'Content.CONTROL': continue else: - completefilelist.append(str(file._path)) + completefilelist.append(str(file._path)) + elif str(file._path).endswith('.xml'): + pass else: completefilelist.append(str(file._path)) #print (completefilelist) @@ -5287,6 +5289,30 @@ def get_content_placeholder(self): nca_meta=str(nca._path) if nca_meta in completefilelist: ncalist.append([nca_meta,nca.size]) + if ofolder != False: + target = Fs.Nca(nca, 'r+b') + target.rewind() + outf= os.path.join(ofolder, str(nca._path)) + fp = open(outf, 'w+b') + for data in iter(lambda: target.read(int(32768)), ""): + fp.write(data) + fp.flush() + if not data: + fp.close() + break + target = Fs.Nca(outf, 'r+b') + block = target.read() + nsha=sha256(block).hexdigest() + target.rewind() + xml=target.xml_gen(ofolder,nsha) + xmlname=nca_meta[:-3]+'xml' + xmlsize=os.path.getsize(xml) + ncalist.append([xmlname,xmlsize]) + target.close() + try: + os.remove(outf) + except: + pass titlerights=titleid2+str('0'*15)+str(crypto2) contentlist.append([str(self._path),titleid2,titlerights,keygen,ncalist,CTYPE,version]) @@ -5297,15 +5323,6 @@ def get_content_placeholder(self): for i in contentlist: if i[2]==test: i[4].append([file._path,file.size]) - elif file._path.endswith('.xml'): - test=file._path - #print(test) - test=test[:-4]+'.nca' - #print(test) - for i in contentlist: - for j in i[4]: - if j[0]==test: - i[4].append([file._path,file.size]) ''' for i in contentlist: print('Filename: '+i[0]) @@ -5318,9 +5335,10 @@ def get_content_placeholder(self): print (j) print("") ''' - return contentlist + + return contentlist - def append_content(self,outf,target,buffer,t,fat,fx,c,index): + def append_content(self,outf,target,buffer,t,fat='exfat',fx='files',c=0,index=0): block=4294934528 indent = 1 tabs = '\t' * indent diff --git a/py/ztools/squirrel.py b/py/ztools/squirrel.py index c32de47a..a40d1f36 100644 --- a/py/ztools/squirrel.py +++ b/py/ztools/squirrel.py @@ -1901,6 +1901,8 @@ export='xci' elif input == "nsp" or input == "NSP": export='nsp' + elif input == "nsx" or input == "NSX": + export='nsp' elif input == "both" or input == "BOTH": export='both' else: @@ -1945,11 +1947,11 @@ print(len(filelist)) counter=len(filelist) for filepath in filelist: - if filepath.endswith('.nsp'): + if filepath.endswith('.nsp') or filepath.endswith('.nsx'): try: prlist=list() f = Fs.Nsp(filepath) - contentlist=f.get_content_placeholder() + contentlist=f.get_content_placeholder(ofolder) #print(contentlist) f.flush() f.close() @@ -2016,8 +2018,9 @@ if filepath.endswith('.nsp'): try: f = Fs.Nsp(filepath) - for file in oflist: - f.append_content(endfile,file,buffer,t) + for file in oflist: + if not file.endswith('xml'): + f.append_content(endfile,file,buffer,t) f.flush() f.close() t.close() From 4900c55e661ccf82314bf9a85ad72c85afc01893 Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Thu, 4 Jul 2019 23:35:58 +0200 Subject: [PATCH 02/13] Add check against S.C. conversions made from nsx files. --- py/ztools/Fs/Nca.py | 7 ++++++- py/ztools/Fs/Nsp.py | 10 ++++++++-- py/ztools/Fs/Xci.py | 12 +++++++++--- py/ztools/squirrel.py | 2 +- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/py/ztools/Fs/Nca.py b/py/ztools/Fs/Nca.py index 275c0979..e0f308d3 100644 --- a/py/ztools/Fs/Nca.py +++ b/py/ztools/Fs/Nca.py @@ -1700,10 +1700,15 @@ def verify(self,feed,targetkg=False,endcheck=False,progress=False,bar=False): if kgchg == False: message=(tabs+'* '+"Original titlerights id is : "+(str(hx(tr)).upper())[2:-1]);print(message);feed+=message+'\n' message=(tabs+'* '+"Original titlekey is : "+(str(hx(titlekey)).upper())[2:-1]);print(message);feed+=message+'\n' + tcheck=(str(hx(titlekey)).upper())[2:-1] + if tcheck == '00000000000000000000000000000000': + message=(tabs+'* '+"WARNING: sum(titlekey)=0 -> S.C. conversion may be incorrect and come from nsx file");print(message);feed+=message+'\n' elif kgchg == True: message=(tabs+'* '+"KEYGENERATION WAS CHANGED FROM "+str(orkg)+" TO "+str(currkg));print(message);feed+=message+'\n' message=(tabs+'* '+"Original titlerights id is -> "+(str(hx(tr)).upper())[2:-1]);print(message);feed+=message+'\n' - message=(tabs+'* '+"Original titlekey is -> "+(str(hx(titlekey)).upper())[2:-1]);print(message);feed+=message+'\n' + message=(tabs+'* '+"Original titlekey is -> "+(str(hx(titlekey)).upper())[2:-1]);print(message);feed+=message+'\n' + if tcheck == '00000000000000000000000000000000': + message=(tabs+'* '+"WARNING: sum(titlekey)=0 -> S.C. conversion may be incorrect and come from nsx file");print(message);feed+=message+'\n' return True,orig_header,self._path,feed,orkg else: message=(indent+self._path+arrow+'was MODIFIED');print(message);feed+=message+'\n' diff --git a/py/ztools/Fs/Nsp.py b/py/ztools/Fs/Nsp.py index 44e56a2e..6b641b62 100644 --- a/py/ztools/Fs/Nsp.py +++ b/py/ztools/Fs/Nsp.py @@ -5217,7 +5217,7 @@ def get_content_placeholder(self,ofolder): pass else: completefilelist.append(str(file._path)) - #print (completefilelist) + print (completefilelist) for nca in self: if type(nca) == Nca: if str(nca.header.contentType) == 'Content.META': @@ -6520,7 +6520,11 @@ def verify(self): if correct == False and f.header.getRightsId() == 0: correct = f.pr_noenc_check() if correct == False and f.header.getRightsId() != 0: - correct = self.verify_nca_key(file) + correct = self.verify_nca_key(file) + if correct == True and f.header.getRightsId() == 0: + correct = f.pr_noenc_check() + if correct == False: + baddec=True elif file.endswith('.tik'): tikfile=str(file) checktik == False @@ -6545,6 +6549,8 @@ def verify(self): message=(tabs+file+' -> is CORRUPT <<<-');print(message);feed+=message+'\n' elif file.endswith('nca'): message=(tabs+file+tabs+' -> is CORRUPT <<<-');print(message);feed+=message+'\n' + if baddec == True: + print(tabs+' * NOTE: S.C. CONVERSION WAS PERFORMED WITH BAD KEY') elif file.endswith('tik'): message=(tabs+file+tabs+' -> titlekey is INCORRECT <<<-');print(message);feed+=message+'\n' for nca in self: diff --git a/py/ztools/Fs/Xci.py b/py/ztools/Fs/Xci.py index f6d987c6..9064a33d 100644 --- a/py/ztools/Fs/Xci.py +++ b/py/ztools/Fs/Xci.py @@ -5969,7 +5969,7 @@ def verify(self): validfiles.append(str(file._path)) for file in listed_files: - correct=False + correct=False;baddec=False if file in validfiles: if file.endswith('cnmt.nca'): for nspF in self.hfs0: @@ -6008,7 +6008,11 @@ def verify(self): if correct == False and f.header.getRightsId() == 0: correct = f.pr_noenc_check() if correct == False and f.header.getRightsId() != 0: - correct = self.verify_nca_key(file) + correct = self.verify_nca_key(file) + if correct == True and f.header.getRightsId() == 0: + correct = f.pr_noenc_check() + if correct == False: + baddec=True elif file.endswith('.tik'): tikfile=str(file) checktik == False @@ -6035,7 +6039,9 @@ def verify(self): if file.endswith('cnmt.nca'): message=(tabs+file+' -> is CORRUPT <<<-');print(message);feed+=message+'\n' elif file.endswith('nca'): - message=(tabs+file+tabs+' -> is CORRUPT <<<-');print(message);feed+=message+'\n' + message=(tabs+file+tabs+' -> is CORRUPT <<<-');print(message);feed+=message+'\n' + if baddec == True: + print(tabs+'* NOTE: S.C. CONVERSION WAS PERFORMED WITH BAD KEY') elif file.endswith('tik'): message=(tabs+file+tabs+' -> titlekey is INCORRECT <<<-');print(message);feed+=message+'\n' for nspF in self.hfs0: diff --git a/py/ztools/squirrel.py b/py/ztools/squirrel.py index a40d1f36..c07416fe 100644 --- a/py/ztools/squirrel.py +++ b/py/ztools/squirrel.py @@ -2015,7 +2015,7 @@ outf.write(nspheader) t.update(len(nspheader)) outf.close() - if filepath.endswith('.nsp'): + if filepath.endswith('.nsp') or filepath.endswith('.nsx'): try: f = Fs.Nsp(filepath) for file in oflist: From 48193fc603a1d4dec3baa595e13976c083ad6f23 Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Fri, 5 Jul 2019 01:45:35 +0200 Subject: [PATCH 03/13] Fixes RSV bar for Suxxor's unlockers verification --- py/ztools/Fs/Nca.py | 64 +++++++++++++++++++++++++++++++-------------- py/ztools/Fs/Nsp.py | 16 +++++++++++- py/ztools/Fs/Xci.py | 15 ++++++++++- 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/py/ztools/Fs/Nca.py b/py/ztools/Fs/Nca.py index e0f308d3..1a1c0bf6 100644 --- a/py/ztools/Fs/Nca.py +++ b/py/ztools/Fs/Nca.py @@ -1754,26 +1754,50 @@ def verify(self,feed,targetkg=False,endcheck=False,progress=False,bar=False): message=(tabs+'* '+"ISGAMECARD WAS CHANGED FROM 1 TO 0");print(message);feed+=message+'\n' return True,orig_header,self._path,feed,chkkg else: - if targetkg == False: - message=(indent+self._path+arrow+'needs RSV check');print(message);feed+=message+'\n' - message=(tabs+'* '+"CHECKING INTERNAL HASHES");print(message);feed+=message+'\n' - feed,correct=self.check_cnmt_hashes(feed) - if correct == True: - message=(tabs+'* '+"INTERNAL HASHES MATCH");print(message);feed+=message+'\n' - if correct == False: - message=(tabs+'* '+"INTERNAL HASH MISSMATCH");print(message);feed+=message+'\n' - message=(tabs+'* '+"BAD CNMT FILE!!!");print(message);feed+=message+'\n' - return 'BADCNMT',False,self._path,feed,False - else: - if endcheck == False: - pass - elif endcheck == True: - message=(indent+self._path+arrow+'was MODIFIED');print(message);feed+=message+'\n' - message=(tabs+'* '+"NOT VERIFIABLE!!!");print(message);feed+=message+'\n' - return False,False,self._path,feed,False - message=(indent+self._path+arrow+'was MODIFIED');print(message);feed+=message+'\n' - message=(tabs+'* '+"NOT VERIFIABLE!!!");print(message);feed+=message+'\n' - return False,False,self._path,feed,False + if self.header.contentType == Type.Content.META: + if targetkg == False: + if os.path.exists(self._path): + printname=str(os.path.basename(os.path.abspath(self._path))) + else: + printname=str(self._path) + if progress != False: + pass + else: + message=(indent+self._path+arrow+'needs RSV check');print(message);feed+=message+'\n' + message=(tabs+'* '+"CHECKING INTERNAL HASHES");print(message);feed+=message+'\n' + if progress == False: + feed,correct=self.check_cnmt_hashes(feed) + if correct == True: + if progress != False: + message=(tabs+'* '+"INTERNAL HASHES MATCH");bar.write(message);feed+=message+'\n' + else: + message=(tabs+'* '+"INTERNAL HASHES MATCH");print(message);feed+=message+'\n' + if correct == False: + if progress != False: + message=(tabs+'* '+"INTERNAL HASH MISSMATCH");bar.write(message);feed+=message+'\n' + message=(tabs+'* '+"BAD CNMT FILE!!!");bar.write(message);feed+=message+'\n' + else: + message=(tabs+'* '+"INTERNAL HASH MISSMATCH");print(message);feed+=message+'\n' + message=(tabs+'* '+"BAD CNMT FILE!!!");print(message);feed+=message+'\n' + return 'BADCNMT',False,self._path,feed,False + else: + if endcheck == False: + pass + elif endcheck == True: + message=(indent+self._path+arrow+'was MODIFIED');print(message);feed+=message+'\n' + message=(tabs+'* '+"NOT VERIFIABLE!!!");print(message);feed+=message+'\n' + return False,False,self._path,feed,False + else: + message=(indent+self._path+arrow+'was MODIFIED');print(message);feed+=message+'\n' + message=(tabs+'* '+"NOT VERIFIABLE!!!");print(message);feed+=message+'\n' + return False,False,self._path,feed,False + if progress != False: + message=(indent+self._path+arrow+'was MODIFIED');bar.write(message);feed+=message+'\n' + message=(tabs+'* '+"NOT VERIFIABLE!!!");bar.write(message);feed+=message+'\n' + else: + message=(indent+self._path+arrow+'was MODIFIED');print(message);feed+=message+'\n' + message=(tabs+'* '+"NOT VERIFIABLE!!!");print(message);feed+=message+'\n' + return False,False,self._path,feed,False def verify_cnmt_withkg(self,targetkg): targetkg=int(targetkg) diff --git a/py/ztools/Fs/Nsp.py b/py/ztools/Fs/Nsp.py index 6b641b62..536b243b 100644 --- a/py/ztools/Fs/Nsp.py +++ b/py/ztools/Fs/Nsp.py @@ -6748,7 +6748,10 @@ def verify_sig(self,feed,tmpfolder): cnmtdidverify=True break break - else:break + else:break + try: + t.close() + except:pass if hlisthash == True: sha0=sha0.hexdigest() hlisthash=sha0 @@ -6796,6 +6799,17 @@ def find_addecuatekg(self,ncameta,keygenerationlist): size=int.from_bytes(size, byteorder='little') ncatype = cnmt.readInt8() unknown = cnmt.read(0x1) + for nca in self: + if type(nca) == Nca: + if str(nca.header.contentType) == 'Content.META': + if nca._path == ncameta: + crypto1=nca.header.getCryptoType() + crypto2=nca.header.getCryptoType2() + if crypto2>crypto1: + keygeneration=crypto2 + if crypto2<=crypto1: + keygeneration=crypto1 + return keygeneration,min_sversion return False,False diff --git a/py/ztools/Fs/Xci.py b/py/ztools/Fs/Xci.py index 9064a33d..19dc47ae 100644 --- a/py/ztools/Fs/Xci.py +++ b/py/ztools/Fs/Xci.py @@ -6299,7 +6299,20 @@ def find_addecuatekg(self,ncameta,keygenerationlist): size=int.from_bytes(size, byteorder='little') ncatype = cnmt.readInt8() unknown = cnmt.read(0x1) - return False,False + for nspF in self.hfs0: + if str(nspF._path)=="secure": + for nca in nspF: + if type(nca) == Nca: + if str(nca.header.contentType) == 'Content.META': + if nca._path == ncameta: + crypto1=nca.header.getCryptoType() + crypto2=nca.header.getCryptoType2() + if crypto2>crypto1: + keygeneration=crypto2 + if crypto2<=crypto1: + keygeneration=crypto1 + return keygeneration,min_sversion + return False,False def verify_hash_nca(self,buffer,headerlist,didverify,feed): verdict=True From deaac122a2eb018409c12aabb9e4760069b3663a Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Sat, 6 Jul 2019 14:34:08 +0200 Subject: [PATCH 04/13] Update sq_tools.py --- py/ztools/lib/sq_tools.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/py/ztools/lib/sq_tools.py b/py/ztools/lib/sq_tools.py index c3519a02..d8e59e02 100644 --- a/py/ztools/lib/sq_tools.py +++ b/py/ztools/lib/sq_tools.py @@ -52,6 +52,12 @@ def kgstring(kg=list()): kg1=[262144,196608,131072,65536];kg.append(kg1) kg0=[450,0];kg.append(kg0) return kg + +def kg2masterkey(kg): + if kg == 1: + return 1 + else: + return kg-1 def getTopRSV(keygeneration, RSV): if keygeneration == 0: From 2127c52f4934bc883768d39cb56965310d9876f3 Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Sat, 6 Jul 2019 16:24:45 +0200 Subject: [PATCH 05/13] Add roman numbers to bad character; Add redundant spaces removal --- py/ztools/squirrel.py | 60 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/py/ztools/squirrel.py b/py/ztools/squirrel.py index c07416fe..a487ebf9 100644 --- a/py/ztools/squirrel.py +++ b/py/ztools/squirrel.py @@ -3335,13 +3335,24 @@ endname=str(f) endname = (re.sub(r'[\/\\\:\*\?]+', '', endname)) endname = re.sub(r'[™©®`~^´ªº¢£€¥$ƒ±¬½¼«»±•²‰œæƳ]', '', endname) - endname = re.sub(r'[Ⅲ]', 'III', 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'[àâá@äå]', '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(' +', ' ',endname) + endname = re.sub(' {3,}', ' ',endname);re.sub(' {2,}', ' ',endname); + try: + endname = endname.replace("( ", "(");endname = endname.replace(" )", ")") + endname = endname.replace("[ ", "[");endname = endname.replace(" ]", "]") + except:pass if endname[-1]==' ': endname=endname[:-1] if fat=="fat32" and fx=="folder": @@ -5548,13 +5559,24 @@ #endname = re.sub(r'[\/\\\:\*\?\"\<\>\|\.\s™©®()\~]+', ' ', endname) endname = (re.sub(r'[\/\\\:\*\?]+', '', endname)) endname = re.sub(r'[™©®`~^´ªº¢£€¥$ƒ±¬½¼«»±•²‰œæƳ]', '', endname) - endname = re.sub(r'[Ⅲ]', 'III', 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'[àâá@äå]', '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(' +', ' ',endname) + endname = re.sub(' {3,}', ' ',endname);re.sub(' {2,}', ' ',endname); + try: + endname = endname.replace("( ", "(");endname = endname.replace(" )", ")") + endname = endname.replace("[ ", "[");endname = endname.replace(" ]", "]") + except:pass if filepath.endswith('.xci'): endname=endname+'.xci' elif filepath.endswith('.nsp'): @@ -5779,13 +5801,24 @@ endname=endname[0].upper()+endname[1:] endname = (re.sub(r'[\/\\\:\*\?]+', '', endname)) endname = re.sub(r'[™©®`~^´ªº¢£€¥$ƒ±¬½¼«»±•²‰œæƳ]', '', endname) - endname = re.sub(r'[Ⅲ]', 'III', 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'[àâá@äå]', '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(' +', ' ',endname) + endname = re.sub(' {3,}', ' ',endname);re.sub(' {2,}', ' ',endname); + try: + endname = endname.replace("( ", "(");endname = endname.replace(" )", ")") + endname = endname.replace("[ ", "[");endname = endname.replace(" ]", "]") + except:pass if endname[-1]==' ': endname=endname[:-1] ext=ruta[-4:] @@ -5884,13 +5917,24 @@ elif san == True: endname = (re.sub(r'[\/\\\:\*\?]+', '', endname)) endname = re.sub(r'[™©®`~^´ªº¢£€¥$ƒ±¬½¼«»±•²‰œæƳ]', '', endname) - endname = re.sub(r'[Ⅲ]', 'III', 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'[àâá@äå]', '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(' +', ' ',endname) + endname = re.sub(' {3,}', ' ',endname);re.sub(' {2,}', ' ',endname); + try: + endname = endname.replace("( ", "(");endname = endname.replace(" )", ")") + endname = endname.replace("[ ", "[");endname = endname.replace(" ]", "]") + except:pass newpath=os.path.join(dir,endname) print('Old Filename: '+basename) print('Filename: '+endname) From 365014d1c2cf41b53639d6dbb92287ab52e0e276 Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Sat, 6 Jul 2019 16:40:12 +0200 Subject: [PATCH 06/13] Update squirrel.py --- py/ztools/squirrel.py | 47 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/py/ztools/squirrel.py b/py/ztools/squirrel.py index a487ebf9..f51d3f28 100644 --- a/py/ztools/squirrel.py +++ b/py/ztools/squirrel.py @@ -3336,7 +3336,7 @@ 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'[Ⅲ]', '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) @@ -5560,7 +5560,7 @@ 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'[Ⅲ]', '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) @@ -5802,7 +5802,7 @@ 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'[Ⅲ]', '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) @@ -5914,27 +5914,26 @@ converter = kakasi.getConverter() endname=converter.do(endname) endname=endname[0].upper()+endname[1:] - elif san == True: - 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'[àâá@äå]', '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(' {3,}', ' ',endname);re.sub(' {2,}', ' ',endname); - try: - endname = endname.replace("( ", "(");endname = endname.replace(" )", ")") - endname = endname.replace("[ ", "[");endname = endname.replace(" ]", "]") - except:pass + 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'[àâá@äå]', '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(' {3,}', ' ',endname);re.sub(' {2,}', ' ',endname); + try: + endname = endname.replace("( ", "(");endname = endname.replace(" )", ")") + endname = endname.replace("[ ", "[");endname = endname.replace(" ]", "]") + except:pass newpath=os.path.join(dir,endname) print('Old Filename: '+basename) print('Filename: '+endname) From 7b3834c5281f0105cc9bf184805255c70aac3a16 Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Sat, 6 Jul 2019 16:54:52 +0200 Subject: [PATCH 07/13] Improve blank space removal after romaji conversion --- py/ztools/squirrel.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/py/ztools/squirrel.py b/py/ztools/squirrel.py index f51d3f28..3b5d8eb9 100644 --- a/py/ztools/squirrel.py +++ b/py/ztools/squirrel.py @@ -3351,7 +3351,9 @@ 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(" ", " ") except:pass if endname[-1]==' ': endname=endname[:-1] @@ -5575,7 +5577,9 @@ 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(" ", " ") except:pass if filepath.endswith('.xci'): endname=endname+'.xci' @@ -5817,7 +5821,9 @@ 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(" ", " ") except:pass if endname[-1]==' ': endname=endname[:-1] @@ -5932,7 +5938,9 @@ 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(" ", " ") except:pass newpath=os.path.join(dir,endname) print('Old Filename: '+basename) From fd6ffb6b5f2e6d269b260c0779b854d60e48c3e2 Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Sat, 6 Jul 2019 17:52:05 +0200 Subject: [PATCH 08/13] Update squirrel.py --- py/ztools/squirrel.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/py/ztools/squirrel.py b/py/ztools/squirrel.py index 3b5d8eb9..62a242b0 100644 --- a/py/ztools/squirrel.py +++ b/py/ztools/squirrel.py @@ -5920,22 +5920,23 @@ 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'[àâá@äå]', '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(' {3,}', ' ',endname);re.sub(' {2,}', ' ',endname); + if san == True: + 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'[àâá@äå]', '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(' {3,}', ' ',endname);re.sub(' {2,}', ' ',endname); try: endname = endname.replace("( ", "(");endname = endname.replace(" )", ")") endname = endname.replace("[ ", "[");endname = endname.replace(" ]", "]") From ddbff73dd536b890f8c176fdaf0499b41fef8e6d Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Mon, 8 Jul 2019 23:22:20 +0200 Subject: [PATCH 09/13] Fixes bug when verifying keys.txt Fixes message "master_key_08 is present but program doesn't have the hash to verify the key" --- py/ztools/lib/sq_tools.py | 2170 ++++++++++++++++++------------------- 1 file changed, 1082 insertions(+), 1088 deletions(-) diff --git a/py/ztools/lib/sq_tools.py b/py/ztools/lib/sq_tools.py index d8e59e02..fc3fef6c 100644 --- a/py/ztools/lib/sq_tools.py +++ b/py/ztools/lib/sq_tools.py @@ -1,1088 +1,1082 @@ -import random -import os, codecs -import Hex -from binascii import hexlify as hx, unhexlify as uhx -import Keys -import re -from hashlib import sha256 -from struct import pack as pk, unpack as upk -import Fs -import aes128 -import sq_tools -indent = 1 -tabs = '\t' * indent -''' -versions = - 0: "1.0.0", -> keygeneration = 0 - 450: "1.0.0", -> keygeneration = 0 - 65536: "2.0.0", -> keygeneration = 1 - 131072: "2.1.0", -> keygeneration = 1 - 196608: "2.2.0", -> keygeneration = 1 - 262144: "2.3.0", -> keygeneration = 1 - 201326592: "3.0.0", -> keygeneration = 2 - 201392128: "3.0.1", -> keygeneration = 3 - 201457664: "3.0.2", -> keygeneration = 3 - 268435456: "4.0.0", -> keygeneration = 4 - 268500992: "4.0.1", -> keygeneration = 4 - 269484032: "4.1.0", -> keygeneration = 4 - 335544320: "5.0.0", -> keygeneration = 5 - 335609856: "5.0.1", -> keygeneration = 5 - 335675392: "5.0.2", -> keygeneration = 5 - 336592896: "5.1.0", -> keygeneration = 5 - 402653184: "6.0.0", -> keygeneration = 6 - 402718720: "6.0.1", -> keygeneration = 6 - 403701760: "6.1.0", -> keygeneration = 6 - 404750336: "6.2.0" -> keygeneration = 7 - 469762048: "7.0.0" -> keygeneration = 8 - 469827584: "7.0.1" -> keygeneration = 8 - 536870912: "8.0.0" -> keygeneration = 8 - 536936448: "8.0.1" -> keygeneration = 8 - 537919488: "8.1.0" -> keygeneration = 9 -''' -def kgstring(kg=list()): - kg=list() - kg9=[537919488];kg.append(kg9) - kg8=[536936448,536870912,469827584,469762048];kg.append(kg8) - kg7=[404750336];kg.append(kg7) - kg6=[403701760,402718720,402653184];kg.append(kg6) - kg5=[336592896,335675392,335609856,335544320];kg.append(kg5) - kg4=[269484032,268500992,268435456];kg.append(kg4) - kg3=[201457664,201392128];kg.append(kg3) - kg2=[201326592];kg.append(kg2) - kg1=[262144,196608,131072,65536];kg.append(kg1) - kg0=[450,0];kg.append(kg0) - return kg - -def kg2masterkey(kg): - if kg == 1: - return 1 - else: - return kg-1 - -def getTopRSV(keygeneration, RSV): - if keygeneration == 0: - return 450 - if keygeneration == 1: - return 262164 - if keygeneration == 2: - return 201327002 - if keygeneration == 3: - return 201457684 - if keygeneration == 4: - return 269484082 - if keygeneration == 5: - return 336592976 - if keygeneration == 6: - return 403701850 - if keygeneration == 7: - return 404750376 - if keygeneration == 8: - return 536936448 - if keygeneration == 9: - return 537919488 - else: - return RSV - -def getMinRSV(keygeneration, RSV): - if keygeneration == 0: - return 0 - if keygeneration == 1: - return 65796 - if keygeneration == 2: - RSV=3*67108864 - return RSV - if keygeneration == 3: - RSV=3*67108864+1*65536 - return RSV - if keygeneration == 4: - RSV=4*67108864 - return RSV - if keygeneration == 5: - RSV=5*67108864 - return RSV - if keygeneration == 6: - RSV=6*67108864 - return RSV - if keygeneration == 7: - RSV=6*67108864+2*1048576 - return RSV - if keygeneration == 8: - RSV=7*67108864 - return RSV - if keygeneration == 9: - RSV=8*67108864+1*1048576 - return RSV - else: - return RSV - -def getFWRangeKG(keygeneration): - if keygeneration == 0: - return "(1.0.0)" - if keygeneration == 1: - return "(2.0.0 - 2.3.0)" - if keygeneration == 2: - return "(3.0.0)" - if keygeneration == 3: - return "(3.0.1 - 3.0.2)" - if keygeneration == 4: - return "(4.0.0 - 4.1.0)" - if keygeneration == 5: - return "(5.0.0 - 5.1.0)" - if keygeneration == 6: - return "(6.0.0 - 6.1.0)" - if keygeneration == 7: - return "(6.2.0)" - if keygeneration == 8: - return "(7.0.0 - 8.0.1)" - if keygeneration == 9: - return "(8.1.0 - >8.1.0)" - else: - return "UNKNOWN" - -def getFWRangeRSV(RSV): - if RSV >= (3*67108864): - RSV=int(RSV) - frst_num=str(int(RSV/67108864)) - remainder=RSV%67108864 - sec_num=str(int(remainder/1048576)) - remainder=remainder%1048576 - thd_num=str(int(remainder/65536)) - remainder=remainder%65536 - fth_num=remainder - version=str(frst_num) - version+='.' - version+=str(sec_num) - version+='.' - version+=str(thd_num) - if fth_num > 0: - version+='-' - version+=str(fth_num) - version="("+version+")" - return version - elif RSV >= 65536: - RSV=int(RSV) - frst_num=2 - sec_num=str(int(RSV/65536)) - remainder=RSV%65536 - thd_num=0 - fth_num=remainder - version=str(frst_num) - version+='.' - version+=str(sec_num) - version+='.' - version+=str(thd_num) - if fth_num > 0: - version+='-' - version+=str(fth_num) - version="("+version+")" - return version - elif RSV > 0: - RSV=int(RSV) - frst_num=1 - sec_num=0 - thd_num=0 - remainder=RSV%65536 - fth_num=remainder - version=str(frst_num) - version+='.' - version+=str(sec_num) - version+='.' - version+=str(thd_num) - if fth_num > 0: - version+='-' - version+=str(fth_num) - version="("+version+")" - return version - elif RSV == 0: - return "(1.0.0)" - else: - return "(-)" - -def getSize(bytes): - if bytes>(1024*1024*1024): - Gbytes=bytes/(1024*1024*1024) - Gbytes=round(Gbytes,2) - Gbytes=str(Gbytes)+"GB" - return Gbytes - if bytes>(1024*1024): - Mbytes=bytes/(1024*1024) - Mbytes=round(Mbytes,2) - Mbytes=str(Mbytes)+"MB" - return Mbytes - if bytes>(1024): - Kbytes=bytes/(1024) - Kbytes=round(Kbytes,2) - Kbytes=str(Kbytes)+"KB" - return Kbytes - else: - bytes=str(bytes)+"B" - return bytes - -def getGCsize(bytes): - Gbytes=bytes/(1024*1024*1024) - Gbytes=round(Gbytes,2) - if Gbytes>=32: - card=0xE3 - firm_ver='1000a100' - return card,firm_ver - if Gbytes>=16: - card=0xE2 - firm_ver='1000a100' - return card,firm_ver - if Gbytes>=8: - card=0xE1 - firm_ver='1000a100' - return card,firm_ver - if Gbytes>=4: - card=0xE0 - firm_ver='1000a100' - return card,firm_ver - if Gbytes>=2: - card=0xF0 - firm_ver='1100a100' - return card,firm_ver - if Gbytes>=1: - card=0xF8 - firm_ver='1100a100' - return card,firm_ver - if Gbytes<1: - card=0xFA - firm_ver='1100a100' - return card,firm_ver - -def getTypeFromCNMT(number): - if number == 0: - return "Meta: " - if number == 1: - return "Program: " - if number == 2: - return "Data: " - if number == 3: - return "Control: " - if number == 4: - return "HtmlDoc: " - if number == 5: - return "LegalInf: " - if number == 6: - return "Delta: " - - -def randhex(size): - hexdigits = "0123456789ABCDEF" - random_digits = "".join([ hexdigits[random.randint(0,0xF)] for _ in range(size*2) ]) - return random_digits - -def get_enc_gameinfo(bytes): - Gbytes=bytes/(1024*1024*1024) - Gbytes=round(Gbytes,2) - if Gbytes>=32 or Gbytes>=16 or Gbytes>=8 or Gbytes>=4: - firm_ver= 0x9298F35088F09F7D - access_freq= 0xa89a60d4 - Read_Wait_Time= 0xcba6f96f - Read_Wait_Time2= 0xa45bb6ac - Write_Wait_Time= 0xabc751f9 - Write_Wait_Time2= 0x5d398742 - Firmware_Mode = 0x6b38c3f2 - CUP_Version = 0x10da0b70 - Empty1 = 0x0e5ece29 - Upd_Hash= 0xa13cbe1da6d052cb - CUP_Id = 0xf2087ce9af590538 - Empty2= 0x570d78b9cdd27fbeb4a0ac2adff9ba77754dd6675ac76223506b3bdabcb2e212fa465111ab7d51afc8b5b2b21c4b3f40654598620282add6 - else: - firm_ver= 0x9109FF82971EE993 - access_freq=0x5011ca06 - Read_Wait_Time=0x3f3c4d87 - Read_Wait_Time2=0xa13d28a9 - Write_Wait_Time=0x928d74f1 - Write_Wait_Time2=0x49919eb7 - Firmware_Mode =0x82e1f0cf - CUP_Version = 0xe4a5a3bd - Empty1 = 0xf978295c - Upd_Hash= 0xd52639a4991bdb1f - CUP_Id = 0xed841779a3f85d23 - Empty2= 0xaa4242135616f5187c03cf0d97e5d218fdb245381fd1cf8dfb796fbeda4bf7f7d6b128ce89bc9eaa8552d42f597c5db866c67bb0dd8eea11 - - firm_ver=firm_ver.to_bytes(8, byteorder='big') - access_freq=access_freq.to_bytes(4, byteorder='big') - Read_Wait_Time=Read_Wait_Time.to_bytes(4, byteorder='big') - Read_Wait_Time2=Read_Wait_Time2.to_bytes(4, byteorder='big') - Write_Wait_Time=Write_Wait_Time.to_bytes(4, byteorder='big') - Write_Wait_Time2=Write_Wait_Time2.to_bytes(4, byteorder='big') - Firmware_Mode=Firmware_Mode.to_bytes(4, byteorder='big') - CUP_Version=CUP_Version.to_bytes(4, byteorder='big') - Empty1=Empty1.to_bytes(4, byteorder='big') - Upd_Hash=Upd_Hash.to_bytes(8, byteorder='big') - CUP_Id=CUP_Id.to_bytes(8, byteorder='big') - Empty2=Empty2.to_bytes(56, byteorder='big') - - Game_info = b'' - Game_info += firm_ver - Game_info += access_freq - Game_info += Read_Wait_Time - Game_info += Read_Wait_Time2 - Game_info += Write_Wait_Time - Game_info += Write_Wait_Time2 - Game_info += Firmware_Mode - Game_info += CUP_Version - Game_info += Empty1 - Game_info += Upd_Hash - Game_info += CUP_Id - Game_info += Empty2 - - #print(Game_info) - return Game_info - -def get_krypto_block(keygeneration): - if keygeneration == 0: - return 'f3cbc0052cac528adf9129210f0a02e4' - if keygeneration == 1: - return 'f3cbc0052cac528adf9129210f0a02e4' - if keygeneration == 2: - return '789800b9e78b860eec2f7862ef05545e' - if keygeneration == 3: - return '99776e03a21f56232d056b8683d9c681' - if keygeneration == 4: - return '48df2c73957fa1b73b8e33fb2d052512' - if keygeneration == 5: - return '91dea3589a56e4fa1ce60a444009e7d8' - if keygeneration == 6: - return 'cd5b0d1abcf6450f37b8a3b68a15d5e9' - if keygeneration == 7: - return 'e7ae8f7303809fd63cbd1f500b31d5b9' - else: - return "UNKNOWN" - -def verify_nkeys(fileName): - indent = 1 - tabs = ' ' * indent - checkkeys = {} - with open(fileName, encoding="utf8") as f: - for line in f.readlines(): - r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) - if r: - checkkeys[r.group(1)] = r.group(2) - print("") - - if 'aes_kek_generation_source' not in checkkeys: - print("aes_kek_generation_source is Missing") - if 'aes_key_generation_source' not in checkkeys: - print("aes_key_generation_source is Missing") - if 'titlekek_source' not in checkkeys: - print("titlekek_source is Missing") - if 'key_area_key_application_source' not in checkkeys: - print("key_area_key_application_source is Missing") - if 'key_area_key_ocean_source' not in checkkeys: - print("key_area_key_ocean_source is Missing") - if 'key_area_key_system_source' not in checkkeys: - print("key_area_key_system_source is Missing") - counter=0 - if 'master_key_00' not in checkkeys: - print("master_key_00 is Missing") - else: - counter+=1 - if 'master_key_01' not in checkkeys: - print("master_key_01 is Missing") - else: - counter+=1 - if 'master_key_02' not in checkkeys: - print("master_key_02 is Missing") - else: - counter+=1 - if 'master_key_03' not in checkkeys: - print("master_key_03 is Missing") - else: - counter+=1 - if 'master_key_04' not in checkkeys: - print("master_key_04 is Missing") - else: - counter+=1 - if 'master_key_05' not in checkkeys: - print("master_key_05 is Missing") - else: - counter+=1 - if 'master_key_06' not in checkkeys: - print("master_key_06 is Missing") - else: - counter+=1 - if 'master_key_07' not in checkkeys: - print("master_key_07 is Missing") - else: - counter+=1 - - if 'header_key' not in checkkeys: - print("header_key is Missing") - if 'xci_header_key' not in checkkeys: - print('OPTIONAL KEY "xci_header_key" is Missing') - - while counter HEX SHA256: '+sha) - print('') - counter+=1 - - for i in checkkeys: - - if i == 'aes_kek_generation_source': - aes_kek_generation_source =checkkeys[i][:] - print('aes_kek_generation_source : '+aes_kek_generation_source ) - sha=sha256(uhx(aes_kek_generation_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'fc02b9d37b42d7a1452e71444f1f700311d1132e301a83b16062e72a78175085': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'aes_key_generation_source': - aes_key_generation_source =checkkeys[i][:] - print('aes_key_generation_source : '+aes_key_generation_source ) - sha=sha256(uhx(aes_key_generation_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'fbd10056999edc7acdb96098e47e2c3606230270d23281e671f0f389fc5bc585': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'titlekek_source': - titlekek_source=checkkeys[i][:] - print('titlekek_source: '+titlekek_source) - sha=sha256(uhx(titlekek_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'c48b619827986c7f4e3081d59db2b460c84312650e9a8e6b458e53e8cbca4e87': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'key_area_key_application_source': - key_area_key_application_source=checkkeys[i][:] - print('key_area_key_application_source: '+key_area_key_application_source) - sha=sha256(uhx(key_area_key_application_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '04ad66143c726b2a139fb6b21128b46f56c553b2b3887110304298d8d0092d9e': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'key_area_key_ocean_source': - key_area_key_ocean_source=checkkeys[i][:] - print('key_area_key_ocean_source: '+key_area_key_ocean_source) - sha=sha256(uhx(key_area_key_ocean_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'fd434000c8ff2b26f8e9a9d2d2c12f6be5773cbb9dc86300e1bd99f8ea33a417': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'key_area_key_system_source': - key_area_key_system_source=checkkeys[i][:] - print('key_area_key_system_source: '+key_area_key_system_source) - sha=sha256(uhx(key_area_key_system_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '1f17b1fd51ad1c2379b58f152ca4912ec2106441e51722f38700d5937a1162f7': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_00': - master_key_00=checkkeys[i][:] - print('master_key_00: '+master_key_00) - sha=sha256(uhx(master_key_00)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '0ee359be3c864bb0782e1d70a718a0342c551eed28c369754f9c4f691becf7ca': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_01': - master_key_01=checkkeys[i][:] - print('master_key_01: '+master_key_01) - sha=sha256(uhx(master_key_01)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '4fe707b7e4abdaf727c894aaf13b1351bfe2ac90d875f73b2e20fa94b9cc661e': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_02': - master_key_02=checkkeys[i][:] - print('master_key_02: '+master_key_02) - sha=sha256(uhx(master_key_02)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '79277c0237a2252ec3dfac1f7c359c2b3d121e9db15bb9ab4c2b4408d2f3ae09': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_03': - master_key_03=checkkeys[i][:] - print('master_key_03: '+master_key_03) - sha=sha256(uhx(master_key_03)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '4f36c565d13325f65ee134073c6a578ffcb0008e02d69400836844eab7432754': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_04': - master_key_04=checkkeys[i][:] - print('master_key_04: '+master_key_04) - sha=sha256(uhx(master_key_04)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '75ff1d95d26113550ee6fcc20acb58e97edeb3a2ff52543ed5aec63bdcc3da50': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_05': - master_key_05=checkkeys[i][:] - print('master_key_05: '+master_key_05) - sha=sha256(uhx(master_key_05)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'ebe2bcd6704673ec0f88a187bb2ad9f1cc82b718c389425941bdc194dc46b0dd': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_06': - master_key_06=checkkeys[i][:] - print('master_key_06: '+master_key_06) - sha=sha256(uhx(master_key_06)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '9497e6779f5d840f2bba1de4e95ba1d6f21efc94717d5ae5ca37d7ec5bd37a19': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_07': - master_key_07=checkkeys[i][:] - print('master_key_07: '+master_key_07) - sha=sha256(uhx(master_key_07)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '4ec96b8cb01b8dce382149443430b2b6ebcb2983348afa04a25e53609dabedf6': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_08': - master_key_08=checkkeys[i][:] - print('master_key_08: '+master_key_08) - sha=sha256(uhx(master_key_08)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '2998e2e23609bc2675ff062a2d64af5b1b78dff463b24119d64a1b64f01b2d51': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'header_key': - header_key=checkkeys[i][:] - print('header_key: '+header_key) - sha=sha256(uhx(header_key)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '8e03de24818d96ce4f2a09b43af979e679974f7570713a61eed8b314864a11d5': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'xci_header_key': - xci_header_key=checkkeys[i][:] - print('xci_header_key: '+xci_header_key) - sha=sha256(uhx(xci_header_key)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '2e36cc55157a351090a73e7ae77cf581f69b0b6e48fb066c984879a6ed7d2e96': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - -def verify_nkeys_startup(fileName): - indent = 1 - tabs = ' ' * indent - checkkeys = {} - startup=False - with open(fileName, encoding="utf8") as f: - for line in f.readlines(): - r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) - if r: - checkkeys[r.group(1)] = r.group(2) - print("") - - if 'aes_kek_generation_source' not in checkkeys: - print("aes_kek_generation_source is Missing") - print("This is a needed key!!!") - startup=True - if 'aes_key_generation_source' not in checkkeys: - print("aes_key_generation_source is Missing") - print("This is a needed key!!!") - startup=True - if 'titlekek_source' not in checkkeys: - print("titlekek_source is Missing") - print("This is a needed key!!!") - startup=True - if 'key_area_key_application_source' not in checkkeys: - print("key_area_key_application_source is Missing") - print("This is a needed key!!!") - startup=True - if 'key_area_key_ocean_source' not in checkkeys: - print("key_area_key_ocean_source is Missing") - print("This is a needed key!!!") - startup=True - if 'key_area_key_system_source' not in checkkeys: - print("key_area_key_system_source is Missing") - print("This is a needed key!!!") - startup=True - counter=0 - if 'master_key_00' not in checkkeys: - print("master_key_00 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 1.0.0-2.3.0 requirement") - startup=True - else: - counter+=1 - if 'master_key_01' not in checkkeys: - print("master_key_01 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 3.0.0 requirement") - startup=True - else: - counter+=1 - if 'master_key_02' not in checkkeys: - print("master_key_02 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 3.0.1-3.0.2 requirement") - startup=True - else: - counter+=1 - if 'master_key_03' not in checkkeys: - print("master_key_03 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 4.0.0-4.0.1 requirement") - startup=True - else: - counter+=1 - if 'master_key_04' not in checkkeys: - print("master_key_04 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 5.0.0-5.1.0 requirement") - startup=True - else: - counter+=1 - if 'master_key_05' not in checkkeys: - print("master_key_05 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 6.0.0-6.1.0 requirement") - startup=True - else: - counter+=1 - if 'master_key_06' not in checkkeys: - print("master_key_06 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 6.2.0 requirement") - startup=True - if 'master_key_07' not in checkkeys: - print("master_key_07 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 7.0.0-8.0.1 requirement") - startup=True - if 'master_key_08' not in checkkeys: - print("master_key_08 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 8.1 requirement") - startup=True - else: - counter+=1 - - if 'header_key' not in checkkeys: - print("header_key is Missing") - if 'xci_header_key' not in checkkeys: - print('OPTIONAL KEY "xci_header_key" is Missing') - - while counter HEX SHA256: '+sha) - print('') - counter+=1 - - for i in checkkeys: - - if i == 'aes_kek_generation_source': - aes_kek_generation_source =checkkeys[i][:] - sha=sha256(uhx(aes_kek_generation_source)).hexdigest() - if sha != 'fc02b9d37b42d7a1452e71444f1f700311d1132e301a83b16062e72a78175085': - print('aes_kek_generation_source : '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'aes_key_generation_source': - aes_key_generation_source =checkkeys[i][:] - sha=sha256(uhx(aes_key_generation_source)).hexdigest() - if sha != 'fbd10056999edc7acdb96098e47e2c3606230270d23281e671f0f389fc5bc585': - print('aes_key_generation_source : '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'titlekek_source': - titlekek_source=checkkeys[i][:] - sha=sha256(uhx(titlekek_source)).hexdigest() - if sha != 'c48b619827986c7f4e3081d59db2b460c84312650e9a8e6b458e53e8cbca4e87': - print('titlekek_source : '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'key_area_key_application_source': - key_area_key_application_source=checkkeys[i][:] - sha=sha256(uhx(key_area_key_application_source)).hexdigest() - if sha != '04ad66143c726b2a139fb6b21128b46f56c553b2b3887110304298d8d0092d9e': - print('key_area_key_application_source: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'key_area_key_ocean_source': - key_area_key_ocean_source=checkkeys[i][:] - sha=sha256(uhx(key_area_key_ocean_source)).hexdigest() - if sha != 'fd434000c8ff2b26f8e9a9d2d2c12f6be5773cbb9dc86300e1bd99f8ea33a417': - print('key_area_key_ocean_source: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'key_area_key_system_source': - key_area_key_system_source=checkkeys[i][:] - sha=sha256(uhx(key_area_key_system_source)).hexdigest() - if sha != '1f17b1fd51ad1c2379b58f152ca4912ec2106441e51722f38700d5937a1162f7': - print('key_area_key_system_source: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_00': - master_key_00=checkkeys[i][:] - sha=sha256(uhx(master_key_00)).hexdigest() - if sha != '0ee359be3c864bb0782e1d70a718a0342c551eed28c369754f9c4f691becf7ca': - print('master_key_00: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_01': - master_key_01=checkkeys[i][:] - sha=sha256(uhx(master_key_01)).hexdigest() - if sha != '4fe707b7e4abdaf727c894aaf13b1351bfe2ac90d875f73b2e20fa94b9cc661e': - print('master_key_01: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_02': - master_key_02=checkkeys[i][:] - sha=sha256(uhx(master_key_02)).hexdigest() - if sha != '79277c0237a2252ec3dfac1f7c359c2b3d121e9db15bb9ab4c2b4408d2f3ae09': - print('master_key_02: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_03': - master_key_03=checkkeys[i][:] - sha=sha256(uhx(master_key_03)).hexdigest() - if sha != '4f36c565d13325f65ee134073c6a578ffcb0008e02d69400836844eab7432754': - print('master_key_03: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_04': - master_key_04=checkkeys[i][:] - sha=sha256(uhx(master_key_04)).hexdigest() - if sha != '75ff1d95d26113550ee6fcc20acb58e97edeb3a2ff52543ed5aec63bdcc3da50': - print('master_key_04: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_05': - master_key_05=checkkeys[i][:] - sha=sha256(uhx(master_key_05)).hexdigest() - if sha != 'ebe2bcd6704673ec0f88a187bb2ad9f1cc82b718c389425941bdc194dc46b0dd': - print('master_key_05: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_06': - master_key_06=checkkeys[i][:] - print('master_key_06: '+master_key_06) - sha=sha256(uhx(master_key_06)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha != '9497e6779f5d840f2bba1de4e95ba1d6f21efc94717d5ae5ca37d7ec5bd37a19': - print('master_key_06: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_07': - master_key_07=checkkeys[i][:] - sha=sha256(uhx(master_key_07)).hexdigest() - if sha != '4ec96b8cb01b8dce382149443430b2b6ebcb2983348afa04a25e53609dabedf6': - print('master_key_07: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_08': - master_key_08=checkkeys[i][:] - sha=sha256(uhx(master_key_08)).hexdigest() - if sha != '2998e2e23609bc2675ff062a2d64af5b1b78dff463b24119d64a1b64f01b2d51': - print('master_key_07: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'header_key': - header_key=checkkeys[i][:] - sha=sha256(uhx(header_key)).hexdigest() - if sha != '8e03de24818d96ce4f2a09b43af979e679974f7570713a61eed8b314864a11d5': - print('header_key: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'xci_header_key': - xci_header_key=checkkeys[i][:] - sha=sha256(uhx(xci_header_key)).hexdigest() - if sha != '2e36cc55157a351090a73e7ae77cf581f69b0b6e48fb066c984879a6ed7d2e96': - print('xci_header_key: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - return startup - - -def gen_nsp_header(files,fileSizes): - ''' - for i in range(len(files)): - print (files[i]) - print (fileSizes[i]) - ''' - filesNb = len(files) - stringTable = '\x00'.join(str(nca) for nca in files) - headerSize = 0x10 + (filesNb)*0x18 + len(stringTable) - remainder = 0x10 - headerSize%0x10 - headerSize += remainder - - fileOffsets = [sum(fileSizes[:n]) for n in range(filesNb)] - - fileNamesLengths = [len(str(nca))+1 for nca in files] # +1 for the \x00 - stringTableOffsets = [sum(fileNamesLengths[:n]) for n in range(filesNb)] - - header = b'' - header += b'PFS0' - header += pk(' keygeneration = 0 + 450: "1.0.0", -> keygeneration = 0 + 65536: "2.0.0", -> keygeneration = 1 + 131072: "2.1.0", -> keygeneration = 1 + 196608: "2.2.0", -> keygeneration = 1 + 262144: "2.3.0", -> keygeneration = 1 + 201326592: "3.0.0", -> keygeneration = 2 + 201392128: "3.0.1", -> keygeneration = 3 + 201457664: "3.0.2", -> keygeneration = 3 + 268435456: "4.0.0", -> keygeneration = 4 + 268500992: "4.0.1", -> keygeneration = 4 + 269484032: "4.1.0", -> keygeneration = 4 + 335544320: "5.0.0", -> keygeneration = 5 + 335609856: "5.0.1", -> keygeneration = 5 + 335675392: "5.0.2", -> keygeneration = 5 + 336592896: "5.1.0", -> keygeneration = 5 + 402653184: "6.0.0", -> keygeneration = 6 + 402718720: "6.0.1", -> keygeneration = 6 + 403701760: "6.1.0", -> keygeneration = 6 + 404750336: "6.2.0" -> keygeneration = 7 + 469762048: "7.0.0" -> keygeneration = 8 + 469827584: "7.0.1" -> keygeneration = 8 + 536870912: "8.0.0" -> keygeneration = 8 + 536936448: "8.0.1" -> keygeneration = 8 + 537919488: "8.1.0" -> keygeneration = 9 +''' +def kgstring(kg=list()): + kg=list() + kg9=[537919488];kg.append(kg9) + kg8=[536936448,536870912,469827584,469762048];kg.append(kg8) + kg7=[404750336];kg.append(kg7) + kg6=[403701760,402718720,402653184];kg.append(kg6) + kg5=[336592896,335675392,335609856,335544320];kg.append(kg5) + kg4=[269484032,268500992,268435456];kg.append(kg4) + kg3=[201457664,201392128];kg.append(kg3) + kg2=[201326592];kg.append(kg2) + kg1=[262144,196608,131072,65536];kg.append(kg1) + kg0=[450,0];kg.append(kg0) + return kg + +def getTopRSV(keygeneration, RSV): + if keygeneration == 0: + return 450 + if keygeneration == 1: + return 262164 + if keygeneration == 2: + return 201327002 + if keygeneration == 3: + return 201457684 + if keygeneration == 4: + return 269484082 + if keygeneration == 5: + return 336592976 + if keygeneration == 6: + return 403701850 + if keygeneration == 7: + return 404750376 + if keygeneration == 8: + return 536936448 + if keygeneration == 9: + return 537919488 + else: + return RSV + +def getMinRSV(keygeneration, RSV): + if keygeneration == 0: + return 0 + if keygeneration == 1: + return 65796 + if keygeneration == 2: + RSV=3*67108864 + return RSV + if keygeneration == 3: + RSV=3*67108864+1*65536 + return RSV + if keygeneration == 4: + RSV=4*67108864 + return RSV + if keygeneration == 5: + RSV=5*67108864 + return RSV + if keygeneration == 6: + RSV=6*67108864 + return RSV + if keygeneration == 7: + RSV=6*67108864+2*1048576 + return RSV + if keygeneration == 8: + RSV=7*67108864 + return RSV + if keygeneration == 9: + RSV=8*67108864+1*1048576 + return RSV + else: + return RSV + +def getFWRangeKG(keygeneration): + if keygeneration == 0: + return "(1.0.0)" + if keygeneration == 1: + return "(2.0.0 - 2.3.0)" + if keygeneration == 2: + return "(3.0.0)" + if keygeneration == 3: + return "(3.0.1 - 3.0.2)" + if keygeneration == 4: + return "(4.0.0 - 4.1.0)" + if keygeneration == 5: + return "(5.0.0 - 5.1.0)" + if keygeneration == 6: + return "(6.0.0 - 6.1.0)" + if keygeneration == 7: + return "(6.2.0)" + if keygeneration == 8: + return "(7.0.0 - 8.0.1)" + if keygeneration == 9: + return "(8.1.0 - >8.1.0)" + else: + return "UNKNOWN" + +def getFWRangeRSV(RSV): + if RSV >= (3*67108864): + RSV=int(RSV) + frst_num=str(int(RSV/67108864)) + remainder=RSV%67108864 + sec_num=str(int(remainder/1048576)) + remainder=remainder%1048576 + thd_num=str(int(remainder/65536)) + remainder=remainder%65536 + fth_num=remainder + version=str(frst_num) + version+='.' + version+=str(sec_num) + version+='.' + version+=str(thd_num) + if fth_num > 0: + version+='-' + version+=str(fth_num) + version="("+version+")" + return version + elif RSV >= 65536: + RSV=int(RSV) + frst_num=2 + sec_num=str(int(RSV/65536)) + remainder=RSV%65536 + thd_num=0 + fth_num=remainder + version=str(frst_num) + version+='.' + version+=str(sec_num) + version+='.' + version+=str(thd_num) + if fth_num > 0: + version+='-' + version+=str(fth_num) + version="("+version+")" + return version + elif RSV > 0: + RSV=int(RSV) + frst_num=1 + sec_num=0 + thd_num=0 + remainder=RSV%65536 + fth_num=remainder + version=str(frst_num) + version+='.' + version+=str(sec_num) + version+='.' + version+=str(thd_num) + if fth_num > 0: + version+='-' + version+=str(fth_num) + version="("+version+")" + return version + elif RSV == 0: + return "(1.0.0)" + else: + return "(-)" + +def getSize(bytes): + if bytes>(1024*1024*1024): + Gbytes=bytes/(1024*1024*1024) + Gbytes=round(Gbytes,2) + Gbytes=str(Gbytes)+"GB" + return Gbytes + if bytes>(1024*1024): + Mbytes=bytes/(1024*1024) + Mbytes=round(Mbytes,2) + Mbytes=str(Mbytes)+"MB" + return Mbytes + if bytes>(1024): + Kbytes=bytes/(1024) + Kbytes=round(Kbytes,2) + Kbytes=str(Kbytes)+"KB" + return Kbytes + else: + bytes=str(bytes)+"B" + return bytes + +def getGCsize(bytes): + Gbytes=bytes/(1024*1024*1024) + Gbytes=round(Gbytes,2) + if Gbytes>=32: + card=0xE3 + firm_ver='1000a100' + return card,firm_ver + if Gbytes>=16: + card=0xE2 + firm_ver='1000a100' + return card,firm_ver + if Gbytes>=8: + card=0xE1 + firm_ver='1000a100' + return card,firm_ver + if Gbytes>=4: + card=0xE0 + firm_ver='1000a100' + return card,firm_ver + if Gbytes>=2: + card=0xF0 + firm_ver='1100a100' + return card,firm_ver + if Gbytes>=1: + card=0xF8 + firm_ver='1100a100' + return card,firm_ver + if Gbytes<1: + card=0xFA + firm_ver='1100a100' + return card,firm_ver + +def getTypeFromCNMT(number): + if number == 0: + return "Meta: " + if number == 1: + return "Program: " + if number == 2: + return "Data: " + if number == 3: + return "Control: " + if number == 4: + return "HtmlDoc: " + if number == 5: + return "LegalInf: " + if number == 6: + return "Delta: " + + +def randhex(size): + hexdigits = "0123456789ABCDEF" + random_digits = "".join([ hexdigits[random.randint(0,0xF)] for _ in range(size*2) ]) + return random_digits + +def get_enc_gameinfo(bytes): + Gbytes=bytes/(1024*1024*1024) + Gbytes=round(Gbytes,2) + if Gbytes>=32 or Gbytes>=16 or Gbytes>=8 or Gbytes>=4: + firm_ver= 0x9298F35088F09F7D + access_freq= 0xa89a60d4 + Read_Wait_Time= 0xcba6f96f + Read_Wait_Time2= 0xa45bb6ac + Write_Wait_Time= 0xabc751f9 + Write_Wait_Time2= 0x5d398742 + Firmware_Mode = 0x6b38c3f2 + CUP_Version = 0x10da0b70 + Empty1 = 0x0e5ece29 + Upd_Hash= 0xa13cbe1da6d052cb + CUP_Id = 0xf2087ce9af590538 + Empty2= 0x570d78b9cdd27fbeb4a0ac2adff9ba77754dd6675ac76223506b3bdabcb2e212fa465111ab7d51afc8b5b2b21c4b3f40654598620282add6 + else: + firm_ver= 0x9109FF82971EE993 + access_freq=0x5011ca06 + Read_Wait_Time=0x3f3c4d87 + Read_Wait_Time2=0xa13d28a9 + Write_Wait_Time=0x928d74f1 + Write_Wait_Time2=0x49919eb7 + Firmware_Mode =0x82e1f0cf + CUP_Version = 0xe4a5a3bd + Empty1 = 0xf978295c + Upd_Hash= 0xd52639a4991bdb1f + CUP_Id = 0xed841779a3f85d23 + Empty2= 0xaa4242135616f5187c03cf0d97e5d218fdb245381fd1cf8dfb796fbeda4bf7f7d6b128ce89bc9eaa8552d42f597c5db866c67bb0dd8eea11 + + firm_ver=firm_ver.to_bytes(8, byteorder='big') + access_freq=access_freq.to_bytes(4, byteorder='big') + Read_Wait_Time=Read_Wait_Time.to_bytes(4, byteorder='big') + Read_Wait_Time2=Read_Wait_Time2.to_bytes(4, byteorder='big') + Write_Wait_Time=Write_Wait_Time.to_bytes(4, byteorder='big') + Write_Wait_Time2=Write_Wait_Time2.to_bytes(4, byteorder='big') + Firmware_Mode=Firmware_Mode.to_bytes(4, byteorder='big') + CUP_Version=CUP_Version.to_bytes(4, byteorder='big') + Empty1=Empty1.to_bytes(4, byteorder='big') + Upd_Hash=Upd_Hash.to_bytes(8, byteorder='big') + CUP_Id=CUP_Id.to_bytes(8, byteorder='big') + Empty2=Empty2.to_bytes(56, byteorder='big') + + Game_info = b'' + Game_info += firm_ver + Game_info += access_freq + Game_info += Read_Wait_Time + Game_info += Read_Wait_Time2 + Game_info += Write_Wait_Time + Game_info += Write_Wait_Time2 + Game_info += Firmware_Mode + Game_info += CUP_Version + Game_info += Empty1 + Game_info += Upd_Hash + Game_info += CUP_Id + Game_info += Empty2 + + #print(Game_info) + return Game_info + +def get_krypto_block(keygeneration): + if keygeneration == 0: + return 'f3cbc0052cac528adf9129210f0a02e4' + if keygeneration == 1: + return 'f3cbc0052cac528adf9129210f0a02e4' + if keygeneration == 2: + return '789800b9e78b860eec2f7862ef05545e' + if keygeneration == 3: + return '99776e03a21f56232d056b8683d9c681' + if keygeneration == 4: + return '48df2c73957fa1b73b8e33fb2d052512' + if keygeneration == 5: + return '91dea3589a56e4fa1ce60a444009e7d8' + if keygeneration == 6: + return 'cd5b0d1abcf6450f37b8a3b68a15d5e9' + if keygeneration == 7: + return 'e7ae8f7303809fd63cbd1f500b31d5b9' + else: + return "UNKNOWN" + +def verify_nkeys(fileName): + indent = 1 + tabs = ' ' * indent + checkkeys = {} + with open(fileName, encoding="utf8") as f: + for line in f.readlines(): + r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) + if r: + checkkeys[r.group(1)] = r.group(2) + print("") + + if 'aes_kek_generation_source' not in checkkeys: + print("aes_kek_generation_source is Missing") + if 'aes_key_generation_source' not in checkkeys: + print("aes_key_generation_source is Missing") + if 'titlekek_source' not in checkkeys: + print("titlekek_source is Missing") + if 'key_area_key_application_source' not in checkkeys: + print("key_area_key_application_source is Missing") + if 'key_area_key_ocean_source' not in checkkeys: + print("key_area_key_ocean_source is Missing") + if 'key_area_key_system_source' not in checkkeys: + print("key_area_key_system_source is Missing") + counter=0 + if 'master_key_00' not in checkkeys: + print("master_key_00 is Missing") + else: + counter+=1 + if 'master_key_01' not in checkkeys: + print("master_key_01 is Missing") + else: + counter+=1 + if 'master_key_02' not in checkkeys: + print("master_key_02 is Missing") + else: + counter+=1 + if 'master_key_03' not in checkkeys: + print("master_key_03 is Missing") + else: + counter+=1 + if 'master_key_04' not in checkkeys: + print("master_key_04 is Missing") + else: + counter+=1 + if 'master_key_05' not in checkkeys: + print("master_key_05 is Missing") + else: + counter+=1 + if 'master_key_06' not in checkkeys: + print("master_key_06 is Missing") + else: + counter+=1 + if 'master_key_07' not in checkkeys: + print("master_key_07 is Missing") + else: + counter+=1 + + if 'header_key' not in checkkeys: + print("header_key is Missing") + if 'xci_header_key' not in checkkeys: + print('OPTIONAL KEY "xci_header_key" is Missing') + + while counter HEX SHA256: '+sha) + print('') + counter+=1 + + for i in checkkeys: + + if i == 'aes_kek_generation_source': + aes_kek_generation_source =checkkeys[i][:] + print('aes_kek_generation_source : '+aes_kek_generation_source ) + sha=sha256(uhx(aes_kek_generation_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'fc02b9d37b42d7a1452e71444f1f700311d1132e301a83b16062e72a78175085': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'aes_key_generation_source': + aes_key_generation_source =checkkeys[i][:] + print('aes_key_generation_source : '+aes_key_generation_source ) + sha=sha256(uhx(aes_key_generation_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'fbd10056999edc7acdb96098e47e2c3606230270d23281e671f0f389fc5bc585': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'titlekek_source': + titlekek_source=checkkeys[i][:] + print('titlekek_source: '+titlekek_source) + sha=sha256(uhx(titlekek_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'c48b619827986c7f4e3081d59db2b460c84312650e9a8e6b458e53e8cbca4e87': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'key_area_key_application_source': + key_area_key_application_source=checkkeys[i][:] + print('key_area_key_application_source: '+key_area_key_application_source) + sha=sha256(uhx(key_area_key_application_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '04ad66143c726b2a139fb6b21128b46f56c553b2b3887110304298d8d0092d9e': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'key_area_key_ocean_source': + key_area_key_ocean_source=checkkeys[i][:] + print('key_area_key_ocean_source: '+key_area_key_ocean_source) + sha=sha256(uhx(key_area_key_ocean_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'fd434000c8ff2b26f8e9a9d2d2c12f6be5773cbb9dc86300e1bd99f8ea33a417': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'key_area_key_system_source': + key_area_key_system_source=checkkeys[i][:] + print('key_area_key_system_source: '+key_area_key_system_source) + sha=sha256(uhx(key_area_key_system_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '1f17b1fd51ad1c2379b58f152ca4912ec2106441e51722f38700d5937a1162f7': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_00': + master_key_00=checkkeys[i][:] + print('master_key_00: '+master_key_00) + sha=sha256(uhx(master_key_00)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '0ee359be3c864bb0782e1d70a718a0342c551eed28c369754f9c4f691becf7ca': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_01': + master_key_01=checkkeys[i][:] + print('master_key_01: '+master_key_01) + sha=sha256(uhx(master_key_01)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '4fe707b7e4abdaf727c894aaf13b1351bfe2ac90d875f73b2e20fa94b9cc661e': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_02': + master_key_02=checkkeys[i][:] + print('master_key_02: '+master_key_02) + sha=sha256(uhx(master_key_02)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '79277c0237a2252ec3dfac1f7c359c2b3d121e9db15bb9ab4c2b4408d2f3ae09': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_03': + master_key_03=checkkeys[i][:] + print('master_key_03: '+master_key_03) + sha=sha256(uhx(master_key_03)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '4f36c565d13325f65ee134073c6a578ffcb0008e02d69400836844eab7432754': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_04': + master_key_04=checkkeys[i][:] + print('master_key_04: '+master_key_04) + sha=sha256(uhx(master_key_04)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '75ff1d95d26113550ee6fcc20acb58e97edeb3a2ff52543ed5aec63bdcc3da50': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_05': + master_key_05=checkkeys[i][:] + print('master_key_05: '+master_key_05) + sha=sha256(uhx(master_key_05)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'ebe2bcd6704673ec0f88a187bb2ad9f1cc82b718c389425941bdc194dc46b0dd': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_06': + master_key_06=checkkeys[i][:] + print('master_key_06: '+master_key_06) + sha=sha256(uhx(master_key_06)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '9497e6779f5d840f2bba1de4e95ba1d6f21efc94717d5ae5ca37d7ec5bd37a19': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_07': + master_key_07=checkkeys[i][:] + print('master_key_07: '+master_key_07) + sha=sha256(uhx(master_key_07)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '4ec96b8cb01b8dce382149443430b2b6ebcb2983348afa04a25e53609dabedf6': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_08': + master_key_08=checkkeys[i][:] + print('master_key_08: '+master_key_08) + sha=sha256(uhx(master_key_08)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '2998e2e23609bc2675ff062a2d64af5b1b78dff463b24119d64a1b64f01b2d51': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'header_key': + header_key=checkkeys[i][:] + print('header_key: '+header_key) + sha=sha256(uhx(header_key)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '8e03de24818d96ce4f2a09b43af979e679974f7570713a61eed8b314864a11d5': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'xci_header_key': + xci_header_key=checkkeys[i][:] + print('xci_header_key: '+xci_header_key) + sha=sha256(uhx(xci_header_key)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '2e36cc55157a351090a73e7ae77cf581f69b0b6e48fb066c984879a6ed7d2e96': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + +def verify_nkeys_startup(fileName): + indent = 1 + tabs = ' ' * indent + checkkeys = {} + startup=False + with open(fileName, encoding="utf8") as f: + for line in f.readlines(): + r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) + if r: + checkkeys[r.group(1)] = r.group(2) + print("") + + if 'aes_kek_generation_source' not in checkkeys: + print("aes_kek_generation_source is Missing") + print("This is a needed key!!!") + startup=True + if 'aes_key_generation_source' not in checkkeys: + print("aes_key_generation_source is Missing") + print("This is a needed key!!!") + startup=True + if 'titlekek_source' not in checkkeys: + print("titlekek_source is Missing") + print("This is a needed key!!!") + startup=True + if 'key_area_key_application_source' not in checkkeys: + print("key_area_key_application_source is Missing") + print("This is a needed key!!!") + startup=True + if 'key_area_key_ocean_source' not in checkkeys: + print("key_area_key_ocean_source is Missing") + print("This is a needed key!!!") + startup=True + if 'key_area_key_system_source' not in checkkeys: + print("key_area_key_system_source is Missing") + print("This is a needed key!!!") + startup=True + counter=0 + if 'master_key_00' not in checkkeys: + print("master_key_00 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 1.0.0-2.3.0 requirement") + startup=True + else: + counter+=1 + if 'master_key_01' not in checkkeys: + print("master_key_01 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 3.0.0 requirement") + startup=True + else: + counter+=1 + if 'master_key_02' not in checkkeys: + print("master_key_02 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 3.0.1-3.0.2 requirement") + startup=True + else: + counter+=1 + if 'master_key_03' not in checkkeys: + print("master_key_03 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 4.0.0-4.0.1 requirement") + startup=True + else: + counter+=1 + if 'master_key_04' not in checkkeys: + print("master_key_04 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 5.0.0-5.1.0 requirement") + startup=True + else: + counter+=1 + if 'master_key_05' not in checkkeys: + print("master_key_05 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 6.0.0-6.1.0 requirement") + startup=True + else: + counter+=1 + if 'master_key_06' not in checkkeys: + print("master_key_06 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 6.2.0 requirement") + startup=True + if 'master_key_07' not in checkkeys: + print("master_key_07 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 7.0.0-8.0.1 requirement") + startup=True + if 'master_key_08' not in checkkeys: + print("master_key_08 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 8.1 requirement") + startup=True + else: + counter+=1 + + if 'header_key' not in checkkeys: + print("header_key is Missing") + if 'xci_header_key' not in checkkeys: + print('OPTIONAL KEY "xci_header_key" is Missing') + + while counter HEX SHA256: '+sha) + print('') + counter+=1 + + for i in checkkeys: + + if i == 'aes_kek_generation_source': + aes_kek_generation_source =checkkeys[i][:] + sha=sha256(uhx(aes_kek_generation_source)).hexdigest() + if sha != 'fc02b9d37b42d7a1452e71444f1f700311d1132e301a83b16062e72a78175085': + print('aes_kek_generation_source : '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'aes_key_generation_source': + aes_key_generation_source =checkkeys[i][:] + sha=sha256(uhx(aes_key_generation_source)).hexdigest() + if sha != 'fbd10056999edc7acdb96098e47e2c3606230270d23281e671f0f389fc5bc585': + print('aes_key_generation_source : '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'titlekek_source': + titlekek_source=checkkeys[i][:] + sha=sha256(uhx(titlekek_source)).hexdigest() + if sha != 'c48b619827986c7f4e3081d59db2b460c84312650e9a8e6b458e53e8cbca4e87': + print('titlekek_source : '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'key_area_key_application_source': + key_area_key_application_source=checkkeys[i][:] + sha=sha256(uhx(key_area_key_application_source)).hexdigest() + if sha != '04ad66143c726b2a139fb6b21128b46f56c553b2b3887110304298d8d0092d9e': + print('key_area_key_application_source: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'key_area_key_ocean_source': + key_area_key_ocean_source=checkkeys[i][:] + sha=sha256(uhx(key_area_key_ocean_source)).hexdigest() + if sha != 'fd434000c8ff2b26f8e9a9d2d2c12f6be5773cbb9dc86300e1bd99f8ea33a417': + print('key_area_key_ocean_source: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'key_area_key_system_source': + key_area_key_system_source=checkkeys[i][:] + sha=sha256(uhx(key_area_key_system_source)).hexdigest() + if sha != '1f17b1fd51ad1c2379b58f152ca4912ec2106441e51722f38700d5937a1162f7': + print('key_area_key_system_source: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_00': + master_key_00=checkkeys[i][:] + sha=sha256(uhx(master_key_00)).hexdigest() + if sha != '0ee359be3c864bb0782e1d70a718a0342c551eed28c369754f9c4f691becf7ca': + print('master_key_00: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_01': + master_key_01=checkkeys[i][:] + sha=sha256(uhx(master_key_01)).hexdigest() + if sha != '4fe707b7e4abdaf727c894aaf13b1351bfe2ac90d875f73b2e20fa94b9cc661e': + print('master_key_01: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_02': + master_key_02=checkkeys[i][:] + sha=sha256(uhx(master_key_02)).hexdigest() + if sha != '79277c0237a2252ec3dfac1f7c359c2b3d121e9db15bb9ab4c2b4408d2f3ae09': + print('master_key_02: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_03': + master_key_03=checkkeys[i][:] + sha=sha256(uhx(master_key_03)).hexdigest() + if sha != '4f36c565d13325f65ee134073c6a578ffcb0008e02d69400836844eab7432754': + print('master_key_03: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_04': + master_key_04=checkkeys[i][:] + sha=sha256(uhx(master_key_04)).hexdigest() + if sha != '75ff1d95d26113550ee6fcc20acb58e97edeb3a2ff52543ed5aec63bdcc3da50': + print('master_key_04: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_05': + master_key_05=checkkeys[i][:] + sha=sha256(uhx(master_key_05)).hexdigest() + if sha != 'ebe2bcd6704673ec0f88a187bb2ad9f1cc82b718c389425941bdc194dc46b0dd': + print('master_key_05: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_06': + master_key_06=checkkeys[i][:] + print('master_key_06: '+master_key_06) + sha=sha256(uhx(master_key_06)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha != '9497e6779f5d840f2bba1de4e95ba1d6f21efc94717d5ae5ca37d7ec5bd37a19': + print('master_key_06: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_07': + master_key_07=checkkeys[i][:] + sha=sha256(uhx(master_key_07)).hexdigest() + if sha != '4ec96b8cb01b8dce382149443430b2b6ebcb2983348afa04a25e53609dabedf6': + print('master_key_07: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_08': + master_key_08=checkkeys[i][:] + sha=sha256(uhx(master_key_08)).hexdigest() + if sha != '2998e2e23609bc2675ff062a2d64af5b1b78dff463b24119d64a1b64f01b2d51': + print('master_key_07: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'header_key': + header_key=checkkeys[i][:] + sha=sha256(uhx(header_key)).hexdigest() + if sha != '8e03de24818d96ce4f2a09b43af979e679974f7570713a61eed8b314864a11d5': + print('header_key: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'xci_header_key': + xci_header_key=checkkeys[i][:] + sha=sha256(uhx(xci_header_key)).hexdigest() + if sha != '2e36cc55157a351090a73e7ae77cf581f69b0b6e48fb066c984879a6ed7d2e96': + print('xci_header_key: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + return startup + + +def gen_nsp_header(files,fileSizes): + ''' + for i in range(len(files)): + print (files[i]) + print (fileSizes[i]) + ''' + filesNb = len(files) + stringTable = '\x00'.join(str(nca) for nca in files) + headerSize = 0x10 + (filesNb)*0x18 + len(stringTable) + remainder = 0x10 - headerSize%0x10 + headerSize += remainder + + fileOffsets = [sum(fileSizes[:n]) for n in range(filesNb)] + + fileNamesLengths = [len(str(nca))+1 for nca in files] # +1 for the \x00 + stringTableOffsets = [sum(fileNamesLengths[:n]) for n in range(filesNb)] + + header = b'' + header += b'PFS0' + header += pk(' Date: Mon, 8 Jul 2019 23:49:26 +0200 Subject: [PATCH 10/13] v0.87c --- py/English CHANGELOG.txt | 13 +++++++++++++ py/NSCB.bat | 2 +- py/NSCB_KR.bat | 2 +- py/ztools/LEGACY.bat | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/py/English CHANGELOG.txt b/py/English CHANGELOG.txt index c60a2aa2..4b3eedd9 100644 --- a/py/English CHANGELOG.txt +++ b/py/English CHANGELOG.txt @@ -21,6 +21,19 @@ Luca Fraga's github: https://github.com/LucaFraga --------------- 0. Changelog --------------- +v0.87c- Bugfixes + - Adds check for correct original titlekey for xci conversions from nsx files without + a titlekey. + - Fixes bug when RSV check progress bar multiplies when checking dlc unlockers + - Fixes message "needs RSV check" for non meta files in community-made nca files + (They still won't verify in level2 since they won't have a proper signature1) + - Adds name sanitizing after romaji conversion + - Improves blankspace removal after romaji conversion + - Adds all roman numbers to the bad character list, they will be replaced by it's + multicharacter equivalent. + Example: Assasin's Creed 3 uses the Ⅲ character which corresponds to 1 character. + This is replaced for III which corresponds for 3 characters + - Fixes message "master_key_08 is present but program doesn't have the hash to verify the key" v0.87- Sanitation of names, romaji convertion and improvements in verification - Automated removal of bad characters on names in direct-multi function - Added option to convert japanese and asian names to romaji in direct-multi name diff --git a/py/NSCB.bat b/py/NSCB.bat index 15c41546..c53c9a28 100644 --- a/py/NSCB.bat +++ b/py/NSCB.bat @@ -3,7 +3,7 @@ set "prog_dir=%~dp0" set "bat_name=%~n0" set "ofile_name=%bat_name%_options.cmd" -Title NSC_Builder v0.87 -- Profile: %ofile_name% -- by JulesOnTheRoad +Title NSC_Builder v0.87c -- Profile: %ofile_name% -- by JulesOnTheRoad set "list_folder=%prog_dir%lists" ::----------------------------------------------------- ::EDIT THIS VARIABLE TO LINK OTHER OPTION FILE diff --git a/py/NSCB_KR.bat b/py/NSCB_KR.bat index 5f3be52a..52d8cbf9 100644 --- a/py/NSCB_KR.bat +++ b/py/NSCB_KR.bat @@ -3,7 +3,7 @@ set "prog_dir=%~dp0" set "bat_name=%~n0" set "ofile_name=%bat_name%_options.cmd" -Title NSC_Builder v0.86.e -- Profile: %ofile_name% -- by JulesOnTheRoad +Title NSC_Builder v0.87.c -- Profile: %ofile_name% -- by JulesOnTheRoad set "list_folder=%prog_dir%lists" ::----------------------------------------------------- ::이 옵션을 다른 옵션 파일과 연결되도록 편집하십시오. diff --git a/py/ztools/LEGACY.bat b/py/ztools/LEGACY.bat index 38e38b80..6a45a3f0 100644 --- a/py/ztools/LEGACY.bat +++ b/py/ztools/LEGACY.bat @@ -2,7 +2,7 @@ :TOP_INIT CD /d "%prog_dir%" set "bat_name=%~n0" -Title NSC_Builder v0.87 -- Profile: %ofile_name% -- by JulesOnTheRoad +Title NSC_Builder v0.87c -- Profile: %ofile_name% -- by JulesOnTheRoad ::Check if user is dragging a folder or a file if "%~1"=="" goto manual From 475ba8b61adb205350e6dc8036c3ae0ab4aa0d6e Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Mon, 8 Jul 2019 23:56:22 +0200 Subject: [PATCH 11/13] Revert "Fixes bug when verifying keys.txt" This reverts commit ddbff73dd536b890f8c176fdaf0499b41fef8e6d. --- py/ztools/lib/sq_tools.py | 2170 +++++++++++++++++++------------------ 1 file changed, 1088 insertions(+), 1082 deletions(-) diff --git a/py/ztools/lib/sq_tools.py b/py/ztools/lib/sq_tools.py index fc3fef6c..d8e59e02 100644 --- a/py/ztools/lib/sq_tools.py +++ b/py/ztools/lib/sq_tools.py @@ -1,1082 +1,1088 @@ -import random -import os, codecs -import Hex -from binascii import hexlify as hx, unhexlify as uhx -import Keys -import re -from hashlib import sha256 -from struct import pack as pk, unpack as upk -import Fs -import aes128 -import sq_tools -indent = 1 -tabs = '\t' * indent -''' -versions = - 0: "1.0.0", -> keygeneration = 0 - 450: "1.0.0", -> keygeneration = 0 - 65536: "2.0.0", -> keygeneration = 1 - 131072: "2.1.0", -> keygeneration = 1 - 196608: "2.2.0", -> keygeneration = 1 - 262144: "2.3.0", -> keygeneration = 1 - 201326592: "3.0.0", -> keygeneration = 2 - 201392128: "3.0.1", -> keygeneration = 3 - 201457664: "3.0.2", -> keygeneration = 3 - 268435456: "4.0.0", -> keygeneration = 4 - 268500992: "4.0.1", -> keygeneration = 4 - 269484032: "4.1.0", -> keygeneration = 4 - 335544320: "5.0.0", -> keygeneration = 5 - 335609856: "5.0.1", -> keygeneration = 5 - 335675392: "5.0.2", -> keygeneration = 5 - 336592896: "5.1.0", -> keygeneration = 5 - 402653184: "6.0.0", -> keygeneration = 6 - 402718720: "6.0.1", -> keygeneration = 6 - 403701760: "6.1.0", -> keygeneration = 6 - 404750336: "6.2.0" -> keygeneration = 7 - 469762048: "7.0.0" -> keygeneration = 8 - 469827584: "7.0.1" -> keygeneration = 8 - 536870912: "8.0.0" -> keygeneration = 8 - 536936448: "8.0.1" -> keygeneration = 8 - 537919488: "8.1.0" -> keygeneration = 9 -''' -def kgstring(kg=list()): - kg=list() - kg9=[537919488];kg.append(kg9) - kg8=[536936448,536870912,469827584,469762048];kg.append(kg8) - kg7=[404750336];kg.append(kg7) - kg6=[403701760,402718720,402653184];kg.append(kg6) - kg5=[336592896,335675392,335609856,335544320];kg.append(kg5) - kg4=[269484032,268500992,268435456];kg.append(kg4) - kg3=[201457664,201392128];kg.append(kg3) - kg2=[201326592];kg.append(kg2) - kg1=[262144,196608,131072,65536];kg.append(kg1) - kg0=[450,0];kg.append(kg0) - return kg - -def getTopRSV(keygeneration, RSV): - if keygeneration == 0: - return 450 - if keygeneration == 1: - return 262164 - if keygeneration == 2: - return 201327002 - if keygeneration == 3: - return 201457684 - if keygeneration == 4: - return 269484082 - if keygeneration == 5: - return 336592976 - if keygeneration == 6: - return 403701850 - if keygeneration == 7: - return 404750376 - if keygeneration == 8: - return 536936448 - if keygeneration == 9: - return 537919488 - else: - return RSV - -def getMinRSV(keygeneration, RSV): - if keygeneration == 0: - return 0 - if keygeneration == 1: - return 65796 - if keygeneration == 2: - RSV=3*67108864 - return RSV - if keygeneration == 3: - RSV=3*67108864+1*65536 - return RSV - if keygeneration == 4: - RSV=4*67108864 - return RSV - if keygeneration == 5: - RSV=5*67108864 - return RSV - if keygeneration == 6: - RSV=6*67108864 - return RSV - if keygeneration == 7: - RSV=6*67108864+2*1048576 - return RSV - if keygeneration == 8: - RSV=7*67108864 - return RSV - if keygeneration == 9: - RSV=8*67108864+1*1048576 - return RSV - else: - return RSV - -def getFWRangeKG(keygeneration): - if keygeneration == 0: - return "(1.0.0)" - if keygeneration == 1: - return "(2.0.0 - 2.3.0)" - if keygeneration == 2: - return "(3.0.0)" - if keygeneration == 3: - return "(3.0.1 - 3.0.2)" - if keygeneration == 4: - return "(4.0.0 - 4.1.0)" - if keygeneration == 5: - return "(5.0.0 - 5.1.0)" - if keygeneration == 6: - return "(6.0.0 - 6.1.0)" - if keygeneration == 7: - return "(6.2.0)" - if keygeneration == 8: - return "(7.0.0 - 8.0.1)" - if keygeneration == 9: - return "(8.1.0 - >8.1.0)" - else: - return "UNKNOWN" - -def getFWRangeRSV(RSV): - if RSV >= (3*67108864): - RSV=int(RSV) - frst_num=str(int(RSV/67108864)) - remainder=RSV%67108864 - sec_num=str(int(remainder/1048576)) - remainder=remainder%1048576 - thd_num=str(int(remainder/65536)) - remainder=remainder%65536 - fth_num=remainder - version=str(frst_num) - version+='.' - version+=str(sec_num) - version+='.' - version+=str(thd_num) - if fth_num > 0: - version+='-' - version+=str(fth_num) - version="("+version+")" - return version - elif RSV >= 65536: - RSV=int(RSV) - frst_num=2 - sec_num=str(int(RSV/65536)) - remainder=RSV%65536 - thd_num=0 - fth_num=remainder - version=str(frst_num) - version+='.' - version+=str(sec_num) - version+='.' - version+=str(thd_num) - if fth_num > 0: - version+='-' - version+=str(fth_num) - version="("+version+")" - return version - elif RSV > 0: - RSV=int(RSV) - frst_num=1 - sec_num=0 - thd_num=0 - remainder=RSV%65536 - fth_num=remainder - version=str(frst_num) - version+='.' - version+=str(sec_num) - version+='.' - version+=str(thd_num) - if fth_num > 0: - version+='-' - version+=str(fth_num) - version="("+version+")" - return version - elif RSV == 0: - return "(1.0.0)" - else: - return "(-)" - -def getSize(bytes): - if bytes>(1024*1024*1024): - Gbytes=bytes/(1024*1024*1024) - Gbytes=round(Gbytes,2) - Gbytes=str(Gbytes)+"GB" - return Gbytes - if bytes>(1024*1024): - Mbytes=bytes/(1024*1024) - Mbytes=round(Mbytes,2) - Mbytes=str(Mbytes)+"MB" - return Mbytes - if bytes>(1024): - Kbytes=bytes/(1024) - Kbytes=round(Kbytes,2) - Kbytes=str(Kbytes)+"KB" - return Kbytes - else: - bytes=str(bytes)+"B" - return bytes - -def getGCsize(bytes): - Gbytes=bytes/(1024*1024*1024) - Gbytes=round(Gbytes,2) - if Gbytes>=32: - card=0xE3 - firm_ver='1000a100' - return card,firm_ver - if Gbytes>=16: - card=0xE2 - firm_ver='1000a100' - return card,firm_ver - if Gbytes>=8: - card=0xE1 - firm_ver='1000a100' - return card,firm_ver - if Gbytes>=4: - card=0xE0 - firm_ver='1000a100' - return card,firm_ver - if Gbytes>=2: - card=0xF0 - firm_ver='1100a100' - return card,firm_ver - if Gbytes>=1: - card=0xF8 - firm_ver='1100a100' - return card,firm_ver - if Gbytes<1: - card=0xFA - firm_ver='1100a100' - return card,firm_ver - -def getTypeFromCNMT(number): - if number == 0: - return "Meta: " - if number == 1: - return "Program: " - if number == 2: - return "Data: " - if number == 3: - return "Control: " - if number == 4: - return "HtmlDoc: " - if number == 5: - return "LegalInf: " - if number == 6: - return "Delta: " - - -def randhex(size): - hexdigits = "0123456789ABCDEF" - random_digits = "".join([ hexdigits[random.randint(0,0xF)] for _ in range(size*2) ]) - return random_digits - -def get_enc_gameinfo(bytes): - Gbytes=bytes/(1024*1024*1024) - Gbytes=round(Gbytes,2) - if Gbytes>=32 or Gbytes>=16 or Gbytes>=8 or Gbytes>=4: - firm_ver= 0x9298F35088F09F7D - access_freq= 0xa89a60d4 - Read_Wait_Time= 0xcba6f96f - Read_Wait_Time2= 0xa45bb6ac - Write_Wait_Time= 0xabc751f9 - Write_Wait_Time2= 0x5d398742 - Firmware_Mode = 0x6b38c3f2 - CUP_Version = 0x10da0b70 - Empty1 = 0x0e5ece29 - Upd_Hash= 0xa13cbe1da6d052cb - CUP_Id = 0xf2087ce9af590538 - Empty2= 0x570d78b9cdd27fbeb4a0ac2adff9ba77754dd6675ac76223506b3bdabcb2e212fa465111ab7d51afc8b5b2b21c4b3f40654598620282add6 - else: - firm_ver= 0x9109FF82971EE993 - access_freq=0x5011ca06 - Read_Wait_Time=0x3f3c4d87 - Read_Wait_Time2=0xa13d28a9 - Write_Wait_Time=0x928d74f1 - Write_Wait_Time2=0x49919eb7 - Firmware_Mode =0x82e1f0cf - CUP_Version = 0xe4a5a3bd - Empty1 = 0xf978295c - Upd_Hash= 0xd52639a4991bdb1f - CUP_Id = 0xed841779a3f85d23 - Empty2= 0xaa4242135616f5187c03cf0d97e5d218fdb245381fd1cf8dfb796fbeda4bf7f7d6b128ce89bc9eaa8552d42f597c5db866c67bb0dd8eea11 - - firm_ver=firm_ver.to_bytes(8, byteorder='big') - access_freq=access_freq.to_bytes(4, byteorder='big') - Read_Wait_Time=Read_Wait_Time.to_bytes(4, byteorder='big') - Read_Wait_Time2=Read_Wait_Time2.to_bytes(4, byteorder='big') - Write_Wait_Time=Write_Wait_Time.to_bytes(4, byteorder='big') - Write_Wait_Time2=Write_Wait_Time2.to_bytes(4, byteorder='big') - Firmware_Mode=Firmware_Mode.to_bytes(4, byteorder='big') - CUP_Version=CUP_Version.to_bytes(4, byteorder='big') - Empty1=Empty1.to_bytes(4, byteorder='big') - Upd_Hash=Upd_Hash.to_bytes(8, byteorder='big') - CUP_Id=CUP_Id.to_bytes(8, byteorder='big') - Empty2=Empty2.to_bytes(56, byteorder='big') - - Game_info = b'' - Game_info += firm_ver - Game_info += access_freq - Game_info += Read_Wait_Time - Game_info += Read_Wait_Time2 - Game_info += Write_Wait_Time - Game_info += Write_Wait_Time2 - Game_info += Firmware_Mode - Game_info += CUP_Version - Game_info += Empty1 - Game_info += Upd_Hash - Game_info += CUP_Id - Game_info += Empty2 - - #print(Game_info) - return Game_info - -def get_krypto_block(keygeneration): - if keygeneration == 0: - return 'f3cbc0052cac528adf9129210f0a02e4' - if keygeneration == 1: - return 'f3cbc0052cac528adf9129210f0a02e4' - if keygeneration == 2: - return '789800b9e78b860eec2f7862ef05545e' - if keygeneration == 3: - return '99776e03a21f56232d056b8683d9c681' - if keygeneration == 4: - return '48df2c73957fa1b73b8e33fb2d052512' - if keygeneration == 5: - return '91dea3589a56e4fa1ce60a444009e7d8' - if keygeneration == 6: - return 'cd5b0d1abcf6450f37b8a3b68a15d5e9' - if keygeneration == 7: - return 'e7ae8f7303809fd63cbd1f500b31d5b9' - else: - return "UNKNOWN" - -def verify_nkeys(fileName): - indent = 1 - tabs = ' ' * indent - checkkeys = {} - with open(fileName, encoding="utf8") as f: - for line in f.readlines(): - r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) - if r: - checkkeys[r.group(1)] = r.group(2) - print("") - - if 'aes_kek_generation_source' not in checkkeys: - print("aes_kek_generation_source is Missing") - if 'aes_key_generation_source' not in checkkeys: - print("aes_key_generation_source is Missing") - if 'titlekek_source' not in checkkeys: - print("titlekek_source is Missing") - if 'key_area_key_application_source' not in checkkeys: - print("key_area_key_application_source is Missing") - if 'key_area_key_ocean_source' not in checkkeys: - print("key_area_key_ocean_source is Missing") - if 'key_area_key_system_source' not in checkkeys: - print("key_area_key_system_source is Missing") - counter=0 - if 'master_key_00' not in checkkeys: - print("master_key_00 is Missing") - else: - counter+=1 - if 'master_key_01' not in checkkeys: - print("master_key_01 is Missing") - else: - counter+=1 - if 'master_key_02' not in checkkeys: - print("master_key_02 is Missing") - else: - counter+=1 - if 'master_key_03' not in checkkeys: - print("master_key_03 is Missing") - else: - counter+=1 - if 'master_key_04' not in checkkeys: - print("master_key_04 is Missing") - else: - counter+=1 - if 'master_key_05' not in checkkeys: - print("master_key_05 is Missing") - else: - counter+=1 - if 'master_key_06' not in checkkeys: - print("master_key_06 is Missing") - else: - counter+=1 - if 'master_key_07' not in checkkeys: - print("master_key_07 is Missing") - else: - counter+=1 - - if 'header_key' not in checkkeys: - print("header_key is Missing") - if 'xci_header_key' not in checkkeys: - print('OPTIONAL KEY "xci_header_key" is Missing') - - while counter HEX SHA256: '+sha) - print('') - counter+=1 - - for i in checkkeys: - - if i == 'aes_kek_generation_source': - aes_kek_generation_source =checkkeys[i][:] - print('aes_kek_generation_source : '+aes_kek_generation_source ) - sha=sha256(uhx(aes_kek_generation_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'fc02b9d37b42d7a1452e71444f1f700311d1132e301a83b16062e72a78175085': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'aes_key_generation_source': - aes_key_generation_source =checkkeys[i][:] - print('aes_key_generation_source : '+aes_key_generation_source ) - sha=sha256(uhx(aes_key_generation_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'fbd10056999edc7acdb96098e47e2c3606230270d23281e671f0f389fc5bc585': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'titlekek_source': - titlekek_source=checkkeys[i][:] - print('titlekek_source: '+titlekek_source) - sha=sha256(uhx(titlekek_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'c48b619827986c7f4e3081d59db2b460c84312650e9a8e6b458e53e8cbca4e87': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'key_area_key_application_source': - key_area_key_application_source=checkkeys[i][:] - print('key_area_key_application_source: '+key_area_key_application_source) - sha=sha256(uhx(key_area_key_application_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '04ad66143c726b2a139fb6b21128b46f56c553b2b3887110304298d8d0092d9e': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'key_area_key_ocean_source': - key_area_key_ocean_source=checkkeys[i][:] - print('key_area_key_ocean_source: '+key_area_key_ocean_source) - sha=sha256(uhx(key_area_key_ocean_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'fd434000c8ff2b26f8e9a9d2d2c12f6be5773cbb9dc86300e1bd99f8ea33a417': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'key_area_key_system_source': - key_area_key_system_source=checkkeys[i][:] - print('key_area_key_system_source: '+key_area_key_system_source) - sha=sha256(uhx(key_area_key_system_source)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '1f17b1fd51ad1c2379b58f152ca4912ec2106441e51722f38700d5937a1162f7': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_00': - master_key_00=checkkeys[i][:] - print('master_key_00: '+master_key_00) - sha=sha256(uhx(master_key_00)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '0ee359be3c864bb0782e1d70a718a0342c551eed28c369754f9c4f691becf7ca': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_01': - master_key_01=checkkeys[i][:] - print('master_key_01: '+master_key_01) - sha=sha256(uhx(master_key_01)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '4fe707b7e4abdaf727c894aaf13b1351bfe2ac90d875f73b2e20fa94b9cc661e': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_02': - master_key_02=checkkeys[i][:] - print('master_key_02: '+master_key_02) - sha=sha256(uhx(master_key_02)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '79277c0237a2252ec3dfac1f7c359c2b3d121e9db15bb9ab4c2b4408d2f3ae09': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_03': - master_key_03=checkkeys[i][:] - print('master_key_03: '+master_key_03) - sha=sha256(uhx(master_key_03)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '4f36c565d13325f65ee134073c6a578ffcb0008e02d69400836844eab7432754': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_04': - master_key_04=checkkeys[i][:] - print('master_key_04: '+master_key_04) - sha=sha256(uhx(master_key_04)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '75ff1d95d26113550ee6fcc20acb58e97edeb3a2ff52543ed5aec63bdcc3da50': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_05': - master_key_05=checkkeys[i][:] - print('master_key_05: '+master_key_05) - sha=sha256(uhx(master_key_05)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == 'ebe2bcd6704673ec0f88a187bb2ad9f1cc82b718c389425941bdc194dc46b0dd': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_06': - master_key_06=checkkeys[i][:] - print('master_key_06: '+master_key_06) - sha=sha256(uhx(master_key_06)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '9497e6779f5d840f2bba1de4e95ba1d6f21efc94717d5ae5ca37d7ec5bd37a19': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_07': - master_key_07=checkkeys[i][:] - print('master_key_07: '+master_key_07) - sha=sha256(uhx(master_key_07)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '4ec96b8cb01b8dce382149443430b2b6ebcb2983348afa04a25e53609dabedf6': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'master_key_08': - master_key_08=checkkeys[i][:] - print('master_key_08: '+master_key_08) - sha=sha256(uhx(master_key_08)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '2998e2e23609bc2675ff062a2d64af5b1b78dff463b24119d64a1b64f01b2d51': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'header_key': - header_key=checkkeys[i][:] - print('header_key: '+header_key) - sha=sha256(uhx(header_key)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '8e03de24818d96ce4f2a09b43af979e679974f7570713a61eed8b314864a11d5': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - - if i == 'xci_header_key': - xci_header_key=checkkeys[i][:] - print('xci_header_key: '+xci_header_key) - sha=sha256(uhx(xci_header_key)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha == '2e36cc55157a351090a73e7ae77cf581f69b0b6e48fb066c984879a6ed7d2e96': - print(tabs+'> Key is valid!!!') - else: - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - print('') - -def verify_nkeys_startup(fileName): - indent = 1 - tabs = ' ' * indent - checkkeys = {} - startup=False - with open(fileName, encoding="utf8") as f: - for line in f.readlines(): - r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) - if r: - checkkeys[r.group(1)] = r.group(2) - print("") - - if 'aes_kek_generation_source' not in checkkeys: - print("aes_kek_generation_source is Missing") - print("This is a needed key!!!") - startup=True - if 'aes_key_generation_source' not in checkkeys: - print("aes_key_generation_source is Missing") - print("This is a needed key!!!") - startup=True - if 'titlekek_source' not in checkkeys: - print("titlekek_source is Missing") - print("This is a needed key!!!") - startup=True - if 'key_area_key_application_source' not in checkkeys: - print("key_area_key_application_source is Missing") - print("This is a needed key!!!") - startup=True - if 'key_area_key_ocean_source' not in checkkeys: - print("key_area_key_ocean_source is Missing") - print("This is a needed key!!!") - startup=True - if 'key_area_key_system_source' not in checkkeys: - print("key_area_key_system_source is Missing") - print("This is a needed key!!!") - startup=True - counter=0 - if 'master_key_00' not in checkkeys: - print("master_key_00 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 1.0.0-2.3.0 requirement") - startup=True - else: - counter+=1 - if 'master_key_01' not in checkkeys: - print("master_key_01 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 3.0.0 requirement") - startup=True - else: - counter+=1 - if 'master_key_02' not in checkkeys: - print("master_key_02 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 3.0.1-3.0.2 requirement") - startup=True - else: - counter+=1 - if 'master_key_03' not in checkkeys: - print("master_key_03 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 4.0.0-4.0.1 requirement") - startup=True - else: - counter+=1 - if 'master_key_04' not in checkkeys: - print("master_key_04 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 5.0.0-5.1.0 requirement") - startup=True - else: - counter+=1 - if 'master_key_05' not in checkkeys: - print("master_key_05 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 6.0.0-6.1.0 requirement") - startup=True - else: - counter+=1 - if 'master_key_06' not in checkkeys: - print("master_key_06 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 6.2.0 requirement") - startup=True - if 'master_key_07' not in checkkeys: - print("master_key_07 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 7.0.0-8.0.1 requirement") - startup=True - if 'master_key_08' not in checkkeys: - print("master_key_08 is Missing!!!") - print("The program won't be able to decrypt games content that uses this key") - print("This key represents FW 8.1 requirement") - startup=True - else: - counter+=1 - - if 'header_key' not in checkkeys: - print("header_key is Missing") - if 'xci_header_key' not in checkkeys: - print('OPTIONAL KEY "xci_header_key" is Missing') - - while counter HEX SHA256: '+sha) - print('') - counter+=1 - - for i in checkkeys: - - if i == 'aes_kek_generation_source': - aes_kek_generation_source =checkkeys[i][:] - sha=sha256(uhx(aes_kek_generation_source)).hexdigest() - if sha != 'fc02b9d37b42d7a1452e71444f1f700311d1132e301a83b16062e72a78175085': - print('aes_kek_generation_source : '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'aes_key_generation_source': - aes_key_generation_source =checkkeys[i][:] - sha=sha256(uhx(aes_key_generation_source)).hexdigest() - if sha != 'fbd10056999edc7acdb96098e47e2c3606230270d23281e671f0f389fc5bc585': - print('aes_key_generation_source : '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'titlekek_source': - titlekek_source=checkkeys[i][:] - sha=sha256(uhx(titlekek_source)).hexdigest() - if sha != 'c48b619827986c7f4e3081d59db2b460c84312650e9a8e6b458e53e8cbca4e87': - print('titlekek_source : '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'key_area_key_application_source': - key_area_key_application_source=checkkeys[i][:] - sha=sha256(uhx(key_area_key_application_source)).hexdigest() - if sha != '04ad66143c726b2a139fb6b21128b46f56c553b2b3887110304298d8d0092d9e': - print('key_area_key_application_source: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'key_area_key_ocean_source': - key_area_key_ocean_source=checkkeys[i][:] - sha=sha256(uhx(key_area_key_ocean_source)).hexdigest() - if sha != 'fd434000c8ff2b26f8e9a9d2d2c12f6be5773cbb9dc86300e1bd99f8ea33a417': - print('key_area_key_ocean_source: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'key_area_key_system_source': - key_area_key_system_source=checkkeys[i][:] - sha=sha256(uhx(key_area_key_system_source)).hexdigest() - if sha != '1f17b1fd51ad1c2379b58f152ca4912ec2106441e51722f38700d5937a1162f7': - print('key_area_key_system_source: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_00': - master_key_00=checkkeys[i][:] - sha=sha256(uhx(master_key_00)).hexdigest() - if sha != '0ee359be3c864bb0782e1d70a718a0342c551eed28c369754f9c4f691becf7ca': - print('master_key_00: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_01': - master_key_01=checkkeys[i][:] - sha=sha256(uhx(master_key_01)).hexdigest() - if sha != '4fe707b7e4abdaf727c894aaf13b1351bfe2ac90d875f73b2e20fa94b9cc661e': - print('master_key_01: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_02': - master_key_02=checkkeys[i][:] - sha=sha256(uhx(master_key_02)).hexdigest() - if sha != '79277c0237a2252ec3dfac1f7c359c2b3d121e9db15bb9ab4c2b4408d2f3ae09': - print('master_key_02: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_03': - master_key_03=checkkeys[i][:] - sha=sha256(uhx(master_key_03)).hexdigest() - if sha != '4f36c565d13325f65ee134073c6a578ffcb0008e02d69400836844eab7432754': - print('master_key_03: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_04': - master_key_04=checkkeys[i][:] - sha=sha256(uhx(master_key_04)).hexdigest() - if sha != '75ff1d95d26113550ee6fcc20acb58e97edeb3a2ff52543ed5aec63bdcc3da50': - print('master_key_04: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_05': - master_key_05=checkkeys[i][:] - sha=sha256(uhx(master_key_05)).hexdigest() - if sha != 'ebe2bcd6704673ec0f88a187bb2ad9f1cc82b718c389425941bdc194dc46b0dd': - print('master_key_05: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_06': - master_key_06=checkkeys[i][:] - print('master_key_06: '+master_key_06) - sha=sha256(uhx(master_key_06)).hexdigest() - print(' > HEX SHA256: '+sha) - if sha != '9497e6779f5d840f2bba1de4e95ba1d6f21efc94717d5ae5ca37d7ec5bd37a19': - print('master_key_06: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_07': - master_key_07=checkkeys[i][:] - sha=sha256(uhx(master_key_07)).hexdigest() - if sha != '4ec96b8cb01b8dce382149443430b2b6ebcb2983348afa04a25e53609dabedf6': - print('master_key_07: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'master_key_08': - master_key_08=checkkeys[i][:] - sha=sha256(uhx(master_key_08)).hexdigest() - if sha != '2998e2e23609bc2675ff062a2d64af5b1b78dff463b24119d64a1b64f01b2d51': - print('master_key_07: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'header_key': - header_key=checkkeys[i][:] - sha=sha256(uhx(header_key)).hexdigest() - if sha != '8e03de24818d96ce4f2a09b43af979e679974f7570713a61eed8b314864a11d5': - print('header_key: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - if i == 'xci_header_key': - xci_header_key=checkkeys[i][:] - sha=sha256(uhx(xci_header_key)).hexdigest() - if sha != '2e36cc55157a351090a73e7ae77cf581f69b0b6e48fb066c984879a6ed7d2e96': - print('xci_header_key: '+aes_kek_generation_source ) - print(' > HEX SHA256: '+sha) - print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') - startup=True - print('') - - return startup - - -def gen_nsp_header(files,fileSizes): - ''' - for i in range(len(files)): - print (files[i]) - print (fileSizes[i]) - ''' - filesNb = len(files) - stringTable = '\x00'.join(str(nca) for nca in files) - headerSize = 0x10 + (filesNb)*0x18 + len(stringTable) - remainder = 0x10 - headerSize%0x10 - headerSize += remainder - - fileOffsets = [sum(fileSizes[:n]) for n in range(filesNb)] - - fileNamesLengths = [len(str(nca))+1 for nca in files] # +1 for the \x00 - stringTableOffsets = [sum(fileNamesLengths[:n]) for n in range(filesNb)] - - header = b'' - header += b'PFS0' - header += pk(' keygeneration = 0 + 450: "1.0.0", -> keygeneration = 0 + 65536: "2.0.0", -> keygeneration = 1 + 131072: "2.1.0", -> keygeneration = 1 + 196608: "2.2.0", -> keygeneration = 1 + 262144: "2.3.0", -> keygeneration = 1 + 201326592: "3.0.0", -> keygeneration = 2 + 201392128: "3.0.1", -> keygeneration = 3 + 201457664: "3.0.2", -> keygeneration = 3 + 268435456: "4.0.0", -> keygeneration = 4 + 268500992: "4.0.1", -> keygeneration = 4 + 269484032: "4.1.0", -> keygeneration = 4 + 335544320: "5.0.0", -> keygeneration = 5 + 335609856: "5.0.1", -> keygeneration = 5 + 335675392: "5.0.2", -> keygeneration = 5 + 336592896: "5.1.0", -> keygeneration = 5 + 402653184: "6.0.0", -> keygeneration = 6 + 402718720: "6.0.1", -> keygeneration = 6 + 403701760: "6.1.0", -> keygeneration = 6 + 404750336: "6.2.0" -> keygeneration = 7 + 469762048: "7.0.0" -> keygeneration = 8 + 469827584: "7.0.1" -> keygeneration = 8 + 536870912: "8.0.0" -> keygeneration = 8 + 536936448: "8.0.1" -> keygeneration = 8 + 537919488: "8.1.0" -> keygeneration = 9 +''' +def kgstring(kg=list()): + kg=list() + kg9=[537919488];kg.append(kg9) + kg8=[536936448,536870912,469827584,469762048];kg.append(kg8) + kg7=[404750336];kg.append(kg7) + kg6=[403701760,402718720,402653184];kg.append(kg6) + kg5=[336592896,335675392,335609856,335544320];kg.append(kg5) + kg4=[269484032,268500992,268435456];kg.append(kg4) + kg3=[201457664,201392128];kg.append(kg3) + kg2=[201326592];kg.append(kg2) + kg1=[262144,196608,131072,65536];kg.append(kg1) + kg0=[450,0];kg.append(kg0) + return kg + +def kg2masterkey(kg): + if kg == 1: + return 1 + else: + return kg-1 + +def getTopRSV(keygeneration, RSV): + if keygeneration == 0: + return 450 + if keygeneration == 1: + return 262164 + if keygeneration == 2: + return 201327002 + if keygeneration == 3: + return 201457684 + if keygeneration == 4: + return 269484082 + if keygeneration == 5: + return 336592976 + if keygeneration == 6: + return 403701850 + if keygeneration == 7: + return 404750376 + if keygeneration == 8: + return 536936448 + if keygeneration == 9: + return 537919488 + else: + return RSV + +def getMinRSV(keygeneration, RSV): + if keygeneration == 0: + return 0 + if keygeneration == 1: + return 65796 + if keygeneration == 2: + RSV=3*67108864 + return RSV + if keygeneration == 3: + RSV=3*67108864+1*65536 + return RSV + if keygeneration == 4: + RSV=4*67108864 + return RSV + if keygeneration == 5: + RSV=5*67108864 + return RSV + if keygeneration == 6: + RSV=6*67108864 + return RSV + if keygeneration == 7: + RSV=6*67108864+2*1048576 + return RSV + if keygeneration == 8: + RSV=7*67108864 + return RSV + if keygeneration == 9: + RSV=8*67108864+1*1048576 + return RSV + else: + return RSV + +def getFWRangeKG(keygeneration): + if keygeneration == 0: + return "(1.0.0)" + if keygeneration == 1: + return "(2.0.0 - 2.3.0)" + if keygeneration == 2: + return "(3.0.0)" + if keygeneration == 3: + return "(3.0.1 - 3.0.2)" + if keygeneration == 4: + return "(4.0.0 - 4.1.0)" + if keygeneration == 5: + return "(5.0.0 - 5.1.0)" + if keygeneration == 6: + return "(6.0.0 - 6.1.0)" + if keygeneration == 7: + return "(6.2.0)" + if keygeneration == 8: + return "(7.0.0 - 8.0.1)" + if keygeneration == 9: + return "(8.1.0 - >8.1.0)" + else: + return "UNKNOWN" + +def getFWRangeRSV(RSV): + if RSV >= (3*67108864): + RSV=int(RSV) + frst_num=str(int(RSV/67108864)) + remainder=RSV%67108864 + sec_num=str(int(remainder/1048576)) + remainder=remainder%1048576 + thd_num=str(int(remainder/65536)) + remainder=remainder%65536 + fth_num=remainder + version=str(frst_num) + version+='.' + version+=str(sec_num) + version+='.' + version+=str(thd_num) + if fth_num > 0: + version+='-' + version+=str(fth_num) + version="("+version+")" + return version + elif RSV >= 65536: + RSV=int(RSV) + frst_num=2 + sec_num=str(int(RSV/65536)) + remainder=RSV%65536 + thd_num=0 + fth_num=remainder + version=str(frst_num) + version+='.' + version+=str(sec_num) + version+='.' + version+=str(thd_num) + if fth_num > 0: + version+='-' + version+=str(fth_num) + version="("+version+")" + return version + elif RSV > 0: + RSV=int(RSV) + frst_num=1 + sec_num=0 + thd_num=0 + remainder=RSV%65536 + fth_num=remainder + version=str(frst_num) + version+='.' + version+=str(sec_num) + version+='.' + version+=str(thd_num) + if fth_num > 0: + version+='-' + version+=str(fth_num) + version="("+version+")" + return version + elif RSV == 0: + return "(1.0.0)" + else: + return "(-)" + +def getSize(bytes): + if bytes>(1024*1024*1024): + Gbytes=bytes/(1024*1024*1024) + Gbytes=round(Gbytes,2) + Gbytes=str(Gbytes)+"GB" + return Gbytes + if bytes>(1024*1024): + Mbytes=bytes/(1024*1024) + Mbytes=round(Mbytes,2) + Mbytes=str(Mbytes)+"MB" + return Mbytes + if bytes>(1024): + Kbytes=bytes/(1024) + Kbytes=round(Kbytes,2) + Kbytes=str(Kbytes)+"KB" + return Kbytes + else: + bytes=str(bytes)+"B" + return bytes + +def getGCsize(bytes): + Gbytes=bytes/(1024*1024*1024) + Gbytes=round(Gbytes,2) + if Gbytes>=32: + card=0xE3 + firm_ver='1000a100' + return card,firm_ver + if Gbytes>=16: + card=0xE2 + firm_ver='1000a100' + return card,firm_ver + if Gbytes>=8: + card=0xE1 + firm_ver='1000a100' + return card,firm_ver + if Gbytes>=4: + card=0xE0 + firm_ver='1000a100' + return card,firm_ver + if Gbytes>=2: + card=0xF0 + firm_ver='1100a100' + return card,firm_ver + if Gbytes>=1: + card=0xF8 + firm_ver='1100a100' + return card,firm_ver + if Gbytes<1: + card=0xFA + firm_ver='1100a100' + return card,firm_ver + +def getTypeFromCNMT(number): + if number == 0: + return "Meta: " + if number == 1: + return "Program: " + if number == 2: + return "Data: " + if number == 3: + return "Control: " + if number == 4: + return "HtmlDoc: " + if number == 5: + return "LegalInf: " + if number == 6: + return "Delta: " + + +def randhex(size): + hexdigits = "0123456789ABCDEF" + random_digits = "".join([ hexdigits[random.randint(0,0xF)] for _ in range(size*2) ]) + return random_digits + +def get_enc_gameinfo(bytes): + Gbytes=bytes/(1024*1024*1024) + Gbytes=round(Gbytes,2) + if Gbytes>=32 or Gbytes>=16 or Gbytes>=8 or Gbytes>=4: + firm_ver= 0x9298F35088F09F7D + access_freq= 0xa89a60d4 + Read_Wait_Time= 0xcba6f96f + Read_Wait_Time2= 0xa45bb6ac + Write_Wait_Time= 0xabc751f9 + Write_Wait_Time2= 0x5d398742 + Firmware_Mode = 0x6b38c3f2 + CUP_Version = 0x10da0b70 + Empty1 = 0x0e5ece29 + Upd_Hash= 0xa13cbe1da6d052cb + CUP_Id = 0xf2087ce9af590538 + Empty2= 0x570d78b9cdd27fbeb4a0ac2adff9ba77754dd6675ac76223506b3bdabcb2e212fa465111ab7d51afc8b5b2b21c4b3f40654598620282add6 + else: + firm_ver= 0x9109FF82971EE993 + access_freq=0x5011ca06 + Read_Wait_Time=0x3f3c4d87 + Read_Wait_Time2=0xa13d28a9 + Write_Wait_Time=0x928d74f1 + Write_Wait_Time2=0x49919eb7 + Firmware_Mode =0x82e1f0cf + CUP_Version = 0xe4a5a3bd + Empty1 = 0xf978295c + Upd_Hash= 0xd52639a4991bdb1f + CUP_Id = 0xed841779a3f85d23 + Empty2= 0xaa4242135616f5187c03cf0d97e5d218fdb245381fd1cf8dfb796fbeda4bf7f7d6b128ce89bc9eaa8552d42f597c5db866c67bb0dd8eea11 + + firm_ver=firm_ver.to_bytes(8, byteorder='big') + access_freq=access_freq.to_bytes(4, byteorder='big') + Read_Wait_Time=Read_Wait_Time.to_bytes(4, byteorder='big') + Read_Wait_Time2=Read_Wait_Time2.to_bytes(4, byteorder='big') + Write_Wait_Time=Write_Wait_Time.to_bytes(4, byteorder='big') + Write_Wait_Time2=Write_Wait_Time2.to_bytes(4, byteorder='big') + Firmware_Mode=Firmware_Mode.to_bytes(4, byteorder='big') + CUP_Version=CUP_Version.to_bytes(4, byteorder='big') + Empty1=Empty1.to_bytes(4, byteorder='big') + Upd_Hash=Upd_Hash.to_bytes(8, byteorder='big') + CUP_Id=CUP_Id.to_bytes(8, byteorder='big') + Empty2=Empty2.to_bytes(56, byteorder='big') + + Game_info = b'' + Game_info += firm_ver + Game_info += access_freq + Game_info += Read_Wait_Time + Game_info += Read_Wait_Time2 + Game_info += Write_Wait_Time + Game_info += Write_Wait_Time2 + Game_info += Firmware_Mode + Game_info += CUP_Version + Game_info += Empty1 + Game_info += Upd_Hash + Game_info += CUP_Id + Game_info += Empty2 + + #print(Game_info) + return Game_info + +def get_krypto_block(keygeneration): + if keygeneration == 0: + return 'f3cbc0052cac528adf9129210f0a02e4' + if keygeneration == 1: + return 'f3cbc0052cac528adf9129210f0a02e4' + if keygeneration == 2: + return '789800b9e78b860eec2f7862ef05545e' + if keygeneration == 3: + return '99776e03a21f56232d056b8683d9c681' + if keygeneration == 4: + return '48df2c73957fa1b73b8e33fb2d052512' + if keygeneration == 5: + return '91dea3589a56e4fa1ce60a444009e7d8' + if keygeneration == 6: + return 'cd5b0d1abcf6450f37b8a3b68a15d5e9' + if keygeneration == 7: + return 'e7ae8f7303809fd63cbd1f500b31d5b9' + else: + return "UNKNOWN" + +def verify_nkeys(fileName): + indent = 1 + tabs = ' ' * indent + checkkeys = {} + with open(fileName, encoding="utf8") as f: + for line in f.readlines(): + r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) + if r: + checkkeys[r.group(1)] = r.group(2) + print("") + + if 'aes_kek_generation_source' not in checkkeys: + print("aes_kek_generation_source is Missing") + if 'aes_key_generation_source' not in checkkeys: + print("aes_key_generation_source is Missing") + if 'titlekek_source' not in checkkeys: + print("titlekek_source is Missing") + if 'key_area_key_application_source' not in checkkeys: + print("key_area_key_application_source is Missing") + if 'key_area_key_ocean_source' not in checkkeys: + print("key_area_key_ocean_source is Missing") + if 'key_area_key_system_source' not in checkkeys: + print("key_area_key_system_source is Missing") + counter=0 + if 'master_key_00' not in checkkeys: + print("master_key_00 is Missing") + else: + counter+=1 + if 'master_key_01' not in checkkeys: + print("master_key_01 is Missing") + else: + counter+=1 + if 'master_key_02' not in checkkeys: + print("master_key_02 is Missing") + else: + counter+=1 + if 'master_key_03' not in checkkeys: + print("master_key_03 is Missing") + else: + counter+=1 + if 'master_key_04' not in checkkeys: + print("master_key_04 is Missing") + else: + counter+=1 + if 'master_key_05' not in checkkeys: + print("master_key_05 is Missing") + else: + counter+=1 + if 'master_key_06' not in checkkeys: + print("master_key_06 is Missing") + else: + counter+=1 + if 'master_key_07' not in checkkeys: + print("master_key_07 is Missing") + else: + counter+=1 + + if 'header_key' not in checkkeys: + print("header_key is Missing") + if 'xci_header_key' not in checkkeys: + print('OPTIONAL KEY "xci_header_key" is Missing') + + while counter HEX SHA256: '+sha) + print('') + counter+=1 + + for i in checkkeys: + + if i == 'aes_kek_generation_source': + aes_kek_generation_source =checkkeys[i][:] + print('aes_kek_generation_source : '+aes_kek_generation_source ) + sha=sha256(uhx(aes_kek_generation_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'fc02b9d37b42d7a1452e71444f1f700311d1132e301a83b16062e72a78175085': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'aes_key_generation_source': + aes_key_generation_source =checkkeys[i][:] + print('aes_key_generation_source : '+aes_key_generation_source ) + sha=sha256(uhx(aes_key_generation_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'fbd10056999edc7acdb96098e47e2c3606230270d23281e671f0f389fc5bc585': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'titlekek_source': + titlekek_source=checkkeys[i][:] + print('titlekek_source: '+titlekek_source) + sha=sha256(uhx(titlekek_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'c48b619827986c7f4e3081d59db2b460c84312650e9a8e6b458e53e8cbca4e87': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'key_area_key_application_source': + key_area_key_application_source=checkkeys[i][:] + print('key_area_key_application_source: '+key_area_key_application_source) + sha=sha256(uhx(key_area_key_application_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '04ad66143c726b2a139fb6b21128b46f56c553b2b3887110304298d8d0092d9e': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'key_area_key_ocean_source': + key_area_key_ocean_source=checkkeys[i][:] + print('key_area_key_ocean_source: '+key_area_key_ocean_source) + sha=sha256(uhx(key_area_key_ocean_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'fd434000c8ff2b26f8e9a9d2d2c12f6be5773cbb9dc86300e1bd99f8ea33a417': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'key_area_key_system_source': + key_area_key_system_source=checkkeys[i][:] + print('key_area_key_system_source: '+key_area_key_system_source) + sha=sha256(uhx(key_area_key_system_source)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '1f17b1fd51ad1c2379b58f152ca4912ec2106441e51722f38700d5937a1162f7': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_00': + master_key_00=checkkeys[i][:] + print('master_key_00: '+master_key_00) + sha=sha256(uhx(master_key_00)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '0ee359be3c864bb0782e1d70a718a0342c551eed28c369754f9c4f691becf7ca': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_01': + master_key_01=checkkeys[i][:] + print('master_key_01: '+master_key_01) + sha=sha256(uhx(master_key_01)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '4fe707b7e4abdaf727c894aaf13b1351bfe2ac90d875f73b2e20fa94b9cc661e': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_02': + master_key_02=checkkeys[i][:] + print('master_key_02: '+master_key_02) + sha=sha256(uhx(master_key_02)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '79277c0237a2252ec3dfac1f7c359c2b3d121e9db15bb9ab4c2b4408d2f3ae09': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_03': + master_key_03=checkkeys[i][:] + print('master_key_03: '+master_key_03) + sha=sha256(uhx(master_key_03)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '4f36c565d13325f65ee134073c6a578ffcb0008e02d69400836844eab7432754': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_04': + master_key_04=checkkeys[i][:] + print('master_key_04: '+master_key_04) + sha=sha256(uhx(master_key_04)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '75ff1d95d26113550ee6fcc20acb58e97edeb3a2ff52543ed5aec63bdcc3da50': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_05': + master_key_05=checkkeys[i][:] + print('master_key_05: '+master_key_05) + sha=sha256(uhx(master_key_05)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == 'ebe2bcd6704673ec0f88a187bb2ad9f1cc82b718c389425941bdc194dc46b0dd': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_06': + master_key_06=checkkeys[i][:] + print('master_key_06: '+master_key_06) + sha=sha256(uhx(master_key_06)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '9497e6779f5d840f2bba1de4e95ba1d6f21efc94717d5ae5ca37d7ec5bd37a19': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_07': + master_key_07=checkkeys[i][:] + print('master_key_07: '+master_key_07) + sha=sha256(uhx(master_key_07)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '4ec96b8cb01b8dce382149443430b2b6ebcb2983348afa04a25e53609dabedf6': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'master_key_08': + master_key_08=checkkeys[i][:] + print('master_key_08: '+master_key_08) + sha=sha256(uhx(master_key_08)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '2998e2e23609bc2675ff062a2d64af5b1b78dff463b24119d64a1b64f01b2d51': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'header_key': + header_key=checkkeys[i][:] + print('header_key: '+header_key) + sha=sha256(uhx(header_key)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '8e03de24818d96ce4f2a09b43af979e679974f7570713a61eed8b314864a11d5': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + + if i == 'xci_header_key': + xci_header_key=checkkeys[i][:] + print('xci_header_key: '+xci_header_key) + sha=sha256(uhx(xci_header_key)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha == '2e36cc55157a351090a73e7ae77cf581f69b0b6e48fb066c984879a6ed7d2e96': + print(tabs+'> Key is valid!!!') + else: + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + print('') + +def verify_nkeys_startup(fileName): + indent = 1 + tabs = ' ' * indent + checkkeys = {} + startup=False + with open(fileName, encoding="utf8") as f: + for line in f.readlines(): + r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) + if r: + checkkeys[r.group(1)] = r.group(2) + print("") + + if 'aes_kek_generation_source' not in checkkeys: + print("aes_kek_generation_source is Missing") + print("This is a needed key!!!") + startup=True + if 'aes_key_generation_source' not in checkkeys: + print("aes_key_generation_source is Missing") + print("This is a needed key!!!") + startup=True + if 'titlekek_source' not in checkkeys: + print("titlekek_source is Missing") + print("This is a needed key!!!") + startup=True + if 'key_area_key_application_source' not in checkkeys: + print("key_area_key_application_source is Missing") + print("This is a needed key!!!") + startup=True + if 'key_area_key_ocean_source' not in checkkeys: + print("key_area_key_ocean_source is Missing") + print("This is a needed key!!!") + startup=True + if 'key_area_key_system_source' not in checkkeys: + print("key_area_key_system_source is Missing") + print("This is a needed key!!!") + startup=True + counter=0 + if 'master_key_00' not in checkkeys: + print("master_key_00 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 1.0.0-2.3.0 requirement") + startup=True + else: + counter+=1 + if 'master_key_01' not in checkkeys: + print("master_key_01 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 3.0.0 requirement") + startup=True + else: + counter+=1 + if 'master_key_02' not in checkkeys: + print("master_key_02 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 3.0.1-3.0.2 requirement") + startup=True + else: + counter+=1 + if 'master_key_03' not in checkkeys: + print("master_key_03 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 4.0.0-4.0.1 requirement") + startup=True + else: + counter+=1 + if 'master_key_04' not in checkkeys: + print("master_key_04 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 5.0.0-5.1.0 requirement") + startup=True + else: + counter+=1 + if 'master_key_05' not in checkkeys: + print("master_key_05 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 6.0.0-6.1.0 requirement") + startup=True + else: + counter+=1 + if 'master_key_06' not in checkkeys: + print("master_key_06 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 6.2.0 requirement") + startup=True + if 'master_key_07' not in checkkeys: + print("master_key_07 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 7.0.0-8.0.1 requirement") + startup=True + if 'master_key_08' not in checkkeys: + print("master_key_08 is Missing!!!") + print("The program won't be able to decrypt games content that uses this key") + print("This key represents FW 8.1 requirement") + startup=True + else: + counter+=1 + + if 'header_key' not in checkkeys: + print("header_key is Missing") + if 'xci_header_key' not in checkkeys: + print('OPTIONAL KEY "xci_header_key" is Missing') + + while counter HEX SHA256: '+sha) + print('') + counter+=1 + + for i in checkkeys: + + if i == 'aes_kek_generation_source': + aes_kek_generation_source =checkkeys[i][:] + sha=sha256(uhx(aes_kek_generation_source)).hexdigest() + if sha != 'fc02b9d37b42d7a1452e71444f1f700311d1132e301a83b16062e72a78175085': + print('aes_kek_generation_source : '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'aes_key_generation_source': + aes_key_generation_source =checkkeys[i][:] + sha=sha256(uhx(aes_key_generation_source)).hexdigest() + if sha != 'fbd10056999edc7acdb96098e47e2c3606230270d23281e671f0f389fc5bc585': + print('aes_key_generation_source : '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'titlekek_source': + titlekek_source=checkkeys[i][:] + sha=sha256(uhx(titlekek_source)).hexdigest() + if sha != 'c48b619827986c7f4e3081d59db2b460c84312650e9a8e6b458e53e8cbca4e87': + print('titlekek_source : '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'key_area_key_application_source': + key_area_key_application_source=checkkeys[i][:] + sha=sha256(uhx(key_area_key_application_source)).hexdigest() + if sha != '04ad66143c726b2a139fb6b21128b46f56c553b2b3887110304298d8d0092d9e': + print('key_area_key_application_source: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'key_area_key_ocean_source': + key_area_key_ocean_source=checkkeys[i][:] + sha=sha256(uhx(key_area_key_ocean_source)).hexdigest() + if sha != 'fd434000c8ff2b26f8e9a9d2d2c12f6be5773cbb9dc86300e1bd99f8ea33a417': + print('key_area_key_ocean_source: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'key_area_key_system_source': + key_area_key_system_source=checkkeys[i][:] + sha=sha256(uhx(key_area_key_system_source)).hexdigest() + if sha != '1f17b1fd51ad1c2379b58f152ca4912ec2106441e51722f38700d5937a1162f7': + print('key_area_key_system_source: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_00': + master_key_00=checkkeys[i][:] + sha=sha256(uhx(master_key_00)).hexdigest() + if sha != '0ee359be3c864bb0782e1d70a718a0342c551eed28c369754f9c4f691becf7ca': + print('master_key_00: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_01': + master_key_01=checkkeys[i][:] + sha=sha256(uhx(master_key_01)).hexdigest() + if sha != '4fe707b7e4abdaf727c894aaf13b1351bfe2ac90d875f73b2e20fa94b9cc661e': + print('master_key_01: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_02': + master_key_02=checkkeys[i][:] + sha=sha256(uhx(master_key_02)).hexdigest() + if sha != '79277c0237a2252ec3dfac1f7c359c2b3d121e9db15bb9ab4c2b4408d2f3ae09': + print('master_key_02: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_03': + master_key_03=checkkeys[i][:] + sha=sha256(uhx(master_key_03)).hexdigest() + if sha != '4f36c565d13325f65ee134073c6a578ffcb0008e02d69400836844eab7432754': + print('master_key_03: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_04': + master_key_04=checkkeys[i][:] + sha=sha256(uhx(master_key_04)).hexdigest() + if sha != '75ff1d95d26113550ee6fcc20acb58e97edeb3a2ff52543ed5aec63bdcc3da50': + print('master_key_04: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_05': + master_key_05=checkkeys[i][:] + sha=sha256(uhx(master_key_05)).hexdigest() + if sha != 'ebe2bcd6704673ec0f88a187bb2ad9f1cc82b718c389425941bdc194dc46b0dd': + print('master_key_05: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_06': + master_key_06=checkkeys[i][:] + print('master_key_06: '+master_key_06) + sha=sha256(uhx(master_key_06)).hexdigest() + print(' > HEX SHA256: '+sha) + if sha != '9497e6779f5d840f2bba1de4e95ba1d6f21efc94717d5ae5ca37d7ec5bd37a19': + print('master_key_06: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_07': + master_key_07=checkkeys[i][:] + sha=sha256(uhx(master_key_07)).hexdigest() + if sha != '4ec96b8cb01b8dce382149443430b2b6ebcb2983348afa04a25e53609dabedf6': + print('master_key_07: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'master_key_08': + master_key_08=checkkeys[i][:] + sha=sha256(uhx(master_key_08)).hexdigest() + if sha != '2998e2e23609bc2675ff062a2d64af5b1b78dff463b24119d64a1b64f01b2d51': + print('master_key_07: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'header_key': + header_key=checkkeys[i][:] + sha=sha256(uhx(header_key)).hexdigest() + if sha != '8e03de24818d96ce4f2a09b43af979e679974f7570713a61eed8b314864a11d5': + print('header_key: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + if i == 'xci_header_key': + xci_header_key=checkkeys[i][:] + sha=sha256(uhx(xci_header_key)).hexdigest() + if sha != '2e36cc55157a351090a73e7ae77cf581f69b0b6e48fb066c984879a6ed7d2e96': + print('xci_header_key: '+aes_kek_generation_source ) + print(' > HEX SHA256: '+sha) + print(tabs+'> Key is invalid!!! -> PLEASE CHECK YOUR KEYS.TXT!!!') + startup=True + print('') + + return startup + + +def gen_nsp_header(files,fileSizes): + ''' + for i in range(len(files)): + print (files[i]) + print (fileSizes[i]) + ''' + filesNb = len(files) + stringTable = '\x00'.join(str(nca) for nca in files) + headerSize = 0x10 + (filesNb)*0x18 + len(stringTable) + remainder = 0x10 - headerSize%0x10 + headerSize += remainder + + fileOffsets = [sum(fileSizes[:n]) for n in range(filesNb)] + + fileNamesLengths = [len(str(nca))+1 for nca in files] # +1 for the \x00 + stringTableOffsets = [sum(fileNamesLengths[:n]) for n in range(filesNb)] + + header = b'' + header += b'PFS0' + header += pk(' Date: Tue, 9 Jul 2019 00:05:24 +0200 Subject: [PATCH 12/13] update --- py/ztools/LEGACY.bat | 2 +- py/ztools/lib/sq_tools.py | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/py/ztools/LEGACY.bat b/py/ztools/LEGACY.bat index 6a45a3f0..a85fe960 100644 --- a/py/ztools/LEGACY.bat +++ b/py/ztools/LEGACY.bat @@ -2,7 +2,7 @@ :TOP_INIT CD /d "%prog_dir%" set "bat_name=%~n0" -Title NSC_Builder v0.87c -- Profile: %ofile_name% -- by JulesOnTheRoad +Title NSC_Builder v0.87.c -- Profile: %ofile_name% -- by JulesOnTheRoad ::Check if user is dragging a folder or a file if "%~1"=="" goto manual diff --git a/py/ztools/lib/sq_tools.py b/py/ztools/lib/sq_tools.py index d8e59e02..c3519a02 100644 --- a/py/ztools/lib/sq_tools.py +++ b/py/ztools/lib/sq_tools.py @@ -52,12 +52,6 @@ def kgstring(kg=list()): kg1=[262144,196608,131072,65536];kg.append(kg1) kg0=[450,0];kg.append(kg0) return kg - -def kg2masterkey(kg): - if kg == 1: - return 1 - else: - return kg-1 def getTopRSV(keygeneration, RSV): if keygeneration == 0: From 3f00102928c95597b29d539928dc4f17b32047cf Mon Sep 17 00:00:00 2001 From: julesontheroad <42461174+julesontheroad@users.noreply.github.com> Date: Tue, 9 Jul 2019 00:06:56 +0200 Subject: [PATCH 13/13] Update sq_tools.py --- py/ztools/lib/sq_tools.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/py/ztools/lib/sq_tools.py b/py/ztools/lib/sq_tools.py index c3519a02..03217a62 100644 --- a/py/ztools/lib/sq_tools.py +++ b/py/ztools/lib/sq_tools.py @@ -52,6 +52,12 @@ def kgstring(kg=list()): kg1=[262144,196608,131072,65536];kg.append(kg1) kg0=[450,0];kg.append(kg0) return kg + +def kg2masterkey(kg): + if kg == 1: + return 1 + else: + return kg-1 def getTopRSV(keygeneration, RSV): if keygeneration == 0: @@ -402,6 +408,10 @@ def verify_nkeys(fileName): print("master_key_07 is Missing") else: counter+=1 + if 'master_key_08' not in checkkeys: + print("master_key_08 is Missing") + else: + counter+=1 if 'header_key' not in checkkeys: print("header_key is Missing")