From d616919713742f13fdfd47b124feedca4afff994 Mon Sep 17 00:00:00 2001 From: seiya-git Date: Mon, 1 Jan 2024 12:39:46 +0300 Subject: [PATCH] update --- py/nstools/Fs/BaseFs.py | 16 ++++++------ py/nstools/Fs/Hfs0.py | 31 +++++++++++++++-------- py/nstools/Fs/Nsp.py | 3 +-- py/nstools/Fs/Pfs0.py | 19 +++++++++----- py/nstools/Fs/Xci.py | 11 ++++---- py/nstools/lib/BlockDecompressorReader.py | 4 +-- py/nstools/lib/Header.py | 2 +- 7 files changed, 52 insertions(+), 34 deletions(-) diff --git a/py/nstools/Fs/BaseFs.py b/py/nstools/Fs/BaseFs.py index 9f8576bc..195ae9f1 100644 --- a/py/nstools/Fs/BaseFs.py +++ b/py/nstools/Fs/BaseFs.py @@ -151,17 +151,17 @@ def getCnmt(self): def printInfo(self, maxDepth = 3, indent = 0): tabs = '\t' * indent - Print.info(tabs + 'magic = ' + str(self.magic)) - Print.info(tabs + 'fsType = ' + str(self.fsType)) - Print.info(tabs + 'cryptoType = ' + str(self.cryptoType)) - Print.info(tabs + 'size = ' + str(self.size)) - Print.info(tabs + 'headerSize = %s' % (str(self._headerSize))) - Print.info(tabs + 'offset = %s - (%s)' % (str(self.offset), str(self.sectionStart))) + Print.info(f'{tabs}magic = {self.magic}') + Print.info(f'{tabs}fsType = {self.fsType}') + Print.info(f'{tabs}cryptoType = {self.cryptoType}') + Print.info(f'{tabs}size = {hex(self.size)}') + Print.info(f'{tabs}headerSize = {self._headerSize}') + Print.info(f'{tabs}offset = {hex(self.offset)} - ({hex(self.sectionStart)})') if self.cryptoCounter: - Print.info(tabs + 'cryptoCounter = ' + str(hx(self.cryptoCounter))) + Print.info(f'{tabs}cryptoCounter = {hx(self.cryptoCounter)}') if self.cryptoKey: - Print.info(tabs + 'cryptoKey = ' + str(hx(self.cryptoKey))) + Print.info(f'{tabs}cryptoKey = {hx(self.cryptoKey)}') Print.info('\n%s\t%s\n' % (tabs, '*' * 64)) Print.info('\n%s\tFiles:\n' % (tabs)) diff --git a/py/nstools/Fs/Hfs0.py b/py/nstools/Fs/Hfs0.py index 6eb5130c..783fde7b 100644 --- a/py/nstools/Fs/Hfs0.py +++ b/py/nstools/Fs/Hfs0.py @@ -25,10 +25,10 @@ def __init__(self, f, mode = 'wb'): super(Hfs0Stream, self).__init__(f, mode) self.headerSize = 0x8000 self.files = [] - self.actualSize = 0 - self.seek(self.headerSize) + self.addpos = self.headerSize + self.written = False def __enter__(self): return self @@ -38,18 +38,25 @@ def __exit__(self, type, value, traceback): def write(self, value, size = None): super(Hfs0Stream, self).write(value, len(value)) - if self.tell() > self.actualSize: - self.actualSize = self.tell() + self.written = True + pos = self.tell() + if pos > self.actualSize: + self.actualSize = pos def add(self, name, size, pleaseNoPrint = None): - Print.info('[ADDING] {0} {1} bytes to NSP'.format(name, size), pleaseNoPrint) - self.files.append({'name': name, 'size': size, 'offset': self.f.tell()}) - return self.partition(self.f.tell(), size, n = BaseFile()) + if self.written: + self.addpos = self.tell() + self.written = False + Print.info(f'[ADDING] {name} {hex(size)} bytes to HFS0 at {hex(self.addpos)}', pleaseNoPrint) + partition = self.partition(self.addpos, size, n = BaseFile()) + self.files.append({'name': name, 'size': size, 'offset': self.addpos, 'partition': partition}) + self.addpos += size + return partition def get(self, name): for i in self.files: if i['name'] == name: - return i + return i['partition'] return None def resize(self, name, size): @@ -68,11 +75,14 @@ def close(self): self.write(self.getHeader()) super(Hfs0Stream, self).close() + def updateHashHeader(self): + pass + def getHeader(self): stringTable = '\x00'.join(file['name'] for file in self.files)+'\x00' headerSize = 0x10 + len(self.files) * 0x40 + len(stringTable) - + h = b'' h += b'HFS0' h += len(self.files).to_bytes(4, byteorder='little') @@ -82,7 +92,7 @@ def getHeader(self): stringOffset = 0 for f in self.files: - sizeOfHashedRegion = 0x200 if 0x200 < f['size'] else f['size'] + sizeOfHashedRegion = 0 #0x200 if 0x200 < f['size'] else f['size'] h += (f['offset'] - headerSize).to_bytes(8, byteorder='little') h += f['size'].to_bytes(8, byteorder='little') @@ -130,6 +140,7 @@ def open(self, path = None, mode = 'rb', cryptoType = -1, cryptoKey = -1, crypto nameOffset = self.readInt32() # just the offset name = stringTable[nameOffset:stringEndOffset].decode('utf-8').rstrip(' \t\r\n\0') stringEndOffset = nameOffset + Print.info(f'[OPEN ] {name} {hex(size)} bytes at {hex(offset)}') self.readInt32() # junk data diff --git a/py/nstools/Fs/Nsp.py b/py/nstools/Fs/Nsp.py index aa62516a..88ed191b 100644 --- a/py/nstools/Fs/Nsp.py +++ b/py/nstools/Fs/Nsp.py @@ -193,7 +193,7 @@ def setPath(self, path): if self.hasValidTicket is None: self.setHasValidTicket(False) else: - # print('unknown extension ' + str(path)) + print('unknown extension ' + str(path)) return def getPath(self): @@ -450,4 +450,3 @@ def verify(self): success = False return success - diff --git a/py/nstools/Fs/Pfs0.py b/py/nstools/Fs/Pfs0.py index a75547a7..378bfa86 100644 --- a/py/nstools/Fs/Pfs0.py +++ b/py/nstools/Fs/Pfs0.py @@ -30,6 +30,7 @@ def __init__(self, headerSize, stringTableSize, path, mode = 'wb'): self.actualSize = 0 self.f.seek(self.headerSize) self.addpos = self.headerSize + self.written = False def __enter__(self): return self @@ -39,13 +40,18 @@ def __exit__(self, type, value, traceback): def write(self, value, size = None): super(Pfs0Stream, self).write(value, len(value)) - if self.tell() > self.actualSize: - self.actualSize = self.tell() + self.written = True + pos = self.tell() + if pos > self.actualSize: + self.actualSize = pos def add(self, name, size, pleaseNoPrint = None): - Print.info('[ADDING] {0} {1} bytes to NSP'.format(name, size), pleaseNoPrint) - partition = self.partition(self.f.tell(), size, n = BaseFile()) - self.files.append({'name': name, 'size': size, 'offset': self.f.tell(), 'partition': partition}) + if self.written: + self.addpos = self.tell() + self.written = False + Print.info(f'[ADDING] {name} {hex(size)} bytes to PFS0 at {hex(self.addpos)}', pleaseNoPrint) + partition = self.partition(self.addpos, size, n = BaseFile()) + self.files.append({'name': name, 'size': size, 'offset': self.addpos, 'partition': partition}) self.addpos += size return partition @@ -137,7 +143,7 @@ def tell(self): return self.pos def add(self, name, size, pleaseNoPrint = None): - Print.info('[ADDING] {0} {1} bytes to NSP'.format(name, size), pleaseNoPrint) + Print.info(f'[ADDING] {name} {hex(size)} bytes to PFS0 at {hex(self.addpos)}', pleaseNoPrint) self.files.append({'name': name, 'size': size, 'offset': self.addpos}) self.addpos += size return self @@ -255,6 +261,7 @@ def open(self, path = None, mode = 'rb', cryptoType = -1, cryptoKey = -1, crypto nameOffset = self.readInt32() # just the offset name = stringTable[nameOffset:stringEndOffset].decode('utf-8').rstrip(' \t\r\n\0') stringEndOffset = nameOffset + Print.info(f'[OPEN ] {name} {hex(size)} bytes at {hex(offset)}') self.readInt32() # junk data diff --git a/py/nstools/Fs/Xci.py b/py/nstools/Fs/Xci.py index 65989e4b..d897c4db 100644 --- a/py/nstools/Fs/Xci.py +++ b/py/nstools/Fs/Xci.py @@ -61,10 +61,11 @@ def __exit__(self, type, value, traceback): self.close() def add(self, name, size, pleaseNoPrint = None): - Print.info('[ADDING] {0} {1} bytes to NSP'.format(name, size), pleaseNoPrint) - self.files.append({'name': name, 'size': size, 'offset': self.f.tell()}) - t = {'name': name, 'size': size, 'offset': self.f.tell()} - return self.f + Print.info(f'[ADDING] {name} {hex(size)} bytes to XCI at {hex(self.f.tell())}', pleaseNoPrint) + partition = self.partition(self.f.tell(), size, n = BaseFile()) + self.files.append({'name': name, 'size': size, 'offset': self.f.tell(), 'partition': partition}) + self.addpos += size + return partition def currentFileSize(self): return self.f.tell() - self.files[-1]['offset'] @@ -72,7 +73,7 @@ def currentFileSize(self): def get(self, name): for i in self.files: if i['name'] == name: - return i + return i['partition'] return None def resize(self, name, size): diff --git a/py/nstools/lib/BlockDecompressorReader.py b/py/nstools/lib/BlockDecompressorReader.py index 3265e29a..e4f35aeb 100644 --- a/py/nstools/lib/BlockDecompressorReader.py +++ b/py/nstools/lib/BlockDecompressorReader.py @@ -16,7 +16,7 @@ def __init__(self, nspf, BlockHeader): self.BlockSize = 2**BlockHeader.blockSizeExponent self.CompressedBlockOffsetList = [initialOffset] - for compressedBlockSize in BlockHeader.compressedBlockSizeList: + for compressedBlockSize in BlockHeader.compressedBlockSizeList[:-1]: self.CompressedBlockOffsetList.append(self.CompressedBlockOffsetList[-1] + compressedBlockSize) self.CompressedBlockSizeList = BlockHeader.compressedBlockSizeList @@ -28,7 +28,7 @@ def __decompressBlock(self, blockID): if blockID >= len(self.CompressedBlockOffsetList) - 1: if blockID >= len(self.CompressedBlockOffsetList): raise EOFError("BlockID exceeds the amounts of compressed blocks in that file!") - decompressedBlockSize = self.BlockHeader.decompressedSize % BlockSize + decompressedBlockSize = self.BlockHeader.decompressedSize % self.BlockSize self.nspf.seek(self.CompressedBlockOffsetList[blockID]) if self.CompressedBlockSizeList[blockID] < decompressedBlockSize: self.CurrentBlock = ZstdDecompressor().decompress(self.nspf.read(decompressedBlockSize)) diff --git a/py/nstools/lib/Header.py b/py/nstools/lib/Header.py index 6de2f12f..26c1b22b 100644 --- a/py/nstools/lib/Header.py +++ b/py/nstools/lib/Header.py @@ -24,4 +24,4 @@ def __init__(self, f): self.blockSizeExponent = f.readInt8() self.numberOfBlocks = f.readInt32() self.decompressedSize = f.readInt64() - self.compressedBlockSizeList = [f.readInt32() for _ in range(self.numberOfBlocks)] + self.compressedBlockSizeList = [f.readInt32() for _ in range(self.numberOfBlocks)] \ No newline at end of file