From 3716bf0b825ec5d6d158c5b8598c47bc889cd06f Mon Sep 17 00:00:00 2001 From: jakcron Date: Wed, 26 Sep 2018 21:48:38 +0800 Subject: [PATCH 1/6] [nstool] Fix critical bug in HashTreeWrappedIFile (bumped to v1.0.5) --- programs/nstool/makefile | 2 +- .../nstool/source/HashTreeWrappedIFile.cpp | 69 ++++++++++--------- programs/nstool/source/version.h | 2 +- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/programs/nstool/makefile b/programs/nstool/makefile index d73e3b4..91999dc 100644 --- a/programs/nstool/makefile +++ b/programs/nstool/makefile @@ -34,7 +34,7 @@ else endif BIN_DIR = bin -OUTPUT = $(BIN_DIR)/$(shell basename $(CURDIR)) +OUTPUT = $(BIN_DIR)/$(shell basename "$(CURDIR)") all: build diff --git a/programs/nstool/source/HashTreeWrappedIFile.cpp b/programs/nstool/source/HashTreeWrappedIFile.cpp index a69acb2..54168de 100644 --- a/programs/nstool/source/HashTreeWrappedIFile.cpp +++ b/programs/nstool/source/HashTreeWrappedIFile.cpp @@ -23,45 +23,49 @@ void HashTreeWrappedIFile::seek(size_t offset) void HashTreeWrappedIFile::read(byte_t* out, size_t len) { - size_t offset_in_start_block = getOffsetInBlock(mDataOffset); - size_t offset_in_end_block = getOffsetInBlock(offset_in_start_block + len); - - size_t start_block = getOffsetBlock(mDataOffset); - size_t block_num = align(offset_in_start_block + len, mDataBlockSize) / mDataBlockSize; - - size_t partial_last_block_num = block_num % mCacheBlockNum; - bool has_partial_block_num = partial_last_block_num > 0; - size_t read_iterations = (block_num / mCacheBlockNum) + has_partial_block_num; - - size_t block_read_len; - size_t block_export_offset; - size_t block_export_size; - size_t block_export_pos = 0; - for (size_t i = 0; i < read_iterations; i++) + struct sBlockPosition { - // how many blocks to read from source file - block_read_len = (i+1 == read_iterations && has_partial_block_num) ? partial_last_block_num : mCacheBlockNum; + size_t index; + size_t pos; + } start_blk, end_blk; - // offset in this current read to copy from - block_export_offset = (i == 0) ? offset_in_start_block : 0; + start_blk.index = getOffsetBlock(mDataOffset); + start_blk.pos = getOffsetInBlock(mDataOffset); - // size of current read to copy - block_export_size = (block_read_len * mDataBlockSize) - block_export_offset; + end_blk.index = getOffsetBlock(mDataOffset + len); + end_blk.pos = getOffsetInBlock(mDataOffset + len); + if (end_blk.pos == 0 && len != 0) + { + end_blk.index -= 1; + end_blk.pos = mDataBlockSize; + } - // if last read, reduce the export size by one block less offset_in_end_block - if (i+1 == read_iterations) - { - block_export_size -= (mDataBlockSize - offset_in_end_block); - } + size_t total_blk_num = (end_blk.index - start_blk.index) + 1; - // read the blocks - readData(start_block + (i * mCacheBlockNum), block_read_len); + size_t read_blk_num = 0; + size_t cache_export_start_pos, cache_export_end_pos, cache_export_size; + size_t export_pos = 0; + for (size_t i = 0; i < total_blk_num; i += read_blk_num, export_pos += cache_export_size) + { + read_blk_num = _MIN(mCacheBlockNum, (total_blk_num - i)); + readData(start_blk.index + i, read_blk_num); - // export the section of data that is relevant - memcpy(out + block_export_pos, mCache.data() + block_export_offset, block_export_size); + // if this is the first read, adjust offset + if (i == 0) + cache_export_start_pos = start_blk.pos; + else + cache_export_start_pos = 0; + + // if this is the last block, adjust end offset + if ((i + read_blk_num) == total_blk_num) + cache_export_end_pos = ((read_blk_num - 1) * mDataBlockSize) + end_blk.pos; + else + cache_export_end_pos = read_blk_num * mDataBlockSize; - // update export position - block_export_pos += block_export_size; + // determine cache export size + cache_export_size = cache_export_end_pos - cache_export_start_pos; + + memcpy(out + export_pos, mCache.data() + cache_export_start_pos, cache_export_size); } // update offset @@ -150,7 +154,6 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr) void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num) { - (*mData)->seek(block_offset * mDataBlockSize); fnd::sha::sSha256Hash hash; // determine read size diff --git a/programs/nstool/source/version.h b/programs/nstool/source/version.h index 24fccdf..4773fb4 100644 --- a/programs/nstool/source/version.h +++ b/programs/nstool/source/version.h @@ -3,5 +3,5 @@ #define BIN_NAME "nstool" #define VER_MAJOR 1 #define VER_MINOR 0 -#define VER_PATCH 4 +#define VER_PATCH 5 #define AUTHORS "jakcron" \ No newline at end of file From 9e86d96b8400b724177304f340eba789c95c3e86 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 6 Oct 2018 13:15:42 +0800 Subject: [PATCH 2/6] [fnd] Update IFile & ISerialisable with bettered virtual dtor. --- lib/libfnd/include/fnd/IFile.h | 2 +- lib/libfnd/include/fnd/ISerialisable.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/libfnd/include/fnd/IFile.h b/lib/libfnd/include/fnd/IFile.h index d992962..e93bbf0 100644 --- a/lib/libfnd/include/fnd/IFile.h +++ b/lib/libfnd/include/fnd/IFile.h @@ -6,7 +6,7 @@ namespace fnd class IFile { public: - inline virtual ~IFile() {} + virtual ~IFile() = default; virtual size_t size() = 0; virtual void seek(size_t offset) = 0; diff --git a/lib/libfnd/include/fnd/ISerialisable.h b/lib/libfnd/include/fnd/ISerialisable.h index a484ea0..b0d49c7 100644 --- a/lib/libfnd/include/fnd/ISerialisable.h +++ b/lib/libfnd/include/fnd/ISerialisable.h @@ -7,6 +7,8 @@ namespace fnd class ISerialisable { public: + virtual ~ISerialisable() = default; + // serialise virtual void toBytes() = 0; // deserialise From 0c4103a620d52417a8d5210a171a98f13727f719 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 6 Oct 2018 13:31:24 +0800 Subject: [PATCH 3/6] [nstool] Rename HashTreeMeta to LayeredIntegrityMetadata and associated WrappedIFile. Improved low couling in LayeredIntegrityMetadata. --- programs/nstool/nstool.vcxproj | 8 +- programs/nstool/nstool.vcxproj.filters | 30 ++-- programs/nstool/source/HashTreeMeta.cpp | 135 ------------------ .../source/LayeredIntegrityMetadata.cpp | 71 +++++++++ ...hTreeMeta.h => LayeredIntegrityMetadata.h} | 25 +--- ...e.cpp => LayeredIntegrityWrappedIFile.cpp} | 22 +-- ...IFile.h => LayeredIntegrityWrappedIFile.h} | 10 +- programs/nstool/source/NcaProcess.cpp | 72 +++++++++- programs/nstool/source/NcaProcess.h | 4 +- 9 files changed, 180 insertions(+), 197 deletions(-) delete mode 100644 programs/nstool/source/HashTreeMeta.cpp create mode 100644 programs/nstool/source/LayeredIntegrityMetadata.cpp rename programs/nstool/source/{HashTreeMeta.h => LayeredIntegrityMetadata.h} (64%) rename programs/nstool/source/{HashTreeWrappedIFile.cpp => LayeredIntegrityWrappedIFile.cpp} (86%) rename programs/nstool/source/{HashTreeWrappedIFile.h => LayeredIntegrityWrappedIFile.h} (78%) diff --git a/programs/nstool/nstool.vcxproj b/programs/nstool/nstool.vcxproj index d0605d4..15f0e71 100644 --- a/programs/nstool/nstool.vcxproj +++ b/programs/nstool/nstool.vcxproj @@ -184,9 +184,9 @@ - - + + @@ -209,9 +209,9 @@ - - + + diff --git a/programs/nstool/nstool.vcxproj.filters b/programs/nstool/nstool.vcxproj.filters index 2cf288a..f7b8765 100644 --- a/programs/nstool/nstool.vcxproj.filters +++ b/programs/nstool/nstool.vcxproj.filters @@ -28,21 +28,24 @@ Header Files + + Header Files + Header Files Header Files - - Header Files - - - Header Files - Header Files + + Header Files + + + Header Files + Header Files @@ -88,9 +91,6 @@ Header Files - - Header Files - @@ -108,15 +108,15 @@ Source Files - - Source Files - - - Source Files - Source Files + + Source Files + + + Source Files + Source Files diff --git a/programs/nstool/source/HashTreeMeta.cpp b/programs/nstool/source/HashTreeMeta.cpp deleted file mode 100644 index 3276d41..0000000 --- a/programs/nstool/source/HashTreeMeta.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "HashTreeMeta.h" - -HashTreeMeta::HashTreeMeta() : - mLayerInfo(), - mDataLayer(), - mMasterHashList(), - mDoAlignHashToBlock(false) -{ - -} - -HashTreeMeta::HashTreeMeta(const byte_t* data, size_t len, HashTreeType type) : - HashTreeMeta() -{ - importData(data, len, type); -} - -void HashTreeMeta::operator=(const HashTreeMeta& other) -{ - mLayerInfo = other.mLayerInfo; - mDataLayer = other.mDataLayer; - mMasterHashList = other.mMasterHashList; - mDoAlignHashToBlock = other.mDoAlignHashToBlock; -} - -bool HashTreeMeta::operator==(const HashTreeMeta& other) const -{ - return (mLayerInfo == other.mLayerInfo) \ - && (mDataLayer == other.mDataLayer) \ - && (mMasterHashList == other.mMasterHashList) \ - && (mDoAlignHashToBlock == other.mDoAlignHashToBlock); -} - -bool HashTreeMeta::operator!=(const HashTreeMeta& other) const -{ - return !(*this == other); -} - -void HashTreeMeta::importData(const byte_t* data, size_t len, HashTreeType type) -{ - if (type == HASH_TYPE_INTEGRITY) - { - nn::hac::HierarchicalIntegrityHeader hdr; - hdr.fromBytes(data, len); - importHierarchicalIntergityHeader(hdr); - } - else if (type == HASH_TYPE_SHA256) - { - nn::hac::HierarchicalSha256Header hdr; - hdr.fromBytes(data, len); - importHierarchicalSha256Header(hdr); - } -} - -const fnd::List& HashTreeMeta::getHashLayerInfo() const -{ - return mLayerInfo; -} - -void HashTreeMeta::setHashLayerInfo(const fnd::List& layer_info) -{ - mLayerInfo = layer_info; -} - -const HashTreeMeta::sLayer& HashTreeMeta::getDataLayer() const -{ - return mDataLayer; -} - -void HashTreeMeta::setDataLayer(const sLayer& data_info) -{ - mDataLayer = data_info; -} - -const fnd::List& HashTreeMeta::getMasterHashList() const -{ - return mMasterHashList; -} - -void HashTreeMeta::setMasterHashList(const fnd::List& master_hash_list) -{ - mMasterHashList = master_hash_list; -} - -bool HashTreeMeta::getAlignHashToBlock() const -{ - return mDoAlignHashToBlock; -} - -void HashTreeMeta::setAlignHashToBlock(bool doAlign) -{ - mDoAlignHashToBlock = doAlign; -} - -void HashTreeMeta::importHierarchicalIntergityHeader(const nn::hac::HierarchicalIntegrityHeader& hdr) -{ - mDoAlignHashToBlock = true; - for (size_t i = 0; i < hdr.getLayerInfo().size(); i++) - { - sLayer layer; - layer.offset = hdr.getLayerInfo()[i].offset; - layer.size = hdr.getLayerInfo()[i].size; - layer.block_size = _BIT(hdr.getLayerInfo()[i].block_size); - if (i+1 == hdr.getLayerInfo().size()) - { - mDataLayer = layer; - } - else - { - mLayerInfo.addElement(layer); - } - } - mMasterHashList = hdr.getMasterHashList(); -} - -void HashTreeMeta::importHierarchicalSha256Header(const nn::hac::HierarchicalSha256Header& hdr) -{ - mDoAlignHashToBlock = false; - for (size_t i = 0; i < hdr.getLayerInfo().size(); i++) - { - sLayer layer; - layer.offset = hdr.getLayerInfo()[i].offset; - layer.size = hdr.getLayerInfo()[i].size; - layer.block_size = hdr.getHashBlockSize(); - if (i+1 == hdr.getLayerInfo().size()) - { - mDataLayer = layer; - } - else - { - mLayerInfo.addElement(layer); - } - } - mMasterHashList.addElement(hdr.getMasterHash()); -} \ No newline at end of file diff --git a/programs/nstool/source/LayeredIntegrityMetadata.cpp b/programs/nstool/source/LayeredIntegrityMetadata.cpp new file mode 100644 index 0000000..296e84e --- /dev/null +++ b/programs/nstool/source/LayeredIntegrityMetadata.cpp @@ -0,0 +1,71 @@ +#include "LayeredIntegrityMetadata.h" + +LayeredIntegrityMetadata::LayeredIntegrityMetadata() : + mLayerInfo(), + mDataLayer(), + mMasterHashList(), + mDoAlignHashToBlock(false) +{ + +} + +void LayeredIntegrityMetadata::operator=(const LayeredIntegrityMetadata& other) +{ + mLayerInfo = other.mLayerInfo; + mDataLayer = other.mDataLayer; + mMasterHashList = other.mMasterHashList; + mDoAlignHashToBlock = other.mDoAlignHashToBlock; +} + +bool LayeredIntegrityMetadata::operator==(const LayeredIntegrityMetadata& other) const +{ + return (mLayerInfo == other.mLayerInfo) \ + && (mDataLayer == other.mDataLayer) \ + && (mMasterHashList == other.mMasterHashList) \ + && (mDoAlignHashToBlock == other.mDoAlignHashToBlock); +} + +bool LayeredIntegrityMetadata::operator!=(const LayeredIntegrityMetadata& other) const +{ + return !(*this == other); +} + +const fnd::List& LayeredIntegrityMetadata::getHashLayerInfo() const +{ + return mLayerInfo; +} + +void LayeredIntegrityMetadata::setHashLayerInfo(const fnd::List& layer_info) +{ + mLayerInfo = layer_info; +} + +const LayeredIntegrityMetadata::sLayer& LayeredIntegrityMetadata::getDataLayer() const +{ + return mDataLayer; +} + +void LayeredIntegrityMetadata::setDataLayerInfo(const sLayer& data_info) +{ + mDataLayer = data_info; +} + +const fnd::List& LayeredIntegrityMetadata::getMasterHashList() const +{ + return mMasterHashList; +} + +void LayeredIntegrityMetadata::setMasterHashList(const fnd::List& master_hash_list) +{ + mMasterHashList = master_hash_list; +} + +bool LayeredIntegrityMetadata::getAlignHashToBlock() const +{ + return mDoAlignHashToBlock; +} + +void LayeredIntegrityMetadata::setAlignHashToBlock(bool doAlign) +{ + mDoAlignHashToBlock = doAlign; +} \ No newline at end of file diff --git a/programs/nstool/source/HashTreeMeta.h b/programs/nstool/source/LayeredIntegrityMetadata.h similarity index 64% rename from programs/nstool/source/HashTreeMeta.h rename to programs/nstool/source/LayeredIntegrityMetadata.h index 1568b5e..dffa39c 100644 --- a/programs/nstool/source/HashTreeMeta.h +++ b/programs/nstool/source/LayeredIntegrityMetadata.h @@ -2,15 +2,9 @@ #include #include -class HashTreeMeta +class LayeredIntegrityMetadata { public: - enum HashTreeType - { - HASH_TYPE_INTEGRITY, - HASH_TYPE_SHA256 - }; - struct sLayer { size_t offset; @@ -35,20 +29,17 @@ public: } }; - HashTreeMeta(); - HashTreeMeta(const byte_t* data, size_t len, HashTreeType type); + LayeredIntegrityMetadata(); - void operator=(const HashTreeMeta& other); - bool operator==(const HashTreeMeta& other) const; - bool operator!=(const HashTreeMeta& other) const; - - void importData(const byte_t* data, size_t len, HashTreeType type); + void operator=(const LayeredIntegrityMetadata& other); + bool operator==(const LayeredIntegrityMetadata& other) const; + bool operator!=(const LayeredIntegrityMetadata& other) const; const fnd::List& getHashLayerInfo() const; void setHashLayerInfo(const fnd::List& layer_info); const sLayer& getDataLayer() const; - void setDataLayer(const sLayer& data_info); + void setDataLayerInfo(const sLayer& data_info); const fnd::List& getMasterHashList() const; void setMasterHashList(const fnd::List& master_hash_list); @@ -56,13 +47,9 @@ public: bool getAlignHashToBlock() const; void setAlignHashToBlock(bool doAlign); private: - // data fnd::List mLayerInfo; sLayer mDataLayer; fnd::List mMasterHashList; bool mDoAlignHashToBlock; - - void importHierarchicalIntergityHeader(const nn::hac::HierarchicalIntegrityHeader& hdr); - void importHierarchicalSha256Header(const nn::hac::HierarchicalSha256Header& hdr); }; \ No newline at end of file diff --git a/programs/nstool/source/HashTreeWrappedIFile.cpp b/programs/nstool/source/LayeredIntegrityWrappedIFile.cpp similarity index 86% rename from programs/nstool/source/HashTreeWrappedIFile.cpp rename to programs/nstool/source/LayeredIntegrityWrappedIFile.cpp index 54168de..41b9faa 100644 --- a/programs/nstool/source/HashTreeWrappedIFile.cpp +++ b/programs/nstool/source/LayeredIntegrityWrappedIFile.cpp @@ -1,8 +1,8 @@ #include "common.h" -#include "HashTreeWrappedIFile.h" +#include "LayeredIntegrityWrappedIFile.h" #include "OffsetAdjustedIFile.h" -HashTreeWrappedIFile::HashTreeWrappedIFile(const fnd::SharedPtr& file, const HashTreeMeta& hdr) : +LayeredIntegrityWrappedIFile::LayeredIntegrityWrappedIFile(const fnd::SharedPtr& file, const LayeredIntegrityMetadata& hdr) : mFile(file), mData(nullptr), mDataHashLayer(), @@ -11,17 +11,17 @@ HashTreeWrappedIFile::HashTreeWrappedIFile(const fnd::SharedPtr& fil initialiseDataLayer(hdr); } -size_t HashTreeWrappedIFile::size() +size_t LayeredIntegrityWrappedIFile::size() { return (*mData)->size(); } -void HashTreeWrappedIFile::seek(size_t offset) +void LayeredIntegrityWrappedIFile::seek(size_t offset) { mDataOffset = offset; } -void HashTreeWrappedIFile::read(byte_t* out, size_t len) +void LayeredIntegrityWrappedIFile::read(byte_t* out, size_t len) { struct sBlockPosition { @@ -72,23 +72,23 @@ void HashTreeWrappedIFile::read(byte_t* out, size_t len) seek(mDataOffset + len); } -void HashTreeWrappedIFile::read(byte_t* out, size_t offset, size_t len) +void LayeredIntegrityWrappedIFile::read(byte_t* out, size_t offset, size_t len) { seek(offset); read(out, len); } -void HashTreeWrappedIFile::write(const byte_t* out, size_t len) +void LayeredIntegrityWrappedIFile::write(const byte_t* out, size_t len) { throw fnd::Exception(kModuleName, "write() not supported"); } -void HashTreeWrappedIFile::write(const byte_t* out, size_t offset, size_t len) +void LayeredIntegrityWrappedIFile::write(const byte_t* out, size_t offset, size_t len) { throw fnd::Exception(kModuleName, "write() not supported"); } -void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr) +void LayeredIntegrityWrappedIFile::initialiseDataLayer(const LayeredIntegrityMetadata& hdr) { fnd::sha::sSha256Hash hash; fnd::Vec cur, prev; @@ -106,7 +106,7 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr) for (size_t i = 0; i < hdr.getHashLayerInfo().size(); i++) { // get block size - const HashTreeMeta::sLayer& layer = hdr.getHashLayerInfo()[i]; + const LayeredIntegrityMetadata::sLayer& layer = hdr.getHashLayerInfo()[i]; // allocate layer cur.alloc(align(layer.size, layer.block_size)); @@ -152,7 +152,7 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr) mCache.alloc(cache_size); } -void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num) +void LayeredIntegrityWrappedIFile::readData(size_t block_offset, size_t block_num) { fnd::sha::sSha256Hash hash; diff --git a/programs/nstool/source/HashTreeWrappedIFile.h b/programs/nstool/source/LayeredIntegrityWrappedIFile.h similarity index 78% rename from programs/nstool/source/HashTreeWrappedIFile.h rename to programs/nstool/source/LayeredIntegrityWrappedIFile.h index dd3f70c..3aa781b 100644 --- a/programs/nstool/source/HashTreeWrappedIFile.h +++ b/programs/nstool/source/LayeredIntegrityWrappedIFile.h @@ -4,13 +4,13 @@ #include #include #include -#include "HashTreeMeta.h" +#include "LayeredIntegrityMetadata.h" -class HashTreeWrappedIFile : public fnd::IFile +class LayeredIntegrityWrappedIFile : public fnd::IFile { public: - HashTreeWrappedIFile(const fnd::SharedPtr& file, const HashTreeMeta& hdr); + LayeredIntegrityWrappedIFile(const fnd::SharedPtr& file, const LayeredIntegrityMetadata& hdr); size_t size(); void seek(size_t offset); @@ -19,7 +19,7 @@ public: void write(const byte_t* out, size_t len); void write(const byte_t* out, size_t offset, size_t len); private: - const std::string kModuleName = "HashTreeWrappedIFile"; + const std::string kModuleName = "LayeredIntegrityWrappedIFile"; static const size_t kDefaultCacheSize = 0x10000; std::stringstream mErrorSs; @@ -40,6 +40,6 @@ private: inline size_t getRemanderBlockReadSize(size_t total_size) const { return total_size % mDataBlockSize; } inline size_t getBlockNum(size_t total_size) const { return (total_size / mDataBlockSize) + (getRemanderBlockReadSize(total_size) > 0); } - void initialiseDataLayer(const HashTreeMeta& hdr); + void initialiseDataLayer(const LayeredIntegrityMetadata& hdr); void readData(size_t block_offset, size_t block_num); }; \ No newline at end of file diff --git a/programs/nstool/source/NcaProcess.cpp b/programs/nstool/source/NcaProcess.cpp index aa4f504..676bcc3 100644 --- a/programs/nstool/source/NcaProcess.cpp +++ b/programs/nstool/source/NcaProcess.cpp @@ -10,7 +10,7 @@ #include "NpdmProcess.h" #include "OffsetAdjustedIFile.h" #include "AesCtrWrappedIFile.h" -#include "HashTreeWrappedIFile.h" +#include "LayeredIntegrityWrappedIFile.h" NcaProcess::NcaProcess() : mFile(), @@ -258,9 +258,69 @@ void NcaProcess::generatePartitionConfiguration() info.hash_type = (nn::hac::nca::HashType)fs_header.hash_type; info.enc_type = (nn::hac::nca::EncryptionType)fs_header.encryption_type; if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256) - info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, HashTreeMeta::HASH_TYPE_SHA256); + { + // info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, LayeredIntegrityMetadata::HASH_TYPE_SHA256); + nn::hac::HierarchicalSha256Header hdr; + fnd::List hash_layers; + LayeredIntegrityMetadata::sLayer data_layer; + fnd::List master_hash_list; + + // import raw data + hdr.fromBytes(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen); + for (size_t i = 0; i < hdr.getLayerInfo().size(); i++) + { + LayeredIntegrityMetadata::sLayer layer; + layer.offset = hdr.getLayerInfo()[i].offset; + layer.size = hdr.getLayerInfo()[i].size; + layer.block_size = hdr.getHashBlockSize(); + if (i + 1 == hdr.getLayerInfo().size()) + { + data_layer = layer; + } + else + { + hash_layers.addElement(layer); + } + } + master_hash_list.addElement(hdr.getMasterHash()); + + // write data into metadata + info.layered_intergrity_metadata.setAlignHashToBlock(false); + info.layered_intergrity_metadata.setHashLayerInfo(hash_layers); + info.layered_intergrity_metadata.setDataLayerInfo(data_layer); + info.layered_intergrity_metadata.setMasterHashList(master_hash_list); + } else if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY) - info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, HashTreeMeta::HASH_TYPE_INTEGRITY); + { + // info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, LayeredIntegrityMetadata::HASH_TYPE_INTEGRITY); + nn::hac::HierarchicalIntegrityHeader hdr; + fnd::List hash_layers; + LayeredIntegrityMetadata::sLayer data_layer; + fnd::List master_hash_list; + + hdr.fromBytes(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen); + for (size_t i = 0; i < hdr.getLayerInfo().size(); i++) + { + LayeredIntegrityMetadata::sLayer layer; + layer.offset = hdr.getLayerInfo()[i].offset; + layer.size = hdr.getLayerInfo()[i].size; + layer.block_size = _BIT(hdr.getLayerInfo()[i].block_size); + if (i + 1 == hdr.getLayerInfo().size()) + { + data_layer = layer; + } + else + { + hash_layers.addElement(layer); + } + } + + // write data into metadata + info.layered_intergrity_metadata.setAlignHashToBlock(true); + info.layered_intergrity_metadata.setHashLayerInfo(hash_layers); + info.layered_intergrity_metadata.setDataLayerInfo(data_layer); + info.layered_intergrity_metadata.setMasterHashList(hdr.getMasterHashList()); + } // create reader try @@ -304,7 +364,7 @@ void NcaProcess::generatePartitionConfiguration() // filter out unrecognised hash types, and hash based readers if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256 || info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY) { - info.reader = new HashTreeWrappedIFile(info.reader, info.hash_tree_meta); + info.reader = new LayeredIntegrityWrappedIFile(info.reader, info.layered_intergrity_metadata); } else if (info.hash_type != nn::hac::nca::HASH_NONE) { @@ -440,7 +500,7 @@ void NcaProcess::displayHeader() } if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY) { - HashTreeMeta& hash_hdr = info.hash_tree_meta; + LayeredIntegrityMetadata& hash_hdr = info.layered_intergrity_metadata; std::cout << " HierarchicalIntegrity Header:" << std::endl; for (size_t j = 0; j < hash_hdr.getHashLayerInfo().size(); j++) { @@ -463,7 +523,7 @@ void NcaProcess::displayHeader() } else if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256) { - HashTreeMeta& hash_hdr = info.hash_tree_meta; + LayeredIntegrityMetadata& hash_hdr = info.layered_intergrity_metadata; std::cout << " HierarchicalSha256 Header:" << std::endl; std::cout << " Master Hash:" << std::endl; std::cout << " " << fnd::SimpleTextOutput::arrayToString(hash_hdr.getMasterHashList()[0].bytes, 0x10, true, ":") << std::endl; diff --git a/programs/nstool/source/NcaProcess.h b/programs/nstool/source/NcaProcess.h index c5b0429..4d98268 100644 --- a/programs/nstool/source/NcaProcess.h +++ b/programs/nstool/source/NcaProcess.h @@ -4,7 +4,7 @@ #include #include #include -#include "HashTreeMeta.h" +#include "LayeredIntegrityMetadata.h" #include "KeyConfiguration.h" @@ -100,7 +100,7 @@ private: nn::hac::nca::FormatType format_type; nn::hac::nca::HashType hash_type; nn::hac::nca::EncryptionType enc_type; - HashTreeMeta hash_tree_meta; + LayeredIntegrityMetadata layered_intergrity_metadata; fnd::aes::sAesIvCtr aes_ctr; } mPartitions[nn::hac::nca::kPartitionNum]; From 02d2408ebe31e8d6228bb4f5095bf86cff1968ec Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 6 Oct 2018 15:58:09 +0800 Subject: [PATCH 4/6] [nstool] Clear dead commented code. --- programs/nstool/source/AesCtrWrappedIFile.cpp | 25 ------------------- .../source/LayeredIntegrityWrappedIFile.cpp | 7 +----- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/programs/nstool/source/AesCtrWrappedIFile.cpp b/programs/nstool/source/AesCtrWrappedIFile.cpp index 3acebd7..c322560 100644 --- a/programs/nstool/source/AesCtrWrappedIFile.cpp +++ b/programs/nstool/source/AesCtrWrappedIFile.cpp @@ -21,8 +21,6 @@ void AesCtrWrappedIFile::seek(size_t offset) void AesCtrWrappedIFile::read(byte_t* out, size_t len) { - //printf("[%x] AesCtrWrappedIFile::read(offset=0x%" PRIx64 ", size=0x%" PRIx64 ")\n", this, mFileOffset, len); - size_t read_len; size_t read_pos; @@ -32,8 +30,6 @@ void AesCtrWrappedIFile::read(byte_t* out, size_t len) { read_len = _MIN(len - (i * kCacheSize), kCacheSize); read_pos = ((mFileOffset >> 4) << 4) + (i * kCacheSize); - - //printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len); (*mFile)->seek(read_pos); (*mFile)->read(mCache.data(), kCacheSizeAllocSize); @@ -64,8 +60,6 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len) { write_len = _MIN(len - (i * kCacheSize), kCacheSize); write_pos = ((mFileOffset >> 4) << 4) + (i * kCacheSize); - - //printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len); memcpy(mCache.data() + (mFileOffset & 0xf), in + (i * kCacheSize), write_len); @@ -77,25 +71,6 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len) } seek(mFileOffset + len); - - /* - for (size_t i = 0; i < (len / kAesCtrScratchSize); i++) - { - memcpy(mScratch.data() + mBlockOffset, out + (i * kAesCtrScratchSize), kAesCtrScratchSize); - fnd::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data()); - (*mFile)->write(mScratch.data() + mBlockOffset, kAesCtrScratchSize); - } - - if (len % kAesCtrScratchSize) - { - size_t write_len = len % kAesCtrScratchSize; - size_t write_pos = ((len / kAesCtrScratchSize) * kAesCtrScratchSize); - memcpy(mScratch.data() + mBlockOffset, out + write_pos, write_len); - fnd::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data()); - (*mFile)->write(mScratch.data() + mBlockOffset, write_len); - } - */ - seek(mFileOffset + len); } void AesCtrWrappedIFile::write(const byte_t* in, size_t offset, size_t len) diff --git a/programs/nstool/source/LayeredIntegrityWrappedIFile.cpp b/programs/nstool/source/LayeredIntegrityWrappedIFile.cpp index 41b9faa..f2148d2 100644 --- a/programs/nstool/source/LayeredIntegrityWrappedIFile.cpp +++ b/programs/nstool/source/LayeredIntegrityWrappedIFile.cpp @@ -143,12 +143,9 @@ void LayeredIntegrityWrappedIFile::initialiseDataLayer(const LayeredIntegrityMet mDataOffset = 0; mDataBlockSize = hdr.getDataLayer().block_size; - // allocate scratchpad - //mScratch.alloc(mDataBlockSize * 0x10); + // allocate cache size_t cache_size = align(kDefaultCacheSize, mDataBlockSize); mCacheBlockNum = cache_size / mDataBlockSize; - //printf("Block Size: 0x%" PRIx64 "\n", mDataBlockSize); - //printf("Cache size: 0x%" PRIx64 ", (block_num: %" PRId64 ")\n", cache_size, mCacheBlockNum); mCache.alloc(cache_size); } @@ -180,8 +177,6 @@ void LayeredIntegrityWrappedIFile::readData(size_t block_offset, size_t block_nu throw fnd::Exception(kModuleName, "Read excessive of cache size"); } - //printf("readlen=0x%" PRIx64 "\n", read_len); - // validate blocks size_t validate_size; for (size_t i = 0; i < block_num; i++) From 739b6200735dae413fb1d46733dccbe21f4206d0 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 6 Oct 2018 16:45:09 +0800 Subject: [PATCH 5/6] [fnd|nstool] Promote IFile wrapped classes to libfnd. --- lib/libfnd/include/fnd/AesCtrWrappedIFile.h | 32 +++++++++ .../include/fnd/LayeredIntegrityMetadata.h | 59 +++++++++++++++ .../fnd/LayeredIntegrityWrappedIFile.h | 47 ++++++++++++ lib/libfnd/include/fnd/OffsetAdjustedIFile.h | 23 ++++++ lib/libfnd/libfnd.vcxproj | 8 +++ lib/libfnd/libfnd.vcxproj.filters | 24 +++++++ .../libfnd}/source/AesCtrWrappedIFile.cpp | 16 ++--- .../source/LayeredIntegrityMetadata.cpp | 71 +++++++++++++++++++ .../source/LayeredIntegrityWrappedIFile.cpp | 27 ++++--- lib/libfnd/source/OffsetAdjustedIFile.cpp | 47 ++++++++++++ programs/nstool/nstool.vcxproj | 8 --- programs/nstool/nstool.vcxproj.filters | 24 ------- programs/nstool/source/AesCtrWrappedIFile.h | 28 -------- programs/nstool/source/AssetProcess.cpp | 6 +- programs/nstool/source/CnmtProcess.cpp | 2 +- programs/nstool/source/EsTikProcess.cpp | 2 +- .../source/LayeredIntegrityMetadata.cpp | 71 ------------------- .../nstool/source/LayeredIntegrityMetadata.h | 55 -------------- .../source/LayeredIntegrityWrappedIFile.h | 45 ------------ programs/nstool/source/NacpProcess.cpp | 2 +- programs/nstool/source/NcaProcess.cpp | 33 +++++---- programs/nstool/source/NcaProcess.h | 4 +- programs/nstool/source/NroProcess.cpp | 4 +- programs/nstool/source/NsoProcess.cpp | 2 +- .../nstool/source/OffsetAdjustedIFile.cpp | 47 ------------ programs/nstool/source/OffsetAdjustedIFile.h | 19 ----- programs/nstool/source/PkiCertProcess.cpp | 2 +- programs/nstool/source/XciProcess.cpp | 6 +- 28 files changed, 365 insertions(+), 349 deletions(-) create mode 100644 lib/libfnd/include/fnd/AesCtrWrappedIFile.h create mode 100644 lib/libfnd/include/fnd/LayeredIntegrityMetadata.h create mode 100644 lib/libfnd/include/fnd/LayeredIntegrityWrappedIFile.h create mode 100644 lib/libfnd/include/fnd/OffsetAdjustedIFile.h rename {programs/nstool => lib/libfnd}/source/AesCtrWrappedIFile.cpp (73%) create mode 100644 lib/libfnd/source/LayeredIntegrityMetadata.cpp rename {programs/nstool => lib/libfnd}/source/LayeredIntegrityWrappedIFile.cpp (82%) create mode 100644 lib/libfnd/source/OffsetAdjustedIFile.cpp delete mode 100644 programs/nstool/source/AesCtrWrappedIFile.h delete mode 100644 programs/nstool/source/LayeredIntegrityMetadata.cpp delete mode 100644 programs/nstool/source/LayeredIntegrityMetadata.h delete mode 100644 programs/nstool/source/LayeredIntegrityWrappedIFile.h delete mode 100644 programs/nstool/source/OffsetAdjustedIFile.cpp delete mode 100644 programs/nstool/source/OffsetAdjustedIFile.h diff --git a/lib/libfnd/include/fnd/AesCtrWrappedIFile.h b/lib/libfnd/include/fnd/AesCtrWrappedIFile.h new file mode 100644 index 0000000..88b2df6 --- /dev/null +++ b/lib/libfnd/include/fnd/AesCtrWrappedIFile.h @@ -0,0 +1,32 @@ +#pragma once +#include +#include +#include +#include + +namespace fnd +{ + class AesCtrWrappedIFile : public fnd::IFile + { + public: + AesCtrWrappedIFile(const fnd::SharedPtr& file, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr); + + size_t size(); + void seek(size_t offset); + void read(byte_t* out, size_t len); + void read(byte_t* out, size_t offset, size_t len); + void write(const byte_t* out, size_t len); + void write(const byte_t* out, size_t offset, size_t len); + private: + const std::string kModuleName = "AesCtrWrappedIFile"; + static const size_t kCacheSize = 0x10000; + static const size_t kCacheSizeAllocSize = kCacheSize + fnd::aes::kAesBlockSize; + + fnd::SharedPtr mFile; + fnd::aes::sAes128Key mKey; + fnd::aes::sAesIvCtr mBaseCtr, mCurrentCtr; + size_t mFileOffset; + + fnd::Vec mCache; + }; +} \ No newline at end of file diff --git a/lib/libfnd/include/fnd/LayeredIntegrityMetadata.h b/lib/libfnd/include/fnd/LayeredIntegrityMetadata.h new file mode 100644 index 0000000..7d1e3ac --- /dev/null +++ b/lib/libfnd/include/fnd/LayeredIntegrityMetadata.h @@ -0,0 +1,59 @@ +#pragma once +#include +#include +#include + +namespace fnd +{ + class LayeredIntegrityMetadata + { + public: + struct sLayer + { + size_t offset; + size_t size; + size_t block_size; + + void operator=(const sLayer& other) + { + offset = other.offset; + size = other.size; + block_size = other.block_size; + } + + bool operator==(const sLayer& other) const + { + return (offset == other.offset && size == other.size && block_size == other.block_size); + } + + bool operator!=(const sLayer& other) const + { + return !(*this == other); + } + }; + + LayeredIntegrityMetadata(); + + void operator=(const LayeredIntegrityMetadata& other); + bool operator==(const LayeredIntegrityMetadata& other) const; + bool operator!=(const LayeredIntegrityMetadata& other) const; + + const fnd::List& getHashLayerInfo() const; + void setHashLayerInfo(const fnd::List& layer_info); + + const sLayer& getDataLayer() const; + void setDataLayerInfo(const sLayer& data_info); + + const fnd::List& getMasterHashList() const; + void setMasterHashList(const fnd::List& master_hash_list); + + bool getAlignHashToBlock() const; + void setAlignHashToBlock(bool doAlign); + private: + // data + fnd::List mLayerInfo; + sLayer mDataLayer; + fnd::List mMasterHashList; + bool mDoAlignHashToBlock; + }; +} \ No newline at end of file diff --git a/lib/libfnd/include/fnd/LayeredIntegrityWrappedIFile.h b/lib/libfnd/include/fnd/LayeredIntegrityWrappedIFile.h new file mode 100644 index 0000000..2bc2a4d --- /dev/null +++ b/lib/libfnd/include/fnd/LayeredIntegrityWrappedIFile.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +namespace fnd +{ + class LayeredIntegrityWrappedIFile : public fnd::IFile + { + public: + LayeredIntegrityWrappedIFile(const fnd::SharedPtr& file, const LayeredIntegrityMetadata& hdr); + + size_t size(); + void seek(size_t offset); + void read(byte_t* out, size_t len); + void read(byte_t* out, size_t offset, size_t len); + void write(const byte_t* out, size_t len); + void write(const byte_t* out, size_t offset, size_t len); + private: + const std::string kModuleName = "LayeredIntegrityWrappedIFile"; + static const size_t kDefaultCacheSize = 0x10000; + std::stringstream mErrorSs; + + fnd::SharedPtr mFile; + + // data file + fnd::SharedPtr mData; + size_t mDataOffset; + size_t mDataBlockSize; + fnd::List mDataHashLayer; + bool mAlignHashCalcToBlock; + + fnd::Vec mCache; + size_t mCacheBlockNum; + + inline size_t getOffsetBlock(size_t offset) const { return offset / mDataBlockSize; } + inline size_t getOffsetInBlock(size_t offset) const { return offset % mDataBlockSize; } + inline size_t getRemanderBlockReadSize(size_t total_size) const { return total_size % mDataBlockSize; } + inline size_t getBlockNum(size_t total_size) const { return (total_size / mDataBlockSize) + (getRemanderBlockReadSize(total_size) > 0); } + + void initialiseDataLayer(const LayeredIntegrityMetadata& hdr); + void readData(size_t block_offset, size_t block_num); + }; +} \ No newline at end of file diff --git a/lib/libfnd/include/fnd/OffsetAdjustedIFile.h b/lib/libfnd/include/fnd/OffsetAdjustedIFile.h new file mode 100644 index 0000000..706e63c --- /dev/null +++ b/lib/libfnd/include/fnd/OffsetAdjustedIFile.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include + +namespace fnd +{ + class OffsetAdjustedIFile : public fnd::IFile + { + public: + OffsetAdjustedIFile(const fnd::SharedPtr& file, size_t offset, size_t size); + + size_t size(); + void seek(size_t offset); + void read(byte_t* out, size_t len); + void read(byte_t* out, size_t offset, size_t len); + void write(const byte_t* out, size_t len); + void write(const byte_t* out, size_t offset, size_t len); + private: + fnd::SharedPtr mFile; + size_t mBaseOffset, mCurrentOffset; + size_t mSize; + }; +} \ No newline at end of file diff --git a/lib/libfnd/libfnd.vcxproj b/lib/libfnd/libfnd.vcxproj index 8be0a87..0603ace 100644 --- a/lib/libfnd/libfnd.vcxproj +++ b/lib/libfnd/libfnd.vcxproj @@ -122,6 +122,7 @@ + @@ -131,8 +132,11 @@ + + + @@ -144,11 +148,15 @@ + + + + diff --git a/lib/libfnd/libfnd.vcxproj.filters b/lib/libfnd/libfnd.vcxproj.filters index 1619016..56f7ae5 100644 --- a/lib/libfnd/libfnd.vcxproj.filters +++ b/lib/libfnd/libfnd.vcxproj.filters @@ -21,6 +21,9 @@ Header Files + + Header Files + Header Files @@ -48,12 +51,21 @@ Header Files + + Header Files + + + Header Files + Header Files Header Files + + Header Files + Header Files @@ -86,6 +98,9 @@ Source Files + + Source Files + Source Files @@ -95,9 +110,18 @@ Source Files + + Source Files + + + Source Files + Source Files + + Source Files + Source Files diff --git a/programs/nstool/source/AesCtrWrappedIFile.cpp b/lib/libfnd/source/AesCtrWrappedIFile.cpp similarity index 73% rename from programs/nstool/source/AesCtrWrappedIFile.cpp rename to lib/libfnd/source/AesCtrWrappedIFile.cpp index c322560..ce8daf3 100644 --- a/programs/nstool/source/AesCtrWrappedIFile.cpp +++ b/lib/libfnd/source/AesCtrWrappedIFile.cpp @@ -1,6 +1,6 @@ -#include "AesCtrWrappedIFile.h" +#include -AesCtrWrappedIFile::AesCtrWrappedIFile(const fnd::SharedPtr& file, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr) : +fnd::AesCtrWrappedIFile::AesCtrWrappedIFile(const fnd::SharedPtr& file, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr) : mFile(file), mKey(key), mBaseCtr(ctr), @@ -9,17 +9,17 @@ AesCtrWrappedIFile::AesCtrWrappedIFile(const fnd::SharedPtr& file, c mCache.alloc(kCacheSizeAllocSize); } -size_t AesCtrWrappedIFile::size() +size_t fnd::AesCtrWrappedIFile::size() { return (*mFile)->size(); } -void AesCtrWrappedIFile::seek(size_t offset) +void fnd::AesCtrWrappedIFile::seek(size_t offset) { mFileOffset = offset; } -void AesCtrWrappedIFile::read(byte_t* out, size_t len) +void fnd::AesCtrWrappedIFile::read(byte_t* out, size_t len) { size_t read_len; size_t read_pos; @@ -43,13 +43,13 @@ void AesCtrWrappedIFile::read(byte_t* out, size_t len) seek(mFileOffset + len); } -void AesCtrWrappedIFile::read(byte_t* out, size_t offset, size_t len) +void fnd::AesCtrWrappedIFile::read(byte_t* out, size_t offset, size_t len) { seek(offset); read(out, len); } -void AesCtrWrappedIFile::write(const byte_t* in, size_t len) +void fnd::AesCtrWrappedIFile::write(const byte_t* in, size_t len) { size_t write_len; size_t write_pos; @@ -73,7 +73,7 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len) seek(mFileOffset + len); } -void AesCtrWrappedIFile::write(const byte_t* in, size_t offset, size_t len) +void fnd::AesCtrWrappedIFile::write(const byte_t* in, size_t offset, size_t len) { seek(offset); write(in, len); diff --git a/lib/libfnd/source/LayeredIntegrityMetadata.cpp b/lib/libfnd/source/LayeredIntegrityMetadata.cpp new file mode 100644 index 0000000..95c06da --- /dev/null +++ b/lib/libfnd/source/LayeredIntegrityMetadata.cpp @@ -0,0 +1,71 @@ +#include + +fnd::LayeredIntegrityMetadata::LayeredIntegrityMetadata() : + mLayerInfo(), + mDataLayer(), + mMasterHashList(), + mDoAlignHashToBlock(false) +{ + +} + +void fnd::LayeredIntegrityMetadata::operator=(const LayeredIntegrityMetadata& other) +{ + mLayerInfo = other.mLayerInfo; + mDataLayer = other.mDataLayer; + mMasterHashList = other.mMasterHashList; + mDoAlignHashToBlock = other.mDoAlignHashToBlock; +} + +bool fnd::LayeredIntegrityMetadata::operator==(const LayeredIntegrityMetadata& other) const +{ + return (mLayerInfo == other.mLayerInfo) \ + && (mDataLayer == other.mDataLayer) \ + && (mMasterHashList == other.mMasterHashList) \ + && (mDoAlignHashToBlock == other.mDoAlignHashToBlock); +} + +bool fnd::LayeredIntegrityMetadata::operator!=(const LayeredIntegrityMetadata& other) const +{ + return !(*this == other); +} + +const fnd::List& fnd::LayeredIntegrityMetadata::getHashLayerInfo() const +{ + return mLayerInfo; +} + +void fnd::LayeredIntegrityMetadata::setHashLayerInfo(const fnd::List& layer_info) +{ + mLayerInfo = layer_info; +} + +const fnd::LayeredIntegrityMetadata::sLayer& fnd::LayeredIntegrityMetadata::getDataLayer() const +{ + return mDataLayer; +} + +void fnd::LayeredIntegrityMetadata::setDataLayerInfo(const sLayer& data_info) +{ + mDataLayer = data_info; +} + +const fnd::List& fnd::LayeredIntegrityMetadata::getMasterHashList() const +{ + return mMasterHashList; +} + +void fnd::LayeredIntegrityMetadata::setMasterHashList(const fnd::List& master_hash_list) +{ + mMasterHashList = master_hash_list; +} + +bool fnd::LayeredIntegrityMetadata::getAlignHashToBlock() const +{ + return mDoAlignHashToBlock; +} + +void fnd::LayeredIntegrityMetadata::setAlignHashToBlock(bool doAlign) +{ + mDoAlignHashToBlock = doAlign; +} \ No newline at end of file diff --git a/programs/nstool/source/LayeredIntegrityWrappedIFile.cpp b/lib/libfnd/source/LayeredIntegrityWrappedIFile.cpp similarity index 82% rename from programs/nstool/source/LayeredIntegrityWrappedIFile.cpp rename to lib/libfnd/source/LayeredIntegrityWrappedIFile.cpp index f2148d2..38b5602 100644 --- a/programs/nstool/source/LayeredIntegrityWrappedIFile.cpp +++ b/lib/libfnd/source/LayeredIntegrityWrappedIFile.cpp @@ -1,8 +1,7 @@ -#include "common.h" -#include "LayeredIntegrityWrappedIFile.h" -#include "OffsetAdjustedIFile.h" +#include +#include -LayeredIntegrityWrappedIFile::LayeredIntegrityWrappedIFile(const fnd::SharedPtr& file, const LayeredIntegrityMetadata& hdr) : +fnd::LayeredIntegrityWrappedIFile::LayeredIntegrityWrappedIFile(const fnd::SharedPtr& file, const fnd::LayeredIntegrityMetadata& hdr) : mFile(file), mData(nullptr), mDataHashLayer(), @@ -11,17 +10,17 @@ LayeredIntegrityWrappedIFile::LayeredIntegrityWrappedIFile(const fnd::SharedPtr< initialiseDataLayer(hdr); } -size_t LayeredIntegrityWrappedIFile::size() +size_t fnd::LayeredIntegrityWrappedIFile::size() { return (*mData)->size(); } -void LayeredIntegrityWrappedIFile::seek(size_t offset) +void fnd::LayeredIntegrityWrappedIFile::seek(size_t offset) { mDataOffset = offset; } -void LayeredIntegrityWrappedIFile::read(byte_t* out, size_t len) +void fnd::LayeredIntegrityWrappedIFile::read(byte_t* out, size_t len) { struct sBlockPosition { @@ -72,23 +71,23 @@ void LayeredIntegrityWrappedIFile::read(byte_t* out, size_t len) seek(mDataOffset + len); } -void LayeredIntegrityWrappedIFile::read(byte_t* out, size_t offset, size_t len) +void fnd::LayeredIntegrityWrappedIFile::read(byte_t* out, size_t offset, size_t len) { seek(offset); read(out, len); } -void LayeredIntegrityWrappedIFile::write(const byte_t* out, size_t len) +void fnd::LayeredIntegrityWrappedIFile::write(const byte_t* out, size_t len) { throw fnd::Exception(kModuleName, "write() not supported"); } -void LayeredIntegrityWrappedIFile::write(const byte_t* out, size_t offset, size_t len) +void fnd::LayeredIntegrityWrappedIFile::write(const byte_t* out, size_t offset, size_t len) { throw fnd::Exception(kModuleName, "write() not supported"); } -void LayeredIntegrityWrappedIFile::initialiseDataLayer(const LayeredIntegrityMetadata& hdr) +void fnd::LayeredIntegrityWrappedIFile::initialiseDataLayer(const fnd::LayeredIntegrityMetadata& hdr) { fnd::sha::sSha256Hash hash; fnd::Vec cur, prev; @@ -106,7 +105,7 @@ void LayeredIntegrityWrappedIFile::initialiseDataLayer(const LayeredIntegrityMet for (size_t i = 0; i < hdr.getHashLayerInfo().size(); i++) { // get block size - const LayeredIntegrityMetadata::sLayer& layer = hdr.getHashLayerInfo()[i]; + const fnd::LayeredIntegrityMetadata::sLayer& layer = hdr.getHashLayerInfo()[i]; // allocate layer cur.alloc(align(layer.size, layer.block_size)); @@ -139,7 +138,7 @@ void LayeredIntegrityWrappedIFile::initialiseDataLayer(const LayeredIntegrityMet } // generate reader for data layer - mData = new OffsetAdjustedIFile(mFile, hdr.getDataLayer().offset, hdr.getDataLayer().size); + mData = new fnd::OffsetAdjustedIFile(mFile, hdr.getDataLayer().offset, hdr.getDataLayer().size); mDataOffset = 0; mDataBlockSize = hdr.getDataLayer().block_size; @@ -149,7 +148,7 @@ void LayeredIntegrityWrappedIFile::initialiseDataLayer(const LayeredIntegrityMet mCache.alloc(cache_size); } -void LayeredIntegrityWrappedIFile::readData(size_t block_offset, size_t block_num) +void fnd::LayeredIntegrityWrappedIFile::readData(size_t block_offset, size_t block_num) { fnd::sha::sSha256Hash hash; diff --git a/lib/libfnd/source/OffsetAdjustedIFile.cpp b/lib/libfnd/source/OffsetAdjustedIFile.cpp new file mode 100644 index 0000000..4cebf16 --- /dev/null +++ b/lib/libfnd/source/OffsetAdjustedIFile.cpp @@ -0,0 +1,47 @@ +#include + +fnd::OffsetAdjustedIFile::OffsetAdjustedIFile(const fnd::SharedPtr& file, size_t offset, size_t size) : + mFile(file), + mBaseOffset(offset), + mCurrentOffset(0), + mSize(size) +{ +} + +size_t fnd::OffsetAdjustedIFile::size() +{ + return mSize; +} + +void fnd::OffsetAdjustedIFile::seek(size_t offset) +{ + mCurrentOffset = _MIN(offset, mSize); +} + +void fnd::OffsetAdjustedIFile::read(byte_t* out, size_t len) +{ + // assert proper position in file + (*mFile)->seek(mCurrentOffset + mBaseOffset); + (*mFile)->read(out, len); + seek(mCurrentOffset + len); +} + +void fnd::OffsetAdjustedIFile::read(byte_t* out, size_t offset, size_t len) +{ + seek(offset); + read(out, len); +} + +void fnd::OffsetAdjustedIFile::write(const byte_t* out, size_t len) +{ + // assert proper position in file + (*mFile)->seek(mCurrentOffset + mBaseOffset); + (*mFile)->write(out, len); + seek(mCurrentOffset + len); +} + +void fnd::OffsetAdjustedIFile::write(const byte_t* out, size_t offset, size_t len) +{ + seek(offset); + write(out, len); +} \ No newline at end of file diff --git a/programs/nstool/nstool.vcxproj b/programs/nstool/nstool.vcxproj index 15f0e71..ea08f49 100644 --- a/programs/nstool/nstool.vcxproj +++ b/programs/nstool/nstool.vcxproj @@ -178,21 +178,17 @@ - - - - @@ -204,21 +200,17 @@ - - - - diff --git a/programs/nstool/nstool.vcxproj.filters b/programs/nstool/nstool.vcxproj.filters index f7b8765..7404275 100644 --- a/programs/nstool/nstool.vcxproj.filters +++ b/programs/nstool/nstool.vcxproj.filters @@ -19,9 +19,6 @@ - - Header Files - Header Files @@ -40,12 +37,6 @@ Header Files - - Header Files - - - Header Files - Header Files @@ -61,9 +52,6 @@ Header Files - - Header Files - Header Files @@ -93,9 +81,6 @@ - - Source Files - Source Files @@ -111,12 +96,6 @@ Source Files - - Source Files - - - Source Files - Source Files @@ -135,9 +114,6 @@ Source Files - - Source Files - Source Files diff --git a/programs/nstool/source/AesCtrWrappedIFile.h b/programs/nstool/source/AesCtrWrappedIFile.h deleted file mode 100644 index 0404cca..0000000 --- a/programs/nstool/source/AesCtrWrappedIFile.h +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include -#include - -class AesCtrWrappedIFile : public fnd::IFile -{ -public: - AesCtrWrappedIFile(const fnd::SharedPtr& file, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr); - - size_t size(); - void seek(size_t offset); - void read(byte_t* out, size_t len); - void read(byte_t* out, size_t offset, size_t len); - void write(const byte_t* out, size_t len); - void write(const byte_t* out, size_t offset, size_t len); -private: - const std::string kModuleName = "AesCtrWrappedIFile"; - static const size_t kCacheSize = 0x10000; - static const size_t kCacheSizeAllocSize = kCacheSize + fnd::aes::kAesBlockSize; - - fnd::SharedPtr mFile; - fnd::aes::sAes128Key mKey; - fnd::aes::sAesIvCtr mBaseCtr, mCurrentCtr; - size_t mFileOffset; - - fnd::Vec mCache; -}; \ No newline at end of file diff --git a/programs/nstool/source/AssetProcess.cpp b/programs/nstool/source/AssetProcess.cpp index a218f20..fcca0ce 100644 --- a/programs/nstool/source/AssetProcess.cpp +++ b/programs/nstool/source/AssetProcess.cpp @@ -1,9 +1,9 @@ #include #include #include +#include #include #include "AssetProcess.h" -#include "OffsetAdjustedIFile.h" AssetProcess::AssetProcess() : @@ -109,7 +109,7 @@ void AssetProcess::processSections() outfile.close(); } - mNacp.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getNacpInfo().offset, mHdr.getNacpInfo().size)); + mNacp.setInputFile(new fnd::OffsetAdjustedIFile(mFile, mHdr.getNacpInfo().offset, mHdr.getNacpInfo().size)); mNacp.setCliOutputMode(mCliOutputMode); mNacp.setVerifyMode(mVerify); @@ -121,7 +121,7 @@ void AssetProcess::processSections() if ((mHdr.getRomfsInfo().size + mHdr.getRomfsInfo().offset) > (*mFile)->size()) throw fnd::Exception(kModuleName, "ASET geometry for romfs beyond file size"); - mRomfs.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getRomfsInfo().offset, mHdr.getRomfsInfo().size)); + mRomfs.setInputFile(new fnd::OffsetAdjustedIFile(mFile, mHdr.getRomfsInfo().offset, mHdr.getRomfsInfo().size)); mRomfs.setCliOutputMode(mCliOutputMode); mRomfs.setVerifyMode(mVerify); diff --git a/programs/nstool/source/CnmtProcess.cpp b/programs/nstool/source/CnmtProcess.cpp index 8abc73d..e49093d 100644 --- a/programs/nstool/source/CnmtProcess.cpp +++ b/programs/nstool/source/CnmtProcess.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "OffsetAdjustedIFile.h" +#include #include "CnmtProcess.h" CnmtProcess::CnmtProcess() : diff --git a/programs/nstool/source/EsTikProcess.cpp b/programs/nstool/source/EsTikProcess.cpp index b3d1c73..41da96c 100644 --- a/programs/nstool/source/EsTikProcess.cpp +++ b/programs/nstool/source/EsTikProcess.cpp @@ -1,8 +1,8 @@ #include #include #include +#include #include -#include "OffsetAdjustedIFile.h" #include "EsTikProcess.h" #include "PkiValidator.h" diff --git a/programs/nstool/source/LayeredIntegrityMetadata.cpp b/programs/nstool/source/LayeredIntegrityMetadata.cpp deleted file mode 100644 index 296e84e..0000000 --- a/programs/nstool/source/LayeredIntegrityMetadata.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "LayeredIntegrityMetadata.h" - -LayeredIntegrityMetadata::LayeredIntegrityMetadata() : - mLayerInfo(), - mDataLayer(), - mMasterHashList(), - mDoAlignHashToBlock(false) -{ - -} - -void LayeredIntegrityMetadata::operator=(const LayeredIntegrityMetadata& other) -{ - mLayerInfo = other.mLayerInfo; - mDataLayer = other.mDataLayer; - mMasterHashList = other.mMasterHashList; - mDoAlignHashToBlock = other.mDoAlignHashToBlock; -} - -bool LayeredIntegrityMetadata::operator==(const LayeredIntegrityMetadata& other) const -{ - return (mLayerInfo == other.mLayerInfo) \ - && (mDataLayer == other.mDataLayer) \ - && (mMasterHashList == other.mMasterHashList) \ - && (mDoAlignHashToBlock == other.mDoAlignHashToBlock); -} - -bool LayeredIntegrityMetadata::operator!=(const LayeredIntegrityMetadata& other) const -{ - return !(*this == other); -} - -const fnd::List& LayeredIntegrityMetadata::getHashLayerInfo() const -{ - return mLayerInfo; -} - -void LayeredIntegrityMetadata::setHashLayerInfo(const fnd::List& layer_info) -{ - mLayerInfo = layer_info; -} - -const LayeredIntegrityMetadata::sLayer& LayeredIntegrityMetadata::getDataLayer() const -{ - return mDataLayer; -} - -void LayeredIntegrityMetadata::setDataLayerInfo(const sLayer& data_info) -{ - mDataLayer = data_info; -} - -const fnd::List& LayeredIntegrityMetadata::getMasterHashList() const -{ - return mMasterHashList; -} - -void LayeredIntegrityMetadata::setMasterHashList(const fnd::List& master_hash_list) -{ - mMasterHashList = master_hash_list; -} - -bool LayeredIntegrityMetadata::getAlignHashToBlock() const -{ - return mDoAlignHashToBlock; -} - -void LayeredIntegrityMetadata::setAlignHashToBlock(bool doAlign) -{ - mDoAlignHashToBlock = doAlign; -} \ No newline at end of file diff --git a/programs/nstool/source/LayeredIntegrityMetadata.h b/programs/nstool/source/LayeredIntegrityMetadata.h deleted file mode 100644 index dffa39c..0000000 --- a/programs/nstool/source/LayeredIntegrityMetadata.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include -#include - -class LayeredIntegrityMetadata -{ -public: - struct sLayer - { - size_t offset; - size_t size; - size_t block_size; - - void operator=(const sLayer& other) - { - offset = other.offset; - size = other.size; - block_size = other.block_size; - } - - bool operator==(const sLayer& other) const - { - return (offset == other.offset && size == other.size && block_size == other.block_size); - } - - bool operator!=(const sLayer& other) const - { - return !(*this == other); - } - }; - - LayeredIntegrityMetadata(); - - void operator=(const LayeredIntegrityMetadata& other); - bool operator==(const LayeredIntegrityMetadata& other) const; - bool operator!=(const LayeredIntegrityMetadata& other) const; - - const fnd::List& getHashLayerInfo() const; - void setHashLayerInfo(const fnd::List& layer_info); - - const sLayer& getDataLayer() const; - void setDataLayerInfo(const sLayer& data_info); - - const fnd::List& getMasterHashList() const; - void setMasterHashList(const fnd::List& master_hash_list); - - bool getAlignHashToBlock() const; - void setAlignHashToBlock(bool doAlign); -private: - // data - fnd::List mLayerInfo; - sLayer mDataLayer; - fnd::List mMasterHashList; - bool mDoAlignHashToBlock; -}; \ No newline at end of file diff --git a/programs/nstool/source/LayeredIntegrityWrappedIFile.h b/programs/nstool/source/LayeredIntegrityWrappedIFile.h deleted file mode 100644 index 3aa781b..0000000 --- a/programs/nstool/source/LayeredIntegrityWrappedIFile.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include "LayeredIntegrityMetadata.h" - - -class LayeredIntegrityWrappedIFile : public fnd::IFile -{ -public: - LayeredIntegrityWrappedIFile(const fnd::SharedPtr& file, const LayeredIntegrityMetadata& hdr); - - size_t size(); - void seek(size_t offset); - void read(byte_t* out, size_t len); - void read(byte_t* out, size_t offset, size_t len); - void write(const byte_t* out, size_t len); - void write(const byte_t* out, size_t offset, size_t len); -private: - const std::string kModuleName = "LayeredIntegrityWrappedIFile"; - static const size_t kDefaultCacheSize = 0x10000; - std::stringstream mErrorSs; - - fnd::SharedPtr mFile; - - // data file - fnd::SharedPtr mData; - size_t mDataOffset; - size_t mDataBlockSize; - fnd::List mDataHashLayer; - bool mAlignHashCalcToBlock; - - fnd::Vec mCache; - size_t mCacheBlockNum; - - inline size_t getOffsetBlock(size_t offset) const { return offset / mDataBlockSize; } - inline size_t getOffsetInBlock(size_t offset) const { return offset % mDataBlockSize; } - inline size_t getRemanderBlockReadSize(size_t total_size) const { return total_size % mDataBlockSize; } - inline size_t getBlockNum(size_t total_size) const { return (total_size / mDataBlockSize) + (getRemanderBlockReadSize(total_size) > 0); } - - void initialiseDataLayer(const LayeredIntegrityMetadata& hdr); - void readData(size_t block_offset, size_t block_num); -}; \ No newline at end of file diff --git a/programs/nstool/source/NacpProcess.cpp b/programs/nstool/source/NacpProcess.cpp index 2d3b02f..fb04870 100644 --- a/programs/nstool/source/NacpProcess.cpp +++ b/programs/nstool/source/NacpProcess.cpp @@ -2,7 +2,7 @@ #include #include #include -#include "OffsetAdjustedIFile.h" +#include #include "NacpProcess.h" NacpProcess::NacpProcess() : diff --git a/programs/nstool/source/NcaProcess.cpp b/programs/nstool/source/NcaProcess.cpp index 676bcc3..870aa7d 100644 --- a/programs/nstool/source/NcaProcess.cpp +++ b/programs/nstool/source/NcaProcess.cpp @@ -2,15 +2,18 @@ #include #include #include +#include +#include +#include #include #include +#include +#include #include "NcaProcess.h" #include "PfsProcess.h" #include "RomfsProcess.h" #include "NpdmProcess.h" -#include "OffsetAdjustedIFile.h" -#include "AesCtrWrappedIFile.h" -#include "LayeredIntegrityWrappedIFile.h" + NcaProcess::NcaProcess() : mFile(), @@ -261,15 +264,15 @@ void NcaProcess::generatePartitionConfiguration() { // info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, LayeredIntegrityMetadata::HASH_TYPE_SHA256); nn::hac::HierarchicalSha256Header hdr; - fnd::List hash_layers; - LayeredIntegrityMetadata::sLayer data_layer; + fnd::List hash_layers; + fnd::LayeredIntegrityMetadata::sLayer data_layer; fnd::List master_hash_list; // import raw data hdr.fromBytes(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen); for (size_t i = 0; i < hdr.getLayerInfo().size(); i++) { - LayeredIntegrityMetadata::sLayer layer; + fnd::LayeredIntegrityMetadata::sLayer layer; layer.offset = hdr.getLayerInfo()[i].offset; layer.size = hdr.getLayerInfo()[i].size; layer.block_size = hdr.getHashBlockSize(); @@ -294,14 +297,14 @@ void NcaProcess::generatePartitionConfiguration() { // info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, LayeredIntegrityMetadata::HASH_TYPE_INTEGRITY); nn::hac::HierarchicalIntegrityHeader hdr; - fnd::List hash_layers; - LayeredIntegrityMetadata::sLayer data_layer; + fnd::List hash_layers; + fnd::LayeredIntegrityMetadata::sLayer data_layer; fnd::List master_hash_list; hdr.fromBytes(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen); for (size_t i = 0; i < hdr.getLayerInfo().size(); i++) { - LayeredIntegrityMetadata::sLayer layer; + fnd::LayeredIntegrityMetadata::sLayer layer; layer.offset = hdr.getLayerInfo()[i].offset; layer.size = hdr.getLayerInfo()[i].size; layer.block_size = _BIT(hdr.getLayerInfo()[i].block_size); @@ -340,13 +343,13 @@ void NcaProcess::generatePartitionConfiguration() // create reader based on encryption type0 if (info.enc_type == nn::hac::nca::CRYPT_NONE) { - info.reader = new OffsetAdjustedIFile(mFile, info.offset, info.size); + info.reader = new fnd::OffsetAdjustedIFile(mFile, info.offset, info.size); } else if (info.enc_type == nn::hac::nca::CRYPT_AESCTR) { if (mContentKey.aes_ctr.isSet == false) throw fnd::Exception(kModuleName, "AES-CTR Key was not determined"); - info.reader = new OffsetAdjustedIFile(new AesCtrWrappedIFile(mFile, mContentKey.aes_ctr.var, info.aes_ctr), info.offset, info.size); + info.reader = new fnd::OffsetAdjustedIFile(new fnd::AesCtrWrappedIFile(mFile, mContentKey.aes_ctr.var, info.aes_ctr), info.offset, info.size); } else if (info.enc_type == nn::hac::nca::CRYPT_AESXTS || info.enc_type == nn::hac::nca::CRYPT_AESCTREX) { @@ -364,7 +367,7 @@ void NcaProcess::generatePartitionConfiguration() // filter out unrecognised hash types, and hash based readers if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256 || info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY) { - info.reader = new LayeredIntegrityWrappedIFile(info.reader, info.layered_intergrity_metadata); + info.reader = new fnd::LayeredIntegrityWrappedIFile(info.reader, info.layered_intergrity_metadata); } else if (info.hash_type != nn::hac::nca::HASH_NONE) { @@ -408,7 +411,7 @@ void NcaProcess::validateNcaSignatures() const nn::hac::PfsHeader::sFile& file = exefs.getPfsHeader().getFileList().getElement(kNpdmExefsPath); NpdmProcess npdm; - npdm.setInputFile(new OffsetAdjustedIFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader, file.offset, file.size)); + npdm.setInputFile(new fnd::OffsetAdjustedIFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader, file.offset, file.size)); npdm.setCliOutputMode(0); npdm.process(); @@ -500,7 +503,7 @@ void NcaProcess::displayHeader() } if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY) { - LayeredIntegrityMetadata& hash_hdr = info.layered_intergrity_metadata; + fnd::LayeredIntegrityMetadata& hash_hdr = info.layered_intergrity_metadata; std::cout << " HierarchicalIntegrity Header:" << std::endl; for (size_t j = 0; j < hash_hdr.getHashLayerInfo().size(); j++) { @@ -523,7 +526,7 @@ void NcaProcess::displayHeader() } else if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256) { - LayeredIntegrityMetadata& hash_hdr = info.layered_intergrity_metadata; + fnd::LayeredIntegrityMetadata& hash_hdr = info.layered_intergrity_metadata; std::cout << " HierarchicalSha256 Header:" << std::endl; std::cout << " Master Hash:" << std::endl; std::cout << " " << fnd::SimpleTextOutput::arrayToString(hash_hdr.getMasterHashList()[0].bytes, 0x10, true, ":") << std::endl; diff --git a/programs/nstool/source/NcaProcess.h b/programs/nstool/source/NcaProcess.h index 4d98268..e87a408 100644 --- a/programs/nstool/source/NcaProcess.h +++ b/programs/nstool/source/NcaProcess.h @@ -3,8 +3,8 @@ #include #include #include +#include #include -#include "LayeredIntegrityMetadata.h" #include "KeyConfiguration.h" @@ -100,7 +100,7 @@ private: nn::hac::nca::FormatType format_type; nn::hac::nca::HashType hash_type; nn::hac::nca::EncryptionType enc_type; - LayeredIntegrityMetadata layered_intergrity_metadata; + fnd::LayeredIntegrityMetadata layered_intergrity_metadata; fnd::aes::sAesIvCtr aes_ctr; } mPartitions[nn::hac::nca::kPartitionNum]; diff --git a/programs/nstool/source/NroProcess.cpp b/programs/nstool/source/NroProcess.cpp index 83c1edb..546e7fa 100644 --- a/programs/nstool/source/NroProcess.cpp +++ b/programs/nstool/source/NroProcess.cpp @@ -1,10 +1,10 @@ #include #include #include +#include #include #include #include -#include "OffsetAdjustedIFile.h" #include "NroProcess.h" NroProcess::NroProcess(): @@ -107,7 +107,7 @@ void NroProcess::importHeader() if (((le_uint64_t*)raw_hdr->reserved_0)->get() == nn::hac::nro::kNroHomebrewStructMagic && (*mFile)->size() > mHdr.getNroSize()) { mIsHomebrewNro = true; - mAssetProc.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getNroSize(), (*mFile)->size() - mHdr.getNroSize())); + mAssetProc.setInputFile(new fnd::OffsetAdjustedIFile(mFile, mHdr.getNroSize(), (*mFile)->size() - mHdr.getNroSize())); mAssetProc.setCliOutputMode(mCliOutputMode); mAssetProc.setVerifyMode(mVerify); } diff --git a/programs/nstool/source/NsoProcess.cpp b/programs/nstool/source/NsoProcess.cpp index 11261c6..3012e98 100644 --- a/programs/nstool/source/NsoProcess.cpp +++ b/programs/nstool/source/NsoProcess.cpp @@ -1,9 +1,9 @@ #include #include #include +#include #include #include -#include "OffsetAdjustedIFile.h" #include "NsoProcess.h" NsoProcess::NsoProcess(): diff --git a/programs/nstool/source/OffsetAdjustedIFile.cpp b/programs/nstool/source/OffsetAdjustedIFile.cpp deleted file mode 100644 index 4891b39..0000000 --- a/programs/nstool/source/OffsetAdjustedIFile.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "OffsetAdjustedIFile.h" - -OffsetAdjustedIFile::OffsetAdjustedIFile(const fnd::SharedPtr& file, size_t offset, size_t size) : - mFile(file), - mBaseOffset(offset), - mCurrentOffset(0), - mSize(size) -{ -} - -size_t OffsetAdjustedIFile::size() -{ - return mSize; -} - -void OffsetAdjustedIFile::seek(size_t offset) -{ - mCurrentOffset = _MIN(offset, mSize); -} - -void OffsetAdjustedIFile::read(byte_t* out, size_t len) -{ - // assert proper position in file - (*mFile)->seek(mCurrentOffset + mBaseOffset); - (*mFile)->read(out, len); - seek(mCurrentOffset + len); -} - -void OffsetAdjustedIFile::read(byte_t* out, size_t offset, size_t len) -{ - seek(offset); - read(out, len); -} - -void OffsetAdjustedIFile::write(const byte_t* out, size_t len) -{ - // assert proper position in file - (*mFile)->seek(mCurrentOffset + mBaseOffset); - (*mFile)->write(out, len); - seek(mCurrentOffset + len); -} - -void OffsetAdjustedIFile::write(const byte_t* out, size_t offset, size_t len) -{ - seek(offset); - write(out, len); -} \ No newline at end of file diff --git a/programs/nstool/source/OffsetAdjustedIFile.h b/programs/nstool/source/OffsetAdjustedIFile.h deleted file mode 100644 index be3f582..0000000 --- a/programs/nstool/source/OffsetAdjustedIFile.h +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -class OffsetAdjustedIFile : public fnd::IFile -{ -public: - OffsetAdjustedIFile(const fnd::SharedPtr& file, size_t offset, size_t size); - - size_t size(); - void seek(size_t offset); - void read(byte_t* out, size_t len); - void read(byte_t* out, size_t offset, size_t len); - void write(const byte_t* out, size_t len); - void write(const byte_t* out, size_t offset, size_t len); -private: - fnd::SharedPtr mFile; - size_t mBaseOffset, mCurrentOffset; - size_t mSize; -}; \ No newline at end of file diff --git a/programs/nstool/source/PkiCertProcess.cpp b/programs/nstool/source/PkiCertProcess.cpp index b3610f0..4433ae7 100644 --- a/programs/nstool/source/PkiCertProcess.cpp +++ b/programs/nstool/source/PkiCertProcess.cpp @@ -1,8 +1,8 @@ #include #include #include +#include #include -#include "OffsetAdjustedIFile.h" #include "PkiCertProcess.h" #include "PkiValidator.h" diff --git a/programs/nstool/source/XciProcess.cpp b/programs/nstool/source/XciProcess.cpp index 7fed532..d86c630 100644 --- a/programs/nstool/source/XciProcess.cpp +++ b/programs/nstool/source/XciProcess.cpp @@ -1,8 +1,8 @@ #include #include #include +#include #include -#include "OffsetAdjustedIFile.h" #include "XciProcess.h" XciProcess::XciProcess() : @@ -206,7 +206,7 @@ void XciProcess::processRootPfs() { std::cout << "[WARNING] XCI Root HFS0: FAIL (bad hash)" << std::endl; } - mRootPfs.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize())); + mRootPfs.setInputFile(new fnd::OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize())); mRootPfs.setListFs(mListFs); mRootPfs.setVerifyMode(false); mRootPfs.setCliOutputMode(mCliOutputMode); @@ -226,7 +226,7 @@ void XciProcess::processPartitionPfs() } PfsProcess tmp; - tmp.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress() + rootPartitions[i].offset, rootPartitions[i].size)); + tmp.setInputFile(new fnd::OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress() + rootPartitions[i].offset, rootPartitions[i].size)); tmp.setListFs(mListFs); tmp.setVerifyMode(mVerify); tmp.setCliOutputMode(mCliOutputMode); From c046340bf83028d1f623be36c787e53923a1aa57 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 6 Oct 2018 18:15:31 +0800 Subject: [PATCH 6/6] Update VSCode include paths. --- .vscode/c_cpp_properties.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index f658b73..d7e3785 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -65,7 +65,14 @@ "name": "Win32", "includePath": [ "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", - "${workspaceRoot}" + "${workspaceRoot}", + "${workspaceRoot}/lib/libfnd/include", + "${workspaceRoot}/lib/libpolarssl/include", + "${workspaceRoot}/lib/liblz4/include", + "${workspaceRoot}/lib/libes/include", + "${workspaceRoot}/lib/libpki/include", + "${workspaceRoot}/lib/libhac/include", + "${workspaceRoot}/lib/libhac-hb/include" ], "defines": [ "_DEBUG",