[nx] Update to new code style/design.

This commit is contained in:
jakcron 2018-06-24 16:18:54 +08:00
parent 91c2d40111
commit 7a8d8e0fea
42 changed files with 1114 additions and 1593 deletions

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <nx/AciHeader.h> #include <nx/AciHeader.h>
#include <nx/FacBinary.h> #include <nx/FacBinary.h>
@ -15,19 +14,15 @@ namespace nx
public: public:
AciBinary(); AciBinary();
AciBinary(const AciBinary& other); 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;
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 // export/import binary
virtual void exportBinary(); virtual void toBytes();
virtual void importBinary(const byte_t* bytes, size_t len); virtual void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
virtual void clear(); virtual void clear();
@ -45,15 +40,12 @@ namespace nx
const std::string kModuleName = "ACI_BINARY"; const std::string kModuleName = "ACI_BINARY";
// raw binary // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
FacBinary mFac; FacBinary mFac;
SacBinary mSac; SacBinary mSac;
KcBinary mKc; KcBinary mKc;
bool isEqual(const AciBinary& other) const;
void copyFrom(const AciBinary& other);
}; };
} }

View file

@ -1,14 +1,13 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/aci.h> #include <nx/aci.h>
namespace nx namespace nx
{ {
class AciHeader : class AciHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
enum AciType enum AciType
@ -42,19 +41,15 @@ namespace nx
AciHeader(); AciHeader();
AciHeader(const AciHeader& other); 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;
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 // export/import binary
virtual void exportBinary(); virtual void toBytes();
virtual void importBinary(const byte_t* bytes, size_t len); virtual void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
virtual void clear(); virtual void clear();
@ -91,7 +86,7 @@ namespace nx
const std::string kModuleName = "ACI_HEADER"; const std::string kModuleName = "ACI_HEADER";
// raw data // raw data
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// ACI variables // ACI variables
uint64_t mProgramId; uint64_t mProgramId;
@ -109,8 +104,6 @@ namespace nx
sSection mFac, mSac, mKc; sSection mFac, mSac, mKc;
void calculateSectionOffsets(); void calculateSectionOffsets();
bool isEqual(const AciHeader& other) const;
void copyFrom(const AciHeader& other);
}; };
} }

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/MemoryBlob.h>
#include <nx/AciBinary.h> #include <nx/AciBinary.h>
#include <crypto/rsa.h> #include <crypto/rsa.h>
@ -12,21 +11,17 @@ namespace nx
public: public:
AcidBinary(); AcidBinary();
AcidBinary(const AcidBinary& other); 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;
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 // export/import binary
virtual void exportBinary(); void toBytes();
void signBinary(const crypto::rsa::sRsa2048Key& key); 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; void verifyBinary(const crypto::rsa::sRsa2048Key& key) const;
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
virtual void clear(); virtual void clear();
@ -38,13 +33,10 @@ namespace nx
const std::string kModuleName = "ACID_BINARY"; const std::string kModuleName = "ACID_BINARY";
// raw binary // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
crypto::rsa::sRsa2048Key mEmbeddedPublicKey; crypto::rsa::sRsa2048Key mEmbeddedPublicKey;
bool isEqual(const AcidBinary& other) const;
void copyFrom(const AcidBinary& other);
}; };
} }

View file

@ -1,15 +1,14 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/nacp.h> #include <nx/nacp.h>
namespace nx namespace nx
{ {
class ApplicationControlPropertyBinary : class ApplicationControlPropertyBinary :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
struct sTitle struct sTitle
@ -86,19 +85,15 @@ namespace nx
ApplicationControlPropertyBinary(); ApplicationControlPropertyBinary();
ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -222,7 +217,7 @@ namespace nx
const std::string kModuleName = "APPLICATION_CONTROL_PROPERTY"; const std::string kModuleName = "APPLICATION_CONTROL_PROPERTY";
// raw data // raw data
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
fnd::List<sTitle> mTitle; fnd::List<sTitle> mTitle;
@ -263,8 +258,5 @@ namespace nx
nacp::PlayLogQueryCapability mPlayLogQueryCapability; nacp::PlayLogQueryCapability mPlayLogQueryCapability;
nacp::RepairFlag mRepairFlag; nacp::RepairFlag mRepairFlag;
byte_t mProgramIndex; byte_t mProgramIndex;
bool isEqual(const ApplicationControlPropertyBinary& other) const;
void copyFrom(const ApplicationControlPropertyBinary& other);
}; };
} }

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <nx/cnmt.h> #include <nx/cnmt.h>
@ -8,7 +8,7 @@
namespace nx namespace nx
{ {
class ContentMetaBinary : class ContentMetaBinary :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
struct ContentInfo struct ContentInfo
@ -18,13 +18,12 @@ namespace nx
size_t size; size_t size;
cnmt::ContentType type; cnmt::ContentType type;
ContentInfo& operator=(const ContentInfo& other) void operator=(const ContentInfo& other)
{ {
hash = other.hash; hash = other.hash;
memcpy(nca_id, other.nca_id, cnmt::kContentIdLen); memcpy(nca_id, other.nca_id, cnmt::kContentIdLen);
size = other.size; size = other.size;
type = other.type; type = other.type;
return *this;
} }
bool operator==(const ContentInfo& other) const bool operator==(const ContentInfo& other) const
@ -48,13 +47,12 @@ namespace nx
cnmt::ContentMetaType type; cnmt::ContentMetaType type;
byte_t attributes; byte_t attributes;
ContentMetaInfo& operator=(const ContentMetaInfo& other) void operator=(const ContentMetaInfo& other)
{ {
id = other.id; id = other.id;
version = other.version; version = other.version;
type = other.type; type = other.type;
attributes = other.attributes; attributes = other.attributes;
return *this;
} }
bool operator==(const ContentMetaInfo& other) const bool operator==(const ContentMetaInfo& other) const
@ -76,11 +74,10 @@ namespace nx
uint64_t patch_id; uint64_t patch_id;
uint32_t required_system_version; uint32_t required_system_version;
ApplicationMetaExtendedHeader& operator=(const ApplicationMetaExtendedHeader& other) void operator=(const ApplicationMetaExtendedHeader& other)
{ {
patch_id = other.patch_id; patch_id = other.patch_id;
required_system_version = other.required_system_version; required_system_version = other.required_system_version;
return *this;
} }
bool operator==(const ApplicationMetaExtendedHeader& other) const bool operator==(const ApplicationMetaExtendedHeader& other) const
@ -100,11 +97,10 @@ namespace nx
uint64_t application_id; uint64_t application_id;
uint32_t required_system_version; uint32_t required_system_version;
PatchMetaExtendedHeader& operator=(const PatchMetaExtendedHeader& other) void operator=(const PatchMetaExtendedHeader& other)
{ {
application_id = other.application_id; application_id = other.application_id;
required_system_version = other.required_system_version; required_system_version = other.required_system_version;
return *this;
} }
bool operator==(const PatchMetaExtendedHeader& other) const bool operator==(const PatchMetaExtendedHeader& other) const
@ -124,11 +120,10 @@ namespace nx
uint64_t application_id; uint64_t application_id;
uint32_t required_system_version; uint32_t required_system_version;
AddOnContentMetaExtendedHeader& operator=(const AddOnContentMetaExtendedHeader& other) void operator=(const AddOnContentMetaExtendedHeader& other)
{ {
application_id = other.application_id; application_id = other.application_id;
required_system_version = other.required_system_version; required_system_version = other.required_system_version;
return *this;
} }
bool operator==(const AddOnContentMetaExtendedHeader& other) const bool operator==(const AddOnContentMetaExtendedHeader& other) const
@ -147,10 +142,9 @@ namespace nx
{ {
uint64_t application_id; uint64_t application_id;
DeltaMetaExtendedHeader& operator=(const DeltaMetaExtendedHeader& other) void operator=(const DeltaMetaExtendedHeader& other)
{ {
application_id = other.application_id; application_id = other.application_id;
return *this;
} }
bool operator==(const DeltaMetaExtendedHeader& other) const bool operator==(const DeltaMetaExtendedHeader& other) const
@ -166,15 +160,15 @@ namespace nx
ContentMetaBinary(); ContentMetaBinary();
ContentMetaBinary(const ContentMetaBinary& other); ContentMetaBinary(const ContentMetaBinary& other);
ContentMetaBinary(const byte_t* bytes, size_t len);
// to be used after export void operator=(const ContentMetaBinary& other);
const byte_t* getBytes() const; bool operator==(const ContentMetaBinary& other) const;
size_t getSize() const; bool operator!=(const ContentMetaBinary& other) const;
// export/import binary // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -212,8 +206,8 @@ namespace nx
const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& getContentMetaInfo() const; const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& getContentMetaInfo() const;
void setContentMetaInfo(const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& info); void setContentMetaInfo(const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& info);
const fnd::MemoryBlob& getExtendedData() const; const fnd::Vec<byte_t>& getExtendedData() const;
void setExtendedData(const fnd::MemoryBlob& data); void setExtendedData(const fnd::Vec<byte_t>& data);
const nx::sDigest& getDigest() const; const nx::sDigest& getDigest() const;
void setDigest(const nx::sDigest& digest); void setDigest(const nx::sDigest& digest);
@ -223,7 +217,7 @@ namespace nx
const std::string kModuleName = "CONTENT_META_BINARY"; const std::string kModuleName = "CONTENT_META_BINARY";
// binary blob // binary blob
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
uint64_t mTitleId; uint64_t mTitleId;
@ -231,7 +225,7 @@ namespace nx
cnmt::ContentMetaType mType; cnmt::ContentMetaType mType;
byte_t mAttributes; byte_t mAttributes;
uint32_t mRequiredDownloadSystemVersion; uint32_t mRequiredDownloadSystemVersion;
fnd::MemoryBlob mExtendedHeader; fnd::Vec<byte_t> mExtendedHeader;
ApplicationMetaExtendedHeader mApplicationMetaExtendedHeader; ApplicationMetaExtendedHeader mApplicationMetaExtendedHeader;
PatchMetaExtendedHeader mPatchMetaExtendedHeader; PatchMetaExtendedHeader mPatchMetaExtendedHeader;
@ -240,7 +234,7 @@ namespace nx
fnd::List<nx::ContentMetaBinary::ContentInfo> mContentInfo; fnd::List<nx::ContentMetaBinary::ContentInfo> mContentInfo;
fnd::List<nx::ContentMetaBinary::ContentMetaInfo> mContentMetaInfo; fnd::List<nx::ContentMetaBinary::ContentMetaInfo> mContentMetaInfo;
fnd::MemoryBlob mExtendedData; fnd::Vec<byte_t> mExtendedData;
nx::sDigest mDigest; nx::sDigest mDigest;
inline size_t getExtendedHeaderOffset() const { return sizeof(sContentMetaHeader); } inline size_t getExtendedHeaderOffset() const { return sizeof(sContentMetaHeader); }
@ -253,8 +247,5 @@ namespace nx
bool validateExtendedHeaderSize(cnmt::ContentMetaType type, size_t exhdrSize) const; bool validateExtendedHeaderSize(cnmt::ContentMetaType type, size_t exhdrSize) const;
size_t getExtendedDataSize(cnmt::ContentMetaType type, const byte_t* data) const; size_t getExtendedDataSize(cnmt::ContentMetaType type, const byte_t* data) const;
void validateBinary(const byte_t* bytes, size_t len) const; void validateBinary(const byte_t* bytes, size_t len) const;
bool isEqual(const ContentMetaBinary& other) const;
void copyFrom(const ContentMetaBinary& other);
}; };
} }

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <nx/FacHeader.h> #include <nx/FacHeader.h>
@ -13,19 +12,15 @@ namespace nx
public: public:
FacBinary(); FacBinary();
FacBinary(const FacBinary& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -41,14 +36,11 @@ namespace nx
static const uint32_t kFacFormatVersion = 1; static const uint32_t kFacFormatVersion = 1;
// raw binary // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
fnd::List<uint32_t> mContentOwnerIdList; fnd::List<uint32_t> mContentOwnerIdList;
fnd::List<uint32_t> mSaveDataOwnerIdList; fnd::List<uint32_t> mSaveDataOwnerIdList;
bool isEqual(const FacBinary& other) const;
void copyFrom(const FacBinary& other);
}; };
} }

View file

@ -1,56 +1,49 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h> #include <nx/fac.h>
namespace nx namespace nx
{ {
class FacHeader : class FacHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
enum FsAccessFlag struct sSection
{ {
FSA_APPLICATION_INFO, size_t offset;
FSA_BOOT_MODE_CONTROL, size_t size;
FSA_CALIBRATION,
FSA_SYSTEM_SAVE_DATA, void operator=(const sSection& other)
FSA_GAME_CARD, {
FSA_SAVE_DATA_BACKUP, offset = other.offset;
FSA_SAVE_DATA_MANAGEMENT, size = other.size;
FSA_BIS_ALL_RAW, }
FSA_GAME_CARD_RAW,
FSA_GAME_CARD_PRIVATE, bool operator==(const sSection& other) const
FSA_SET_TIME, {
FSA_CONTENT_MANAGER, return (offset == other.offset) \
FSA_IMAGE_MANAGER, && (size == other.size);
FSA_CREATE_SAVE_DATA, }
FSA_SYSTEM_SAVE_DATA_MANAGEMENT,
FSA_BIS_FILE_SYSTEM, bool operator!=(const sSection& other) const
FSA_SYSTEM_UPDATE, {
FSA_SAVE_DATA_META, return !operator==(other);
FSA_DEVICE_SAVE_CONTROL, }
FSA_SETTINGS_CONTROL,
FSA_DEBUG = 62,
FSA_FULL_PERMISSION = 63,
}; };
FacHeader(); FacHeader();
FacHeader(const FacHeader& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -59,49 +52,28 @@ namespace nx
uint32_t getFormatVersion() const; uint32_t getFormatVersion() const;
void setFormatVersion(uint32_t version); void setFormatVersion(uint32_t version);
const fnd::List<FsAccessFlag>& getFsaRightsList() const; const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const;
void setFsaRightsList(const fnd::List<FsAccessFlag>& list); void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list);
size_t getContentOwnerIdOffset() const; const sSection& getContentOwnerIdPos() const;
size_t getContentOwnerIdSize() const;
void setContentOwnerIdSize(size_t size); void setContentOwnerIdSize(size_t size);
size_t getSaveDataOwnerIdOffset() const; const sSection& getSaveDataOwnerIdPos() const;;
size_t getSaveDataOwnerIdSize() const;
void setSaveDataOwnerIdSize(size_t size); void setSaveDataOwnerIdSize(size_t size);
private: private:
const std::string kModuleName = "FAC_HEADER"; 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 // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
uint32_t mVersion; uint32_t mVersion;
fnd::List<FsAccessFlag> mFsaRights; fnd::List<fac::FsAccessFlag> mFsaRights;
struct sSection sSection mContentOwnerIdPos;
{ sSection mSaveDataOwnerIdPos;
size_t offset;
size_t size;
} mContentOwnerIdPos, mSaveDataOwnerIdPos;
void calculateOffsets(); void calculateOffsets();
bool isEqual(const FacHeader& other) const;
void copyFrom(const FacHeader& other);
}; };
} }

View file

@ -1,13 +1,12 @@
#pragma once #pragma once
#include <nx/hierarchicalintegrity.h> #include <nx/hierarchicalintegrity.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {
class HierarchicalIntegrityHeader : class HierarchicalIntegrityHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
struct sLayer struct sLayer
@ -36,19 +35,15 @@ namespace nx
HierarchicalIntegrityHeader(); HierarchicalIntegrityHeader();
HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -62,14 +57,11 @@ namespace nx
const std::string kModuleName = "HIERARCHICAL_INTEGRITY_HEADER"; const std::string kModuleName = "HIERARCHICAL_INTEGRITY_HEADER";
// binary // binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// data // data
fnd::List<sLayer> mLayerInfo; fnd::List<sLayer> mLayerInfo;
fnd::List<crypto::sha::sSha256Hash> mMasterHashList; fnd::List<crypto::sha::sSha256Hash> mMasterHashList;
bool isEqual(const HierarchicalIntegrityHeader& other) const;
void copyFrom(const HierarchicalIntegrityHeader& other);
}; };
} }

View file

@ -1,13 +1,12 @@
#pragma once #pragma once
#include <nx/hierarchicalsha256.h> #include <nx/hierarchicalsha256.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {
class HierarchicalSha256Header : class HierarchicalSha256Header :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
struct sLayer struct sLayer
@ -34,19 +33,15 @@ namespace nx
HierarchicalSha256Header(); HierarchicalSha256Header();
HierarchicalSha256Header(const HierarchicalSha256Header& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -63,15 +58,12 @@ namespace nx
const std::string kModuleName = "HIERARCHICAL_SHA256_HEADER"; const std::string kModuleName = "HIERARCHICAL_SHA256_HEADER";
// binary // binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// data // data
crypto::sha::sSha256Hash mMasterHash; crypto::sha::sSha256Hash mMasterHash;
size_t mHashBlockSize; size_t mHashBlockSize;
fnd::List<sLayer> mLayerInfo; fnd::List<sLayer> mLayerInfo;
bool isEqual(const HierarchicalSha256Header& other) const;
void copyFrom(const HierarchicalSha256Header& other);
}; };
} }

View file

@ -1,9 +1,8 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector> #include <vector>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/ThreadInfoHandler.h> #include <nx/ThreadInfoHandler.h>
#include <nx/SystemCallHandler.h> #include <nx/SystemCallHandler.h>
#include <nx/MemoryMappingHandler.h> #include <nx/MemoryMappingHandler.h>
@ -16,24 +15,20 @@
namespace nx namespace nx
{ {
class KcBinary : class KcBinary :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
KcBinary(); KcBinary();
KcBinary(const KcBinary& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
virtual const fnd::Vec<byte_t>& getBytes() const;
// variables (consider further abstraction?) // variables (consider further abstraction?)
void clear(); void clear();
@ -65,7 +60,7 @@ namespace nx
const std::string kModuleName = "KC_BINARY"; const std::string kModuleName = "KC_BINARY";
// raw binary // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
ThreadInfoHandler mThreadInfo; ThreadInfoHandler mThreadInfo;
@ -76,11 +71,6 @@ namespace nx
KernelVersionHandler mKernelVersion; KernelVersionHandler mKernelVersion;
HandleTableSizeHandler mHandleTableSize; HandleTableSizeHandler mHandleTableSize;
MiscFlagsHandler mMiscFlags; MiscFlagsHandler mMiscFlags;
void clearVariables();
bool isEqual(const KcBinary& other) const;
void copyFrom(const KcBinary& other);
}; };
} }

View file

@ -49,19 +49,18 @@ namespace nx
NcaHeader(); NcaHeader();
NcaHeader(const NcaHeader& other); 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;
bool operator!=(const NcaHeader& other) const; bool operator!=(const NcaHeader& other) const;
void operator=(const NcaHeader& other);
// to be used after export // to be used after export
const byte_t* getBytes() const;
size_t getSize() const; size_t getSize() const;
// export/import binary // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -95,7 +94,7 @@ namespace nx
const std::string kModuleName = "NCA_HEADER"; const std::string kModuleName = "NCA_HEADER";
// binary // binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// data // data
FormatVersion mFormatVersion; FormatVersion mFormatVersion;
@ -113,8 +112,6 @@ namespace nx
uint64_t blockNumToSize(uint32_t block_num) const; uint64_t blockNumToSize(uint32_t block_num) const;
uint32_t sizeToBlockNum(uint64_t real_size) const; uint32_t sizeToBlockNum(uint64_t real_size) const;
bool isEqual(const NcaHeader& other) const;
void copyFrom(const NcaHeader& other);
}; };
} }

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <nx/NpdmHeader.h> #include <nx/NpdmHeader.h>
#include <nx/AciBinary.h> #include <nx/AciBinary.h>
@ -15,19 +14,15 @@ namespace nx
public: public:
NpdmBinary(); NpdmBinary();
NpdmBinary(const NpdmBinary& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -41,14 +36,11 @@ namespace nx
const std::string kModuleName = "NPDM_BINARY"; const std::string kModuleName = "NPDM_BINARY";
// raw binary // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
AciBinary mAci; AciBinary mAci;
AcidBinary mAcid; AcidBinary mAcid;
bool isEqual(const NpdmBinary& other) const;
void copyFrom(const NpdmBinary& other);
}; };
} }

View file

@ -1,14 +1,13 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/npdm.h> #include <nx/npdm.h>
namespace nx namespace nx
{ {
class NpdmHeader : class NpdmHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
struct sSection struct sSection
@ -36,19 +35,15 @@ namespace nx
NpdmHeader(); NpdmHeader();
NpdmHeader(const NpdmHeader& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -87,7 +82,7 @@ namespace nx
const std::string kModuleName = "NPDM_HEADER"; const std::string kModuleName = "NPDM_HEADER";
// raw binary // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
npdm::InstructionType mInstructionType; npdm::InstructionType mInstructionType;
@ -102,8 +97,6 @@ namespace nx
sSection mAcidPos; sSection mAcidPos;
void calculateOffsets(); void calculateOffsets();
bool isEqual(const NpdmHeader& other) const;
void copyFrom(const NpdmHeader& other);
}; };
} }

View file

@ -1,13 +1,12 @@
#pragma once #pragma once
#include <nx/nro.h> #include <nx/nro.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {
class NroHeader : class NroHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
struct sRoCrt struct sRoCrt
@ -75,19 +74,15 @@ namespace nx
NroHeader(); NroHeader();
NroHeader(const NroHeader& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -125,7 +120,7 @@ namespace nx
const std::string kModuleName = "NRO_HEADER"; const std::string kModuleName = "NRO_HEADER";
// binary // binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// data // data
sRoCrt mRoCrt; sRoCrt mRoCrt;
@ -138,10 +133,6 @@ namespace nx
sSection mRoEmbeddedInfo; sSection mRoEmbeddedInfo;
sSection mRoDynStrInfo; sSection mRoDynStrInfo;
sSection mRoDynSymInfo; sSection mRoDynSymInfo;
// helpers
bool isEqual(const NroHeader& other) const;
void copyFrom(const NroHeader& other);
}; };
} }

View file

@ -1,13 +1,12 @@
#pragma once #pragma once
#include <nx/nso.h> #include <nx/nso.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {
class NsoHeader : class NsoHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
struct sModuleId struct sModuleId
@ -87,19 +86,15 @@ namespace nx
NsoHeader(); NsoHeader();
NsoHeader(const NsoHeader& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -134,7 +129,7 @@ namespace nx
const std::string kModuleName = "NSO_HEADER"; const std::string kModuleName = "NSO_HEADER";
// binary // binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// data // data
sModuleId mModuleId; sModuleId mModuleId;
@ -146,10 +141,6 @@ namespace nx
sLayout mRoEmbeddedInfo; sLayout mRoEmbeddedInfo;
sLayout mRoDynStrInfo; sLayout mRoDynStrInfo;
sLayout mRoDynSymInfo; sLayout mRoDynSymInfo;
// helpers
bool isEqual(const NsoHeader& other) const;
void copyFrom(const NsoHeader& other);
}; };
} }

View file

@ -1,16 +1,15 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/pfs.h> #include <nx/pfs.h>
namespace nx namespace nx
{ {
class PfsHeader : class PfsHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
enum FsType enum FsType
@ -64,24 +63,22 @@ namespace nx
PfsHeader(); PfsHeader();
PfsHeader(const PfsHeader& other); 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;
bool operator!=(const PfsHeader& other) const; bool operator!=(const PfsHeader& other) const;
void operator=(const PfsHeader& other);
// to be used after export // to be used after export
const byte_t* getBytes() const;
size_t getSize() const; size_t getSize() const;
// export/import binary // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
FsType getFsType() const; FsType getFsType() const;
void setFsType(FsType type); void setFsType(FsType type);
const fnd::List<sFile>& getFileList() const; const fnd::List<sFile>& getFileList() const;
@ -92,7 +89,7 @@ namespace nx
const std::string kModuleName = "PFS_HEADER"; const std::string kModuleName = "PFS_HEADER";
// binary blob // binary blob
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
FsType mFsType; FsType mFsType;
@ -100,8 +97,6 @@ namespace nx
size_t getFileEntrySize(FsType fs_type); size_t getFileEntrySize(FsType fs_type);
void calculateOffsets(size_t data_offset); void calculateOffsets(size_t data_offset);
bool isEqual(const PfsHeader& other) const;
void copyFrom(const PfsHeader& other);
}; };
} }

View file

@ -1,32 +1,27 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector> #include <vector>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/SacEntry.h> #include <nx/SacEntry.h>
namespace nx namespace nx
{ {
class SacBinary : class SacBinary :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
SacBinary(); SacBinary();
SacBinary(const SacBinary& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -36,13 +31,10 @@ namespace nx
const std::string kModuleName = "SAC_BINARY"; const std::string kModuleName = "SAC_BINARY";
// raw binary // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
fnd::List<SacEntry> mServices; fnd::List<SacEntry> mServices;
bool isEqual(const SacBinary& other) const;
void copyFrom(const SacBinary& other);
}; };
} }

View file

@ -1,30 +1,26 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {
class SacEntry : class SacEntry :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
SacEntry(); SacEntry();
SacEntry(const std::string& name, bool isServer); SacEntry(const std::string& name, bool isServer);
SacEntry(const SacEntry& other); SacEntry(const SacEntry& other);
void operator=(const SacEntry& other);
bool operator==(const SacEntry& other) const; bool operator==(const SacEntry& other) const;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -38,12 +34,12 @@ namespace nx
enum SacEntryFlag enum SacEntryFlag
{ {
SAC_IS_SERVER = BIT(7), SAC_IS_SERVER = _BIT(7),
SAC_NAME_LEN_MASK = BIT(7) - 1 SAC_NAME_LEN_MASK = _BIT(7) - 1
}; };
// raw binary // raw binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// variables // variables
bool mIsServer; bool mIsServer;

View file

@ -1,30 +1,25 @@
#pragma once #pragma once
#include <nx/xci.h> #include <nx/xci.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {
class XciHeader : class XciHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
XciHeader(); XciHeader();
XciHeader(const XciHeader& other); 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;
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 // export/import binary
void exportBinary(); void toBytes();
void importBinary(const byte_t* bytes, size_t len); void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
@ -92,7 +87,7 @@ namespace nx
const std::string kModuleName = "XCI_HEADER"; const std::string kModuleName = "XCI_HEADER";
// binary // binary
fnd::MemoryBlob mBinaryBlob; fnd::Vec<byte_t> mRawBinary;
// data // data
uint32_t mRomAreaStartPage; uint32_t mRomAreaStartPage;
@ -125,10 +120,6 @@ namespace nx
uint32_t mUppVersion; uint32_t mUppVersion;
byte_t mUppHash[8]; byte_t mUppHash[8];
uint64_t mUppId; uint64_t mUppId;
// helpers
bool isEqual(const XciHeader& other) const;
void copyFrom(const XciHeader& other);
}; };
} }

View file

@ -1,9 +1,6 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/aes.h>
#include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h> #include <nx/macro.h>
namespace nx namespace nx

View file

@ -0,0 +1,49 @@
#pragma once
#include <fnd/types.h>
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)
}

View file

@ -29,6 +29,7 @@
<ClInclude Include="include\nx\cnmt.h" /> <ClInclude Include="include\nx\cnmt.h" />
<ClInclude Include="include\nx\ContentMetaBinary.h" /> <ClInclude Include="include\nx\ContentMetaBinary.h" />
<ClInclude Include="include\nx\elf.h" /> <ClInclude Include="include\nx\elf.h" />
<ClInclude Include="include\nx\fac.h" />
<ClInclude Include="include\nx\FacBinary.h" /> <ClInclude Include="include\nx\FacBinary.h" />
<ClInclude Include="include\nx\FacHeader.h" /> <ClInclude Include="include\nx\FacHeader.h" />
<ClInclude Include="include\nx\HandleTableSizeEntry.h" /> <ClInclude Include="include\nx\HandleTableSizeEntry.h" />

View file

@ -186,6 +186,9 @@
<ClInclude Include="include\nx\elf.h"> <ClInclude Include="include\nx\elf.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="include\nx\fac.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="makefile" /> <None Include="makefile" />

View file

@ -1,7 +1,5 @@
#include <nx/AciBinary.h> #include <nx/AciBinary.h>
nx::AciBinary::AciBinary() nx::AciBinary::AciBinary()
{ {
clear(); clear();
@ -9,96 +7,100 @@ nx::AciBinary::AciBinary()
nx::AciBinary::AciBinary(const AciBinary & other) nx::AciBinary::AciBinary(const AciBinary & other)
{ {
copyFrom(other); *this = 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);
} }
void nx::AciBinary::operator=(const AciBinary & 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 // export components
mFac.exportBinary(); mFac.toBytes();
mSac.exportBinary(); mSac.toBytes();
mKc.exportBinary(); mKc.toBytes();
// set sizes // set sizes
setFacSize(mFac.getSize()); setFacSize(mFac.getBytes().size());
setSacSize(mSac.getSize()); setSacSize(mSac.getBytes().size());
setKcSize(mKc.getSize()); setKcSize(mKc.getBytes().size());
// export header // export header
AciHeader::exportBinary(); AciHeader::toBytes();
// allocate binary // allocate binary
mBinaryBlob.alloc(getAciSize()); mRawBinary.alloc(getAciSize());
// copy header // copy header
memcpy(mBinaryBlob.getBytes(), AciHeader::getBytes(), AciHeader::getSize()); memcpy(mRawBinary.data(), AciHeader::getBytes().data(), AciHeader::getBytes().size());
// copy components // copy components
memcpy(mBinaryBlob.getBytes() + getFacPos().offset, mFac.getBytes(), mFac.getSize()); memcpy(mRawBinary.data() + getFacPos().offset, mFac.getBytes().data(), mFac.getBytes().size());
memcpy(mBinaryBlob.getBytes() + getSacPos().offset, mSac.getBytes(), mSac.getSize()); memcpy(mRawBinary.data() + getSacPos().offset, mSac.getBytes().data(), mSac.getBytes().size());
memcpy(mBinaryBlob.getBytes() + getKcPos().offset, mKc.getBytes(), mKc.getSize()); 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) if (getAciSize() > len)
{ {
throw fnd::Exception(kModuleName, "ACI binary too small"); throw fnd::Exception(kModuleName, "ACI binary too small");
} }
mBinaryBlob.alloc(getAciSize()); mRawBinary.alloc(getAciSize());
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), bytes, mRawBinary.size());
if (getFacPos().size > 0) if (getFacPos().size > 0)
{ {
mFac.importBinary(mBinaryBlob.getBytes() + getFacPos().offset, getFacPos().size); mFac.fromBytes(mRawBinary.data() + getFacPos().offset, getFacPos().size);
} }
if (getSacPos().size > 0) if (getSacPos().size > 0)
{ {
mSac.importBinary(mBinaryBlob.getBytes() + getSacPos().offset, getSacPos().size); mSac.fromBytes(mRawBinary.data() + getSacPos().offset, getSacPos().size);
} }
if (getKcPos().size > 0) if (getKcPos().size > 0)
{ {
mKc.importBinary(mBinaryBlob.getBytes() + getKcPos().offset, getKcPos().size); mKc.fromBytes(mRawBinary.data() + getKcPos().offset, getKcPos().size);
} }
} }
const fnd::Vec<byte_t>& nx::AciBinary::getBytes() const
{
return mRawBinary;
}
void nx::AciBinary::clear() void nx::AciBinary::clear()
{ {
AciHeader::clear(); AciHeader::clear();
mRawBinary.clear();
mFac.clear(); mFac.clear();
mSac.clear(); mSac.clear();
mKc.clear(); mKc.clear();
@ -132,27 +134,4 @@ const nx::KcBinary & nx::AciBinary::getKc() const
void nx::AciBinary::setKc(const KcBinary & kc) void nx::AciBinary::setKc(const KcBinary & kc)
{ {
mKc = 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;
}
}

View file

@ -2,33 +2,21 @@
using namespace nx; using namespace nx;
void AciHeader::calculateSectionOffsets() AciHeader::AciHeader()
{ {
mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize); clear();
mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize);
mKc.offset = mSac.offset + align(mSac.size, aci::kAciAlignSize);
} }
bool AciHeader::isEqual(const AciHeader & other) const AciHeader::AciHeader(const AciHeader & other)
{ {
return (mHeaderOffset == other.mHeaderOffset) \ *this = other;
&& (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);
} }
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 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 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 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()); mRawBinary.alloc(sizeof(sAciHeader));
} sAciHeader* hdr = (sAciHeader*)mRawBinary.data();
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();
// set type // set type
switch (mType) 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)) if (len < sizeof(sAciHeader))
{ {
@ -144,10 +112,10 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
clear(); clear();
mBinaryBlob.alloc(sizeof(sAciHeader)); mRawBinary.alloc(sizeof(sAciHeader));
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sAciHeader)); memcpy(mRawBinary.data(), bytes, sizeof(sAciHeader));
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes(); sAciHeader* hdr = (sAciHeader*)mRawBinary.data();
switch (hdr->signature.get()) switch (hdr->signature.get())
{ {
@ -192,9 +160,14 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
mKc.size = hdr->kc.size.get(); mKc.size = hdr->kc.size.get();
} }
const fnd::Vec<byte_t>& AciHeader::getBytes() const
{
return mRawBinary;
}
void nx::AciHeader::clear() void nx::AciHeader::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
mHeaderOffset = 0; mHeaderOffset = 0;
mType = TYPE_ACI0; mType = TYPE_ACI0;
mProgramId = 0; mProgramId = 0;
@ -322,3 +295,10 @@ void AciHeader::setKcSize(size_t size)
{ {
mKc.size = 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);
}

View file

@ -1,7 +1,5 @@
#include <nx/AcidBinary.h> #include <nx/AcidBinary.h>
nx::AcidBinary::AcidBinary() nx::AcidBinary::AcidBinary()
{ {
clear(); clear();
@ -9,17 +7,106 @@ nx::AcidBinary::AcidBinary()
nx::AcidBinary::AcidBinary(const AcidBinary & other) 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<byte_t>& nx::AcidBinary::getBytes() const
{
return mRawBinary;
} }
void nx::AcidBinary::clear() void nx::AcidBinary::clear()
{ {
AciBinary::clear(); AciBinary::clear();
mRawBinary.clear();
mEmbeddedPublicKey = crypto::rsa::sRsa2048Key(); mEmbeddedPublicKey = crypto::rsa::sRsa2048Key();
} }
@ -32,111 +119,3 @@ void nx::AcidBinary::setNcaHeader2RsaKey(const crypto::rsa::sRsa2048Key & key)
{ {
mEmbeddedPublicKey = 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");
}
}

View file

@ -7,17 +7,92 @@ nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary()
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other) 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 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 bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPropertyBinary& other) const
@ -25,30 +100,15 @@ bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPr
return !(*this == other); 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 sApplicationControlProperty* data = (sApplicationControlProperty*)mRawBinary.data();
{
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();
// strings // strings
uint32_t supported_langs = 0; 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); supported_langs = _BIT(mTitle[i].language);
strncpy(data->title[mTitle[i].language].name, mTitle[i].name.c_str(), nacp::kNameLength); strncpy(data->title[mTitle[i].language].name, mTitle[i].name.c_str(), nacp::kNameLength);
@ -82,18 +142,18 @@ void nx::ApplicationControlPropertyBinary::exportBinary()
// misc params // misc params
data->presence_group_id = mPresenceGroupId; data->presence_group_id = mPresenceGroupId;
memset(data->rating_age, nacp::kUnusedAgeRating, nacp::kRatingAgeCount); // clear ratings 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->rating_age[mRatingAge[i].organisation] = mRatingAge[i].age;
} }
data->add_on_content_base_id = mAocBaseId; data->add_on_content_base_id = mAocBaseId;
data->save_data_owner_id = mSaveDatawOwnerId; 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->local_communication_id[i] = mLocalCommunicationId[i];
} }
data->seed_for_pseudo_device_id = mSeedForPsuedoDeviceId; 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]; 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; 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)) if (len < sizeof(nx::sApplicationControlProperty))
{ {
@ -125,10 +185,10 @@ void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, siz
clear(); clear();
mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty)); mRawBinary.alloc(sizeof(nx::sApplicationControlProperty));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), bytes, mRawBinary.size());
const sApplicationControlProperty* data = (const sApplicationControlProperty*)mBinaryBlob.getBytes(); const sApplicationControlProperty* data = (const sApplicationControlProperty*)mRawBinary.data();
// strings // strings
for (size_t i = 0; i < nacp::kMaxLanguageCount; i++) 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(); mCacheStorageDataAndJournalSizeMax = (int64_t)data->cache_storage_data_and_journal_size_max.get();
} }
const fnd::Vec<byte_t>& nx::ApplicationControlPropertyBinary::getBytes() const
{
return mRawBinary;
}
void nx::ApplicationControlPropertyBinary::clear() void nx::ApplicationControlPropertyBinary::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
mTitle.clear(); mTitle.clear();
mIsbn.clear(); mIsbn.clear();
mStartupUserAccount = nacp::USER_None; mStartupUserAccount = nacp::USER_None;
@ -625,89 +690,4 @@ byte_t nx::ApplicationControlPropertyBinary::getProgramIndex() const
void nx::ApplicationControlPropertyBinary::setProgramIndex(byte_t var) void nx::ApplicationControlPropertyBinary::setProgramIndex(byte_t var)
{ {
mProgramIndex = 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;
}

View file

@ -17,12 +17,12 @@ nx::ContentMetaBinary::ContentMetaBinary(const byte_t * bytes, size_t len)
const byte_t * nx::ContentMetaBinary::getBytes() const const byte_t * nx::ContentMetaBinary::getBytes() const
{ {
return mBinaryBlob.getBytes(); return mRawBinary.getBytes();
} }
size_t nx::ContentMetaBinary::getSize() const size_t nx::ContentMetaBinary::getSize() const
{ {
return mBinaryBlob.getSize(); return mRawBinary.getSize();
} }
void nx::ContentMetaBinary::exportBinary() void nx::ContentMetaBinary::exportBinary()
@ -118,7 +118,7 @@ void nx::ContentMetaBinary::importBinary(const byte_t * bytes, size_t len)
void nx::ContentMetaBinary::clear() void nx::ContentMetaBinary::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
mTitleId = 0; mTitleId = 0;
mTitleVersion = 0; mTitleVersion = 0;
mType = cnmt::METATYPE_SYSTEM_PROGRAM; mType = cnmt::METATYPE_SYSTEM_PROGRAM;

View file

@ -1,118 +1,100 @@
#include <nx/FacBinary.h> #include <nx/FacBinary.h>
nx::FacBinary::FacBinary() nx::FacBinary::FacBinary()
{} {
clear();
}
nx::FacBinary::FacBinary(const FacBinary & other) nx::FacBinary::FacBinary(const FacBinary & other)
{ {
copyFrom(other); *this = 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);
} }
void nx::FacBinary::operator=(const FacBinary & other) void nx::FacBinary::operator=(const FacBinary & other)
{ {
copyFrom(other); if (other.getBytes().size())
}
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++)
{ {
rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]); fromBytes(other.getBytes().data(), other.getBytes().size());
}
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());
} }
else else
{ {
clear();
FacHeader::operator=(other); FacHeader::operator=(other);
mContentOwnerIdList = other.mContentOwnerIdList; mContentOwnerIdList = other.mContentOwnerIdList;
mSaveDataOwnerIdList = other.mSaveDataOwnerIdList; 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<byte_t>& nx::FacBinary::getBytes() const
{
return mRawBinary;
}
void nx::FacBinary::clear() void nx::FacBinary::clear()
{ {
FacHeader::clear(); FacHeader::clear();
mRawBinary.clear();
mContentOwnerIdList.clear(); mContentOwnerIdList.clear();
mSaveDataOwnerIdList.clear(); mSaveDataOwnerIdList.clear();
} }

View file

@ -1,7 +1,5 @@
#include <nx/FacHeader.h> #include <nx/FacHeader.h>
nx::FacHeader::FacHeader() : nx::FacHeader::FacHeader() :
mFsaRights() mFsaRights()
{ {
@ -11,55 +9,55 @@ nx::FacHeader::FacHeader() :
nx::FacHeader::FacHeader(const FacHeader & other) : nx::FacHeader::FacHeader(const FacHeader & other) :
mFsaRights() mFsaRights()
{ {
copyFrom(other); *this = 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);
} }
void nx::FacHeader::operator=(const FacHeader & 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)); mRawBinary.alloc(sizeof(sFacHeader));
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes(); sFacHeader* hdr = (sFacHeader*)mRawBinary.data();
if (mVersion != kFacFormatVersion) if (mVersion != fac::kFacFormatVersion)
{ {
fnd::Exception(kModuleName, "Unsupported format version"); fnd::Exception(kModuleName, "Unsupported format version");
} }
hdr->version = (mVersion); hdr->version = (mVersion);
uint64_t flag = 0; 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); hdr->fac_flags = (flag);
@ -70,18 +68,18 @@ void nx::FacHeader::exportBinary()
hdr->save_data_owner_ids.end = (uint32_t)(mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size); 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)) if (len < sizeof(sFacHeader))
{ {
throw fnd::Exception(kModuleName, "FAC header too small"); throw fnd::Exception(kModuleName, "FAC header too small");
} }
mBinaryBlob.alloc(sizeof(sFacHeader)); mRawBinary.alloc(sizeof(sFacHeader));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes(); sFacHeader* hdr = (sFacHeader*)mRawBinary.data();
if (hdr->version.get() != kFacFormatVersion) if (hdr->version.get() != fac::kFacFormatVersion)
{ {
throw fnd::Exception(kModuleName, "Unsupported FAC format version"); throw fnd::Exception(kModuleName, "Unsupported FAC format version");
} }
@ -90,9 +88,9 @@ void nx::FacHeader::importBinary(const byte_t * bytes, size_t len)
clear(); clear();
for (uint64_t i = 0; i < 64; i++) 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(); 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; 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<byte_t>& nx::FacHeader::getBytes() const
{
return mRawBinary;
}
void nx::FacHeader::clear() void nx::FacHeader::clear()
{ {
mFsaRights.clear(); mFsaRights.clear();
@ -112,9 +115,9 @@ void nx::FacHeader::clear()
size_t nx::FacHeader::getFacSize() const size_t nx::FacHeader::getFacSize() const
{ {
size_t savedata = getSaveDataOwnerIdOffset() + getSaveDataOwnerIdSize(); size_t savedata = mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size;
size_t content = getContentOwnerIdOffset() + getContentOwnerIdSize(); size_t content = mContentOwnerIdPos.offset + mContentOwnerIdPos.size;
return MAX(MAX(savedata, content), sizeof(sFacHeader)); return _MAX(_MAX(savedata, content), sizeof(sFacHeader));
} }
uint32_t nx::FacHeader::getFormatVersion() const uint32_t nx::FacHeader::getFormatVersion() const
@ -127,28 +130,23 @@ void nx::FacHeader::setFormatVersion(uint32_t version)
mVersion = version; mVersion = version;
} }
const fnd::List<nx::FacHeader::FsAccessFlag>& nx::FacHeader::getFsaRightsList() const const fnd::List<nx::fac::FsAccessFlag>& nx::FacHeader::getFsaRightsList() const
{ {
return mFsaRights; return mFsaRights;
} }
void nx::FacHeader::setFsaRightsList(const fnd::List<FsAccessFlag>& list) void nx::FacHeader::setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list)
{ {
mFsaRights.clear(); 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"); 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; return mContentOwnerIdPos;
}
size_t nx::FacHeader::getContentOwnerIdSize() const
{
return mContentOwnerIdPos.size;
} }
void nx::FacHeader::setContentOwnerIdSize(size_t size) void nx::FacHeader::setContentOwnerIdSize(size_t size)
@ -156,14 +154,9 @@ void nx::FacHeader::setContentOwnerIdSize(size_t size)
mContentOwnerIdPos.size = size; mContentOwnerIdPos.size = size;
} }
size_t nx::FacHeader::getSaveDataOwnerIdOffset() const const nx::FacHeader::sSection& nx::FacHeader::getSaveDataOwnerIdPos() const
{ {
return mSaveDataOwnerIdPos.offset; return mSaveDataOwnerIdPos;
}
size_t nx::FacHeader::getSaveDataOwnerIdSize() const
{
return mSaveDataOwnerIdPos.size;
} }
void nx::FacHeader::setSaveDataOwnerIdSize(size_t size) void nx::FacHeader::setSaveDataOwnerIdSize(size_t size)
@ -175,30 +168,4 @@ void nx::FacHeader::calculateOffsets()
{ {
mContentOwnerIdPos.offset = align(sizeof(sFacHeader), 4); mContentOwnerIdPos.offset = align(sizeof(sFacHeader), 4);
mSaveDataOwnerIdPos.offset = mContentOwnerIdPos.offset + align(mContentOwnerIdPos.size, 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;
}
}

View file

@ -8,45 +8,40 @@ nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader()
nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader & other) nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader & other)
{ {
copyFrom(other); *this = 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);
} }
void nx::HierarchicalIntegrityHeader::operator=(const HierarchicalIntegrityHeader & 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"); 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; 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"); 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" // Validate Header Sig "IVFC"
if (hdr->signature.get() != hierarchicalintegrity::kStructSig) if (hdr->signature.get() != hierarchicalintegrity::kStructSig)
@ -92,24 +87,29 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t
} }
// copy to internal storage // copy to internal storage
mBinaryBlob.alloc(total_size); mRawBinary.alloc(total_size);
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
// save layer info // 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++) 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()}); mLayerInfo.addElement({layer_info[i].offset.get(), layer_info[i].size.get(), layer_info[i].block_size.get()});
} }
// save hash list // 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++) for (size_t i = 0; i < hdr->master_hash_size.get()/sizeof(crypto::sha::sSha256Hash); i++)
{ {
mMasterHashList.addElement(hash_list[i]); mMasterHashList.addElement(hash_list[i]);
} }
} }
const fnd::Vec<byte_t>& nx::HierarchicalIntegrityHeader::getBytes() const
{
return mRawBinary;
}
void nx::HierarchicalIntegrityHeader::clear() void nx::HierarchicalIntegrityHeader::clear()
{ {
mLayerInfo.clear(); mLayerInfo.clear();
@ -134,23 +134,4 @@ const fnd::List<crypto::sha::sSha256Hash>& nx::HierarchicalIntegrityHeader::getM
void nx::HierarchicalIntegrityHeader::setMasterHashList(const fnd::List<crypto::sha::sSha256Hash>& master_hash_list) void nx::HierarchicalIntegrityHeader::setMasterHashList(const fnd::List<crypto::sha::sSha256Hash>& master_hash_list)
{ {
mMasterHashList = 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;
}
}

View file

@ -1,7 +1,6 @@
#include <sstream> #include <sstream>
#include <nx/HierarchicalSha256Header.h> #include <nx/HierarchicalSha256Header.h>
nx::HierarchicalSha256Header::HierarchicalSha256Header() nx::HierarchicalSha256Header::HierarchicalSha256Header()
{ {
clear(); clear();
@ -9,45 +8,41 @@ nx::HierarchicalSha256Header::HierarchicalSha256Header()
nx::HierarchicalSha256Header::HierarchicalSha256Header(const HierarchicalSha256Header & other) nx::HierarchicalSha256Header::HierarchicalSha256Header(const HierarchicalSha256Header & other)
{ {
copyFrom(other); *this = 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);
} }
void nx::HierarchicalSha256Header::operator=(const HierarchicalSha256Header & 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"); 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; 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"); 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) 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<byte_t>& nx::HierarchicalSha256Header::getBytes() const
{
return mRawBinary;
}
void nx::HierarchicalSha256Header::clear() void nx::HierarchicalSha256Header::clear()
{ {
memset(mMasterHash.bytes, 0, sizeof(crypto::sha::sSha256Hash)); memset(mMasterHash.bytes, 0, sizeof(crypto::sha::sSha256Hash));
@ -109,25 +109,4 @@ const fnd::List<nx::HierarchicalSha256Header::sLayer>& nx::HierarchicalSha256Hea
void nx::HierarchicalSha256Header::setLayerInfo(const fnd::List<sLayer>& layer_info) void nx::HierarchicalSha256Header::setLayerInfo(const fnd::List<sLayer>& layer_info)
{ {
mLayerInfo = 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;
}
}

View file

@ -1,46 +1,44 @@
#include <nx/KcBinary.h> #include <nx/KcBinary.h>
nx::KcBinary::KcBinary() nx::KcBinary::KcBinary()
{} {}
nx::KcBinary::KcBinary(const KcBinary & other) nx::KcBinary::KcBinary(const KcBinary & other)
{ {
copyFrom(other); *this = 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);
} }
void nx::KcBinary::operator=(const KcBinary & 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<KernelCapability> caps; fnd::List<KernelCapability> caps;
@ -55,23 +53,27 @@ void nx::KcBinary::exportBinary()
mMiscFlags.exportKernelCapabilityList(caps); mMiscFlags.exportKernelCapabilityList(caps);
// allocate memory // allocate memory
mBinaryBlob.alloc(caps.getSize() * sizeof(uint32_t)); mRawBinary.alloc(caps.size() * sizeof(uint32_t));
// write to binary // write to binary
uint32_t* raw_caps = (uint32_t*)mBinaryBlob.getBytes(); uint32_t* raw_caps = (uint32_t*)mRawBinary.data();
for (size_t i = 0; i < caps.getSize(); i++) for (size_t i = 0; i < caps.size(); i++)
{ {
raw_caps[i] = le_word(caps[i].getCap()); 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) if ((len % sizeof(uint32_t)) != 0)
{ {
throw fnd::Exception(kModuleName, "KernelCapability list must be aligned to 4 bytes"); 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<KernelCapability> threadInfoCaps; fnd::List<KernelCapability> threadInfoCaps;
fnd::List<KernelCapability> systemCallCaps; fnd::List<KernelCapability> systemCallCaps;
fnd::List<KernelCapability> memoryMapCaps; fnd::List<KernelCapability> memoryMapCaps;
@ -81,8 +83,8 @@ void nx::KcBinary::importBinary(const byte_t * bytes, size_t len)
fnd::List<KernelCapability> handleTableSizeCaps; fnd::List<KernelCapability> handleTableSizeCaps;
fnd::List<KernelCapability> miscFlagsCaps; fnd::List<KernelCapability> miscFlagsCaps;
const uint32_t* raw_caps = (const uint32_t*)bytes; const uint32_t* raw_caps = (const uint32_t*)mRawBinary.data();
size_t cap_num = len / sizeof(uint32_t); size_t cap_num = mRawBinary.size() / sizeof(uint32_t);
KernelCapability cap; KernelCapability cap;
for (size_t i = 0; i < cap_num; i++) 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); mMiscFlags.importKernelCapabilityList(miscFlagsCaps);
} }
const fnd::Vec<byte_t>& nx::KcBinary::getBytes() const
{
return mRawBinary;
}
void nx::KcBinary::clear() void nx::KcBinary::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
mThreadInfo.clear(); mThreadInfo.clear();
mSystemCalls.clear(); mSystemCalls.clear();
mMemoryMap.clear(); mMemoryMap.clear();
@ -220,28 +227,4 @@ const nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags() const
nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags() nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags()
{ {
return mMiscFlags; 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;
}

View file

@ -2,11 +2,61 @@
using namespace nx; using namespace nx;
NcaHeader::NcaHeader()
void NcaHeader::exportBinary()
{ {
mBinaryBlob.alloc(sizeof(sNcaHeader)); clear();
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes(); }
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) switch(mFormatVersion)
@ -41,7 +91,7 @@ void NcaHeader::exportBinary()
memcpy(hdr->rights_id, mRightsId, nca::kRightsIdLen); memcpy(hdr->rights_id, mRightsId, nca::kRightsIdLen);
// TODO: properly reconstruct NCA layout? atm in hands of user // 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 // determine partition index
byte_t idx = mPartitions[i].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)) if (len < sizeof(sNcaHeader))
{ {
@ -69,10 +119,10 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len)
clear(); clear();
mBinaryBlob.alloc(sizeof(sNcaHeader)); mRawBinary.alloc(sizeof(sNcaHeader));
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sNcaHeader)); memcpy(mRawBinary.data(), data, sizeof(sNcaHeader));
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes(); sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data();
switch(hdr->signature.get()) switch(hdr->signature.get())
{ {
@ -110,6 +160,11 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len)
} }
} }
const fnd::Vec<byte_t>& NcaHeader::getBytes() const
{
return mRawBinary;
}
void nx::NcaHeader::clear() void nx::NcaHeader::clear()
{ {
mFormatVersion = NCA3_FORMAT; mFormatVersion = NCA3_FORMAT;
@ -247,7 +302,7 @@ const fnd::List<NcaHeader::sPartition>& NcaHeader::getPartitions() const
void NcaHeader::setPartitions(const fnd::List<NcaHeader::sPartition>& partitions) void NcaHeader::setPartitions(const fnd::List<NcaHeader::sPartition>& partitions)
{ {
mPartitions = partitions; mPartitions = partitions;
if (mPartitions.getSize() >= nca::kPartitionNum) if (mPartitions.size() >= nca::kPartitionNum)
{ {
throw fnd::Exception(kModuleName, "Too many NCA partitions"); 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 uint32_t NcaHeader::sizeToBlockNum(uint64_t real_size) const
{ {
return (uint32_t)(align(real_size, nca::kSectorSize) / nca::kSectorSize); 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();
} }

View file

@ -1,7 +1,5 @@
#include <nx/NpdmBinary.h> #include <nx/NpdmBinary.h>
nx::NpdmBinary::NpdmBinary() : nx::NpdmBinary::NpdmBinary() :
mAci(), mAci(),
mAcid() mAcid()
@ -13,47 +11,51 @@ nx::NpdmBinary::NpdmBinary(const NpdmBinary & other) :
mAci(), mAci(),
mAcid() mAcid()
{ {
copyFrom(other); *this = 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);
} }
void nx::NpdmBinary::operator=(const NpdmBinary & 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(); mAci.exportBinary();
mAcid.exportBinary(); mAcid.exportBinary();
setAciSize(mAci.getSize()); setAciSize(mAci.getBytes().size());
setAcidSize(mAcid.getSize()); 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
clear(); clear();
// import header // import header
NpdmHeader::importBinary(bytes, len); NpdmHeader::fromBytes(data, len);
// check size // check size
if (getNpdmSize() > len) if (getNpdmSize() > len)
@ -62,19 +64,23 @@ void nx::NpdmBinary::importBinary(const byte_t * bytes, size_t len)
} }
// save local copy // save local copy
mBinaryBlob.alloc(getNpdmSize()); mRawBinary.alloc(getNpdmSize());
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
// import Aci/Acid // import Aci/Acid
if (getAciPos().size) if (getAciPos().size)
{ {
mAci.importBinary(mBinaryBlob.getBytes() + getAciPos().offset, getAciPos().size); mAci.importBinary(mRawBinary.data() + getAciPos().offset, getAciPos().size);
} }
if (getAcidPos().size) if (getAcidPos().size)
{ {
mAcid.importBinary(mBinaryBlob.getBytes() + getAcidPos().offset, getAcidPos().size); mAcid.importBinary(mRawBinary.data() + getAcidPos().offset, getAcidPos().size);
} }
}
const fnd::Vec<byte_t>& nx::NpdmBinary::getBytes() const
{
return mRawBinary;
} }
void nx::NpdmBinary::clear() void nx::NpdmBinary::clear()
@ -102,35 +108,4 @@ const nx::AcidBinary & nx::NpdmBinary::getAcid() const
void nx::NpdmBinary::setAcid(const AcidBinary & acid) void nx::NpdmBinary::setAcid(const AcidBinary & acid)
{ {
mAcid = 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();
}

View file

@ -1,7 +1,5 @@
#include <nx/NpdmHeader.h> #include <nx/NpdmHeader.h>
nx::NpdmHeader::NpdmHeader() nx::NpdmHeader::NpdmHeader()
{ {
clear(); clear();
@ -9,67 +7,18 @@ nx::NpdmHeader::NpdmHeader()
nx::NpdmHeader::NpdmHeader(const NpdmHeader & other) nx::NpdmHeader::NpdmHeader(const NpdmHeader & other)
{ {
copyFrom(other); *this = 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);
} }
void nx::NpdmHeader::operator=(const NpdmHeader & other) void nx::NpdmHeader::operator=(const NpdmHeader & other)
{ {
copyFrom(other); if (other.getBytes().size())
}
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())
{ {
importBinary(other.getBytes(), other.getSize()); fromBytes(other.getBytes().data, other.getBytes().size());
} }
else else
{ {
clear();
mInstructionType = other.mInstructionType; mInstructionType = other.mInstructionType;
mProcAddressSpaceType = other.mProcAddressSpaceType; mProcAddressSpaceType = other.mProcAddressSpaceType;
mMainThreadPriority = other.mMainThreadPriority; 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)); return (mInstructionType == other.mInstructionType) \
sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes(); && (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; hdr->signature = npdm::kNpdmStructSig;
byte_t flag = ((byte_t)(mInstructionType & 1) | (byte_t)((mProcAddressSpaceType & 3) << 1)) & 0xf; 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; 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)) if (len < sizeof(sNpdmHeader))
{ {
@ -114,9 +82,9 @@ void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len)
clear(); clear();
mBinaryBlob.alloc(sizeof(sNpdmHeader)); mRawBinary.alloc(sizeof(sNpdmHeader));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes(); sNpdmHeader* hdr = (sNpdmHeader*)mRawBinary.data();
if (hdr->signature.get() != npdm::kNpdmStructSig) 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(); mAcidPos.size = hdr->acid.size.get();
} }
const fnd::Vec<byte_t>& nx::NpdmHeader::getBytes() const
{
return mRawBinary;
}
void nx::NpdmHeader::clear() void nx::NpdmHeader::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
mInstructionType = npdm::INSTR_64BIT; mInstructionType = npdm::INSTR_64BIT;
mProcAddressSpaceType = npdm::ADDR_SPACE_64BIT; mProcAddressSpaceType = npdm::ADDR_SPACE_64BIT;
mMainThreadPriority = 0; mMainThreadPriority = 0;
@ -282,3 +255,9 @@ void nx::NpdmHeader::setAcidSize(size_t size)
{ {
mAcidPos.size = size; mAcidPos.size = size;
} }
void nx::NpdmHeader::calculateOffsets()
{
mAcidPos.offset = align(sizeof(sNpdmHeader), npdm::kNpdmAlignSize);
mAciPos.offset = mAcidPos.offset + align(mAcidPos.size, npdm::kNpdmAlignSize);
}

View file

@ -7,17 +7,38 @@ nx::NroHeader::NroHeader()
nx::NroHeader::NroHeader(const NroHeader& other) 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 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 bool nx::NroHeader::operator!=(const NroHeader& other) const
@ -25,25 +46,10 @@ bool nx::NroHeader::operator!=(const NroHeader& other) const
return !(*this == other); return !(*this == other);
} }
void nx::NroHeader::operator=(const NroHeader& other) void nx::NroHeader::toBytes()
{ {
copyFrom(other); mRawBinary.alloc(sizeof(sNroHeader));
} nx::sNroHeader* hdr = (nx::sNroHeader*)mRawBinary.data();
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();
// set header identifers // set header identifers
hdr->signature = nro::kNroSig; hdr->signature = nro::kNroSig;
@ -87,7 +93,7 @@ void nx::NroHeader::exportBinary()
hdr->dyn_sym.size = mRoDynSymInfo.size; 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 // check input data size
if (len < sizeof(sNroHeader)) if (len < sizeof(sNroHeader))
@ -99,11 +105,11 @@ void nx::NroHeader::importBinary(const byte_t* bytes, size_t len)
clear(); clear();
// allocate internal local binary copy // allocate internal local binary copy
mBinaryBlob.alloc(sizeof(sNroHeader)); mRawBinary.alloc(sizeof(sNroHeader));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
// get sNroHeader ptr // get sNroHeader ptr
const nx::sNroHeader* hdr = (const nx::sNroHeader*)mBinaryBlob.getBytes(); const nx::sNroHeader* hdr = (const nx::sNroHeader*)mRawBinary.data();
// check NRO signature // check NRO signature
if (hdr->signature.get() != nro::kNroSig) 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(); mRoDynSymInfo.size = hdr->dyn_sym.size.get();
} }
const fnd::Vec<byte_t>& nx::NroHeader::getBytes() const
{
return mRawBinary;
}
void nx::NroHeader::clear() void nx::NroHeader::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
memset(&mRoCrt, 0, sizeof(mRoCrt)); memset(&mRoCrt, 0, sizeof(mRoCrt));
memset(&mTextInfo, 0, sizeof(mTextInfo)); memset(&mTextInfo, 0, sizeof(mTextInfo));
memset(&mRoInfo, 0, sizeof(mRoInfo)); memset(&mRoInfo, 0, sizeof(mRoInfo));
@ -256,35 +267,4 @@ const nx::NroHeader::sSection& nx::NroHeader::getRoDynSymInfo() const
void nx::NroHeader::setRoDynSymInfo(const sSection& info) void nx::NroHeader::setRoDynSymInfo(const sSection& info)
{ {
mRoDynSymInfo = 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;
} }

View file

@ -2,22 +2,40 @@
nx::NsoHeader::NsoHeader() nx::NsoHeader::NsoHeader()
{ {
clear();
} }
nx::NsoHeader::NsoHeader(const NsoHeader& other) 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 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 bool nx::NsoHeader::operator!=(const NsoHeader& other) const
@ -25,25 +43,10 @@ bool nx::NsoHeader::operator!=(const NsoHeader& other) const
return !(*this == other); return !(*this == other);
} }
void nx::NsoHeader::operator=(const NsoHeader& other) void nx::NsoHeader::toBytes()
{ {
copyFrom(other); mRawBinary.alloc(sizeof(sNsoHeader));
} nx::sNsoHeader* hdr = (nx::sNsoHeader*)mRawBinary.data();
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();
// set header identifers // set header identifers
hdr->signature = nso::kNsoSig; hdr->signature = nso::kNsoSig;
@ -122,7 +125,7 @@ void nx::NsoHeader::exportBinary()
hdr->flags = flags; 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 // check input data size
if (len < sizeof(sNsoHeader)) if (len < sizeof(sNsoHeader))
@ -134,11 +137,11 @@ void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len)
clear(); clear();
// allocate internal local binary copy // allocate internal local binary copy
mBinaryBlob.alloc(sizeof(sNsoHeader)); mRawBinary.alloc(sizeof(sNsoHeader));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
// get sNsoHeader ptr // get sNsoHeader ptr
const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mBinaryBlob.getBytes(); const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mRawBinary.data();
// check NSO signature // check NSO signature
if (hdr->signature.get() != nso::kNsoSig) 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(); mRoDynSymInfo.size = hdr->dyn_sym.size.get();
} }
const fnd::Vec<byte_t>& nx::NsoHeader::getBytes() const
{
return mRawBinary;
}
void nx::NsoHeader::clear() void nx::NsoHeader::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
memset(&mModuleId, 0, sizeof(mModuleId)); memset(&mModuleId, 0, sizeof(mModuleId));
mBssSize = 0; mBssSize = 0;
memset(&mTextSegmentInfo, 0, sizeof(mTextSegmentInfo)); memset(&mTextSegmentInfo, 0, sizeof(mTextSegmentInfo));
@ -295,30 +303,4 @@ const nx::NsoHeader::sLayout& nx::NsoHeader::getRoDynSymInfo() const
void nx::NsoHeader::setRoDynSymInfo(const sLayout& info) void nx::NsoHeader::setRoDynSymInfo(const sLayout& info)
{ {
mRoDynSymInfo = 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;
} }

View file

@ -1,37 +1,63 @@
#include <nx/PfsHeader.h> #include <nx/PfsHeader.h>
nx::PfsHeader::PfsHeader() nx::PfsHeader::PfsHeader()
{} {
clear();
}
nx::PfsHeader::PfsHeader(const PfsHeader & other) 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<byte_t>& nx::PfsHeader::getBytes() const
{
return mRawBinary;
}
void nx::PfsHeader::toBytes()
{ {
// calculate name table size // calculate name table size
size_t name_table_size = 0; 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; 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 // 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 // allocate pfs header binary
mBinaryBlob.alloc(pfs_header_size); mRawBinary.alloc(pfs_header_size);
sPfsHeader* hdr = (sPfsHeader*)mBinaryBlob.getBytes(); sPfsHeader* hdr = (sPfsHeader*)mRawBinary.data();
// set header fields // set header fields
switch (mFsType) switch (mFsType)
@ -44,18 +70,18 @@ void nx::PfsHeader::exportBinary()
break; break;
} }
hdr->file_num = (uint32_t)mFileList.getSize(); hdr->file_num = (uint32_t)mFileList.size();
hdr->name_table_size = (uint32_t)name_table_size; hdr->name_table_size = (uint32_t)name_table_size;
// set file entries // set file entries
if (mFsType == TYPE_PFS0) if (mFsType == TYPE_PFS0)
{ {
sPfsFile* raw_files = (sPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader)); sPfsFile* raw_files = (sPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader));
char* raw_name_table = (char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sPfsFile) * mFileList.getSize()); char* raw_name_table = (char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sPfsFile) * mFileList.size());
size_t raw_name_table_pos = 0; size_t raw_name_table_pos = 0;
calculateOffsets(pfs_header_size); 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].data_offset = (mFileList[i].offset - pfs_header_size);
raw_files[i].size = mFileList[i].size; raw_files[i].size = mFileList[i].size;
@ -67,12 +93,12 @@ void nx::PfsHeader::exportBinary()
} }
else if (mFsType == TYPE_HFS0) else if (mFsType == TYPE_HFS0)
{ {
sHashedPfsFile* raw_files = (sHashedPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader)); sHashedPfsFile* raw_files = (sHashedPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader));
char* raw_name_table = (char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * mFileList.getSize()); char* raw_name_table = (char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * mFileList.size());
size_t raw_name_table_pos = 0; size_t raw_name_table_pos = 0;
calculateOffsets(pfs_header_size); 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].data_offset = (mFileList[i].offset - pfs_header_size);
raw_files[i].size = mFileList[i].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 // check input length meets minimum size
if (len < sizeof(sPfsHeader)) if (len < sizeof(sPfsHeader))
@ -96,9 +122,9 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
} }
// import minimum header // import minimum header
mBinaryBlob.alloc(sizeof(sPfsHeader)); mRawBinary.alloc(sizeof(sPfsHeader));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
const sPfsHeader* hdr = (const sPfsHeader*)mBinaryBlob.getBytes(); const sPfsHeader* hdr = (const sPfsHeader*)mRawBinary.data();
// check struct signature // check struct signature
FsType fs_type; FsType fs_type;
@ -124,9 +150,9 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
} }
// import full header // import full header
mBinaryBlob.alloc(pfs_full_header_size); mRawBinary.alloc(pfs_full_header_size);
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
hdr = (const sPfsHeader*)mBinaryBlob.getBytes(); hdr = (const sPfsHeader*)mRawBinary.data();
// clear variables // clear variables
clear(); clear();
@ -135,8 +161,8 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
if (mFsType == TYPE_PFS0) if (mFsType == TYPE_PFS0)
{ {
// get pointers to raw data // get pointers to raw data
const sPfsFile* raw_files = (const sPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader)); const sPfsFile* raw_files = (const sPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader));
const char* raw_name_table = (const char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sPfsFile) * hdr->file_num.get()); const char* raw_name_table = (const char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sPfsFile) * hdr->file_num.get());
// process file entries // process file entries
for (size_t i = 0; i < hdr->file_num.get(); i++) 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) else if (mFsType == TYPE_HFS0)
{ {
// get pointers to raw data // get pointers to raw data
const sHashedPfsFile* raw_files = (const sHashedPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader)); const sHashedPfsFile* raw_files = (const sHashedPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader));
const char* raw_name_table = (const char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * hdr->file_num.get()); const char* raw_name_table = (const char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * hdr->file_num.get());
// process file entries // process file entries
for (size_t i = 0; i < hdr->file_num.get(); i++) 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() void nx::PfsHeader::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
mFsType = TYPE_PFS0; mFsType = TYPE_PFS0;
mFileList.clear(); mFileList.clear();
} }
@ -220,52 +246,8 @@ size_t nx::PfsHeader::getFileEntrySize(FsType fs_type)
void nx::PfsHeader::calculateOffsets(size_t data_offset) 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; 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();
}

View file

@ -4,76 +4,75 @@ using namespace nx;
SacBinary::SacBinary() SacBinary::SacBinary()
{ {
clear();
} }
SacBinary::SacBinary(const SacBinary & other) SacBinary::SacBinary(const SacBinary & other)
{ {
copyFrom(other); *this = 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);
} }
void SacBinary::operator=(const SacBinary & 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; 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(); mServices[i].toBytes();
totalSize += mServices[i].getSize(); totalSize += mServices[i].getBytes().size();
} }
mBinaryBlob.alloc(totalSize); mRawBinary.alloc(totalSize);
for (size_t i = 0, pos = 0; i < mServices.getSize(); pos += mServices[i].getSize(), i++) 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(); clear();
mBinaryBlob.alloc(len); mRawBinary.alloc(len);
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
SacEntry svc; SacEntry sac;
for (size_t pos = 0; pos < len; pos += mServices.atBack().getSize()) for (size_t pos = 0; pos < len; pos += mServices.atBack().getBytes().size())
{ {
svc.importBinary((const byte_t*)(mBinaryBlob.getBytes() + pos), len - pos); sac.fromBytes((const byte_t*)(mRawBinary.data() + pos), len - pos);
mServices.addElement(svc); mServices.addElement(sac);
} }
} }
const fnd::Vec<byte_t>& SacBinary::getBytes() const
{
return mRawBinary;
}
void nx::SacBinary::clear() void nx::SacBinary::clear()
{ {
mBinaryBlob.clear(); mRawBinary.clear();
mServices.clear(); mServices.clear();
} }
@ -85,22 +84,4 @@ const fnd::List<SacEntry>& SacBinary::getServiceList() const
void SacBinary::addService(const SacEntry& service) void SacBinary::addService(const SacEntry& service)
{ {
mServices.addElement(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;
}
}

View file

@ -3,52 +3,52 @@
using namespace nx; using namespace nx;
SacEntry::SacEntry() : SacEntry::SacEntry() :
mIsServer(false),
mName("")
{ {
clear();
} }
SacEntry::SacEntry(const std::string & name, bool isServer) : SacEntry::SacEntry(const std::string & name, bool isServer) :
mIsServer(isServer), mIsServer(isServer),
mName(name) mName(name)
{ {
exportBinary(); toBytes();
} }
SacEntry::SacEntry(const SacEntry & other) SacEntry::SacEntry(const SacEntry & other)
{ {
copyFrom(other); *this = other;
}
bool SacEntry::operator==(const SacEntry & other) const
{
return isEqual(other);
}
bool SacEntry::operator!=(const SacEntry & other) const
{
return !isEqual(other);
} }
void SacEntry::operator=(const SacEntry & 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 { try {
mBinaryBlob.alloc(mName.size() + 1); mRawBinary.alloc(mName.size() + 1);
} }
catch (const fnd::Exception& e) catch (const fnd::Exception& e)
{ {
@ -66,14 +66,14 @@ void SacEntry::exportBinary()
} }
// copy data into binary blob // copy data into binary blob
mBinaryBlob[0] = (mIsServer ? SAC_IS_SERVER : 0) | ((mName.length()-1) & SAC_NAME_LEN_MASK); // bug? mRawBinary[0] = (mIsServer ? SAC_IS_SERVER : 0) | ((mName.length()-1) & SAC_NAME_LEN_MASK); // bug?
memcpy(mBinaryBlob.getBytes() + 1, mName.c_str(), mName.length()); 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; bool isServer = (data[0] & SAC_IS_SERVER) == SAC_IS_SERVER;
size_t nameLen = (bytes[0] & SAC_NAME_LEN_MASK) + 1; // bug? size_t nameLen = (data[0] & SAC_NAME_LEN_MASK) + 1; // bug?
if (nameLen+1 > len) 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)"); throw fnd::Exception(kModuleName, "Service name string too long (max 8 chars)");
} }
mBinaryBlob.alloc(nameLen + 1); mRawBinary.alloc(nameLen + 1);
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
mIsServer = isServer; mIsServer = isServer;
mName = std::string((const char*)(mBinaryBlob.getBytes() + 1), nameLen); mName = std::string((const char*)(mRawBinary.data() + 1), nameLen);
}
const fnd::Vec<byte_t>& SacEntry::getBytes() const
{
return mRawBinary;
} }
void nx::SacEntry::clear() void nx::SacEntry::clear()
@ -125,23 +130,4 @@ void SacEntry::setName(const std::string & name)
} }
mName = 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;
}
}

View file

@ -1,39 +1,16 @@
#include <nx/XciHeader.h> #include <nx/XciHeader.h>
bool nx::XciHeader::isEqual(const XciHeader& other) const nx::XciHeader::XciHeader()
{ {
return ( mRomAreaStartPage == other.mRomAreaStartPage \ clear();
&& 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 );
} }
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; mRomAreaStartPage = other.mRomAreaStartPage;
mBackupAreaStartPage = other.mBackupAreaStartPage; mBackupAreaStartPage = other.mBackupAreaStartPage;
@ -66,51 +43,50 @@ void nx::XciHeader::copyFrom(const XciHeader& other)
mUppId = other.mUppId; 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 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 bool nx::XciHeader::operator!=(const XciHeader& other) const
{ {
return isEqual(other) == false; return !(*this == other);
}
void nx::XciHeader::operator=(const XciHeader& other)
{
copyFrom(other);
} }
// to be used after export void nx::XciHeader::toBytes()
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()
{ {
fnd::Exception(kModuleName, "exportBinary() not implemented"); 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 // check input data size
if (len < sizeof(sXciHeader)) if (len < sizeof(sXciHeader))
@ -122,11 +98,11 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
clear(); clear();
// allocate internal local binary copy // allocate internal local binary copy
mBinaryBlob.alloc(sizeof(sXciHeader)); mRawBinary.alloc(sizeof(sXciHeader));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mRawBinary.data(), data, mRawBinary.size());
// get sXciHeader ptr // get sXciHeader ptr
const nx::sXciHeader* hdr = (const nx::sXciHeader*)mBinaryBlob.getBytes(); const nx::sXciHeader* hdr = (const nx::sXciHeader*)mRawBinary.data();
// check XCI signature // check XCI signature
if (hdr->signature.get() != xci::kXciSig) if (hdr->signature.get() != xci::kXciSig)
@ -172,6 +148,11 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
} }
const fnd::Vec<byte_t>& nx::XciHeader::getBytes() const
{
return mRawBinary;
}
// variables // variables
void nx::XciHeader::clear() void nx::XciHeader::clear()
{ {