From 7a8d8e0feaa3ffc4e99825e8c32e0b2f8b581e9e Mon Sep 17 00:00:00 2001 From: jakcron Date: Sun, 24 Jun 2018 16:18:54 +0800 Subject: [PATCH] [nx] Update to new code style/design. --- lib/libnx/include/nx/AciBinary.h | 18 +- lib/libnx/include/nx/AciHeader.h | 21 +- lib/libnx/include/nx/AcidBinary.h | 18 +- .../nx/ApplicationControlPropertyBinary.h | 22 +- lib/libnx/include/nx/ContentMetaBinary.h | 47 ++-- lib/libnx/include/nx/FacBinary.h | 18 +- lib/libnx/include/nx/FacHeader.h | 100 +++----- .../include/nx/HierarchicalIntegrityHeader.h | 22 +- .../include/nx/HierarchicalSha256Header.h | 22 +- lib/libnx/include/nx/KcBinary.h | 24 +- lib/libnx/include/nx/NcaHeader.h | 13 +- lib/libnx/include/nx/NpdmBinary.h | 18 +- lib/libnx/include/nx/NpdmHeader.h | 21 +- lib/libnx/include/nx/NroHeader.h | 23 +- lib/libnx/include/nx/NsoHeader.h | 23 +- lib/libnx/include/nx/PfsHeader.h | 19 +- lib/libnx/include/nx/SacBinary.h | 22 +- lib/libnx/include/nx/SacEntry.h | 22 +- lib/libnx/include/nx/XciHeader.h | 23 +- lib/libnx/include/nx/aci.h | 3 - lib/libnx/include/nx/fac.h | 49 ++++ lib/libnx/nx.vcxproj | 1 + lib/libnx/nx.vcxproj.filters | 3 + lib/libnx/source/AciBinary.cpp | 113 ++++----- lib/libnx/source/AciHeader.cpp | 98 ++++---- lib/libnx/source/AcidBinary.cpp | 205 ++++++++--------- .../ApplicationControlPropertyBinary.cpp | 214 ++++++++---------- lib/libnx/source/ContentMetaBinary.cpp | 6 +- lib/libnx/source/FacBinary.cpp | 166 ++++++-------- lib/libnx/source/FacHeader.cpp | 135 +++++------ .../source/HierarchicalIntegrityHeader.cpp | 77 +++---- lib/libnx/source/HierarchicalSha256Header.cpp | 73 +++--- lib/libnx/source/KcBinary.cpp | 95 ++++---- lib/libnx/source/NcaHeader.cpp | 151 ++++++------ lib/libnx/source/NpdmBinary.cpp | 103 ++++----- lib/libnx/source/NpdmHeader.cpp | 105 ++++----- lib/libnx/source/NroHeader.cpp | 96 ++++---- lib/libnx/source/NsoHeader.cpp | 90 +++----- lib/libnx/source/PfsHeader.cpp | 136 +++++------ lib/libnx/source/SacBinary.cpp | 91 +++----- lib/libnx/source/SacEntry.cpp | 84 +++---- lib/libnx/source/XciHeader.cpp | 117 ++++------ 42 files changed, 1114 insertions(+), 1593 deletions(-) create mode 100644 lib/libnx/include/nx/fac.h diff --git a/lib/libnx/include/nx/AciBinary.h b/lib/libnx/include/nx/AciBinary.h index c32e01c..b8d43b4 100644 --- a/lib/libnx/include/nx/AciBinary.h +++ b/lib/libnx/include/nx/AciBinary.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include #include @@ -15,19 +14,15 @@ namespace nx public: AciBinary(); AciBinary(const AciBinary& other); - AciBinary(const byte_t* bytes, size_t len); + void operator=(const AciBinary& other); bool operator==(const AciBinary& other) const; bool operator!=(const AciBinary& other) const; - void operator=(const AciBinary& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - virtual void exportBinary(); - virtual void importBinary(const byte_t* bytes, size_t len); + virtual void toBytes(); + virtual void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables virtual void clear(); @@ -45,15 +40,12 @@ namespace nx const std::string kModuleName = "ACI_BINARY"; // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables FacBinary mFac; SacBinary mSac; KcBinary mKc; - - bool isEqual(const AciBinary& other) const; - void copyFrom(const AciBinary& other); }; } diff --git a/lib/libnx/include/nx/AciHeader.h b/lib/libnx/include/nx/AciHeader.h index 71734d0..2d6e2c6 100644 --- a/lib/libnx/include/nx/AciHeader.h +++ b/lib/libnx/include/nx/AciHeader.h @@ -1,14 +1,13 @@ #pragma once #include #include -#include -#include +#include #include namespace nx { class AciHeader : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: enum AciType @@ -42,19 +41,15 @@ namespace nx AciHeader(); AciHeader(const AciHeader& other); - AciHeader(const byte_t* bytes, size_t len); + void operator=(const AciHeader& other); bool operator==(const AciHeader& other) const; bool operator!=(const AciHeader& other) const; - void operator=(const AciHeader& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - virtual void exportBinary(); - virtual void importBinary(const byte_t* bytes, size_t len); + virtual void toBytes(); + virtual void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables virtual void clear(); @@ -91,7 +86,7 @@ namespace nx const std::string kModuleName = "ACI_HEADER"; // raw data - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // ACI variables uint64_t mProgramId; @@ -109,8 +104,6 @@ namespace nx sSection mFac, mSac, mKc; void calculateSectionOffsets(); - bool isEqual(const AciHeader& other) const; - void copyFrom(const AciHeader& other); }; } diff --git a/lib/libnx/include/nx/AcidBinary.h b/lib/libnx/include/nx/AcidBinary.h index c00b1d7..c8bb558 100644 --- a/lib/libnx/include/nx/AcidBinary.h +++ b/lib/libnx/include/nx/AcidBinary.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include @@ -12,21 +11,17 @@ namespace nx public: AcidBinary(); AcidBinary(const AcidBinary& other); - AcidBinary(const byte_t* bytes, size_t len); + void operator=(const AcidBinary& other); bool operator==(const AcidBinary& other) const; bool operator!=(const AcidBinary& other) const; - void operator=(const AcidBinary& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - virtual void exportBinary(); + void toBytes(); void signBinary(const crypto::rsa::sRsa2048Key& key); - virtual void importBinary(const byte_t* bytes, size_t len); + void fromBytes(const byte_t* bytes, size_t len); void verifyBinary(const crypto::rsa::sRsa2048Key& key) const; + const fnd::Vec& getBytes() const; // variables virtual void clear(); @@ -38,13 +33,10 @@ namespace nx const std::string kModuleName = "ACID_BINARY"; // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables crypto::rsa::sRsa2048Key mEmbeddedPublicKey; - - bool isEqual(const AcidBinary& other) const; - void copyFrom(const AcidBinary& other); }; } diff --git a/lib/libnx/include/nx/ApplicationControlPropertyBinary.h b/lib/libnx/include/nx/ApplicationControlPropertyBinary.h index a5aed57..ed5a96d 100644 --- a/lib/libnx/include/nx/ApplicationControlPropertyBinary.h +++ b/lib/libnx/include/nx/ApplicationControlPropertyBinary.h @@ -1,15 +1,14 @@ #pragma once #include #include -#include +#include #include -#include #include namespace nx { class ApplicationControlPropertyBinary : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: struct sTitle @@ -86,19 +85,15 @@ namespace nx ApplicationControlPropertyBinary(); ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other); - ApplicationControlPropertyBinary(const byte_t* bytes, size_t len); + void operator=(const ApplicationControlPropertyBinary& other); bool operator==(const ApplicationControlPropertyBinary& other) const; bool operator!=(const ApplicationControlPropertyBinary& other) const; - void operator=(const ApplicationControlPropertyBinary& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -222,7 +217,7 @@ namespace nx const std::string kModuleName = "APPLICATION_CONTROL_PROPERTY"; // raw data - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables fnd::List mTitle; @@ -263,8 +258,5 @@ namespace nx nacp::PlayLogQueryCapability mPlayLogQueryCapability; nacp::RepairFlag mRepairFlag; byte_t mProgramIndex; - - bool isEqual(const ApplicationControlPropertyBinary& other) const; - void copyFrom(const ApplicationControlPropertyBinary& other); }; } \ No newline at end of file diff --git a/lib/libnx/include/nx/ContentMetaBinary.h b/lib/libnx/include/nx/ContentMetaBinary.h index 6bf2ddb..59eee5d 100644 --- a/lib/libnx/include/nx/ContentMetaBinary.h +++ b/lib/libnx/include/nx/ContentMetaBinary.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include @@ -8,7 +8,7 @@ namespace nx { class ContentMetaBinary : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: struct ContentInfo @@ -18,13 +18,12 @@ namespace nx size_t size; cnmt::ContentType type; - ContentInfo& operator=(const ContentInfo& other) + void operator=(const ContentInfo& other) { hash = other.hash; memcpy(nca_id, other.nca_id, cnmt::kContentIdLen); size = other.size; type = other.type; - return *this; } bool operator==(const ContentInfo& other) const @@ -48,13 +47,12 @@ namespace nx cnmt::ContentMetaType type; byte_t attributes; - ContentMetaInfo& operator=(const ContentMetaInfo& other) + void operator=(const ContentMetaInfo& other) { id = other.id; version = other.version; type = other.type; attributes = other.attributes; - return *this; } bool operator==(const ContentMetaInfo& other) const @@ -76,11 +74,10 @@ namespace nx uint64_t patch_id; uint32_t required_system_version; - ApplicationMetaExtendedHeader& operator=(const ApplicationMetaExtendedHeader& other) + void operator=(const ApplicationMetaExtendedHeader& other) { patch_id = other.patch_id; required_system_version = other.required_system_version; - return *this; } bool operator==(const ApplicationMetaExtendedHeader& other) const @@ -100,11 +97,10 @@ namespace nx uint64_t application_id; uint32_t required_system_version; - PatchMetaExtendedHeader& operator=(const PatchMetaExtendedHeader& other) + void operator=(const PatchMetaExtendedHeader& other) { application_id = other.application_id; required_system_version = other.required_system_version; - return *this; } bool operator==(const PatchMetaExtendedHeader& other) const @@ -124,11 +120,10 @@ namespace nx uint64_t application_id; uint32_t required_system_version; - AddOnContentMetaExtendedHeader& operator=(const AddOnContentMetaExtendedHeader& other) + void operator=(const AddOnContentMetaExtendedHeader& other) { application_id = other.application_id; required_system_version = other.required_system_version; - return *this; } bool operator==(const AddOnContentMetaExtendedHeader& other) const @@ -147,10 +142,9 @@ namespace nx { uint64_t application_id; - DeltaMetaExtendedHeader& operator=(const DeltaMetaExtendedHeader& other) + void operator=(const DeltaMetaExtendedHeader& other) { application_id = other.application_id; - return *this; } bool operator==(const DeltaMetaExtendedHeader& other) const @@ -166,15 +160,15 @@ namespace nx ContentMetaBinary(); ContentMetaBinary(const ContentMetaBinary& other); - ContentMetaBinary(const byte_t* bytes, size_t len); - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; + void operator=(const ContentMetaBinary& other); + bool operator==(const ContentMetaBinary& other) const; + bool operator!=(const ContentMetaBinary& other) const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -212,8 +206,8 @@ namespace nx const fnd::List& getContentMetaInfo() const; void setContentMetaInfo(const fnd::List& info); - const fnd::MemoryBlob& getExtendedData() const; - void setExtendedData(const fnd::MemoryBlob& data); + const fnd::Vec& getExtendedData() const; + void setExtendedData(const fnd::Vec& data); const nx::sDigest& getDigest() const; void setDigest(const nx::sDigest& digest); @@ -223,7 +217,7 @@ namespace nx const std::string kModuleName = "CONTENT_META_BINARY"; // binary blob - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables uint64_t mTitleId; @@ -231,7 +225,7 @@ namespace nx cnmt::ContentMetaType mType; byte_t mAttributes; uint32_t mRequiredDownloadSystemVersion; - fnd::MemoryBlob mExtendedHeader; + fnd::Vec mExtendedHeader; ApplicationMetaExtendedHeader mApplicationMetaExtendedHeader; PatchMetaExtendedHeader mPatchMetaExtendedHeader; @@ -240,7 +234,7 @@ namespace nx fnd::List mContentInfo; fnd::List mContentMetaInfo; - fnd::MemoryBlob mExtendedData; + fnd::Vec mExtendedData; nx::sDigest mDigest; inline size_t getExtendedHeaderOffset() const { return sizeof(sContentMetaHeader); } @@ -253,8 +247,5 @@ namespace nx bool validateExtendedHeaderSize(cnmt::ContentMetaType type, size_t exhdrSize) const; size_t getExtendedDataSize(cnmt::ContentMetaType type, const byte_t* data) const; void validateBinary(const byte_t* bytes, size_t len) const; - - bool isEqual(const ContentMetaBinary& other) const; - void copyFrom(const ContentMetaBinary& other); }; } \ No newline at end of file diff --git a/lib/libnx/include/nx/FacBinary.h b/lib/libnx/include/nx/FacBinary.h index 619617c..bba22a6 100644 --- a/lib/libnx/include/nx/FacBinary.h +++ b/lib/libnx/include/nx/FacBinary.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include @@ -13,19 +12,15 @@ namespace nx public: FacBinary(); FacBinary(const FacBinary& other); - FacBinary(const byte_t* bytes, size_t len); + void operator=(const FacBinary& other); bool operator==(const FacBinary& other) const; bool operator!=(const FacBinary& other) const; - void operator=(const FacBinary& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -41,14 +36,11 @@ namespace nx static const uint32_t kFacFormatVersion = 1; // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables fnd::List mContentOwnerIdList; fnd::List mSaveDataOwnerIdList; - - bool isEqual(const FacBinary& other) const; - void copyFrom(const FacBinary& other); }; } diff --git a/lib/libnx/include/nx/FacHeader.h b/lib/libnx/include/nx/FacHeader.h index 672c451..55bcc7d 100644 --- a/lib/libnx/include/nx/FacHeader.h +++ b/lib/libnx/include/nx/FacHeader.h @@ -1,56 +1,49 @@ #pragma once #include -#include +#include #include -#include +#include namespace nx { class FacHeader : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: - enum FsAccessFlag + struct sSection { - FSA_APPLICATION_INFO, - FSA_BOOT_MODE_CONTROL, - FSA_CALIBRATION, - FSA_SYSTEM_SAVE_DATA, - FSA_GAME_CARD, - FSA_SAVE_DATA_BACKUP, - FSA_SAVE_DATA_MANAGEMENT, - FSA_BIS_ALL_RAW, - FSA_GAME_CARD_RAW, - FSA_GAME_CARD_PRIVATE, - FSA_SET_TIME, - FSA_CONTENT_MANAGER, - FSA_IMAGE_MANAGER, - FSA_CREATE_SAVE_DATA, - FSA_SYSTEM_SAVE_DATA_MANAGEMENT, - FSA_BIS_FILE_SYSTEM, - FSA_SYSTEM_UPDATE, - FSA_SAVE_DATA_META, - FSA_DEVICE_SAVE_CONTROL, - FSA_SETTINGS_CONTROL, - FSA_DEBUG = 62, - FSA_FULL_PERMISSION = 63, + size_t offset; + size_t size; + + void operator=(const sSection& other) + { + offset = other.offset; + size = other.size; + } + + bool operator==(const sSection& other) const + { + return (offset == other.offset) \ + && (size == other.size); + } + + bool operator!=(const sSection& other) const + { + return !operator==(other); + } }; FacHeader(); FacHeader(const FacHeader& other); - FacHeader(const byte_t* bytes, size_t len); + void operator=(const FacHeader& other); bool operator==(const FacHeader& other) const; bool operator!=(const FacHeader& other) const; - void operator=(const FacHeader& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -59,49 +52,28 @@ namespace nx uint32_t getFormatVersion() const; void setFormatVersion(uint32_t version); - const fnd::List& getFsaRightsList() const; - void setFsaRightsList(const fnd::List& list); + const fnd::List& getFsaRightsList() const; + void setFsaRightsList(const fnd::List& list); - size_t getContentOwnerIdOffset() const; - size_t getContentOwnerIdSize() const; + const sSection& getContentOwnerIdPos() const; void setContentOwnerIdSize(size_t size); - size_t getSaveDataOwnerIdOffset() const; - size_t getSaveDataOwnerIdSize() const; + const sSection& getSaveDataOwnerIdPos() const;; void setSaveDataOwnerIdSize(size_t size); private: const std::string kModuleName = "FAC_HEADER"; - static const uint32_t kFacFormatVersion = 1; - -#pragma pack (push, 1) - struct sFacHeader - { - le_uint32_t version; // default 1 - le_uint64_t fac_flags; - struct sFacSection - { - le_uint32_t start; - le_uint32_t end; - } content_owner_ids, save_data_owner_ids; // the data for these follow later in binary. start/end relative to base of FacData instance - }; -#pragma pack (pop) - + // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables uint32_t mVersion; - fnd::List mFsaRights; - struct sSection - { - size_t offset; - size_t size; - } mContentOwnerIdPos, mSaveDataOwnerIdPos; + fnd::List mFsaRights; + sSection mContentOwnerIdPos; + sSection mSaveDataOwnerIdPos; void calculateOffsets(); - bool isEqual(const FacHeader& other) const; - void copyFrom(const FacHeader& other); }; } diff --git a/lib/libnx/include/nx/HierarchicalIntegrityHeader.h b/lib/libnx/include/nx/HierarchicalIntegrityHeader.h index ddcb5f9..66b933c 100644 --- a/lib/libnx/include/nx/HierarchicalIntegrityHeader.h +++ b/lib/libnx/include/nx/HierarchicalIntegrityHeader.h @@ -1,13 +1,12 @@ #pragma once #include -#include +#include #include -#include namespace nx { class HierarchicalIntegrityHeader : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: struct sLayer @@ -36,19 +35,15 @@ namespace nx HierarchicalIntegrityHeader(); HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader& other); - HierarchicalIntegrityHeader(const byte_t* bytes, size_t len); + void operator=(const HierarchicalIntegrityHeader& other); bool operator==(const HierarchicalIntegrityHeader& other) const; bool operator!=(const HierarchicalIntegrityHeader& other) const; - void operator=(const HierarchicalIntegrityHeader& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -62,14 +57,11 @@ namespace nx const std::string kModuleName = "HIERARCHICAL_INTEGRITY_HEADER"; // binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // data fnd::List mLayerInfo; fnd::List mMasterHashList; - - bool isEqual(const HierarchicalIntegrityHeader& other) const; - void copyFrom(const HierarchicalIntegrityHeader& other); }; } \ No newline at end of file diff --git a/lib/libnx/include/nx/HierarchicalSha256Header.h b/lib/libnx/include/nx/HierarchicalSha256Header.h index f5568e8..4082916 100644 --- a/lib/libnx/include/nx/HierarchicalSha256Header.h +++ b/lib/libnx/include/nx/HierarchicalSha256Header.h @@ -1,13 +1,12 @@ #pragma once #include -#include +#include #include -#include namespace nx { class HierarchicalSha256Header : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: struct sLayer @@ -34,19 +33,15 @@ namespace nx HierarchicalSha256Header(); HierarchicalSha256Header(const HierarchicalSha256Header& other); - HierarchicalSha256Header(const byte_t* bytes, size_t len); + void operator=(const HierarchicalSha256Header& other); bool operator==(const HierarchicalSha256Header& other) const; bool operator!=(const HierarchicalSha256Header& other) const; - void operator=(const HierarchicalSha256Header& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -63,15 +58,12 @@ namespace nx const std::string kModuleName = "HIERARCHICAL_SHA256_HEADER"; // binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // data crypto::sha::sSha256Hash mMasterHash; size_t mHashBlockSize; fnd::List mLayerInfo; - - bool isEqual(const HierarchicalSha256Header& other) const; - void copyFrom(const HierarchicalSha256Header& other); }; } \ No newline at end of file diff --git a/lib/libnx/include/nx/KcBinary.h b/lib/libnx/include/nx/KcBinary.h index ca2ad3a..cab1261 100644 --- a/lib/libnx/include/nx/KcBinary.h +++ b/lib/libnx/include/nx/KcBinary.h @@ -1,9 +1,8 @@ #pragma once #include #include -#include +#include #include -#include #include #include #include @@ -16,24 +15,20 @@ namespace nx { class KcBinary : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: KcBinary(); KcBinary(const KcBinary& other); - KcBinary(const byte_t* bytes, size_t len); + void operator=(const KcBinary& other); bool operator==(const KcBinary& other) const; bool operator!=(const KcBinary& other) const; - void operator=(const KcBinary& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + virtual const fnd::Vec& getBytes() const; // variables (consider further abstraction?) void clear(); @@ -65,7 +60,7 @@ namespace nx const std::string kModuleName = "KC_BINARY"; // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables ThreadInfoHandler mThreadInfo; @@ -76,11 +71,6 @@ namespace nx KernelVersionHandler mKernelVersion; HandleTableSizeHandler mHandleTableSize; MiscFlagsHandler mMiscFlags; - - - void clearVariables(); - bool isEqual(const KcBinary& other) const; - void copyFrom(const KcBinary& other); }; } diff --git a/lib/libnx/include/nx/NcaHeader.h b/lib/libnx/include/nx/NcaHeader.h index 3b417d4..5917f4d 100644 --- a/lib/libnx/include/nx/NcaHeader.h +++ b/lib/libnx/include/nx/NcaHeader.h @@ -49,19 +49,18 @@ namespace nx NcaHeader(); NcaHeader(const NcaHeader& other); - NcaHeader(const byte_t* bytes, size_t len); + void operator=(const NcaHeader& other); bool operator==(const NcaHeader& other) const; bool operator!=(const NcaHeader& other) const; - void operator=(const NcaHeader& other); // to be used after export - const byte_t* getBytes() const; size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -95,7 +94,7 @@ namespace nx const std::string kModuleName = "NCA_HEADER"; // binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // data FormatVersion mFormatVersion; @@ -113,8 +112,6 @@ namespace nx uint64_t blockNumToSize(uint32_t block_num) const; uint32_t sizeToBlockNum(uint64_t real_size) const; - bool isEqual(const NcaHeader& other) const; - void copyFrom(const NcaHeader& other); }; } \ No newline at end of file diff --git a/lib/libnx/include/nx/NpdmBinary.h b/lib/libnx/include/nx/NpdmBinary.h index e6aaa35..c09ae6c 100644 --- a/lib/libnx/include/nx/NpdmBinary.h +++ b/lib/libnx/include/nx/NpdmBinary.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include #include @@ -15,19 +14,15 @@ namespace nx public: NpdmBinary(); NpdmBinary(const NpdmBinary& other); - NpdmBinary(const byte_t* bytes, size_t len); + void operator=(const NpdmBinary& other); bool operator==(const NpdmBinary& other) const; bool operator!=(const NpdmBinary& other) const; - void operator=(const NpdmBinary& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -41,14 +36,11 @@ namespace nx const std::string kModuleName = "NPDM_BINARY"; // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables AciBinary mAci; AcidBinary mAcid; - - bool isEqual(const NpdmBinary& other) const; - void copyFrom(const NpdmBinary& other); }; } diff --git a/lib/libnx/include/nx/NpdmHeader.h b/lib/libnx/include/nx/NpdmHeader.h index 7054bee..f258ade 100644 --- a/lib/libnx/include/nx/NpdmHeader.h +++ b/lib/libnx/include/nx/NpdmHeader.h @@ -1,14 +1,13 @@ #pragma once #include #include -#include -#include +#include #include namespace nx { class NpdmHeader : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: struct sSection @@ -36,19 +35,15 @@ namespace nx NpdmHeader(); NpdmHeader(const NpdmHeader& other); - NpdmHeader(const byte_t* bytes, size_t len); + void operator=(const NpdmHeader& other); bool operator==(const NpdmHeader& other) const; bool operator!=(const NpdmHeader& other) const; - void operator=(const NpdmHeader& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -87,7 +82,7 @@ namespace nx const std::string kModuleName = "NPDM_HEADER"; // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables npdm::InstructionType mInstructionType; @@ -102,8 +97,6 @@ namespace nx sSection mAcidPos; void calculateOffsets(); - bool isEqual(const NpdmHeader& other) const; - void copyFrom(const NpdmHeader& other); }; } diff --git a/lib/libnx/include/nx/NroHeader.h b/lib/libnx/include/nx/NroHeader.h index f259e5d..cb1dc95 100644 --- a/lib/libnx/include/nx/NroHeader.h +++ b/lib/libnx/include/nx/NroHeader.h @@ -1,13 +1,12 @@ #pragma once #include -#include +#include #include -#include namespace nx { class NroHeader : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: struct sRoCrt @@ -75,19 +74,15 @@ namespace nx NroHeader(); NroHeader(const NroHeader& other); - NroHeader(const byte_t* bytes, size_t len); + void operator=(const NroHeader& other); bool operator==(const NroHeader& other) const; bool operator!=(const NroHeader& other) const; - void operator=(const NroHeader& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -125,7 +120,7 @@ namespace nx const std::string kModuleName = "NRO_HEADER"; // binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // data sRoCrt mRoCrt; @@ -138,10 +133,6 @@ namespace nx sSection mRoEmbeddedInfo; sSection mRoDynStrInfo; sSection mRoDynSymInfo; - - // helpers - bool isEqual(const NroHeader& other) const; - void copyFrom(const NroHeader& other); }; } \ No newline at end of file diff --git a/lib/libnx/include/nx/NsoHeader.h b/lib/libnx/include/nx/NsoHeader.h index 37cca28..cd65fde 100644 --- a/lib/libnx/include/nx/NsoHeader.h +++ b/lib/libnx/include/nx/NsoHeader.h @@ -1,13 +1,12 @@ #pragma once #include -#include +#include #include -#include namespace nx { class NsoHeader : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: struct sModuleId @@ -87,19 +86,15 @@ namespace nx NsoHeader(); NsoHeader(const NsoHeader& other); - NsoHeader(const byte_t* bytes, size_t len); + void operator=(const NsoHeader& other); bool operator==(const NsoHeader& other) const; bool operator!=(const NsoHeader& other) const; - void operator=(const NsoHeader& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -134,7 +129,7 @@ namespace nx const std::string kModuleName = "NSO_HEADER"; // binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // data sModuleId mModuleId; @@ -146,10 +141,6 @@ namespace nx sLayout mRoEmbeddedInfo; sLayout mRoDynStrInfo; sLayout mRoDynSymInfo; - - // helpers - bool isEqual(const NsoHeader& other) const; - void copyFrom(const NsoHeader& other); }; } \ No newline at end of file diff --git a/lib/libnx/include/nx/PfsHeader.h b/lib/libnx/include/nx/PfsHeader.h index c3a76a1..2c5ed37 100644 --- a/lib/libnx/include/nx/PfsHeader.h +++ b/lib/libnx/include/nx/PfsHeader.h @@ -1,16 +1,15 @@ #pragma once #include #include -#include +#include #include -#include #include namespace nx { class PfsHeader : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: enum FsType @@ -64,24 +63,22 @@ namespace nx PfsHeader(); PfsHeader(const PfsHeader& other); - PfsHeader(const byte_t* bytes, size_t len); + void operator=(const PfsHeader& other); bool operator==(const PfsHeader& other) const; bool operator!=(const PfsHeader& other) const; - void operator=(const PfsHeader& other); // to be used after export - const byte_t* getBytes() const; size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); - FsType getFsType() const; void setFsType(FsType type); const fnd::List& getFileList() const; @@ -92,7 +89,7 @@ namespace nx const std::string kModuleName = "PFS_HEADER"; // binary blob - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables FsType mFsType; @@ -100,8 +97,6 @@ namespace nx size_t getFileEntrySize(FsType fs_type); void calculateOffsets(size_t data_offset); - bool isEqual(const PfsHeader& other) const; - void copyFrom(const PfsHeader& other); }; } diff --git a/lib/libnx/include/nx/SacBinary.h b/lib/libnx/include/nx/SacBinary.h index 8e8fcd8..77d025c 100644 --- a/lib/libnx/include/nx/SacBinary.h +++ b/lib/libnx/include/nx/SacBinary.h @@ -1,32 +1,27 @@ #pragma once #include #include -#include +#include #include -#include #include namespace nx { class SacBinary : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: SacBinary(); SacBinary(const SacBinary& other); - SacBinary(const byte_t* bytes, size_t len); + void operator=(const SacBinary& other); bool operator==(const SacBinary& other) const; bool operator!=(const SacBinary& other) const; - void operator=(const SacBinary& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -36,13 +31,10 @@ namespace nx const std::string kModuleName = "SAC_BINARY"; // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables fnd::List mServices; - - bool isEqual(const SacBinary& other) const; - void copyFrom(const SacBinary& other); }; } diff --git a/lib/libnx/include/nx/SacEntry.h b/lib/libnx/include/nx/SacEntry.h index c6d4117..7e1d4b1 100644 --- a/lib/libnx/include/nx/SacEntry.h +++ b/lib/libnx/include/nx/SacEntry.h @@ -1,30 +1,26 @@ #pragma once #include #include -#include -#include +#include namespace nx { class SacEntry : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: SacEntry(); SacEntry(const std::string& name, bool isServer); SacEntry(const SacEntry& other); + void operator=(const SacEntry& other); bool operator==(const SacEntry& other) const; bool operator!=(const SacEntry& other) const; - void operator=(const SacEntry& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -38,12 +34,12 @@ namespace nx enum SacEntryFlag { - SAC_IS_SERVER = BIT(7), - SAC_NAME_LEN_MASK = BIT(7) - 1 + SAC_IS_SERVER = _BIT(7), + SAC_NAME_LEN_MASK = _BIT(7) - 1 }; // raw binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // variables bool mIsServer; diff --git a/lib/libnx/include/nx/XciHeader.h b/lib/libnx/include/nx/XciHeader.h index f469f12..bbbf2cd 100644 --- a/lib/libnx/include/nx/XciHeader.h +++ b/lib/libnx/include/nx/XciHeader.h @@ -1,30 +1,25 @@ #pragma once #include -#include +#include #include -#include namespace nx { class XciHeader : - public fnd::ISerialiseableBinary + public fnd::ISerialisable { public: XciHeader(); XciHeader(const XciHeader& other); - XciHeader(const byte_t* bytes, size_t len); + void operator=(const XciHeader& other); bool operator==(const XciHeader& other) const; bool operator!=(const XciHeader& other) const; - void operator=(const XciHeader& other); - - // to be used after export - const byte_t* getBytes() const; - size_t getSize() const; // export/import binary - void exportBinary(); - void importBinary(const byte_t* bytes, size_t len); + void toBytes(); + void fromBytes(const byte_t* bytes, size_t len); + const fnd::Vec& getBytes() const; // variables void clear(); @@ -92,7 +87,7 @@ namespace nx const std::string kModuleName = "XCI_HEADER"; // binary - fnd::MemoryBlob mBinaryBlob; + fnd::Vec mRawBinary; // data uint32_t mRomAreaStartPage; @@ -125,10 +120,6 @@ namespace nx uint32_t mUppVersion; byte_t mUppHash[8]; uint64_t mUppId; - - // helpers - bool isEqual(const XciHeader& other) const; - void copyFrom(const XciHeader& other); }; } \ No newline at end of file diff --git a/lib/libnx/include/nx/aci.h b/lib/libnx/include/nx/aci.h index a5bf705..1f6cfea 100644 --- a/lib/libnx/include/nx/aci.h +++ b/lib/libnx/include/nx/aci.h @@ -1,9 +1,6 @@ #pragma once #include #include -#include -#include -#include #include namespace nx diff --git a/lib/libnx/include/nx/fac.h b/lib/libnx/include/nx/fac.h new file mode 100644 index 0000000..4202698 --- /dev/null +++ b/lib/libnx/include/nx/fac.h @@ -0,0 +1,49 @@ +#pragma once +#include + +namespace nx +{ + namespace fac + { + enum FsAccessFlag + { + FSA_APPLICATION_INFO, + FSA_BOOT_MODE_CONTROL, + FSA_CALIBRATION, + FSA_SYSTEM_SAVE_DATA, + FSA_GAME_CARD, + FSA_SAVE_DATA_BACKUP, + FSA_SAVE_DATA_MANAGEMENT, + FSA_BIS_ALL_RAW, + FSA_GAME_CARD_RAW, + FSA_GAME_CARD_PRIVATE, + FSA_SET_TIME, + FSA_CONTENT_MANAGER, + FSA_IMAGE_MANAGER, + FSA_CREATE_SAVE_DATA, + FSA_SYSTEM_SAVE_DATA_MANAGEMENT, + FSA_BIS_FILE_SYSTEM, + FSA_SYSTEM_UPDATE, + FSA_SAVE_DATA_META, + FSA_DEVICE_SAVE_CONTROL, + FSA_SETTINGS_CONTROL, + FSA_DEBUG = 62, + FSA_FULL_PERMISSION = 63, + }; + + static const uint32_t kFacFormatVersion = 1; + } + +#pragma pack(push,1) + struct sFacHeader + { + le_uint32_t version; // default 1 + le_uint64_t fac_flags; + struct sFacSection + { + le_uint32_t start; + le_uint32_t end; + } content_owner_ids, save_data_owner_ids; // the data for these follow later in binary. start/end relative to base of FacData instance + }; +#pragma pack(pop) +} \ No newline at end of file diff --git a/lib/libnx/nx.vcxproj b/lib/libnx/nx.vcxproj index c8becaa..7b42859 100644 --- a/lib/libnx/nx.vcxproj +++ b/lib/libnx/nx.vcxproj @@ -29,6 +29,7 @@ + diff --git a/lib/libnx/nx.vcxproj.filters b/lib/libnx/nx.vcxproj.filters index 065a177..8521759 100644 --- a/lib/libnx/nx.vcxproj.filters +++ b/lib/libnx/nx.vcxproj.filters @@ -186,6 +186,9 @@ Header Files + + Header Files + diff --git a/lib/libnx/source/AciBinary.cpp b/lib/libnx/source/AciBinary.cpp index e6c3376..02462f9 100644 --- a/lib/libnx/source/AciBinary.cpp +++ b/lib/libnx/source/AciBinary.cpp @@ -1,7 +1,5 @@ #include - - nx::AciBinary::AciBinary() { clear(); @@ -9,96 +7,100 @@ nx::AciBinary::AciBinary() nx::AciBinary::AciBinary(const AciBinary & other) { - copyFrom(other); -} - -nx::AciBinary::AciBinary(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - -bool nx::AciBinary::operator==(const AciBinary & other) const -{ - return isEqual(other); -} - -bool nx::AciBinary::operator!=(const AciBinary & other) const -{ - return !isEqual(other); + *this = other; } void nx::AciBinary::operator=(const AciBinary & other) { - copyFrom(other); + if (other.getBytes().size()) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + AciHeader::operator=(other); + mFac = other.mFac; + mSac = other.mSac; + mKc = other.mKc; + } } -const byte_t * nx::AciBinary::getBytes() const +bool nx::AciBinary::operator==(const AciBinary & other) const { - return mBinaryBlob.getBytes(); + return (AciHeader::operator==(other)) \ + && (mFac == other.mFac) \ + && (mSac == other.mSac) \ + && (mKc == other.mKc); } -size_t nx::AciBinary::getSize() const +bool nx::AciBinary::operator!=(const AciBinary & other) const { - return mBinaryBlob.getSize(); + return !(*this == other); } -void nx::AciBinary::exportBinary() +void nx::AciBinary::toBytes() { // export components - mFac.exportBinary(); - mSac.exportBinary(); - mKc.exportBinary(); + mFac.toBytes(); + mSac.toBytes(); + mKc.toBytes(); // set sizes - setFacSize(mFac.getSize()); - setSacSize(mSac.getSize()); - setKcSize(mKc.getSize()); + setFacSize(mFac.getBytes().size()); + setSacSize(mSac.getBytes().size()); + setKcSize(mKc.getBytes().size()); // export header - AciHeader::exportBinary(); + AciHeader::toBytes(); // allocate binary - mBinaryBlob.alloc(getAciSize()); + mRawBinary.alloc(getAciSize()); // copy header - memcpy(mBinaryBlob.getBytes(), AciHeader::getBytes(), AciHeader::getSize()); + memcpy(mRawBinary.data(), AciHeader::getBytes().data(), AciHeader::getBytes().size()); // copy components - memcpy(mBinaryBlob.getBytes() + getFacPos().offset, mFac.getBytes(), mFac.getSize()); - memcpy(mBinaryBlob.getBytes() + getSacPos().offset, mSac.getBytes(), mSac.getSize()); - memcpy(mBinaryBlob.getBytes() + getKcPos().offset, mKc.getBytes(), mKc.getSize()); + memcpy(mRawBinary.data() + getFacPos().offset, mFac.getBytes().data(), mFac.getBytes().size()); + memcpy(mRawBinary.data() + getSacPos().offset, mSac.getBytes().data(), mSac.getBytes().size()); + memcpy(mRawBinary.data() + getKcPos().offset, mKc.getBytes().data(), mKc.getBytes().size()); } -void nx::AciBinary::importBinary(const byte_t * bytes, size_t len) +void nx::AciBinary::fromBytes(const byte_t * bytes, size_t len) { - AciHeader::importBinary(bytes, len); + AciHeader::fromBytes(bytes, len); if (getAciSize() > len) { throw fnd::Exception(kModuleName, "ACI binary too small"); } - mBinaryBlob.alloc(getAciSize()); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(getAciSize()); + memcpy(mRawBinary.data(), bytes, mRawBinary.size()); if (getFacPos().size > 0) { - mFac.importBinary(mBinaryBlob.getBytes() + getFacPos().offset, getFacPos().size); + mFac.fromBytes(mRawBinary.data() + getFacPos().offset, getFacPos().size); } if (getSacPos().size > 0) { - mSac.importBinary(mBinaryBlob.getBytes() + getSacPos().offset, getSacPos().size); + mSac.fromBytes(mRawBinary.data() + getSacPos().offset, getSacPos().size); } if (getKcPos().size > 0) { - mKc.importBinary(mBinaryBlob.getBytes() + getKcPos().offset, getKcPos().size); + mKc.fromBytes(mRawBinary.data() + getKcPos().offset, getKcPos().size); } } +const fnd::Vec& nx::AciBinary::getBytes() const +{ + return mRawBinary; +} + void nx::AciBinary::clear() { AciHeader::clear(); + mRawBinary.clear(); mFac.clear(); mSac.clear(); mKc.clear(); @@ -132,27 +134,4 @@ const nx::KcBinary & nx::AciBinary::getKc() const void nx::AciBinary::setKc(const KcBinary & kc) { mKc = kc; -} - -bool nx::AciBinary::isEqual(const AciBinary & other) const -{ - return (AciHeader::operator==(other)) \ - && (mFac == other.mFac) \ - && (mSac == other.mSac) \ - && (mKc == other.mKc); -} - -void nx::AciBinary::copyFrom(const AciBinary & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - AciHeader::operator=(other); - mFac = other.mFac; - mSac = other.mSac; - mKc = other.mKc; - } -} +} \ No newline at end of file diff --git a/lib/libnx/source/AciHeader.cpp b/lib/libnx/source/AciHeader.cpp index 9bbcc00..c017676 100644 --- a/lib/libnx/source/AciHeader.cpp +++ b/lib/libnx/source/AciHeader.cpp @@ -2,33 +2,21 @@ using namespace nx; -void AciHeader::calculateSectionOffsets() +AciHeader::AciHeader() { - mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize); - mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize); - mKc.offset = mSac.offset + align(mSac.size, aci::kAciAlignSize); + clear(); } -bool AciHeader::isEqual(const AciHeader & other) const +AciHeader::AciHeader(const AciHeader & other) { - return (mHeaderOffset == other.mHeaderOffset) \ - && (mType == other.mType) \ - && (mIsProduction == other.mIsProduction) \ - && (mIsUnqualifiedApproval == other.mIsUnqualifiedApproval) \ - && (mAcidSize == other.mAcidSize) \ - && (mProgramIdMin == other.mProgramIdMin) \ - && (mProgramIdMax == other.mProgramIdMax) \ - && (mProgramId == other.mProgramId) \ - && (mFac == other.mFac) \ - && (mSac == other.mSac) \ - && (mKc == other.mKc); + *this = other; } -void AciHeader::copyFrom(const AciHeader & other) +void AciHeader::operator=(const AciHeader & other) { - if (other.getSize()) + if (other.getBytes().size()) { - importBinary(other.getBytes(), other.getSize()); + fromBytes(other.getBytes().data(), other.getBytes().size()); } else { @@ -46,50 +34,30 @@ void AciHeader::copyFrom(const AciHeader & other) } } -AciHeader::AciHeader() -{ - clear(); -} - -AciHeader::AciHeader(const AciHeader & other) -{ - importBinary(other.getBytes(), other.getSize()); -} - -AciHeader::AciHeader(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - bool AciHeader::operator==(const AciHeader & other) const { - return isEqual(other); + return (mHeaderOffset == other.mHeaderOffset) \ + && (mType == other.mType) \ + && (mIsProduction == other.mIsProduction) \ + && (mIsUnqualifiedApproval == other.mIsUnqualifiedApproval) \ + && (mAcidSize == other.mAcidSize) \ + && (mProgramIdMin == other.mProgramIdMin) \ + && (mProgramIdMax == other.mProgramIdMax) \ + && (mProgramId == other.mProgramId) \ + && (mFac == other.mFac) \ + && (mSac == other.mSac) \ + && (mKc == other.mKc); } bool AciHeader::operator!=(const AciHeader & other) const { - return !isEqual(other); + return !(*this == other); } -void AciHeader::operator=(const AciHeader & other) +void AciHeader::toBytes() { - this->importBinary(other.getBytes(), other.getSize()); -} - -const byte_t * AciHeader::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t AciHeader::getSize() const -{ - return mBinaryBlob.getSize(); -} - -void AciHeader::exportBinary() -{ - mBinaryBlob.alloc(sizeof(sAciHeader)); - sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(sizeof(sAciHeader)); + sAciHeader* hdr = (sAciHeader*)mRawBinary.data(); // set type switch (mType) @@ -135,7 +103,7 @@ void AciHeader::exportBinary() } } -void AciHeader::importBinary(const byte_t * bytes, size_t len) +void AciHeader::fromBytes(const byte_t * bytes, size_t len) { if (len < sizeof(sAciHeader)) { @@ -144,10 +112,10 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len) clear(); - mBinaryBlob.alloc(sizeof(sAciHeader)); - memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sAciHeader)); + mRawBinary.alloc(sizeof(sAciHeader)); + memcpy(mRawBinary.data(), bytes, sizeof(sAciHeader)); - sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes(); + sAciHeader* hdr = (sAciHeader*)mRawBinary.data(); switch (hdr->signature.get()) { @@ -192,9 +160,14 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len) mKc.size = hdr->kc.size.get(); } +const fnd::Vec& AciHeader::getBytes() const +{ + return mRawBinary; +} + void nx::AciHeader::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); mHeaderOffset = 0; mType = TYPE_ACI0; mProgramId = 0; @@ -322,3 +295,10 @@ void AciHeader::setKcSize(size_t size) { mKc.size = size; } + +void AciHeader::calculateSectionOffsets() +{ + mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize); + mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize); + mKc.offset = mSac.offset + align(mSac.size, aci::kAciAlignSize); +} \ No newline at end of file diff --git a/lib/libnx/source/AcidBinary.cpp b/lib/libnx/source/AcidBinary.cpp index c1017a2..f77ea61 100644 --- a/lib/libnx/source/AcidBinary.cpp +++ b/lib/libnx/source/AcidBinary.cpp @@ -1,7 +1,5 @@ #include - - nx::AcidBinary::AcidBinary() { clear(); @@ -9,17 +7,106 @@ nx::AcidBinary::AcidBinary() nx::AcidBinary::AcidBinary(const AcidBinary & other) { - copyFrom(other); + *this = other; } -nx::AcidBinary::AcidBinary(const byte_t * bytes, size_t len) +bool nx::AcidBinary::operator==(const AcidBinary & other) const { - importBinary(bytes, len); + return AciBinary::operator==(other) \ + && (mEmbeddedPublicKey == other.mEmbeddedPublicKey); +} + +bool nx::AcidBinary::operator!=(const AcidBinary & other) const +{ + return !(*this == other); +} + +void nx::AcidBinary::operator=(const AcidBinary & other) +{ + if (other.getBytes().size()) + { + importBinary(other.getBytes().data(), other.getBytes().size()); + } + else + { + AciBinary::operator=(other); + mEmbeddedPublicKey = other.mEmbeddedPublicKey; + } +} + +void nx::AcidBinary::toBytes() +{ + AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature + AciBinary::exportBinary(); + mRawBinary.alloc(AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2); + + memcpy(mRawBinary.data() + crypto::rsa::kRsa2048Size, mEmbeddedPublicKey.modulus, crypto::rsa::kRsa2048Size); + memcpy(mRawBinary.data() + crypto::rsa::kRsa2048Size * 2, AciBinary::getBytes().data(), AciBinary::getBytes().size()); +} + +void nx::AcidBinary::signBinary(const crypto::rsa::sRsa2048Key & key) +{ + if (mRawBinary.size() == 0) + { + exportBinary(); + } + + byte_t hash[crypto::sha::kSha256HashLen]; + crypto::sha::Sha256(mRawBinary.data() + crypto::rsa::kRsa2048Size, mRawBinary.size() - crypto::rsa::kRsa2048Size, hash); + + if (crypto::rsa::pkcs::rsaSign(key, crypto::sha::HASH_SHA256, hash, mRawBinary.data()) != 0) + { + throw fnd::Exception(kModuleName, "Failed to sign ACID"); + } +} + +void nx::AcidBinary::fromBytes(const byte_t * bytes, size_t len) +{ + if (len <= crypto::rsa::kRsa2048Size*2) + { + throw fnd::Exception(kModuleName, "ACID binary too small"); + } + + // import aci binary past sig + pubkey + AciBinary::importBinary(bytes + crypto::rsa::kRsa2048Size * 2, len - crypto::rsa::kRsa2048Size * 2); + + // save internal copy + size_t acid_size = AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2; + if (acid_size > len) + { + throw fnd::Exception(kModuleName, "ACID binary too small"); + } + + mRawBinary.alloc(acid_size); + memcpy(mRawBinary.data(), bytes, mRawBinary.size()); + memcpy(mEmbeddedPublicKey.modulus, bytes + crypto::rsa::kRsa2048Size, crypto::rsa::kRsa2048Size); +} + +void nx::AcidBinary::verifyBinary(const crypto::rsa::sRsa2048Key & key) const +{ + if (mRawBinary.size() == 0) + { + throw fnd::Exception(kModuleName, "No ACID binary exists to verify"); + } + + byte_t hash[crypto::sha::kSha256HashLen]; + crypto::sha::Sha256(mRawBinary.data() + crypto::rsa::kRsa2048Size, mRawBinary.size() - crypto::rsa::kRsa2048Size, hash); + + if (crypto::rsa::pss::rsaVerify(key, crypto::sha::HASH_SHA256, hash, mRawBinary.data()) != 0) + { + throw fnd::Exception(kModuleName, "Failed to verify ACID"); + } +} + +const fnd::Vec& nx::AcidBinary::getBytes() const +{ + return mRawBinary; } void nx::AcidBinary::clear() { AciBinary::clear(); + mRawBinary.clear(); mEmbeddedPublicKey = crypto::rsa::sRsa2048Key(); } @@ -32,111 +119,3 @@ void nx::AcidBinary::setNcaHeader2RsaKey(const crypto::rsa::sRsa2048Key & key) { mEmbeddedPublicKey = key; } - -bool nx::AcidBinary::isEqual(const AcidBinary & other) const -{ - return AciBinary::operator==(other) \ - && (mEmbeddedPublicKey == other.mEmbeddedPublicKey); -} - -void nx::AcidBinary::copyFrom(const AcidBinary & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - AciBinary::operator=(other); - mEmbeddedPublicKey = other.mEmbeddedPublicKey; - } -} - -bool nx::AcidBinary::operator==(const AcidBinary & other) const -{ - return isEqual(other); -} - -bool nx::AcidBinary::operator!=(const AcidBinary & other) const -{ - return !isEqual(other); -} - -void nx::AcidBinary::operator=(const AcidBinary & other) -{ - copyFrom(other); -} - -const byte_t * nx::AcidBinary::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::AcidBinary::getSize() const -{ - return mBinaryBlob.getSize(); -} - -void nx::AcidBinary::exportBinary() -{ - AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature - AciBinary::exportBinary(); - mBinaryBlob.alloc(AciBinary::getSize() + crypto::rsa::kRsa2048Size * 2); - - memcpy(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mEmbeddedPublicKey.modulus, crypto::rsa::kRsa2048Size); - memcpy(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size * 2, AciBinary::getBytes(), AciBinary::getSize()); -} - -void nx::AcidBinary::signBinary(const crypto::rsa::sRsa2048Key & key) -{ - if (mBinaryBlob.getSize() == 0) - { - exportBinary(); - } - - byte_t hash[crypto::sha::kSha256HashLen]; - crypto::sha::Sha256(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mBinaryBlob.getSize() - crypto::rsa::kRsa2048Size, hash); - - if (crypto::rsa::pkcs::rsaSign(key, crypto::sha::HASH_SHA256, hash, mBinaryBlob.getBytes()) != 0) - { - throw fnd::Exception(kModuleName, "Failed to sign ACID"); - } -} - -void nx::AcidBinary::importBinary(const byte_t * bytes, size_t len) -{ - if (len <= crypto::rsa::kRsa2048Size*2) - { - throw fnd::Exception(kModuleName, "ACID binary too small"); - } - - // import aci binary past sig + pubkey - AciBinary::importBinary(bytes + crypto::rsa::kRsa2048Size * 2, len - crypto::rsa::kRsa2048Size * 2); - - // save internal copy - size_t acid_size = AciBinary::getSize() + crypto::rsa::kRsa2048Size * 2; - if (acid_size > len) - { - throw fnd::Exception(kModuleName, "ACID binary too small"); - } - - mBinaryBlob.alloc(acid_size); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); - memcpy(mEmbeddedPublicKey.modulus, bytes + crypto::rsa::kRsa2048Size, crypto::rsa::kRsa2048Size); -} - -void nx::AcidBinary::verifyBinary(const crypto::rsa::sRsa2048Key & key) const -{ - if (mBinaryBlob.getSize() == 0) - { - throw fnd::Exception(kModuleName, "No ACID binary exists to verify"); - } - - byte_t hash[crypto::sha::kSha256HashLen]; - crypto::sha::Sha256(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mBinaryBlob.getSize() - crypto::rsa::kRsa2048Size, hash); - - if (crypto::rsa::pss::rsaVerify(key, crypto::sha::HASH_SHA256, hash, mBinaryBlob.getBytes()) != 0) - { - throw fnd::Exception(kModuleName, "Failed to verify ACID"); - } -} diff --git a/lib/libnx/source/ApplicationControlPropertyBinary.cpp b/lib/libnx/source/ApplicationControlPropertyBinary.cpp index c5f60a8..5edb57b 100644 --- a/lib/libnx/source/ApplicationControlPropertyBinary.cpp +++ b/lib/libnx/source/ApplicationControlPropertyBinary.cpp @@ -7,17 +7,92 @@ nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary() nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other) { - copyFrom(other); + *this = other; } -nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const byte_t* bytes, size_t len) +void nx::ApplicationControlPropertyBinary::operator=(const ApplicationControlPropertyBinary& other) { - importBinary(bytes, len); + clear(); + mTitle = other.mTitle; + mIsbn = other.mIsbn; + mStartupUserAccount = other.mStartupUserAccount; + mTouchScreenUsageMode = other.mTouchScreenUsageMode; + mAocRegistrationType = other.mAocRegistrationType; + mAttributeFlag = other.mAttributeFlag; + mParentalControlFlag = other.mParentalControlFlag; + mScreenshotMode = other.mScreenshotMode; + mVideoCaptureMode = other.mVideoCaptureMode; + mDataLossConfirmation = other.mDataLossConfirmation; + mPlayLogPolicy = other.mPlayLogPolicy; + mPresenceGroupId = other.mPresenceGroupId; + mRatingAge = other.mRatingAge; + mDisplayVersion = other.mDisplayVersion; + mAocBaseId = other.mAocBaseId; + mSaveDatawOwnerId = other.mSaveDatawOwnerId; + mUserAccountSaveDataSize = other.mUserAccountSaveDataSize; + mDeviceSaveDataSize = other.mDeviceSaveDataSize; + mBcatDeliveryCacheStorageSize = other.mBcatDeliveryCacheStorageSize; + mApplicationErrorCodeCategory = other.mApplicationErrorCodeCategory; + mLocalCommunicationId = other.mLocalCommunicationId; + mLogoType = other.mLogoType; + mLogoHandling = other.mLogoHandling; + mRuntimeAocInstallMode = other.mRuntimeAocInstallMode; + mCrashReportMode = other.mCrashReportMode; + mHdcp = other.mHdcp; + mSeedForPsuedoDeviceId = other.mSeedForPsuedoDeviceId; + mBcatPassphase = other.mBcatPassphase; + mUserAccountSaveDataMax = other.mUserAccountSaveDataMax; + mDeviceSaveDataMax = other.mDeviceSaveDataMax; + mTemporaryStorageSize = other.mTemporaryStorageSize; + mCacheStorageSize = other.mCacheStorageSize; + mCacheStorageDataAndJournalSizeMax = other.mCacheStorageDataAndJournalSizeMax; + mCacheStorageIndex = other.mCacheStorageIndex; + mPlayLogQueryableApplicationId = other.mPlayLogQueryableApplicationId; + mPlayLogQueryCapability = other.mPlayLogQueryCapability; + mRepairFlag = other.mRepairFlag; + mProgramIndex = other.mProgramIndex; } bool nx::ApplicationControlPropertyBinary::operator==(const ApplicationControlPropertyBinary& other) const { - return isEqual(other); + return (mTitle == other.mTitle) \ + && (mIsbn == other.mIsbn) \ + && (mStartupUserAccount == other.mStartupUserAccount) \ + && (mTouchScreenUsageMode == other.mTouchScreenUsageMode) \ + && (mAocRegistrationType == other.mAocRegistrationType) \ + && (mAttributeFlag == other.mAttributeFlag) \ + && (mParentalControlFlag == other.mParentalControlFlag) \ + && (mScreenshotMode == other.mScreenshotMode) \ + && (mVideoCaptureMode == other.mVideoCaptureMode) \ + && (mDataLossConfirmation == other.mDataLossConfirmation) \ + && (mPlayLogPolicy == other.mPlayLogPolicy) \ + && (mPresenceGroupId == other.mPresenceGroupId) \ + && (mRatingAge == other.mRatingAge) \ + && (mDisplayVersion == other.mDisplayVersion) \ + && (mAocBaseId == other.mAocBaseId) \ + && (mSaveDatawOwnerId == other.mSaveDatawOwnerId) \ + && (mUserAccountSaveDataSize == other.mUserAccountSaveDataSize) \ + && (mDeviceSaveDataSize == other.mDeviceSaveDataSize) \ + && (mBcatDeliveryCacheStorageSize == other.mBcatDeliveryCacheStorageSize) \ + && (mApplicationErrorCodeCategory == other.mApplicationErrorCodeCategory) \ + && (mLocalCommunicationId == other.mLocalCommunicationId) \ + && (mLogoType == other.mLogoType) \ + && (mLogoHandling == other.mLogoHandling) \ + && (mRuntimeAocInstallMode == other.mRuntimeAocInstallMode) \ + && (mCrashReportMode == other.mCrashReportMode) \ + && (mHdcp == other.mHdcp) \ + && (mSeedForPsuedoDeviceId == other.mSeedForPsuedoDeviceId) \ + && (mBcatPassphase == other.mBcatPassphase) \ + && (mUserAccountSaveDataMax == other.mUserAccountSaveDataMax) \ + && (mDeviceSaveDataMax == other.mDeviceSaveDataMax) \ + && (mTemporaryStorageSize == other.mTemporaryStorageSize) \ + && (mCacheStorageSize == other.mCacheStorageSize) \ + && (mCacheStorageDataAndJournalSizeMax == other.mCacheStorageDataAndJournalSizeMax) \ + && (mCacheStorageIndex == other.mCacheStorageIndex) \ + && (mPlayLogQueryableApplicationId == other.mPlayLogQueryableApplicationId) \ + && (mPlayLogQueryCapability == other.mPlayLogQueryCapability) \ + && (mRepairFlag == other.mRepairFlag) \ + && (mProgramIndex == other.mProgramIndex); } bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPropertyBinary& other) const @@ -25,30 +100,15 @@ bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPr return !(*this == other); } -void nx::ApplicationControlPropertyBinary::operator=(const ApplicationControlPropertyBinary& other) +void nx::ApplicationControlPropertyBinary::toBytes() { - copyFrom(other); -} + mRawBinary.alloc(sizeof(nx::sApplicationControlProperty)); -const byte_t* nx::ApplicationControlPropertyBinary::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::ApplicationControlPropertyBinary::getSize() const -{ - return mBinaryBlob.getSize(); -} - -void nx::ApplicationControlPropertyBinary::exportBinary() -{ - mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty)); - - sApplicationControlProperty* data = (sApplicationControlProperty*)mBinaryBlob.getBytes(); + sApplicationControlProperty* data = (sApplicationControlProperty*)mRawBinary.data(); // strings uint32_t supported_langs = 0; - for (size_t i = 0; i < mTitle.getSize(); i++) + for (size_t i = 0; i < mTitle.size(); i++) { supported_langs = _BIT(mTitle[i].language); strncpy(data->title[mTitle[i].language].name, mTitle[i].name.c_str(), nacp::kNameLength); @@ -82,18 +142,18 @@ void nx::ApplicationControlPropertyBinary::exportBinary() // misc params data->presence_group_id = mPresenceGroupId; memset(data->rating_age, nacp::kUnusedAgeRating, nacp::kRatingAgeCount); // clear ratings - for (size_t i = 0; i < mRatingAge.getSize(); i++) + for (size_t i = 0; i < mRatingAge.size(); i++) { data->rating_age[mRatingAge[i].organisation] = mRatingAge[i].age; } data->add_on_content_base_id = mAocBaseId; data->save_data_owner_id = mSaveDatawOwnerId; - for (size_t i = 0; i < mLocalCommunicationId.getSize() && i < nacp::kLocalCommunicationIdCount; i++) + for (size_t i = 0; i < mLocalCommunicationId.size() && i < nacp::kLocalCommunicationIdCount; i++) { data->local_communication_id[i] = mLocalCommunicationId[i]; } data->seed_for_pseudo_device_id = mSeedForPsuedoDeviceId; - for (size_t i = 0; i < mPlayLogQueryableApplicationId.getSize() && i < nacp::kPlayLogQueryableApplicationIdCount; i++) + for (size_t i = 0; i < mPlayLogQueryableApplicationId.size() && i < nacp::kPlayLogQueryableApplicationIdCount; i++) { data->play_log_queryable_application_id[i] = mPlayLogQueryableApplicationId[i]; } @@ -116,7 +176,7 @@ void nx::ApplicationControlPropertyBinary::exportBinary() data->cache_storage_data_and_journal_size_max = mCacheStorageDataAndJournalSizeMax; } -void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, size_t len) +void nx::ApplicationControlPropertyBinary::fromBytes(const byte_t* bytes, size_t len) { if (len < sizeof(nx::sApplicationControlProperty)) { @@ -125,10 +185,10 @@ void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, siz clear(); - mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty)); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(sizeof(nx::sApplicationControlProperty)); + memcpy(mRawBinary.data(), bytes, mRawBinary.size()); - const sApplicationControlProperty* data = (const sApplicationControlProperty*)mBinaryBlob.getBytes(); + const sApplicationControlProperty* data = (const sApplicationControlProperty*)mRawBinary.data(); // strings for (size_t i = 0; i < nacp::kMaxLanguageCount; i++) @@ -204,9 +264,14 @@ void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, siz mCacheStorageDataAndJournalSizeMax = (int64_t)data->cache_storage_data_and_journal_size_max.get(); } +const fnd::Vec& nx::ApplicationControlPropertyBinary::getBytes() const +{ + return mRawBinary; +} + void nx::ApplicationControlPropertyBinary::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); mTitle.clear(); mIsbn.clear(); mStartupUserAccount = nacp::USER_None; @@ -625,89 +690,4 @@ byte_t nx::ApplicationControlPropertyBinary::getProgramIndex() const void nx::ApplicationControlPropertyBinary::setProgramIndex(byte_t var) { mProgramIndex = var; -} - -bool nx::ApplicationControlPropertyBinary::isEqual(const ApplicationControlPropertyBinary& other) const -{ - return (mTitle == other.mTitle) \ - && (mIsbn == other.mIsbn) \ - && (mStartupUserAccount == other.mStartupUserAccount) \ - && (mTouchScreenUsageMode == other.mTouchScreenUsageMode) \ - && (mAocRegistrationType == other.mAocRegistrationType) \ - && (mAttributeFlag == other.mAttributeFlag) \ - && (mParentalControlFlag == other.mParentalControlFlag) \ - && (mScreenshotMode == other.mScreenshotMode) \ - && (mVideoCaptureMode == other.mVideoCaptureMode) \ - && (mDataLossConfirmation == other.mDataLossConfirmation) \ - && (mPlayLogPolicy == other.mPlayLogPolicy) \ - && (mPresenceGroupId == other.mPresenceGroupId) \ - && (mRatingAge == other.mRatingAge) \ - && (mDisplayVersion == other.mDisplayVersion) \ - && (mAocBaseId == other.mAocBaseId) \ - && (mSaveDatawOwnerId == other.mSaveDatawOwnerId) \ - && (mUserAccountSaveDataSize == other.mUserAccountSaveDataSize) \ - && (mDeviceSaveDataSize == other.mDeviceSaveDataSize) \ - && (mBcatDeliveryCacheStorageSize == other.mBcatDeliveryCacheStorageSize) \ - && (mApplicationErrorCodeCategory == other.mApplicationErrorCodeCategory) \ - && (mLocalCommunicationId == other.mLocalCommunicationId) \ - && (mLogoType == other.mLogoType) \ - && (mLogoHandling == other.mLogoHandling) \ - && (mRuntimeAocInstallMode == other.mRuntimeAocInstallMode) \ - && (mCrashReportMode == other.mCrashReportMode) \ - && (mHdcp == other.mHdcp) \ - && (mSeedForPsuedoDeviceId == other.mSeedForPsuedoDeviceId) \ - && (mBcatPassphase == other.mBcatPassphase) \ - && (mUserAccountSaveDataMax == other.mUserAccountSaveDataMax) \ - && (mDeviceSaveDataMax == other.mDeviceSaveDataMax) \ - && (mTemporaryStorageSize == other.mTemporaryStorageSize) \ - && (mCacheStorageSize == other.mCacheStorageSize) \ - && (mCacheStorageDataAndJournalSizeMax == other.mCacheStorageDataAndJournalSizeMax) \ - && (mCacheStorageIndex == other.mCacheStorageIndex) \ - && (mPlayLogQueryableApplicationId == other.mPlayLogQueryableApplicationId) \ - && (mPlayLogQueryCapability == other.mPlayLogQueryCapability) \ - && (mRepairFlag == other.mRepairFlag) \ - && (mProgramIndex == other.mProgramIndex); -} - -void nx::ApplicationControlPropertyBinary::copyFrom(const ApplicationControlPropertyBinary& other) -{ - clear(); - mTitle = other.mTitle; - mIsbn = other.mIsbn; - mStartupUserAccount = other.mStartupUserAccount; - mTouchScreenUsageMode = other.mTouchScreenUsageMode; - mAocRegistrationType = other.mAocRegistrationType; - mAttributeFlag = other.mAttributeFlag; - mParentalControlFlag = other.mParentalControlFlag; - mScreenshotMode = other.mScreenshotMode; - mVideoCaptureMode = other.mVideoCaptureMode; - mDataLossConfirmation = other.mDataLossConfirmation; - mPlayLogPolicy = other.mPlayLogPolicy; - mPresenceGroupId = other.mPresenceGroupId; - mRatingAge = other.mRatingAge; - mDisplayVersion = other.mDisplayVersion; - mAocBaseId = other.mAocBaseId; - mSaveDatawOwnerId = other.mSaveDatawOwnerId; - mUserAccountSaveDataSize = other.mUserAccountSaveDataSize; - mDeviceSaveDataSize = other.mDeviceSaveDataSize; - mBcatDeliveryCacheStorageSize = other.mBcatDeliveryCacheStorageSize; - mApplicationErrorCodeCategory = other.mApplicationErrorCodeCategory; - mLocalCommunicationId = other.mLocalCommunicationId; - mLogoType = other.mLogoType; - mLogoHandling = other.mLogoHandling; - mRuntimeAocInstallMode = other.mRuntimeAocInstallMode; - mCrashReportMode = other.mCrashReportMode; - mHdcp = other.mHdcp; - mSeedForPsuedoDeviceId = other.mSeedForPsuedoDeviceId; - mBcatPassphase = other.mBcatPassphase; - mUserAccountSaveDataMax = other.mUserAccountSaveDataMax; - mDeviceSaveDataMax = other.mDeviceSaveDataMax; - mTemporaryStorageSize = other.mTemporaryStorageSize; - mCacheStorageSize = other.mCacheStorageSize; - mCacheStorageDataAndJournalSizeMax = other.mCacheStorageDataAndJournalSizeMax; - mCacheStorageIndex = other.mCacheStorageIndex; - mPlayLogQueryableApplicationId = other.mPlayLogQueryableApplicationId; - mPlayLogQueryCapability = other.mPlayLogQueryCapability; - mRepairFlag = other.mRepairFlag; - mProgramIndex = other.mProgramIndex; -} +} \ No newline at end of file diff --git a/lib/libnx/source/ContentMetaBinary.cpp b/lib/libnx/source/ContentMetaBinary.cpp index 450eb61..5c47776 100644 --- a/lib/libnx/source/ContentMetaBinary.cpp +++ b/lib/libnx/source/ContentMetaBinary.cpp @@ -17,12 +17,12 @@ nx::ContentMetaBinary::ContentMetaBinary(const byte_t * bytes, size_t len) const byte_t * nx::ContentMetaBinary::getBytes() const { - return mBinaryBlob.getBytes(); + return mRawBinary.getBytes(); } size_t nx::ContentMetaBinary::getSize() const { - return mBinaryBlob.getSize(); + return mRawBinary.getSize(); } void nx::ContentMetaBinary::exportBinary() @@ -118,7 +118,7 @@ void nx::ContentMetaBinary::importBinary(const byte_t * bytes, size_t len) void nx::ContentMetaBinary::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); mTitleId = 0; mTitleVersion = 0; mType = cnmt::METATYPE_SYSTEM_PROGRAM; diff --git a/lib/libnx/source/FacBinary.cpp b/lib/libnx/source/FacBinary.cpp index a955591..b557d4c 100644 --- a/lib/libnx/source/FacBinary.cpp +++ b/lib/libnx/source/FacBinary.cpp @@ -1,118 +1,100 @@ #include - - nx::FacBinary::FacBinary() -{} +{ + clear(); +} nx::FacBinary::FacBinary(const FacBinary & other) { - copyFrom(other); -} - -nx::FacBinary::FacBinary(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - -bool nx::FacBinary::operator==(const FacBinary & other) const -{ - return isEqual(other); -} - -bool nx::FacBinary::operator!=(const FacBinary & other) const -{ - return !isEqual(other); + *this = other; } void nx::FacBinary::operator=(const FacBinary & other) { - copyFrom(other); -} - -const byte_t * nx::FacBinary::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::FacBinary::getSize() const -{ - return mBinaryBlob.getSize(); -} - -void nx::FacBinary::exportBinary() -{ - FacHeader::setContentOwnerIdSize(mContentOwnerIdList.getSize() * sizeof(uint32_t)); - FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.getSize() * sizeof(uint32_t)); - FacHeader::exportBinary(); - - mBinaryBlob.alloc(getFacSize()); - memcpy(mBinaryBlob.getBytes(), FacHeader::getBytes(), FacHeader::getSize()); - - uint32_t* rawContentOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getContentOwnerIdOffset()); - for (size_t i = 0; i < mContentOwnerIdList.getSize(); i++) + if (other.getBytes().size()) { - rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]); - } - - uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getSaveDataOwnerIdOffset()); - for (size_t i = 0; i < mSaveDataOwnerIdList.getSize(); i++) - { - rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]); - } -} - -void nx::FacBinary::importBinary(const byte_t * bytes, size_t len) -{ - clear(); - FacHeader::importBinary(bytes, len); - if (FacHeader::getFacSize() > len) - { - throw fnd::Exception(kModuleName, "FAC binary too small"); - } - - mBinaryBlob.alloc(FacHeader::getFacSize()); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); - - uint32_t* rawContentOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getContentOwnerIdOffset()); - size_t rawContentOwnerIdNum = FacHeader::getContentOwnerIdSize() / sizeof(uint32_t); - for (size_t i = 0; i < rawContentOwnerIdNum; i++) - { - mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i])); - } - - uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getSaveDataOwnerIdOffset()); - size_t rawSaveDataOwnerIdNum = FacHeader::getSaveDataOwnerIdSize() / sizeof(uint32_t); - for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++) - { - mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i])); - } -} - -bool nx::FacBinary::isEqual(const FacBinary & other) const -{ - return (FacHeader::operator==(other)) \ - && (mContentOwnerIdList == other.mContentOwnerIdList) \ - && (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList); -} - -void nx::FacBinary::copyFrom(const FacBinary & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); + fromBytes(other.getBytes().data(), other.getBytes().size()); } else { + clear(); FacHeader::operator=(other); mContentOwnerIdList = other.mContentOwnerIdList; mSaveDataOwnerIdList = other.mSaveDataOwnerIdList; } } +bool nx::FacBinary::operator==(const FacBinary & other) const +{ + return (FacHeader::operator==(other)) \ + && (mContentOwnerIdList == other.mContentOwnerIdList) \ + && (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList); +} + +bool nx::FacBinary::operator!=(const FacBinary & other) const +{ + return !(*this == other); +} + +void nx::FacBinary::toBytes() +{ + FacHeader::setContentOwnerIdSize(mContentOwnerIdList.size() * sizeof(uint32_t)); + FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.size() * sizeof(uint32_t)); + FacHeader::toBytes(); + + mRawBinary.alloc(getFacSize()); + memcpy(mRawBinary.data(), FacHeader::getBytes().data(), FacHeader::getBytes().size()); + + uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getContentOwnerIdPos().offset); + for (size_t i = 0; i < mContentOwnerIdList.size(); i++) + { + rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]); + } + + uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getSaveDataOwnerIdPos().offset); + for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++) + { + rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]); + } +} + +void nx::FacBinary::fromBytes(const byte_t* data, size_t len) +{ + clear(); + FacHeader::fromBytes(data, len); + if (FacHeader::getFacSize() > len) + { + throw fnd::Exception(kModuleName, "FAC binary too small"); + } + + mRawBinary.alloc(FacHeader::getFacSize()); + memcpy(mRawBinary.data(), data, mRawBinary.size()); + + uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getContentOwnerIdPos().offset); + size_t rawContentOwnerIdNum = FacHeader::getContentOwnerIdPos().size / sizeof(uint32_t); + for (size_t i = 0; i < rawContentOwnerIdNum; i++) + { + mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i])); + } + + uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getSaveDataOwnerIdPos().offset); + size_t rawSaveDataOwnerIdNum = FacHeader::getSaveDataOwnerIdPos().size / sizeof(uint32_t); + for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++) + { + mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i])); + } +} + +const fnd::Vec& nx::FacBinary::getBytes() const +{ + return mRawBinary; +} + void nx::FacBinary::clear() { FacHeader::clear(); + mRawBinary.clear(); mContentOwnerIdList.clear(); mSaveDataOwnerIdList.clear(); } diff --git a/lib/libnx/source/FacHeader.cpp b/lib/libnx/source/FacHeader.cpp index 7c09b21..064565e 100644 --- a/lib/libnx/source/FacHeader.cpp +++ b/lib/libnx/source/FacHeader.cpp @@ -1,7 +1,5 @@ #include - - nx::FacHeader::FacHeader() : mFsaRights() { @@ -11,55 +9,55 @@ nx::FacHeader::FacHeader() : nx::FacHeader::FacHeader(const FacHeader & other) : mFsaRights() { - copyFrom(other); -} - -nx::FacHeader::FacHeader(const byte_t * bytes, size_t len) : - mFsaRights() -{ - importBinary(bytes, len); -} - -bool nx::FacHeader::operator==(const FacHeader & other) const -{ - return isEqual(other); -} - -bool nx::FacHeader::operator!=(const FacHeader & other) const -{ - return !isEqual(other); + *this = other; } void nx::FacHeader::operator=(const FacHeader & other) { - copyFrom(other); + if (other.getBytes().size()) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + clear(); + mFsaRights = other.mFsaRights; + mContentOwnerIdPos.offset = other.mContentOwnerIdPos.offset; + mContentOwnerIdPos.size = other.mContentOwnerIdPos.size; + mSaveDataOwnerIdPos.offset = other.mSaveDataOwnerIdPos.offset; + mSaveDataOwnerIdPos.size = other.mSaveDataOwnerIdPos.size; + } } -const byte_t * nx::FacHeader::getBytes() const +bool nx::FacHeader::operator==(const FacHeader & other) const { - return mBinaryBlob.getBytes(); + return (mFsaRights == other.mFsaRights) \ + && (mContentOwnerIdPos.offset == other.mContentOwnerIdPos.offset) \ + && (mContentOwnerIdPos.size == other.mContentOwnerIdPos.size) \ + && (mSaveDataOwnerIdPos.offset == other.mSaveDataOwnerIdPos.offset) \ + && (mSaveDataOwnerIdPos.size == other.mSaveDataOwnerIdPos.size); } -size_t nx::FacHeader::getSize() const +bool nx::FacHeader::operator!=(const FacHeader & other) const { - return mBinaryBlob.getSize(); + return !(*this == other); } -void nx::FacHeader::exportBinary() +void nx::FacHeader::toBytes() { - mBinaryBlob.alloc(sizeof(sFacHeader)); - sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(sizeof(sFacHeader)); + sFacHeader* hdr = (sFacHeader*)mRawBinary.data(); - if (mVersion != kFacFormatVersion) + if (mVersion != fac::kFacFormatVersion) { fnd::Exception(kModuleName, "Unsupported format version"); } hdr->version = (mVersion); uint64_t flag = 0; - for (size_t i = 0; i < mFsaRights.getSize(); i++) + for (size_t i = 0; i < mFsaRights.size(); i++) { - flag |= BIT((uint64_t)mFsaRights[i]); + flag |= _BIT((uint64_t)mFsaRights[i]); } hdr->fac_flags = (flag); @@ -70,18 +68,18 @@ void nx::FacHeader::exportBinary() hdr->save_data_owner_ids.end = (uint32_t)(mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size); } -void nx::FacHeader::importBinary(const byte_t * bytes, size_t len) +void nx::FacHeader::fromBytes(const byte_t* data, size_t len) { if (len < sizeof(sFacHeader)) { throw fnd::Exception(kModuleName, "FAC header too small"); } - mBinaryBlob.alloc(sizeof(sFacHeader)); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); - sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(sizeof(sFacHeader)); + memcpy(mRawBinary.data(), data, mRawBinary.size()); + sFacHeader* hdr = (sFacHeader*)mRawBinary.data(); - if (hdr->version.get() != kFacFormatVersion) + if (hdr->version.get() != fac::kFacFormatVersion) { throw fnd::Exception(kModuleName, "Unsupported FAC format version"); } @@ -90,9 +88,9 @@ void nx::FacHeader::importBinary(const byte_t * bytes, size_t len) clear(); for (uint64_t i = 0; i < 64; i++) { - if ((hdr->fac_flags.get() >> i) & 1) + if (_HAS_BIT(hdr->fac_flags.get(), i)) { - mFsaRights.addElement((FsAccessFlag)i); + mFsaRights.addElement((fac::FsAccessFlag)i); } } mContentOwnerIdPos.offset = hdr->content_owner_ids.start.get(); @@ -101,6 +99,11 @@ void nx::FacHeader::importBinary(const byte_t * bytes, size_t len) mSaveDataOwnerIdPos.size = hdr->save_data_owner_ids.end.get() > hdr->save_data_owner_ids.start.get() ? hdr->save_data_owner_ids.end.get() - hdr->save_data_owner_ids.start.get() : 0; } +const fnd::Vec& nx::FacHeader::getBytes() const +{ + return mRawBinary; +} + void nx::FacHeader::clear() { mFsaRights.clear(); @@ -112,9 +115,9 @@ void nx::FacHeader::clear() size_t nx::FacHeader::getFacSize() const { - size_t savedata = getSaveDataOwnerIdOffset() + getSaveDataOwnerIdSize(); - size_t content = getContentOwnerIdOffset() + getContentOwnerIdSize(); - return MAX(MAX(savedata, content), sizeof(sFacHeader)); + size_t savedata = mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size; + size_t content = mContentOwnerIdPos.offset + mContentOwnerIdPos.size; + return _MAX(_MAX(savedata, content), sizeof(sFacHeader)); } uint32_t nx::FacHeader::getFormatVersion() const @@ -127,28 +130,23 @@ void nx::FacHeader::setFormatVersion(uint32_t version) mVersion = version; } -const fnd::List& nx::FacHeader::getFsaRightsList() const +const fnd::List& nx::FacHeader::getFsaRightsList() const { return mFsaRights; } -void nx::FacHeader::setFsaRightsList(const fnd::List& list) +void nx::FacHeader::setFsaRightsList(const fnd::List& list) { mFsaRights.clear(); - for (size_t i = 0; i < list.getSize(); i++) + for (size_t i = 0; i < list.size(); i++) { mFsaRights.hasElement(list[i]) ? mFsaRights.addElement(list[i]) : throw fnd::Exception(kModuleName, "FSA right already exists"); } } -size_t nx::FacHeader::getContentOwnerIdOffset() const +const nx::FacHeader::sSection& nx::FacHeader::getContentOwnerIdPos() const { - return mContentOwnerIdPos.offset; -} - -size_t nx::FacHeader::getContentOwnerIdSize() const -{ - return mContentOwnerIdPos.size; + return mContentOwnerIdPos; } void nx::FacHeader::setContentOwnerIdSize(size_t size) @@ -156,14 +154,9 @@ void nx::FacHeader::setContentOwnerIdSize(size_t size) mContentOwnerIdPos.size = size; } -size_t nx::FacHeader::getSaveDataOwnerIdOffset() const +const nx::FacHeader::sSection& nx::FacHeader::getSaveDataOwnerIdPos() const { - return mSaveDataOwnerIdPos.offset; -} - -size_t nx::FacHeader::getSaveDataOwnerIdSize() const -{ - return mSaveDataOwnerIdPos.size; + return mSaveDataOwnerIdPos; } void nx::FacHeader::setSaveDataOwnerIdSize(size_t size) @@ -175,30 +168,4 @@ void nx::FacHeader::calculateOffsets() { mContentOwnerIdPos.offset = align(sizeof(sFacHeader), 4); mSaveDataOwnerIdPos.offset = mContentOwnerIdPos.offset + align(mContentOwnerIdPos.size, 4); -} - -bool nx::FacHeader::isEqual(const FacHeader & other) const -{ - return (mFsaRights == other.mFsaRights) \ - && (mContentOwnerIdPos.offset == other.mContentOwnerIdPos.offset) \ - && (mContentOwnerIdPos.size == other.mContentOwnerIdPos.size) \ - && (mSaveDataOwnerIdPos.offset == other.mSaveDataOwnerIdPos.offset) \ - && (mSaveDataOwnerIdPos.size == other.mSaveDataOwnerIdPos.size); -} - -void nx::FacHeader::copyFrom(const FacHeader & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - mBinaryBlob.clear(); - mFsaRights = other.mFsaRights; - mContentOwnerIdPos.offset = other.mContentOwnerIdPos.offset; - mContentOwnerIdPos.size = other.mContentOwnerIdPos.size; - mSaveDataOwnerIdPos.offset = other.mSaveDataOwnerIdPos.offset; - mSaveDataOwnerIdPos.size = other.mSaveDataOwnerIdPos.size; - } -} +} \ No newline at end of file diff --git a/lib/libnx/source/HierarchicalIntegrityHeader.cpp b/lib/libnx/source/HierarchicalIntegrityHeader.cpp index 3eee01d..35f235f 100644 --- a/lib/libnx/source/HierarchicalIntegrityHeader.cpp +++ b/lib/libnx/source/HierarchicalIntegrityHeader.cpp @@ -8,45 +8,40 @@ nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader() nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader & other) { - copyFrom(other); -} - -nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - -bool nx::HierarchicalIntegrityHeader::operator==(const HierarchicalIntegrityHeader & other) const -{ - return isEqual(other); -} - -bool nx::HierarchicalIntegrityHeader::operator!=(const HierarchicalIntegrityHeader & other) const -{ - return !isEqual(other); + *this = other; } void nx::HierarchicalIntegrityHeader::operator=(const HierarchicalIntegrityHeader & other) { - copyFrom(other); + if (other.getBytes().size() != 0) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + clear(); + mLayerInfo = other.mLayerInfo; + mMasterHashList = other.mMasterHashList; + } } -const byte_t * nx::HierarchicalIntegrityHeader::getBytes() const +bool nx::HierarchicalIntegrityHeader::operator==(const HierarchicalIntegrityHeader & other) const { - return mBinaryBlob.getBytes(); + return (mLayerInfo == other.mLayerInfo) \ + && (mMasterHashList == other.mMasterHashList); } -size_t nx::HierarchicalIntegrityHeader::getSize() const +bool nx::HierarchicalIntegrityHeader::operator!=(const HierarchicalIntegrityHeader & other) const { - return mBinaryBlob.getSize(); + return !(*this == other); } -void nx::HierarchicalIntegrityHeader::exportBinary() +void nx::HierarchicalIntegrityHeader::toBytes() { throw fnd::Exception(kModuleName, "exportBinary() not implemented"); } -void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t len) +void nx::HierarchicalIntegrityHeader::fromBytes(const byte_t* data, size_t len) { std::stringstream error_str; @@ -56,7 +51,7 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t throw fnd::Exception(kModuleName, "Header too small"); } - const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)bytes; + const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)data; // Validate Header Sig "IVFC" if (hdr->signature.get() != hierarchicalintegrity::kStructSig) @@ -92,24 +87,29 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t } // copy to internal storage - mBinaryBlob.alloc(total_size); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(total_size); + memcpy(mRawBinary.data(), data, mRawBinary.size()); // save layer info - const nx::sHierarchicalIntegrityLayerInfo* layer_info = (const nx::sHierarchicalIntegrityLayerInfo*)(mBinaryBlob.getBytes() + sizeof(nx::sHierarchicalIntegrityHeader)); + const nx::sHierarchicalIntegrityLayerInfo* layer_info = (const nx::sHierarchicalIntegrityLayerInfo*)(mRawBinary.data() + sizeof(nx::sHierarchicalIntegrityHeader)); for (size_t i = 0; i < hierarchicalintegrity::kDefaultLayerNum; i++) { mLayerInfo.addElement({layer_info[i].offset.get(), layer_info[i].size.get(), layer_info[i].block_size.get()}); } // save hash list - const crypto::sha::sSha256Hash* hash_list = (const crypto::sha::sSha256Hash*)(mBinaryBlob.getBytes() + master_hash_offset); + const crypto::sha::sSha256Hash* hash_list = (const crypto::sha::sSha256Hash*)(mRawBinary.data() + master_hash_offset); for (size_t i = 0; i < hdr->master_hash_size.get()/sizeof(crypto::sha::sSha256Hash); i++) { mMasterHashList.addElement(hash_list[i]); } } +const fnd::Vec& nx::HierarchicalIntegrityHeader::getBytes() const +{ + return mRawBinary; +} + void nx::HierarchicalIntegrityHeader::clear() { mLayerInfo.clear(); @@ -134,23 +134,4 @@ const fnd::List& nx::HierarchicalIntegrityHeader::getM void nx::HierarchicalIntegrityHeader::setMasterHashList(const fnd::List& master_hash_list) { mMasterHashList = master_hash_list; -} - -bool nx::HierarchicalIntegrityHeader::isEqual(const HierarchicalIntegrityHeader & other) const -{ - return (mLayerInfo == other.mLayerInfo) \ - && (mMasterHashList == other.mMasterHashList); -} - -void nx::HierarchicalIntegrityHeader::copyFrom(const HierarchicalIntegrityHeader & other) -{ - if (other.getSize() != 0) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - mLayerInfo = other.mLayerInfo; - mMasterHashList = other.mMasterHashList; - } -} +} \ No newline at end of file diff --git a/lib/libnx/source/HierarchicalSha256Header.cpp b/lib/libnx/source/HierarchicalSha256Header.cpp index a7d288d..e199075 100644 --- a/lib/libnx/source/HierarchicalSha256Header.cpp +++ b/lib/libnx/source/HierarchicalSha256Header.cpp @@ -1,7 +1,6 @@ #include #include - nx::HierarchicalSha256Header::HierarchicalSha256Header() { clear(); @@ -9,45 +8,41 @@ nx::HierarchicalSha256Header::HierarchicalSha256Header() nx::HierarchicalSha256Header::HierarchicalSha256Header(const HierarchicalSha256Header & other) { - copyFrom(other); -} - -nx::HierarchicalSha256Header::HierarchicalSha256Header(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - -bool nx::HierarchicalSha256Header::operator==(const HierarchicalSha256Header & other) const -{ - return isEqual(other); -} - -bool nx::HierarchicalSha256Header::operator!=(const HierarchicalSha256Header & other) const -{ - return !isEqual(other); + *this = other; } void nx::HierarchicalSha256Header::operator=(const HierarchicalSha256Header & other) { - copyFrom(other); + if (other.getBytes().size() != 0) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + mMasterHash = other.mMasterHash; + mHashBlockSize = other.mHashBlockSize; + mLayerInfo = other.mLayerInfo; + } } -const byte_t * nx::HierarchicalSha256Header::getBytes() const +bool nx::HierarchicalSha256Header::operator==(const HierarchicalSha256Header & other) const { - return mBinaryBlob.getBytes(); + return (mMasterHash == other.mMasterHash) \ + && (mHashBlockSize == other.mHashBlockSize) \ + && (mLayerInfo == other.mLayerInfo); } -size_t nx::HierarchicalSha256Header::getSize() const +bool nx::HierarchicalSha256Header::operator!=(const HierarchicalSha256Header & other) const { - return mBinaryBlob.getSize(); + return !(*this == other); } -void nx::HierarchicalSha256Header::exportBinary() +void nx::HierarchicalSha256Header::toBytes() { throw fnd::Exception(kModuleName, "exportBinary() not implemented"); } -void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len) +void nx::HierarchicalSha256Header::fromBytes(const byte_t* data, size_t len) { std::stringstream error_str; @@ -56,7 +51,7 @@ void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len throw fnd::Exception(kModuleName, "Header too small"); } - const nx::sHierarchicalSha256Header* hdr = (const nx::sHierarchicalSha256Header*)bytes; + const nx::sHierarchicalSha256Header* hdr = (const nx::sHierarchicalSha256Header*)data; if (hdr->layer_num.get() != nx::hierarchicalsha256::kDefaultLayerNum) { @@ -74,6 +69,11 @@ void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len } } +const fnd::Vec& nx::HierarchicalSha256Header::getBytes() const +{ + return mRawBinary; +} + void nx::HierarchicalSha256Header::clear() { memset(mMasterHash.bytes, 0, sizeof(crypto::sha::sSha256Hash)); @@ -109,25 +109,4 @@ const fnd::List& nx::HierarchicalSha256Hea void nx::HierarchicalSha256Header::setLayerInfo(const fnd::List& layer_info) { mLayerInfo = layer_info; -} - -bool nx::HierarchicalSha256Header::isEqual(const HierarchicalSha256Header & other) const -{ - return (mMasterHash == other.mMasterHash) \ - && (mHashBlockSize == other.mHashBlockSize) \ - && (mLayerInfo == other.mLayerInfo); -} - -void nx::HierarchicalSha256Header::copyFrom(const HierarchicalSha256Header & other) -{ - if (other.getSize() != 0) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - mMasterHash = other.mMasterHash; - mHashBlockSize = other.mHashBlockSize; - mLayerInfo = other.mLayerInfo; - } -} +} \ No newline at end of file diff --git a/lib/libnx/source/KcBinary.cpp b/lib/libnx/source/KcBinary.cpp index 69330fe..88fc6c0 100644 --- a/lib/libnx/source/KcBinary.cpp +++ b/lib/libnx/source/KcBinary.cpp @@ -1,46 +1,44 @@ #include - - nx::KcBinary::KcBinary() {} nx::KcBinary::KcBinary(const KcBinary & other) { - copyFrom(other); -} - -nx::KcBinary::KcBinary(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - -bool nx::KcBinary::operator==(const KcBinary & other) const -{ - return isEqual(other); -} - -bool nx::KcBinary::operator!=(const KcBinary & other) const -{ - return !isEqual(other); + *this = other; } void nx::KcBinary::operator=(const KcBinary & other) { - copyFrom(other); + clear(); + mThreadInfo = other.mThreadInfo; + mSystemCalls = other.mSystemCalls; + mMemoryMap = other.mMemoryMap; + mInterupts = other.mInterupts; + mMiscParams = other.mMiscParams; + mKernelVersion = other.mKernelVersion; + mHandleTableSize = other.mHandleTableSize; + mMiscFlags = other.mMiscFlags; } -const byte_t * nx::KcBinary::getBytes() const +bool nx::KcBinary::operator==(const KcBinary & other) const { - return mBinaryBlob.getBytes(); + return (mThreadInfo == other.mThreadInfo) \ + && (mSystemCalls == other.mSystemCalls) \ + && (mMemoryMap == other.mMemoryMap) \ + && (mInterupts == other.mInterupts) \ + && (mMiscParams == other.mMiscParams) \ + && (mKernelVersion == other.mKernelVersion) \ + && (mHandleTableSize == other.mHandleTableSize) \ + && (mMiscFlags == other.mMiscFlags); } -size_t nx::KcBinary::getSize() const +bool nx::KcBinary::operator!=(const KcBinary & other) const { - return mBinaryBlob.getSize(); + return !(*this == other); } -void nx::KcBinary::exportBinary() +void nx::KcBinary::toBytes() { fnd::List caps; @@ -55,23 +53,27 @@ void nx::KcBinary::exportBinary() mMiscFlags.exportKernelCapabilityList(caps); // allocate memory - mBinaryBlob.alloc(caps.getSize() * sizeof(uint32_t)); + mRawBinary.alloc(caps.size() * sizeof(uint32_t)); // write to binary - uint32_t* raw_caps = (uint32_t*)mBinaryBlob.getBytes(); - for (size_t i = 0; i < caps.getSize(); i++) + uint32_t* raw_caps = (uint32_t*)mRawBinary.data(); + for (size_t i = 0; i < caps.size(); i++) { raw_caps[i] = le_word(caps[i].getCap()); } } -void nx::KcBinary::importBinary(const byte_t * bytes, size_t len) +void nx::KcBinary::fromBytes(const byte_t * data, size_t len) { if ((len % sizeof(uint32_t)) != 0) { throw fnd::Exception(kModuleName, "KernelCapability list must be aligned to 4 bytes"); } + // save copy of KcBinary + mRawBinary.alloc(len); + memcpy(mRawBinary.data(), data, len); + fnd::List threadInfoCaps; fnd::List systemCallCaps; fnd::List memoryMapCaps; @@ -81,8 +83,8 @@ void nx::KcBinary::importBinary(const byte_t * bytes, size_t len) fnd::List handleTableSizeCaps; fnd::List miscFlagsCaps; - const uint32_t* raw_caps = (const uint32_t*)bytes; - size_t cap_num = len / sizeof(uint32_t); + const uint32_t* raw_caps = (const uint32_t*)mRawBinary.data(); + size_t cap_num = mRawBinary.size() / sizeof(uint32_t); KernelCapability cap; for (size_t i = 0; i < cap_num; i++) { @@ -129,9 +131,14 @@ void nx::KcBinary::importBinary(const byte_t * bytes, size_t len) mMiscFlags.importKernelCapabilityList(miscFlagsCaps); } +const fnd::Vec& nx::KcBinary::getBytes() const +{ + return mRawBinary; +} + void nx::KcBinary::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); mThreadInfo.clear(); mSystemCalls.clear(); mMemoryMap.clear(); @@ -220,28 +227,4 @@ const nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags() const nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags() { return mMiscFlags; -} - -bool nx::KcBinary::isEqual(const KcBinary & other) const -{ - return (mThreadInfo == other.mThreadInfo) \ - && (mSystemCalls == other.mSystemCalls) \ - && (mMemoryMap == other.mMemoryMap) \ - && (mInterupts == other.mInterupts) \ - && (mMiscParams == other.mMiscParams) \ - && (mKernelVersion == other.mKernelVersion) \ - && (mHandleTableSize == other.mHandleTableSize) \ - && (mMiscFlags == other.mMiscFlags); -} - -void nx::KcBinary::copyFrom(const KcBinary & other) -{ - mThreadInfo = other.mThreadInfo; - mSystemCalls = other.mSystemCalls; - mMemoryMap = other.mMemoryMap; - mInterupts = other.mInterupts; - mMiscParams = other.mMiscParams; - mKernelVersion = other.mKernelVersion; - mHandleTableSize = other.mHandleTableSize; - mMiscFlags = other.mMiscFlags; -} +} \ No newline at end of file diff --git a/lib/libnx/source/NcaHeader.cpp b/lib/libnx/source/NcaHeader.cpp index 3e1d691..f0cde41 100644 --- a/lib/libnx/source/NcaHeader.cpp +++ b/lib/libnx/source/NcaHeader.cpp @@ -2,11 +2,61 @@ using namespace nx; - -void NcaHeader::exportBinary() +NcaHeader::NcaHeader() { - mBinaryBlob.alloc(sizeof(sNcaHeader)); - sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes(); + clear(); +} + +NcaHeader::NcaHeader(const NcaHeader & other) +{ + *this = other; +} + +bool NcaHeader::operator==(const NcaHeader & other) const +{ + return (mDistributionType == other.mDistributionType) \ + && (mContentType == other.mContentType) \ + && (mKeyGeneration == other.mKeyGeneration) \ + && (mKaekIndex == other.mKaekIndex) \ + && (mContentSize == other.mContentSize) \ + && (mProgramId == other.mProgramId) \ + && (mContentIndex == other.mContentIndex) \ + && (mSdkAddonVersion == other.mSdkAddonVersion) \ + && (mPartitions == other.mPartitions) \ + && (mEncAesKeys == other.mEncAesKeys); +} + +bool NcaHeader::operator!=(const NcaHeader & other) const +{ + return !(*this == other); +} + +void NcaHeader::operator=(const NcaHeader & other) +{ + if (other.getBytes().size()) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + mRawBinary.clear(); + mDistributionType = other.mDistributionType; + mContentType = other.mContentType; + mKeyGeneration = other.mKeyGeneration; + mKaekIndex = other.mKaekIndex; + mContentSize = other.mContentSize; + mProgramId = other.mProgramId; + mContentIndex = other.mContentIndex; + mSdkAddonVersion = other.mSdkAddonVersion; + mPartitions = other.mPartitions; + mEncAesKeys = other.mEncAesKeys; + } +} + +void NcaHeader::toBytes() +{ + mRawBinary.alloc(sizeof(sNcaHeader)); + sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data(); switch(mFormatVersion) @@ -41,7 +91,7 @@ void NcaHeader::exportBinary() memcpy(hdr->rights_id, mRightsId, nca::kRightsIdLen); // TODO: properly reconstruct NCA layout? atm in hands of user - for (size_t i = 0; i < mPartitions.getSize(); i++) + for (size_t i = 0; i < mPartitions.size(); i++) { // determine partition index byte_t idx = mPartitions[i].index; @@ -60,7 +110,7 @@ void NcaHeader::exportBinary() } } -void NcaHeader::importBinary(const byte_t * bytes, size_t len) +void NcaHeader::fromBytes(const byte_t * data, size_t len) { if (len < sizeof(sNcaHeader)) { @@ -69,10 +119,10 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len) clear(); - mBinaryBlob.alloc(sizeof(sNcaHeader)); - memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sNcaHeader)); + mRawBinary.alloc(sizeof(sNcaHeader)); + memcpy(mRawBinary.data(), data, sizeof(sNcaHeader)); - sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes(); + sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data(); switch(hdr->signature.get()) { @@ -110,6 +160,11 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len) } } +const fnd::Vec& NcaHeader::getBytes() const +{ + return mRawBinary; +} + void nx::NcaHeader::clear() { mFormatVersion = NCA3_FORMAT; @@ -247,7 +302,7 @@ const fnd::List& NcaHeader::getPartitions() const void NcaHeader::setPartitions(const fnd::List& partitions) { mPartitions = partitions; - if (mPartitions.getSize() >= nca::kPartitionNum) + if (mPartitions.size() >= nca::kPartitionNum) { throw fnd::Exception(kModuleName, "Too many NCA partitions"); } @@ -271,80 +326,4 @@ uint64_t NcaHeader::blockNumToSize(uint32_t block_num) const uint32_t NcaHeader::sizeToBlockNum(uint64_t real_size) const { return (uint32_t)(align(real_size, nca::kSectorSize) / nca::kSectorSize); -} - -bool NcaHeader::isEqual(const NcaHeader & other) const -{ - return (mDistributionType == other.mDistributionType) \ - && (mContentType == other.mContentType) \ - && (mKeyGeneration == other.mKeyGeneration) \ - && (mKaekIndex == other.mKaekIndex) \ - && (mContentSize == other.mContentSize) \ - && (mProgramId == other.mProgramId) \ - && (mContentIndex == other.mContentIndex) \ - && (mSdkAddonVersion == other.mSdkAddonVersion) \ - && (mPartitions == other.mPartitions) \ - && (mEncAesKeys == other.mEncAesKeys); -} - -void NcaHeader::copyFrom(const NcaHeader & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - mBinaryBlob.clear(); - mDistributionType = other.mDistributionType; - mContentType = other.mContentType; - mKeyGeneration = other.mKeyGeneration; - mKaekIndex = other.mKaekIndex; - mContentSize = other.mContentSize; - mProgramId = other.mProgramId; - mContentIndex = other.mContentIndex; - mSdkAddonVersion = other.mSdkAddonVersion; - mPartitions = other.mPartitions; - mEncAesKeys = other.mEncAesKeys; - } -} - -NcaHeader::NcaHeader() -{ - clear(); -} - -NcaHeader::NcaHeader(const NcaHeader & other) -{ - copyFrom(other); -} - -NcaHeader::NcaHeader(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - -bool NcaHeader::operator==(const NcaHeader & other) const -{ - return isEqual(other); -} - -bool NcaHeader::operator!=(const NcaHeader & other) const -{ - return !isEqual(other); -} - -void NcaHeader::operator=(const NcaHeader & other) -{ - this->importBinary(other.getBytes(), other.getSize()); -} - -const byte_t * NcaHeader::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t NcaHeader::getSize() const -{ - return mBinaryBlob.getSize(); } \ No newline at end of file diff --git a/lib/libnx/source/NpdmBinary.cpp b/lib/libnx/source/NpdmBinary.cpp index acfc356..8d93026 100644 --- a/lib/libnx/source/NpdmBinary.cpp +++ b/lib/libnx/source/NpdmBinary.cpp @@ -1,7 +1,5 @@ #include - - nx::NpdmBinary::NpdmBinary() : mAci(), mAcid() @@ -13,47 +11,51 @@ nx::NpdmBinary::NpdmBinary(const NpdmBinary & other) : mAci(), mAcid() { - copyFrom(other); -} - -nx::NpdmBinary::NpdmBinary(const byte_t * bytes, size_t len) : - mAci(), - mAcid() -{ - importBinary(bytes, len); -} - -bool nx::NpdmBinary::operator==(const NpdmBinary & other) const -{ - return isEqual(other); -} - -bool nx::NpdmBinary::operator!=(const NpdmBinary & other) const -{ - return !isEqual(other); + *this = other; } void nx::NpdmBinary::operator=(const NpdmBinary & other) { - copyFrom(other); + if (other.getBytes().size()) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + NpdmHeader::operator=(other); + mAci = other.mAci; + mAcid = other.mAcid; + } } -void nx::NpdmBinary::exportBinary() +bool nx::NpdmBinary::operator==(const NpdmBinary & other) const +{ + return (NpdmHeader::operator==(other)) \ + && (mAci == other.mAci) \ + && (mAcid == other.mAcid); +} + +bool nx::NpdmBinary::operator!=(const NpdmBinary & other) const +{ + return !(*this == other); +} + +void nx::NpdmBinary::toBytes() { mAci.exportBinary(); mAcid.exportBinary(); - setAciSize(mAci.getSize()); - setAcidSize(mAcid.getSize()); + setAciSize(mAci.getBytes().size()); + setAcidSize(mAcid.getBytes().size()); } -void nx::NpdmBinary::importBinary(const byte_t * bytes, size_t len) +void nx::NpdmBinary::fromBytes(const byte_t* data, size_t len) { // clear clear(); // import header - NpdmHeader::importBinary(bytes, len); + NpdmHeader::fromBytes(data, len); // check size if (getNpdmSize() > len) @@ -62,19 +64,23 @@ void nx::NpdmBinary::importBinary(const byte_t * bytes, size_t len) } // save local copy - mBinaryBlob.alloc(getNpdmSize()); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(getNpdmSize()); + memcpy(mRawBinary.data(), data, mRawBinary.size()); // import Aci/Acid if (getAciPos().size) { - mAci.importBinary(mBinaryBlob.getBytes() + getAciPos().offset, getAciPos().size); + mAci.importBinary(mRawBinary.data() + getAciPos().offset, getAciPos().size); } if (getAcidPos().size) { - mAcid.importBinary(mBinaryBlob.getBytes() + getAcidPos().offset, getAcidPos().size); - } - + mAcid.importBinary(mRawBinary.data() + getAcidPos().offset, getAcidPos().size); + } +} + +const fnd::Vec& nx::NpdmBinary::getBytes() const +{ + return mRawBinary; } void nx::NpdmBinary::clear() @@ -102,35 +108,4 @@ const nx::AcidBinary & nx::NpdmBinary::getAcid() const void nx::NpdmBinary::setAcid(const AcidBinary & acid) { mAcid = acid; -} - -bool nx::NpdmBinary::isEqual(const NpdmBinary & other) const -{ - return (NpdmHeader::operator==(other)) \ - && (mAci == other.mAci) \ - && (mAcid == other.mAcid); -} - -void nx::NpdmBinary::copyFrom(const NpdmBinary & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - NpdmHeader::operator=(other); - mAci = other.mAci; - mAcid = other.mAcid; - } -} - -const byte_t * nx::NpdmBinary::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::NpdmBinary::getSize() const -{ - return mBinaryBlob.getSize(); -} +} \ No newline at end of file diff --git a/lib/libnx/source/NpdmHeader.cpp b/lib/libnx/source/NpdmHeader.cpp index db81574..21fb558 100644 --- a/lib/libnx/source/NpdmHeader.cpp +++ b/lib/libnx/source/NpdmHeader.cpp @@ -1,7 +1,5 @@ #include - - nx::NpdmHeader::NpdmHeader() { clear(); @@ -9,67 +7,18 @@ nx::NpdmHeader::NpdmHeader() nx::NpdmHeader::NpdmHeader(const NpdmHeader & other) { - copyFrom(other); -} - -nx::NpdmHeader::NpdmHeader(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - -bool nx::NpdmHeader::operator==(const NpdmHeader & other) const -{ - return isEqual(other); -} - -bool nx::NpdmHeader::operator!=(const NpdmHeader & other) const -{ - return isEqual(other); + *this = other; } void nx::NpdmHeader::operator=(const NpdmHeader & other) { - copyFrom(other); -} - -const byte_t * nx::NpdmHeader::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::NpdmHeader::getSize() const -{ - return mBinaryBlob.getSize(); -} - -void nx::NpdmHeader::calculateOffsets() -{ - mAcidPos.offset = align(sizeof(sNpdmHeader), npdm::kNpdmAlignSize); - mAciPos.offset = mAcidPos.offset + align(mAcidPos.size, npdm::kNpdmAlignSize); -} - -bool nx::NpdmHeader::isEqual(const NpdmHeader & other) const -{ - return (mInstructionType == other.mInstructionType) \ - && (mProcAddressSpaceType == other.mProcAddressSpaceType) \ - && (mMainThreadPriority == other.mMainThreadPriority) \ - && (mMainThreadCpuId == other.mMainThreadCpuId) \ - && (mVersion == other.mVersion) \ - && (mMainThreadStackSize == other.mMainThreadStackSize) \ - && (mName == other.mName) \ - && (mProductCode == other.mProductCode) \ - && (mAciPos == other.mAciPos) \ - && (mAcidPos == other.mAcidPos); -} - -void nx::NpdmHeader::copyFrom(const NpdmHeader & other) -{ - if (other.getSize()) + if (other.getBytes().size()) { - importBinary(other.getBytes(), other.getSize()); + fromBytes(other.getBytes().data, other.getBytes().size()); } else { + clear(); mInstructionType = other.mInstructionType; mProcAddressSpaceType = other.mProcAddressSpaceType; mMainThreadPriority = other.mMainThreadPriority; @@ -83,10 +32,29 @@ void nx::NpdmHeader::copyFrom(const NpdmHeader & other) } } -void nx::NpdmHeader::exportBinary() +bool nx::NpdmHeader::operator==(const NpdmHeader & other) const { - mBinaryBlob.alloc(sizeof(sNpdmHeader)); - sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes(); + return (mInstructionType == other.mInstructionType) \ + && (mProcAddressSpaceType == other.mProcAddressSpaceType) \ + && (mMainThreadPriority == other.mMainThreadPriority) \ + && (mMainThreadCpuId == other.mMainThreadCpuId) \ + && (mVersion == other.mVersion) \ + && (mMainThreadStackSize == other.mMainThreadStackSize) \ + && (mName == other.mName) \ + && (mProductCode == other.mProductCode) \ + && (mAciPos == other.mAciPos) \ + && (mAcidPos == other.mAcidPos); +} + +bool nx::NpdmHeader::operator!=(const NpdmHeader & other) const +{ + return !(*this == other); +} + +void nx::NpdmHeader::toBytes() +{ + mRawBinary.alloc(sizeof(sNpdmHeader)); + sNpdmHeader* hdr = (sNpdmHeader*)mRawBinary.data(); hdr->signature = npdm::kNpdmStructSig; byte_t flag = ((byte_t)(mInstructionType & 1) | (byte_t)((mProcAddressSpaceType & 3) << 1)) & 0xf; @@ -105,7 +73,7 @@ void nx::NpdmHeader::exportBinary() hdr->acid.size = (uint32_t)mAcidPos.size; } -void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len) +void nx::NpdmHeader::fromBytes(const byte_t* data, size_t len) { if (len < sizeof(sNpdmHeader)) { @@ -114,9 +82,9 @@ void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len) clear(); - mBinaryBlob.alloc(sizeof(sNpdmHeader)); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); - sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(sizeof(sNpdmHeader)); + memcpy(mRawBinary.data(), data, mRawBinary.size()); + sNpdmHeader* hdr = (sNpdmHeader*)mRawBinary.data(); if (hdr->signature.get() != npdm::kNpdmStructSig) { @@ -146,9 +114,14 @@ void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len) mAcidPos.size = hdr->acid.size.get(); } +const fnd::Vec& nx::NpdmHeader::getBytes() const +{ + return mRawBinary; +} + void nx::NpdmHeader::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); mInstructionType = npdm::INSTR_64BIT; mProcAddressSpaceType = npdm::ADDR_SPACE_64BIT; mMainThreadPriority = 0; @@ -282,3 +255,9 @@ void nx::NpdmHeader::setAcidSize(size_t size) { mAcidPos.size = size; } + +void nx::NpdmHeader::calculateOffsets() +{ + mAcidPos.offset = align(sizeof(sNpdmHeader), npdm::kNpdmAlignSize); + mAciPos.offset = mAcidPos.offset + align(mAcidPos.size, npdm::kNpdmAlignSize); +} \ No newline at end of file diff --git a/lib/libnx/source/NroHeader.cpp b/lib/libnx/source/NroHeader.cpp index 8d031b8..f83beb7 100644 --- a/lib/libnx/source/NroHeader.cpp +++ b/lib/libnx/source/NroHeader.cpp @@ -7,17 +7,38 @@ nx::NroHeader::NroHeader() nx::NroHeader::NroHeader(const NroHeader& other) { - copyFrom(other); + *this = other; } -nx::NroHeader::NroHeader(const byte_t* bytes, size_t len) +void nx::NroHeader::operator=(const NroHeader& other) { - importBinary(bytes, len); + clear(); + mRoCrt = other.mRoCrt; + mNroSize = other.mNroSize; + mTextInfo = other.mTextInfo; + mTextInfo = other.mTextInfo; + mRoInfo = other.mRoInfo; + mDataInfo = other.mDataInfo; + mBssSize = other.mBssSize; + mModuleId = other.mModuleId; + mRoEmbeddedInfo = other.mRoEmbeddedInfo; + mRoDynStrInfo = other.mRoDynStrInfo; + mRoDynSymInfo = other.mRoDynSymInfo; } bool nx::NroHeader::operator==(const NroHeader& other) const { - return isEqual(other); + return (mRoCrt == other.mRoCrt) \ + && (mNroSize == other.mNroSize) \ + && (mTextInfo == other.mTextInfo) \ + && (mTextInfo == other.mTextInfo) \ + && (mRoInfo == other.mRoInfo) \ + && (mDataInfo == other.mDataInfo) \ + && (mBssSize == other.mBssSize) \ + && (mModuleId == other.mModuleId) \ + && (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \ + && (mRoDynStrInfo == other.mRoDynStrInfo) \ + && (mRoDynSymInfo == other.mRoDynSymInfo); } bool nx::NroHeader::operator!=(const NroHeader& other) const @@ -25,25 +46,10 @@ bool nx::NroHeader::operator!=(const NroHeader& other) const return !(*this == other); } -void nx::NroHeader::operator=(const NroHeader& other) +void nx::NroHeader::toBytes() { - copyFrom(other); -} - -const byte_t* nx::NroHeader::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::NroHeader::getSize() const -{ - return mBinaryBlob.getSize(); -} - -void nx::NroHeader::exportBinary() -{ - mBinaryBlob.alloc(sizeof(sNroHeader)); - nx::sNroHeader* hdr = (nx::sNroHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(sizeof(sNroHeader)); + nx::sNroHeader* hdr = (nx::sNroHeader*)mRawBinary.data(); // set header identifers hdr->signature = nro::kNroSig; @@ -87,7 +93,7 @@ void nx::NroHeader::exportBinary() hdr->dyn_sym.size = mRoDynSymInfo.size; } -void nx::NroHeader::importBinary(const byte_t* bytes, size_t len) +void nx::NroHeader::fromBytes(const byte_t* data, size_t len) { // check input data size if (len < sizeof(sNroHeader)) @@ -99,11 +105,11 @@ void nx::NroHeader::importBinary(const byte_t* bytes, size_t len) clear(); // allocate internal local binary copy - mBinaryBlob.alloc(sizeof(sNroHeader)); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(sizeof(sNroHeader)); + memcpy(mRawBinary.data(), data, mRawBinary.size()); // get sNroHeader ptr - const nx::sNroHeader* hdr = (const nx::sNroHeader*)mBinaryBlob.getBytes(); + const nx::sNroHeader* hdr = (const nx::sNroHeader*)mRawBinary.data(); // check NRO signature if (hdr->signature.get() != nro::kNroSig) @@ -144,9 +150,14 @@ void nx::NroHeader::importBinary(const byte_t* bytes, size_t len) mRoDynSymInfo.size = hdr->dyn_sym.size.get(); } +const fnd::Vec& nx::NroHeader::getBytes() const +{ + return mRawBinary; +} + void nx::NroHeader::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); memset(&mRoCrt, 0, sizeof(mRoCrt)); memset(&mTextInfo, 0, sizeof(mTextInfo)); memset(&mRoInfo, 0, sizeof(mRoInfo)); @@ -256,35 +267,4 @@ const nx::NroHeader::sSection& nx::NroHeader::getRoDynSymInfo() const void nx::NroHeader::setRoDynSymInfo(const sSection& info) { mRoDynSymInfo = info; -} - -bool nx::NroHeader::isEqual(const NroHeader& other) const -{ - return (mRoCrt == other.mRoCrt) \ - && (mNroSize == other.mNroSize) \ - && (mTextInfo == other.mTextInfo) \ - && (mTextInfo == other.mTextInfo) \ - && (mRoInfo == other.mRoInfo) \ - && (mDataInfo == other.mDataInfo) \ - && (mBssSize == other.mBssSize) \ - && (mModuleId == other.mModuleId) \ - && (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \ - && (mRoDynStrInfo == other.mRoDynStrInfo) \ - && (mRoDynSymInfo == other.mRoDynSymInfo); -} - -void nx::NroHeader::copyFrom(const NroHeader& other) -{ - clear(); - mRoCrt = other.mRoCrt; - mNroSize = other.mNroSize; - mTextInfo = other.mTextInfo; - mTextInfo = other.mTextInfo; - mRoInfo = other.mRoInfo; - mDataInfo = other.mDataInfo; - mBssSize = other.mBssSize; - mModuleId = other.mModuleId; - mRoEmbeddedInfo = other.mRoEmbeddedInfo; - mRoDynStrInfo = other.mRoDynStrInfo; - mRoDynSymInfo = other.mRoDynSymInfo; } \ No newline at end of file diff --git a/lib/libnx/source/NsoHeader.cpp b/lib/libnx/source/NsoHeader.cpp index 55521ec..f12d38e 100644 --- a/lib/libnx/source/NsoHeader.cpp +++ b/lib/libnx/source/NsoHeader.cpp @@ -2,22 +2,40 @@ nx::NsoHeader::NsoHeader() { - + clear(); } nx::NsoHeader::NsoHeader(const NsoHeader& other) { - copyFrom(other); + *this = other; } -nx::NsoHeader::NsoHeader(const byte_t* bytes, size_t len) +void nx::NsoHeader::operator=(const NsoHeader& other) { - importBinary(bytes, len); + clear(); + mModuleId = other.mModuleId; + mBssSize = other.mBssSize; + mTextSegmentInfo = other.mTextSegmentInfo; + mRoSegmentInfo = other.mRoSegmentInfo; + mDataSegmentInfo = other.mDataSegmentInfo; + mModuleNameInfo = other.mModuleNameInfo; + mRoEmbeddedInfo = other.mRoEmbeddedInfo; + mRoDynStrInfo = other.mRoDynStrInfo; + mRoDynSymInfo = other.mRoDynSymInfo; } + bool nx::NsoHeader::operator==(const NsoHeader& other) const { - return isEqual(other); + return (mModuleId == other.mModuleId) \ + && (mBssSize == other.mBssSize) \ + && (mTextSegmentInfo == other.mTextSegmentInfo) \ + && (mRoSegmentInfo == other.mRoSegmentInfo) \ + && (mDataSegmentInfo == other.mDataSegmentInfo) \ + && (mModuleNameInfo == other.mModuleNameInfo) \ + && (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \ + && (mRoDynStrInfo == other.mRoDynStrInfo) \ + && (mRoDynSymInfo == other.mRoDynSymInfo); } bool nx::NsoHeader::operator!=(const NsoHeader& other) const @@ -25,25 +43,10 @@ bool nx::NsoHeader::operator!=(const NsoHeader& other) const return !(*this == other); } -void nx::NsoHeader::operator=(const NsoHeader& other) +void nx::NsoHeader::toBytes() { - copyFrom(other); -} - -const byte_t* nx::NsoHeader::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::NsoHeader::getSize() const -{ - return mBinaryBlob.getSize(); -} - -void nx::NsoHeader::exportBinary() -{ - mBinaryBlob.alloc(sizeof(sNsoHeader)); - nx::sNsoHeader* hdr = (nx::sNsoHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(sizeof(sNsoHeader)); + nx::sNsoHeader* hdr = (nx::sNsoHeader*)mRawBinary.data(); // set header identifers hdr->signature = nso::kNsoSig; @@ -122,7 +125,7 @@ void nx::NsoHeader::exportBinary() hdr->flags = flags; } -void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len) +void nx::NsoHeader::fromBytes(const byte_t* data, size_t len) { // check input data size if (len < sizeof(sNsoHeader)) @@ -134,11 +137,11 @@ void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len) clear(); // allocate internal local binary copy - mBinaryBlob.alloc(sizeof(sNsoHeader)); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(sizeof(sNsoHeader)); + memcpy(mRawBinary.data(), data, mRawBinary.size()); // get sNsoHeader ptr - const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mBinaryBlob.getBytes(); + const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mRawBinary.data(); // check NSO signature if (hdr->signature.get() != nso::kNsoSig) @@ -193,9 +196,14 @@ void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len) mRoDynSymInfo.size = hdr->dyn_sym.size.get(); } +const fnd::Vec& nx::NsoHeader::getBytes() const +{ + return mRawBinary; +} + void nx::NsoHeader::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); memset(&mModuleId, 0, sizeof(mModuleId)); mBssSize = 0; memset(&mTextSegmentInfo, 0, sizeof(mTextSegmentInfo)); @@ -295,30 +303,4 @@ const nx::NsoHeader::sLayout& nx::NsoHeader::getRoDynSymInfo() const void nx::NsoHeader::setRoDynSymInfo(const sLayout& info) { mRoDynSymInfo = info; -} - -bool nx::NsoHeader::isEqual(const NsoHeader& other) const -{ - return (mModuleId == other.mModuleId) \ - && (mBssSize == other.mBssSize) \ - && (mTextSegmentInfo == other.mTextSegmentInfo) \ - && (mRoSegmentInfo == other.mRoSegmentInfo) \ - && (mDataSegmentInfo == other.mDataSegmentInfo) \ - && (mModuleNameInfo == other.mModuleNameInfo) \ - && (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \ - && (mRoDynStrInfo == other.mRoDynStrInfo) \ - && (mRoDynSymInfo == other.mRoDynSymInfo); -} -void nx::NsoHeader::copyFrom(const NsoHeader& other) -{ - clear(); - mModuleId = other.mModuleId; - mBssSize = other.mBssSize; - mTextSegmentInfo = other.mTextSegmentInfo; - mRoSegmentInfo = other.mRoSegmentInfo; - mDataSegmentInfo = other.mDataSegmentInfo; - mModuleNameInfo = other.mModuleNameInfo; - mRoEmbeddedInfo = other.mRoEmbeddedInfo; - mRoDynStrInfo = other.mRoDynStrInfo; - mRoDynSymInfo = other.mRoDynSymInfo; } \ No newline at end of file diff --git a/lib/libnx/source/PfsHeader.cpp b/lib/libnx/source/PfsHeader.cpp index 1d6af09..cf6324a 100644 --- a/lib/libnx/source/PfsHeader.cpp +++ b/lib/libnx/source/PfsHeader.cpp @@ -1,37 +1,63 @@ #include - - nx::PfsHeader::PfsHeader() -{} +{ + clear(); +} nx::PfsHeader::PfsHeader(const PfsHeader & other) { - copyFrom(other); + *this = other; } -nx::PfsHeader::PfsHeader(const byte_t * bytes, size_t len) +void nx::PfsHeader::operator=(const PfsHeader & other) { - importBinary(bytes, len); + if (other.getBytes().size()) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + clear(); + mFsType = other.mFsType; + mFileList = other.mFileList; + } } -void nx::PfsHeader::exportBinary() +bool nx::PfsHeader::operator==(const PfsHeader & other) const +{ + return (mFsType == other.mFsType) \ + && (mFileList == other.mFileList); +} + +bool nx::PfsHeader::operator!=(const PfsHeader & other) const +{ + return !(*this == other); +} + +const fnd::Vec& nx::PfsHeader::getBytes() const +{ + return mRawBinary; +} + + +void nx::PfsHeader::toBytes() { // calculate name table size size_t name_table_size = 0; - for (size_t i = 0; i < mFileList.getSize(); i++) + for (size_t i = 0; i < mFileList.size(); i++) { name_table_size += mFileList[i].name.length() + 1; } - size_t pfs_header_size = align(sizeof(sPfsHeader) + getFileEntrySize(mFsType) * mFileList.getSize() + name_table_size, pfs::kHeaderAlign); + size_t pfs_header_size = align(sizeof(sPfsHeader) + getFileEntrySize(mFsType) * mFileList.size() + name_table_size, pfs::kHeaderAlign); // align name_table_size - name_table_size = pfs_header_size - (sizeof(sPfsHeader) + getFileEntrySize(mFsType) * mFileList.getSize()); + name_table_size = pfs_header_size - (sizeof(sPfsHeader) + getFileEntrySize(mFsType) * mFileList.size()); // allocate pfs header binary - mBinaryBlob.alloc(pfs_header_size); - sPfsHeader* hdr = (sPfsHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(pfs_header_size); + sPfsHeader* hdr = (sPfsHeader*)mRawBinary.data(); // set header fields switch (mFsType) @@ -44,18 +70,18 @@ void nx::PfsHeader::exportBinary() break; } - hdr->file_num = (uint32_t)mFileList.getSize(); + hdr->file_num = (uint32_t)mFileList.size(); hdr->name_table_size = (uint32_t)name_table_size; // set file entries if (mFsType == TYPE_PFS0) { - sPfsFile* raw_files = (sPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader)); - char* raw_name_table = (char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sPfsFile) * mFileList.getSize()); + sPfsFile* raw_files = (sPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader)); + char* raw_name_table = (char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sPfsFile) * mFileList.size()); size_t raw_name_table_pos = 0; calculateOffsets(pfs_header_size); - for (size_t i = 0; i < mFileList.getSize(); i++) + for (size_t i = 0; i < mFileList.size(); i++) { raw_files[i].data_offset = (mFileList[i].offset - pfs_header_size); raw_files[i].size = mFileList[i].size; @@ -67,12 +93,12 @@ void nx::PfsHeader::exportBinary() } else if (mFsType == TYPE_HFS0) { - sHashedPfsFile* raw_files = (sHashedPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader)); - char* raw_name_table = (char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * mFileList.getSize()); + sHashedPfsFile* raw_files = (sHashedPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader)); + char* raw_name_table = (char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * mFileList.size()); size_t raw_name_table_pos = 0; calculateOffsets(pfs_header_size); - for (size_t i = 0; i < mFileList.getSize(); i++) + for (size_t i = 0; i < mFileList.size(); i++) { raw_files[i].data_offset = (mFileList[i].offset - pfs_header_size); raw_files[i].size = mFileList[i].size; @@ -87,7 +113,7 @@ void nx::PfsHeader::exportBinary() } -void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len) +void nx::PfsHeader::fromBytes(const byte_t* data, size_t len) { // check input length meets minimum size if (len < sizeof(sPfsHeader)) @@ -96,9 +122,9 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len) } // import minimum header - mBinaryBlob.alloc(sizeof(sPfsHeader)); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); - const sPfsHeader* hdr = (const sPfsHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(sizeof(sPfsHeader)); + memcpy(mRawBinary.data(), data, mRawBinary.size()); + const sPfsHeader* hdr = (const sPfsHeader*)mRawBinary.data(); // check struct signature FsType fs_type; @@ -124,9 +150,9 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len) } // import full header - mBinaryBlob.alloc(pfs_full_header_size); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); - hdr = (const sPfsHeader*)mBinaryBlob.getBytes(); + mRawBinary.alloc(pfs_full_header_size); + memcpy(mRawBinary.data(), data, mRawBinary.size()); + hdr = (const sPfsHeader*)mRawBinary.data(); // clear variables clear(); @@ -135,8 +161,8 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len) if (mFsType == TYPE_PFS0) { // get pointers to raw data - const sPfsFile* raw_files = (const sPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader)); - const char* raw_name_table = (const char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sPfsFile) * hdr->file_num.get()); + const sPfsFile* raw_files = (const sPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader)); + const char* raw_name_table = (const char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sPfsFile) * hdr->file_num.get()); // process file entries for (size_t i = 0; i < hdr->file_num.get(); i++) @@ -151,8 +177,8 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len) else if (mFsType == TYPE_HFS0) { // get pointers to raw data - const sHashedPfsFile* raw_files = (const sHashedPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader)); - const char* raw_name_table = (const char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * hdr->file_num.get()); + const sHashedPfsFile* raw_files = (const sHashedPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader)); + const char* raw_name_table = (const char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * hdr->file_num.get()); // process file entries for (size_t i = 0; i < hdr->file_num.get(); i++) @@ -171,7 +197,7 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len) void nx::PfsHeader::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); mFsType = TYPE_PFS0; mFileList.clear(); } @@ -220,52 +246,8 @@ size_t nx::PfsHeader::getFileEntrySize(FsType fs_type) void nx::PfsHeader::calculateOffsets(size_t data_offset) { - for (size_t i = 0; i < mFileList.getSize(); i++) + for (size_t i = 0; i < mFileList.size(); i++) { mFileList[i].offset = (i == 0) ? data_offset : mFileList[i - 1].offset + mFileList[i - 1].size; } -} - -bool nx::PfsHeader::isEqual(const PfsHeader & other) const -{ - return (mFsType == other.mFsType) && (mFileList == other.mFileList); -} - -void nx::PfsHeader::copyFrom(const PfsHeader & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - clear(); - mFsType = other.mFsType; - mFileList = other.mFileList; - } -} - -bool nx::PfsHeader::operator==(const PfsHeader & other) const -{ - return isEqual(other); -} - -bool nx::PfsHeader::operator!=(const PfsHeader & other) const -{ - return !isEqual(other); -} - -void nx::PfsHeader::operator=(const PfsHeader & other) -{ - copyFrom(other); -} - -const byte_t * nx::PfsHeader::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::PfsHeader::getSize() const -{ - return mBinaryBlob.getSize(); -} +} \ No newline at end of file diff --git a/lib/libnx/source/SacBinary.cpp b/lib/libnx/source/SacBinary.cpp index 81efb30..4591c3a 100644 --- a/lib/libnx/source/SacBinary.cpp +++ b/lib/libnx/source/SacBinary.cpp @@ -4,76 +4,75 @@ using namespace nx; SacBinary::SacBinary() { + clear(); } SacBinary::SacBinary(const SacBinary & other) { - copyFrom(other); -} - -SacBinary::SacBinary(const byte_t * bytes, size_t len) -{ - importBinary(bytes, len); -} - -bool SacBinary::operator==(const SacBinary & other) const -{ - return isEqual(other); -} - -bool SacBinary::operator!=(const SacBinary & other) const -{ - return !isEqual(other); + *this = other; } void SacBinary::operator=(const SacBinary & other) { - copyFrom(other); + if (other.getBytes().data()) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + clear(); + mServices = other.mServices; + } } -const byte_t * SacBinary::getBytes() const +bool SacBinary::operator==(const SacBinary & other) const { - return mBinaryBlob.getBytes(); + return mServices == other.mServices; } -size_t SacBinary::getSize() const +bool SacBinary::operator!=(const SacBinary & other) const { - return mBinaryBlob.getSize(); + return !(*this == other); } -void SacBinary::exportBinary() +void SacBinary::toBytes() { size_t totalSize = 0; - for (size_t i = 0; i < mServices.getSize(); i++) + for (size_t i = 0; i < mServices.size(); i++) { - mServices[i].exportBinary(); - totalSize += mServices[i].getSize(); + mServices[i].toBytes(); + totalSize += mServices[i].getBytes().size(); } - mBinaryBlob.alloc(totalSize); - for (size_t i = 0, pos = 0; i < mServices.getSize(); pos += mServices[i].getSize(), i++) + mRawBinary.alloc(totalSize); + for (size_t i = 0, pos = 0; i < mServices.size(); pos += mServices[i].getBytes().size(), i++) { - memcpy((mBinaryBlob.getBytes() + pos), mServices[i].getBytes(), mServices[i].getSize()); + memcpy((mRawBinary.data() + pos), mServices[i].getBytes().data(), mServices[i].getBytes().size()); } } -void SacBinary::importBinary(const byte_t * bytes, size_t len) +void SacBinary::fromBytes(const byte_t* data, size_t len) { clear(); - mBinaryBlob.alloc(len); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(len); + memcpy(mRawBinary.data(), data, mRawBinary.size()); - SacEntry svc; - for (size_t pos = 0; pos < len; pos += mServices.atBack().getSize()) + SacEntry sac; + for (size_t pos = 0; pos < len; pos += mServices.atBack().getBytes().size()) { - svc.importBinary((const byte_t*)(mBinaryBlob.getBytes() + pos), len - pos); - mServices.addElement(svc); + sac.fromBytes((const byte_t*)(mRawBinary.data() + pos), len - pos); + mServices.addElement(sac); } } +const fnd::Vec& SacBinary::getBytes() const +{ + return mRawBinary; +} + void nx::SacBinary::clear() { - mBinaryBlob.clear(); + mRawBinary.clear(); mServices.clear(); } @@ -85,22 +84,4 @@ const fnd::List& SacBinary::getServiceList() const void SacBinary::addService(const SacEntry& service) { mServices.addElement(service); -} - -bool SacBinary::isEqual(const SacBinary & other) const -{ - return mServices == other.mServices; -} - -void SacBinary::copyFrom(const SacBinary & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - this->mBinaryBlob.clear(); - this->mServices = other.mServices; - } -} +} \ No newline at end of file diff --git a/lib/libnx/source/SacEntry.cpp b/lib/libnx/source/SacEntry.cpp index d6dc2d4..8fb63be 100644 --- a/lib/libnx/source/SacEntry.cpp +++ b/lib/libnx/source/SacEntry.cpp @@ -3,52 +3,52 @@ using namespace nx; SacEntry::SacEntry() : - mIsServer(false), - mName("") { + clear(); } SacEntry::SacEntry(const std::string & name, bool isServer) : mIsServer(isServer), mName(name) { - exportBinary(); + toBytes(); } SacEntry::SacEntry(const SacEntry & other) { - copyFrom(other); -} - -bool SacEntry::operator==(const SacEntry & other) const -{ - return isEqual(other); -} - -bool SacEntry::operator!=(const SacEntry & other) const -{ - return !isEqual(other); + *this = other; } void SacEntry::operator=(const SacEntry & other) { - copyFrom(other); + if (other.getBytes().size()) + { + fromBytes(other.getBytes().data(), other.getBytes().size()); + } + else + { + clear(); + this->mIsServer = other.mIsServer; + this->mName = other.mName; + } } -const byte_t * SacEntry::getBytes() const +bool SacEntry::operator==(const SacEntry & other) const { - return mBinaryBlob.getBytes(); + return (mIsServer == other.mIsServer) \ + && (mName == other.mName); } -size_t SacEntry::getSize() const +bool SacEntry::operator!=(const SacEntry & other) const { - return mBinaryBlob.getSize(); + return !(*this == other); } -void SacEntry::exportBinary() + +void SacEntry::toBytes() { try { - mBinaryBlob.alloc(mName.size() + 1); + mRawBinary.alloc(mName.size() + 1); } catch (const fnd::Exception& e) { @@ -66,14 +66,14 @@ void SacEntry::exportBinary() } // copy data into binary blob - mBinaryBlob[0] = (mIsServer ? SAC_IS_SERVER : 0) | ((mName.length()-1) & SAC_NAME_LEN_MASK); // bug? - memcpy(mBinaryBlob.getBytes() + 1, mName.c_str(), mName.length()); + mRawBinary[0] = (mIsServer ? SAC_IS_SERVER : 0) | ((mName.length()-1) & SAC_NAME_LEN_MASK); // bug? + memcpy(mRawBinary.data() + 1, mName.c_str(), mName.length()); } -void SacEntry::importBinary(const byte_t * bytes, size_t len) +void SacEntry::fromBytes(const byte_t* data, size_t len) { - bool isServer = (bytes[0] & SAC_IS_SERVER) == SAC_IS_SERVER; - size_t nameLen = (bytes[0] & SAC_NAME_LEN_MASK) + 1; // bug? + bool isServer = (data[0] & SAC_IS_SERVER) == SAC_IS_SERVER; + size_t nameLen = (data[0] & SAC_NAME_LEN_MASK) + 1; // bug? if (nameLen+1 > len) { @@ -89,11 +89,16 @@ void SacEntry::importBinary(const byte_t * bytes, size_t len) throw fnd::Exception(kModuleName, "Service name string too long (max 8 chars)"); } - mBinaryBlob.alloc(nameLen + 1); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(nameLen + 1); + memcpy(mRawBinary.data(), data, mRawBinary.size()); mIsServer = isServer; - mName = std::string((const char*)(mBinaryBlob.getBytes() + 1), nameLen); + mName = std::string((const char*)(mRawBinary.data() + 1), nameLen); +} + +const fnd::Vec& SacEntry::getBytes() const +{ + return mRawBinary; } void nx::SacEntry::clear() @@ -125,23 +130,4 @@ void SacEntry::setName(const std::string & name) } mName = name; -} - -bool SacEntry::isEqual(const SacEntry & other) const -{ - return (mIsServer == other.mIsServer) \ - && (mName == other.mName); -} - -void SacEntry::copyFrom(const SacEntry & other) -{ - if (other.getSize()) - { - importBinary(other.getBytes(), other.getSize()); - } - else - { - this->mIsServer = other.mIsServer; - this->mName = other.mName; - } -} +} \ No newline at end of file diff --git a/lib/libnx/source/XciHeader.cpp b/lib/libnx/source/XciHeader.cpp index 7c896de..d1dd252 100644 --- a/lib/libnx/source/XciHeader.cpp +++ b/lib/libnx/source/XciHeader.cpp @@ -1,39 +1,16 @@ #include -bool nx::XciHeader::isEqual(const XciHeader& other) const +nx::XciHeader::XciHeader() { - return ( mRomAreaStartPage == other.mRomAreaStartPage \ - && mBackupAreaStartPage == other.mBackupAreaStartPage \ - && mKekIndex == other.mKekIndex \ - && mTitleKeyDecIndex == other.mTitleKeyDecIndex \ - && mRomSize == other.mRomSize \ - && mCardHeaderVersion == other.mCardHeaderVersion \ - && mFlags == other.mFlags \ - && mPackageId == other.mPackageId \ - && mValidDataEndPage == other.mValidDataEndPage \ - && mAesCbcIv == other.mAesCbcIv \ - && mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress \ - && mPartitionFsHeaderSize == other.mPartitionFsHeaderSize \ - && mPartitionFsHeaderHash == other.mPartitionFsHeaderHash \ - && mInitialDataHash == other.mInitialDataHash \ - && mSelSec == other.mSelSec \ - && mSelT1Key == other.mSelT1Key \ - && mSelKey == other.mSelKey \ - && mLimAreaPage == other.mLimAreaPage \ - && mFwVersion[0] == other.mFwVersion[0] \ - && mFwVersion[1] == other.mFwVersion[1] \ - && mAccCtrl1 == other.mAccCtrl1 \ - && mWait1TimeRead == other.mWait1TimeRead \ - && mWait2TimeRead == other.mWait2TimeRead \ - && mWait1TimeWrite == other.mWait1TimeWrite \ - && mWait2TimeWrite == other.mWait2TimeWrite \ - && mFwMode == other.mFwMode \ - && mUppVersion == other.mUppVersion \ - && memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) \ - && mUppId == other.mUppId ); + clear(); } -void nx::XciHeader::copyFrom(const XciHeader& other) +nx::XciHeader::XciHeader(const XciHeader& other) +{ + *this = other; +} + +void nx::XciHeader::operator=(const XciHeader& other) { mRomAreaStartPage = other.mRomAreaStartPage; mBackupAreaStartPage = other.mBackupAreaStartPage; @@ -66,51 +43,50 @@ void nx::XciHeader::copyFrom(const XciHeader& other) mUppId = other.mUppId; } -nx::XciHeader::XciHeader() -{ - -} - -nx::XciHeader::XciHeader(const XciHeader& other) -{ - importBinary(other.getBytes(), other.getSize()); -} -nx::XciHeader::XciHeader(const byte_t* bytes, size_t len) -{ - importBinary(bytes, len); -} - bool nx::XciHeader::operator==(const XciHeader& other) const { - return isEqual(other); + return (mRomAreaStartPage == other.mRomAreaStartPage \ + && mBackupAreaStartPage == other.mBackupAreaStartPage \ + && mKekIndex == other.mKekIndex \ + && mTitleKeyDecIndex == other.mTitleKeyDecIndex \ + && mRomSize == other.mRomSize \ + && mCardHeaderVersion == other.mCardHeaderVersion \ + && mFlags == other.mFlags \ + && mPackageId == other.mPackageId \ + && mValidDataEndPage == other.mValidDataEndPage \ + && mAesCbcIv == other.mAesCbcIv \ + && mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress \ + && mPartitionFsHeaderSize == other.mPartitionFsHeaderSize \ + && mPartitionFsHeaderHash == other.mPartitionFsHeaderHash \ + && mInitialDataHash == other.mInitialDataHash \ + && mSelSec == other.mSelSec \ + && mSelT1Key == other.mSelT1Key \ + && mSelKey == other.mSelKey \ + && mLimAreaPage == other.mLimAreaPage \ + && mFwVersion[0] == other.mFwVersion[0] \ + && mFwVersion[1] == other.mFwVersion[1] \ + && mAccCtrl1 == other.mAccCtrl1 \ + && mWait1TimeRead == other.mWait1TimeRead \ + && mWait2TimeRead == other.mWait2TimeRead \ + && mWait1TimeWrite == other.mWait1TimeWrite \ + && mWait2TimeWrite == other.mWait2TimeWrite \ + && mFwMode == other.mFwMode \ + && mUppVersion == other.mUppVersion \ + && memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) \ + && mUppId == other.mUppId); } + bool nx::XciHeader::operator!=(const XciHeader& other) const { - return isEqual(other) == false; -} -void nx::XciHeader::operator=(const XciHeader& other) -{ - copyFrom(other); + return !(*this == other); } -// to be used after export -const byte_t* nx::XciHeader::getBytes() const -{ - return mBinaryBlob.getBytes(); -} - -size_t nx::XciHeader::getSize() const -{ - return mBinaryBlob.getSize(); -} - -// export/import binary -void nx::XciHeader::exportBinary() +void nx::XciHeader::toBytes() { fnd::Exception(kModuleName, "exportBinary() not implemented"); } -void nx::XciHeader::importBinary(const byte_t* bytes, size_t len) +void nx::XciHeader::fromBytes(const byte_t* data, size_t len) { // check input data size if (len < sizeof(sXciHeader)) @@ -122,11 +98,11 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len) clear(); // allocate internal local binary copy - mBinaryBlob.alloc(sizeof(sXciHeader)); - memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); + mRawBinary.alloc(sizeof(sXciHeader)); + memcpy(mRawBinary.data(), data, mRawBinary.size()); // get sXciHeader ptr - const nx::sXciHeader* hdr = (const nx::sXciHeader*)mBinaryBlob.getBytes(); + const nx::sXciHeader* hdr = (const nx::sXciHeader*)mRawBinary.data(); // check XCI signature if (hdr->signature.get() != xci::kXciSig) @@ -172,6 +148,11 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len) } +const fnd::Vec& nx::XciHeader::getBytes() const +{ + return mRawBinary; +} + // variables void nx::XciHeader::clear() {