Exemplo n.º 1
0
 def gen(self):
     from math import log2
     lvl = b''
     lvl += pk_u64(self.offset)
     lvl += pk_u64(self.size)
     lvl += pk_u32(int(log2(self.block_size)))
     lvl += 0x4 * b'\0'
     return lvl
Exemplo n.º 2
0
    def _gen_header(self):
        dir_hash_table_offset = ROMFS_FILEPARTITION_OFS + self.data_size
        dir_hash_table_length = 4 * self.dir_hash_table_entry_count
        dir_table_offset = dir_hash_table_offset + dir_hash_table_length
        dir_table_length = len(self.dir_table)
        file_hash_table_offset = dir_table_offset + len(self.dir_table)
        file_hash_table_length = 4 * self.file_hash_table_entry_count
        file_table_offset = file_hash_table_offset + file_hash_table_length
        file_table_length = len(self.file_table)

        header = b''
        header += pk_u64(ROMFS_HEADER_LENGTH)
        header += pk_u64(dir_hash_table_offset)
        header += pk_u64(dir_hash_table_length)
        header += pk_u64(dir_table_offset)
        header += pk_u64(dir_table_length)
        header += pk_u64(file_hash_table_offset)
        header += pk_u64(file_hash_table_length)
        header += pk_u64(file_table_offset)
        header += pk_u64(file_table_length)
        header += pk_u64(ROMFS_FILEPARTITION_OFS)
        header = pad_to(header, length=ROMFS_FILEPARTITION_OFS)
        return header
Exemplo n.º 3
0
 def add(self, entry):
     assert isinstance(entry, self.entry_type), 'Invalid entry type'
     if (len(self.data) <= self.entry_nb) and (self.entry_type is DirEntry):
         self.data.append({
             'Parent': pk_u32(entry.offsets['Parent']),
             'Sibling': pk_u32(entry.offsets['Sibling']),
             'Child': pk_u32(entry.offsets['Child']),
             'File': pk_u32(entry.offsets['File']),
             'PreviousHash': pk_u32(ROMFS_ENTRY_EMPTY),
             'NameLength': pk_u32(len(entry.name)),
             'Name': pad_to(entry.name.encode(), multiple=4)
         })
     elif len(self.data) <= self.entry_nb:
         self.data.append({
             'Parent': pk_u32(entry.offsets['Parent']),
             'Sibling': pk_u32(entry.offsets['Sibling']),
             'DataOffset': pk_u64(entry.offsets['Data']),
             'Size': pk_u64(entry.offsets['Size']),
             'PreviousHash': pk_u32(ROMFS_ENTRY_EMPTY),
             'NameLength': pk_u32(len(entry.name)),
             'Name': pad_to(entry.name.encode(), multiple=4)
         })
     else:
         raise ValueError('Table is already filled up')
        def __init__(self,
                     nca3,
                     section_header,
                     verify=False,
                     ifo=0,
                     buffer=65536):
            self.nca = nca3
            self.section_header = section_header

            self.key = self.nca.body_key
            self.nonce = pk_u64(self.section_header.section_ctr,
                                endianness='>')

            self.section_offset = self.section_header.offset
            self.section_size = self.section_header.size
            self.fs_type = self.section_header.fs_type
            self.crypto = self.section_header.crypto_type
            self.ifo = ifo
            self.buffer = buffer

            if self.crypto in ('BTKR', 'XTS'):
                raise NotImplementedError('BTKR/XTS not implemented')

            super(NCA3.SectionInNCA3,
                  self).__init__(self.nca.f, self.section_offset,
                                 self.section_size)

            self.is_exefs = False
            if self.fs_type == 'PFS0':
                self.cont_offset = self.section_header.superblock.offset
                self.cont_size = self.section_header.superblock.size
                self.fs = HashTableWrappedPFS0(self.section_header.superblock,
                                               self,
                                               verify=verify)
                if 'main.npdm' in self.fs.files:
                    self.is_exefs = True
            elif self.fs_type == 'RomFS':
                self.cont_offset = self.section_header.superblock.lvls[
                    IVFCSuperblock.IVFC_MAX_LEVEL - 1].offset
                self.cont_size = self.section_header.superblock.lvls[
                    IVFCSuperblock.IVFC_MAX_LEVEL - 1].size
                self.fs = HashTreeWrappedRomFS(self.section_header.superblock,
                                               self,
                                               verify=verify)