diff --git a/lib/libnx/include/nx/aci.h b/lib/libnx/include/nx/aci.h index 0295bf3..a5bf705 100644 --- a/lib/libnx/include/nx/aci.h +++ b/lib/libnx/include/nx/aci.h @@ -4,13 +4,14 @@ #include #include #include +#include namespace nx { namespace aci { - const std::string kAciStructSig = "ACI0"; - const std::string kAciDescStructSig = "ACID"; + static const uint32_t kAciStructSig = _MAKE_STRUCT_SIGNATURE("ACI0"); + static const uint32_t kAciDescStructSig = _MAKE_STRUCT_SIGNATURE("ACID"); static const size_t kAciAlignSize = 0x10; enum Flags @@ -22,7 +23,7 @@ namespace nx #pragma pack(push,1) struct sAciHeader { - char signature[4]; + le_uint32_t signature; le_uint32_t size; // includes prefacing signature, set only in ACID made by SDK (it enables easy resigning) byte_t reserved_0[4]; le_uint32_t flags; // set in ACID only diff --git a/lib/libnx/include/nx/hierarchicalintegrity.h b/lib/libnx/include/nx/hierarchicalintegrity.h index e60350e..3e23eb3 100644 --- a/lib/libnx/include/nx/hierarchicalintegrity.h +++ b/lib/libnx/include/nx/hierarchicalintegrity.h @@ -3,13 +3,14 @@ #include #include #include +#include namespace nx { // Also known to the public as IVFC namespace hierarchicalintegrity { - const std::string kStructSig = "IVFC"; + static const uint32_t kStructSig = _MAKE_STRUCT_SIGNATURE("IVFC"); static const uint32_t kRomfsTypeId = 0x20000; static const size_t kDefaultLayerNum = 6; static const size_t kHeaderAlignLen = 0x20; @@ -18,7 +19,7 @@ namespace nx #pragma pack(push,1) struct sHierarchicalIntegrityHeader { - char signature[4]; + le_uint32_t signature; le_uint32_t type_id; le_uint32_t master_hash_size; le_uint32_t layer_num; diff --git a/lib/libnx/include/nx/macro.h b/lib/libnx/include/nx/macro.h new file mode 100644 index 0000000..9ad295c --- /dev/null +++ b/lib/libnx/include/nx/macro.h @@ -0,0 +1,3 @@ +#pragma once + +#define _MAKE_STRUCT_SIGNATURE(x) ((uint32_t)(x[3]) << 24 | (uint32_t)(x[2]) << 16 | (uint32_t)(x[1]) << 8 | (uint32_t)(x[0])) diff --git a/lib/libnx/include/nx/nca.h b/lib/libnx/include/nx/nca.h index 7158813..e9764dc 100644 --- a/lib/libnx/include/nx/nca.h +++ b/lib/libnx/include/nx/nca.h @@ -5,13 +5,14 @@ #include #include #include +#include namespace nx { namespace nca { - const std::string kNca2Sig = "NCA2"; - const std::string kNca3Sig = "NCA3"; + static const uint32_t kNca2Sig = _MAKE_STRUCT_SIGNATURE("NCA2"); + static const uint32_t kNca3Sig = _MAKE_STRUCT_SIGNATURE("NCA3"); static const size_t kSectorSize = 0x200; static const size_t kPartitionNum = 4; static const size_t kHeaderSectorNum = 6; @@ -88,7 +89,7 @@ namespace nx #pragma pack(push,1) struct sNcaHeader { - char signature[4]; + le_uint32_t signature; byte_t distribution_type; byte_t content_type; byte_t key_generation; diff --git a/lib/libnx/include/nx/npdm.h b/lib/libnx/include/nx/npdm.h index 20aaa8a..2551929 100644 --- a/lib/libnx/include/nx/npdm.h +++ b/lib/libnx/include/nx/npdm.h @@ -4,12 +4,13 @@ #include #include #include +#include namespace nx { namespace npdm { - const std::string kNpdmStructSig = "META"; + static const uint32_t kNpdmStructSig = _MAKE_STRUCT_SIGNATURE("META"); static const size_t kNameMaxLen = 0x10; static const size_t kProductCodeMaxLen = 0x10; static const uint32_t kMaxPriority = BIT(6) -1 ; @@ -33,7 +34,7 @@ namespace nx struct sNpdmHeader { - char signature[4]; + le_uint32_t signature; byte_t reserved_0[8]; byte_t flags; byte_t reserved_1; diff --git a/lib/libnx/include/nx/nso.h b/lib/libnx/include/nx/nso.h index 7f40f8a..67ed525 100644 --- a/lib/libnx/include/nx/nso.h +++ b/lib/libnx/include/nx/nso.h @@ -4,12 +4,13 @@ #include #include #include +#include namespace nx { namespace nso { - const std::string kNsoSig = "NSO0"; + static const uint32_t kNsoSig = _MAKE_STRUCT_SIGNATURE("NSO0"); enum HeaderFlags { @@ -41,7 +42,7 @@ namespace nx struct sNsoHeader { - char signature[4]; + le_uint32_t signature; le_uint32_t format_version; byte_t reserved_1[4]; le_uint32_t flags; diff --git a/lib/libnx/include/nx/pfs.h b/lib/libnx/include/nx/pfs.h index 2375d44..f00d7f9 100644 --- a/lib/libnx/include/nx/pfs.h +++ b/lib/libnx/include/nx/pfs.h @@ -2,20 +2,21 @@ #include #include #include +#include namespace nx { namespace pfs { - const std::string kPfsSig = "PFS0"; - const std::string kHashedPfsSig = "HFS0"; + static const uint32_t kPfsSig = _MAKE_STRUCT_SIGNATURE("PFS0"); + static const uint32_t kHashedPfsSig = _MAKE_STRUCT_SIGNATURE("HFS0"); static const size_t kHeaderAlign = 64; } #pragma pack(push,1) struct sPfsHeader { - char signature[4]; + le_uint32_t signature; le_uint32_t file_num; le_uint32_t name_table_size; byte_t padding[4]; diff --git a/lib/libnx/include/nx/xci.h b/lib/libnx/include/nx/xci.h index 08b35e4..bf25699 100644 --- a/lib/libnx/include/nx/xci.h +++ b/lib/libnx/include/nx/xci.h @@ -6,12 +6,13 @@ #include #include #include +#include namespace nx { namespace xci { - const std::string kXciSig = "HEAD"; + static const uint32_t kXciSig = _MAKE_STRUCT_SIGNATURE("HEAD"); static const uint32_t kHeaderEncOffset = 0x90; static const uint32_t kHeaderEncSize = 0x70; static const uint32_t kPageSize = 0x200; @@ -68,7 +69,7 @@ namespace nx #pragma pack(push,1) struct sXciHeader { - char signature[4]; + le_uint32_t signature; le_uint32_t rom_area_start_page; le_uint32_t backup_area_start_page; byte_t key_flag; diff --git a/lib/libnx/source/AciHeader.cpp b/lib/libnx/source/AciHeader.cpp index 5a7308a..9bbcc00 100644 --- a/lib/libnx/source/AciHeader.cpp +++ b/lib/libnx/source/AciHeader.cpp @@ -95,10 +95,10 @@ void AciHeader::exportBinary() switch (mType) { case (TYPE_ACI0): - memcpy(hdr->signature, aci::kAciStructSig.c_str(), 4); + hdr->signature = aci::kAciStructSig; break; case (TYPE_ACID): - memcpy(hdr->signature, aci::kAciDescStructSig.c_str(), 4); + hdr->signature = aci::kAciDescStructSig; break; default: throw fnd::Exception(kModuleName, "Unexpected ACI type"); @@ -149,16 +149,15 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len) sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes(); - if (std::string(hdr->signature, 4) == aci::kAciStructSig) + switch (hdr->signature.get()) { + case (aci::kAciStructSig): mType = TYPE_ACI0; - } - else if (std::string(hdr->signature, 4) == aci::kAciDescStructSig) - { + break; + case (aci::kAciDescStructSig): mType = TYPE_ACID; - } - else - { + break; + default: throw fnd::Exception(kModuleName, "ACI header corrupt"); } diff --git a/lib/libnx/source/HierarchicalIntegrityHeader.cpp b/lib/libnx/source/HierarchicalIntegrityHeader.cpp index 5c37e16..3eee01d 100644 --- a/lib/libnx/source/HierarchicalIntegrityHeader.cpp +++ b/lib/libnx/source/HierarchicalIntegrityHeader.cpp @@ -59,7 +59,7 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)bytes; // Validate Header Sig "IVFC" - if (std::string(hdr->signature, 4) != hierarchicalintegrity::kStructSig) + if (hdr->signature.get() != hierarchicalintegrity::kStructSig) { throw fnd::Exception(kModuleName, "Invalid struct magic"); } diff --git a/lib/libnx/source/NcaHeader.cpp b/lib/libnx/source/NcaHeader.cpp index f019276..3e1d691 100644 --- a/lib/libnx/source/NcaHeader.cpp +++ b/lib/libnx/source/NcaHeader.cpp @@ -12,10 +12,10 @@ void NcaHeader::exportBinary() switch(mFormatVersion) { case (NCA2_FORMAT): - strncpy(hdr->signature, nca::kNca2Sig.c_str(), 4); + hdr->signature = nca::kNca2Sig; break; case (NCA3_FORMAT): - strncpy(hdr->signature, nca::kNca3Sig.c_str(), 4); + hdr->signature = nca::kNca3Sig; break; default: throw fnd::Exception(kModuleName, "Unsupported format version"); @@ -74,17 +74,14 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len) sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes(); - std::string sig = std::string(hdr->signature, 4); - if (sig == nca::kNca2Sig) - { - mFormatVersion = NCA2_FORMAT; - } - else if (sig == nca::kNca3Sig) - { - mFormatVersion = NCA3_FORMAT; - } - else + switch(hdr->signature.get()) { + case (nca::kNca2Sig) : + mFormatVersion = NCA2_FORMAT; + break; + case (nca::kNca3Sig) : + mFormatVersion = NCA3_FORMAT; + break; throw fnd::Exception(kModuleName, "NCA header corrupt"); } diff --git a/lib/libnx/source/NcaUtils.cpp b/lib/libnx/source/NcaUtils.cpp index 3ee87a6..5ebb4a1 100644 --- a/lib/libnx/source/NcaUtils.cpp +++ b/lib/libnx/source/NcaUtils.cpp @@ -9,7 +9,7 @@ void nx::NcaUtils::decryptNcaHeader(const byte_t* src, byte_t* dst, const crypto crypto::aes::AesXtsMakeTweak(tweak, 1); crypto::aes::AesXtsDecryptSector(src + sectorToOffset(1), nx::nca::kSectorSize, key.key[0], key.key[1], tweak, raw_hdr); - bool useNca2SectorIndex = memcmp(((nx::sNcaHeader*)(raw_hdr))->signature, nx::nca::kNca2Sig.c_str(), 4) == 0; + bool useNca2SectorIndex = ((nx::sNcaHeader*)(raw_hdr))->signature.get() == nx::nca::kNca2Sig; // decrypt whole header for (size_t i = 0; i < nx::nca::kHeaderSectorNum; i++) diff --git a/lib/libnx/source/NpdmHeader.cpp b/lib/libnx/source/NpdmHeader.cpp index 4d2a049..db81574 100644 --- a/lib/libnx/source/NpdmHeader.cpp +++ b/lib/libnx/source/NpdmHeader.cpp @@ -88,7 +88,7 @@ void nx::NpdmHeader::exportBinary() mBinaryBlob.alloc(sizeof(sNpdmHeader)); sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes(); - memcpy(hdr->signature, npdm::kNpdmStructSig.c_str(), 4); + hdr->signature = npdm::kNpdmStructSig; byte_t flag = ((byte_t)(mInstructionType & 1) | (byte_t)((mProcAddressSpaceType & 3) << 1)) & 0xf; hdr->flags = flag; hdr->main_thread_priority = mMainThreadPriority; @@ -118,7 +118,7 @@ void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len) memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes(); - if (std::string(hdr->signature, 4) != npdm::kNpdmStructSig) + if (hdr->signature.get() != npdm::kNpdmStructSig) { throw fnd::Exception(kModuleName, "NPDM header corrupt"); } diff --git a/lib/libnx/source/NsoHeader.cpp b/lib/libnx/source/NsoHeader.cpp index e6163e4..77109c9 100644 --- a/lib/libnx/source/NsoHeader.cpp +++ b/lib/libnx/source/NsoHeader.cpp @@ -46,7 +46,7 @@ void nx::NsoHeader::exportBinary() nx::sNsoHeader* hdr = (nx::sNsoHeader*)mBinaryBlob.getBytes(); // set header identifers - memcpy(hdr->signature, nso::kNsoSig.c_str(), 4); + hdr->signature = nso::kNsoSig; hdr->format_version = nso::kDefaultFormatVersion; // variable to store flags before commiting to header @@ -141,7 +141,7 @@ void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len) const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mBinaryBlob.getBytes(); // check NSO signature - if (std::string(hdr->signature, 4) != nso::kNsoSig) + if (hdr->signature.get() != nso::kNsoSig) { throw fnd::Exception(kModuleName, "NSO header corrupt (unrecognised header signature)"); } diff --git a/lib/libnx/source/PfsHeader.cpp b/lib/libnx/source/PfsHeader.cpp index c7b0ecc..1d6af09 100644 --- a/lib/libnx/source/PfsHeader.cpp +++ b/lib/libnx/source/PfsHeader.cpp @@ -37,10 +37,10 @@ void nx::PfsHeader::exportBinary() switch (mFsType) { case (TYPE_PFS0): - strncpy(hdr->signature, pfs::kPfsSig.c_str(), 4); + hdr->signature = pfs::kPfsSig; break; case (TYPE_HFS0): - strncpy(hdr->signature, pfs::kHashedPfsSig.c_str(), 4); + hdr->signature = pfs::kHashedPfsSig; break; } @@ -102,12 +102,17 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len) // check struct signature FsType fs_type; - if (memcmp(hdr->signature, pfs::kPfsSig.c_str(), 4) == 0) - fs_type = TYPE_PFS0; - else if (memcmp(hdr->signature, pfs::kHashedPfsSig.c_str(), 4) == 0) - fs_type = TYPE_HFS0; - else - throw fnd::Exception(kModuleName, "PFS header corrupt"); + switch(hdr->signature.get()) + { + case (pfs::kPfsSig): + fs_type = TYPE_PFS0; + break; + case (pfs::kHashedPfsSig): + fs_type = TYPE_HFS0; + break; + default: + throw fnd::Exception(kModuleName, "PFS header corrupt"); + } // determine complete header size size_t pfs_full_header_size = sizeof(sPfsHeader) + getFileEntrySize(fs_type) * hdr->file_num.get() + hdr->name_table_size.get(); diff --git a/lib/libnx/source/XciHeader.cpp b/lib/libnx/source/XciHeader.cpp index 35b02ff..7c896de 100644 --- a/lib/libnx/source/XciHeader.cpp +++ b/lib/libnx/source/XciHeader.cpp @@ -129,7 +129,7 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len) const nx::sXciHeader* hdr = (const nx::sXciHeader*)mBinaryBlob.getBytes(); // check XCI signature - if (std::string(hdr->signature, 4) != xci::kXciSig) + if (hdr->signature.get() != xci::kXciSig) { throw fnd::Exception(kModuleName, "XCI header corrupt"); } diff --git a/programs/nstool/source/PfsProcess.cpp b/programs/nstool/source/PfsProcess.cpp index 3fffc0b..1f63f2c 100644 --- a/programs/nstool/source/PfsProcess.cpp +++ b/programs/nstool/source/PfsProcess.cpp @@ -124,7 +124,7 @@ void PfsProcess::displayFs() size_t PfsProcess::determineHeaderSize(const nx::sPfsHeader* hdr) { size_t fileEntrySize = 0; - if (std::string(hdr->signature, 4) == nx::pfs::kPfsSig) + if (hdr->signature.get() == nx::pfs::kPfsSig) fileEntrySize = sizeof(nx::sPfsFile); else fileEntrySize = sizeof(nx::sHashedPfsFile); @@ -134,7 +134,7 @@ size_t PfsProcess::determineHeaderSize(const nx::sPfsHeader* hdr) bool PfsProcess::validateHeaderMagic(const nx::sPfsHeader* hdr) { - return std::string(hdr->signature, 4) == nx::pfs::kPfsSig || std::string(hdr->signature, 4) == nx::pfs::kHashedPfsSig; + return hdr->signature.get() == nx::pfs::kPfsSig || hdr->signature.get() == nx::pfs::kHashedPfsSig; } void PfsProcess::validateHfs() diff --git a/programs/nstool/source/UserSettings.cpp b/programs/nstool/source/UserSettings.cpp index 1aeb524..75dc481 100644 --- a/programs/nstool/source/UserSettings.cpp +++ b/programs/nstool/source/UserSettings.cpp @@ -650,27 +650,28 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path) #define _ASSERT_SIZE(size) (scratch.getSize() >= (size)) // test npdm - if (_ASSERT_SIZE(sizeof(nx::sXciHeaderPage)) && std::string(_QUICK_CAST(nx::sXciHeaderPage, 0)->header.signature, 4) == nx::xci::kXciSig) + if (_ASSERT_SIZE(sizeof(nx::sXciHeaderPage)) && _QUICK_CAST(nx::sXciHeaderPage, 0)->header.signature.get() == nx::xci::kXciSig) file_type = FILE_XCI; // test pfs0 - else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && std::string(_QUICK_CAST(nx::sPfsHeader, 0)->signature, 4) == nx::pfs::kPfsSig) + else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && _QUICK_CAST(nx::sPfsHeader, 0)->signature.get() == nx::pfs::kPfsSig) file_type = FILE_PARTITIONFS; // test hfs0 - else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && std::string(_QUICK_CAST(nx::sPfsHeader, 0)->signature, 4) == nx::pfs::kHashedPfsSig) + else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && _QUICK_CAST(nx::sPfsHeader, 0)->signature.get() == nx::pfs::kHashedPfsSig) file_type = FILE_PARTITIONFS; // test romfs else if (_ASSERT_SIZE(sizeof(nx::sRomfsHeader)) && _QUICK_CAST(nx::sRomfsHeader, 0)->header_size.get() == sizeof(nx::sRomfsHeader) && _QUICK_CAST(nx::sRomfsHeader, 0)->sections[1].offset.get() == (_QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].offset.get() + _QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].size.get())) file_type = FILE_ROMFS; // test nca2 - else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && std::string(nca_header->signature, 4) == nx::nca::kNca2Sig) + else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && nca_header->signature.get() == nx::nca::kNca2Sig) file_type = FILE_NCA; // test nca3 - else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && std::string(nca_header->signature, 4) == nx::nca::kNca3Sig) + else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && nca_header->signature.get() == nx::nca::kNca3Sig) file_type = FILE_NCA; // test npdm - else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && std::string(_QUICK_CAST(nx::sNpdmHeader, 0)->signature, 4) == nx::npdm::kNpdmStructSig) + else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && _QUICK_CAST(nx::sNpdmHeader, 0)->signature.get() == nx::npdm::kNpdmStructSig) file_type = FILE_NPDM; - else if (_ASSERT_SIZE(sizeof(nx::sNsoHeader)) && std::string(_QUICK_CAST(nx::sNsoHeader, 0)->signature, 4) == nx::nso::kNsoSig) + // test nso + else if (_ASSERT_SIZE(sizeof(nx::sNsoHeader)) && _QUICK_CAST(nx::sNsoHeader, 0)->signature.get() == nx::nso::kNsoSig) file_type = FILE_NSO; // else unrecognised else