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];