Пример #1
0
    def verify(self):
        ncaHeader = NcaHeader()
        ncaHeader.open(
            MemoryFile(self.ncaHeader, Type.Crypto.XTS,
                       uhx(Keys.get('header_key'))))

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

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

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

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

        return True
Пример #2
0
    def verify(self):
        ncaHeader = NcaHeader()
        ncaHeader.open(
            MemoryFile(self.ncaHeader, Type.Crypto.XTS,
                       uhx(Keys.get('header_key'))))

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

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

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

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

        return True
Пример #3
0
    def verifyKey(self, userkey):
        if not self.header.hasTitleRights():
            titleKeyDec = Keys.decryptTitleKey(
                file.getTitleKeyBlock().to_bytes(16, byteorder='big'),
                Keys.getMasterKeyIndex(self.masterKey()))
        else:
            encKey = userkey

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

        decKey = titleKeyDec
        f = self

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

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

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

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

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

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

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

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

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

                        data = mem.read()

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

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

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

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

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