Пример #1
0
    def fileName(self):
        bt = None
        if not self.titleId in Titles.keys():
            if not Title.getBaseId(self.titleId) in Titles.keys():
                Print.info('could not find title key for ' +
                           str(self.titleId) + ' or ' +
                           str(Title.getBaseId(self.titleId)))
                return None
            bt = Titles.get(Title.getBaseId(self.titleId))
            t = Title()
            t.loadCsv(self.titleId + '0000000000000000|0000000000000000|' +
                      bt.name)
        else:
            t = Titles.get(self.titleId)

            if not t:
                Print.error('could not find title id ' + str(self.titleId))
                return None

            try:
                if not t.baseId in Titles.keys():
                    Print.info('could not find baseId for ' + self.path)
                    return None
            except BaseException as e:
                print('exception: could not find title id ' +
                      str(self.titleId) + ' ' + str(e))
                return None
            bt = Titles.get(t.baseId)

        if t.isDLC:
            format = Config.paths.getTitleDLC(not self.hasValidTicket)
        elif t.isDemo:
            if t.idExt != 0:
                format = Config.paths.getTitleDemoUpdate(
                    not self.hasValidTicket)
            else:
                format = Config.paths.getTitleDemo(not self.hasValidTicket)
        elif t.idExt != 0:
            format = Config.paths.getTitleUpdate(not self.hasValidTicket)
        else:
            format = Config.paths.getTitleBase(not self.hasValidTicket)

        format = format.replace('{id}', self.cleanFilename(t.id))
        format = format.replace('{region}',
                                self.cleanFilename(t.getRegion() or ''))
        format = format.replace('{name}', self.cleanFilename(t.getName()
                                                             or ''))
        format = format.replace('{version}', str(self.getVersion() or 0))
        format = format.replace('{baseId}', self.cleanFilename(bt.id))

        baseName = self.cleanFilename(bt.getName() or '')
        result = format.replace('{baseName}', baseName)

        while (len(os.path.basename(result).encode('utf-8')) > 240
               and len(baseName) > 3):
            baseName = baseName[:-1]
            result = format.replace('{baseName}', baseName)

        return result
Пример #2
0
    def title(self):
        if not self.titleId:
            raise IOError('NSP no titleId set')

        if self.titleId in Titles.keys():
            return Titles.get(self.titleId)

        t = Title.Title()
        t.setId(self.titleId)
        Titles.data()[self.titleId] = t
        return t
Пример #3
0
    def open(self,
             file=None,
             mode='rb',
             cryptoType=-1,
             cryptoKey=-1,
             cryptoCounter=-1):
        super(NcaHeader, self).open(file, mode, cryptoType, cryptoKey,
                                    cryptoCounter)
        self.rewind()
        self.signature1 = self.read(0x100)
        self.signature2 = self.read(0x100)
        self.magic = self.read(0x4)
        self.isGameCard = self.readInt8()
        self.contentType = self.readInt8()

        try:
            self.contentType = Fs.Type.Content(self.contentType)
        except:
            pass

        self.cryptoType = self.readInt8()
        self.keyIndex = self.readInt8()
        self.size = self.readInt64()
        self.titleId = hx(self.read(8)[::-1]).decode('utf-8').upper()
        self.contentIndex = self.readInt32()
        self.sdkVersion = self.readInt32()
        self.cryptoType2 = self.readInt8()

        self.read(0xF)  # padding

        self.rightsId = hx(self.read(0x10))

        if self.magic not in [b'NCA3', b'NCA2']:
            raise Exception('Failed to decrypt NCA header: ' + str(self.magic))

        self.sectionHashes = []

        for i in range(4):
            self.sectionTables.append(SectionTableEntry(self.read(0x10)))

        for i in range(4):
            self.sectionHashes.append(self.sectionTables[i])

        self.masterKey = (self.cryptoType if self.cryptoType > self.cryptoType2
                          else self.cryptoType2) - 1

        if self.masterKey < 0:
            self.masterKey = 0

        self.encKeyBlock = self.getKeyBlock()
        #for i in range(4):
        #	offset = i * 0x10
        #	key = encKeyBlock[offset:offset+0x10]
        #	Print.info('enc %d: %s' % (i, hx(key)))

        #crypto = aes128.AESECB(Keys.keyAreaKey(self.masterKey, 0))
        self.keyBlock = Keys.unwrapAesWrappedTitlekey(self.encKeyBlock,
                                                      self.masterKey)
        self.keys = []
        for i in range(4):
            offset = i * 0x10
            key = self.keyBlock[offset:offset + 0x10]
            #Print.info('dec %d: %s' % (i, hx(key)))
            self.keys.append(key)

        if self.hasTitleRights():
            titleRightsTitleId = self.rightsId.decode()[0:16].upper()

            if titleRightsTitleId in Titles.keys() and Titles.get(
                    titleRightsTitleId).key:
                self.titleKeyDec = Keys.decryptTitleKey(
                    uhx(Titles.get(titleRightsTitleId).key), self.masterKey)
            else:
                Print.info('could not find title key!')
        else:
            self.titleKeyDec = self.key()

        return True
Пример #4
0
    def fileName(self, forceNsp=False):
        bt = None

        if self.titleId not in Titles.keys():
            if not Title.getBaseId(self.titleId) in Titles.keys():
                Print.error('could not find base title for ' +
                            str(self.titleId) + ' or ' +
                            str(Title.getBaseId(self.titleId)))
                return None
            bt = Titles.get(Title.getBaseId(self.titleId))
            t = Title.Title()
            if bt.name is not None:
                t.loadCsv(self.titleId + '0000000000000000|0000000000000000|' +
                          bt.name)
            else:
                t.setId(self.titleId)
        else:
            t = Titles.get(self.titleId)

            if not t:
                Print.error('could not find title id ' + str(self.titleId))
                return None

            try:
                if t.baseId not in Titles.keys():
                    Print.info('could not find baseId for ' + self.path)
                    return None
            except BaseException as e:
                Print.error('exception: could not find title id ' +
                            str(self.titleId) + ' ' + str(e))
                return None
            bt = Titles.get(t.baseId)

        isNsx = not self.hasValidTicket and not forceNsp

        try:
            if t.isDLC:
                format = Config.paths.getTitleDLC(isNsx, self.path)
            elif t.isDemo:
                if t.idExt != 0:
                    format = Config.paths.getTitleDemoUpdate(isNsx, self.path)
                else:
                    format = Config.paths.getTitleDemo(isNsx, self.path)
            elif t.idExt != 0:
                if bt and bt.isDemo:
                    format = Config.paths.getTitleDemoUpdate(isNsx, self.path)
                else:
                    format = Config.paths.getTitleUpdate(isNsx, self.path)
            else:
                format = Config.paths.getTitleBase(isNsx, self.path)
        except BaseException as e:
            Print.error('calc path exception: ' + str(e))
            return None

        if not format:
            return None

        newName = self.cleanFilename(t.getName() or '')

        format = format.replace('{id}', self.cleanFilename(t.id))
        format = format.replace(
            '{region}', self.cleanFilename(t.getRegion() or bt.getRegion()))
        format = format.replace('{name}', newName)
        format = format.replace('{version}', str(self.getVersion() or 0))
        format = format.replace('{baseId}', self.cleanFilename(bt.id))

        if '{cr}' in format:
            format = format.replace('{cr}', str(self.getCr()))

        if '{icr}' in format:
            format = format.replace('{icr}', str(self.getCr(True)))

        bn = os.path.basename(self.path)
        if (not newName or len(newName)
                == 0) and not bn.upper().startswith(t.id.upper()):
            Print.error('could not get new name for ' + bn)
            return os.path.join(os.path.dirname(format),
                                os.path.basename(self.path))

        baseName = self.cleanFilename(bt.getName() or '')

        if not baseName or len(baseName) == 0:
            baseName = os.path.basename(self.path)

        result = format.replace('{baseName}', baseName)

        while (len(os.path.basename(result).encode('utf-8')) > 240
               and len(baseName) > 3):
            baseName = baseName[:-1]
            result = format.replace('{baseName}', baseName)

        return os.path.abspath(result)