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

View file

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

View file

@ -1,6 +1,5 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <nx/AciBinary.h>
#include <crypto/rsa.h>
@ -12,21 +11,17 @@ namespace nx
public:
AcidBinary();
AcidBinary(const AcidBinary& other);
AcidBinary(const byte_t* bytes, size_t len);
void operator=(const AcidBinary& other);
bool operator==(const AcidBinary& other) const;
bool operator!=(const AcidBinary& other) const;
void operator=(const AcidBinary& other);
// to be used after export
const byte_t* getBytes() const;
size_t getSize() const;
// export/import binary
virtual void exportBinary();
void toBytes();
void signBinary(const crypto::rsa::sRsa2048Key& key);
virtual void importBinary(const byte_t* bytes, size_t len);
void fromBytes(const byte_t* bytes, size_t len);
void verifyBinary(const crypto::rsa::sRsa2048Key& key) const;
const fnd::Vec<byte_t>& getBytes() const;
// variables
virtual void clear();
@ -38,13 +33,10 @@ namespace nx
const std::string kModuleName = "ACID_BINARY";
// raw binary
fnd::MemoryBlob mBinaryBlob;
fnd::Vec<byte_t> mRawBinary;
// variables
crypto::rsa::sRsa2048Key mEmbeddedPublicKey;
bool isEqual(const AcidBinary& other) const;
void copyFrom(const AcidBinary& other);
};
}

View file

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

View file

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

View file

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

View file

@ -1,56 +1,49 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/ISerialisable.h>
#include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/fac.h>
namespace nx
{
class FacHeader :
public fnd::ISerialiseableBinary
public fnd::ISerialisable
{
public:
enum FsAccessFlag
struct sSection
{
FSA_APPLICATION_INFO,
FSA_BOOT_MODE_CONTROL,
FSA_CALIBRATION,
FSA_SYSTEM_SAVE_DATA,
FSA_GAME_CARD,
FSA_SAVE_DATA_BACKUP,
FSA_SAVE_DATA_MANAGEMENT,
FSA_BIS_ALL_RAW,
FSA_GAME_CARD_RAW,
FSA_GAME_CARD_PRIVATE,
FSA_SET_TIME,
FSA_CONTENT_MANAGER,
FSA_IMAGE_MANAGER,
FSA_CREATE_SAVE_DATA,
FSA_SYSTEM_SAVE_DATA_MANAGEMENT,
FSA_BIS_FILE_SYSTEM,
FSA_SYSTEM_UPDATE,
FSA_SAVE_DATA_META,
FSA_DEVICE_SAVE_CONTROL,
FSA_SETTINGS_CONTROL,
FSA_DEBUG = 62,
FSA_FULL_PERMISSION = 63,
size_t offset;
size_t size;
void operator=(const sSection& other)
{
offset = other.offset;
size = other.size;
}
bool operator==(const sSection& other) const
{
return (offset == other.offset) \
&& (size == other.size);
}
bool operator!=(const sSection& other) const
{
return !operator==(other);
}
};
FacHeader();
FacHeader(const FacHeader& other);
FacHeader(const byte_t* bytes, size_t len);
void operator=(const FacHeader& other);
bool operator==(const FacHeader& other) const;
bool operator!=(const FacHeader& other) const;
void operator=(const FacHeader& other);
// to be used after export
const byte_t* getBytes() const;
size_t getSize() const;
// export/import binary
void exportBinary();
void importBinary(const byte_t* bytes, size_t len);
void toBytes();
void fromBytes(const byte_t* bytes, size_t len);
const fnd::Vec<byte_t>& getBytes() const;
// variables
void clear();
@ -59,49 +52,28 @@ namespace nx
uint32_t getFormatVersion() const;
void setFormatVersion(uint32_t version);
const fnd::List<FsAccessFlag>& getFsaRightsList() const;
void setFsaRightsList(const fnd::List<FsAccessFlag>& list);
const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const;
void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list);
size_t getContentOwnerIdOffset() const;
size_t getContentOwnerIdSize() const;
const sSection& getContentOwnerIdPos() const;
void setContentOwnerIdSize(size_t size);
size_t getSaveDataOwnerIdOffset() const;
size_t getSaveDataOwnerIdSize() const;
const sSection& getSaveDataOwnerIdPos() const;;
void setSaveDataOwnerIdSize(size_t size);
private:
const std::string kModuleName = "FAC_HEADER";
static const uint32_t kFacFormatVersion = 1;
#pragma pack (push, 1)
struct sFacHeader
{
le_uint32_t version; // default 1
le_uint64_t fac_flags;
struct sFacSection
{
le_uint32_t start;
le_uint32_t end;
} content_owner_ids, save_data_owner_ids; // the data for these follow later in binary. start/end relative to base of FacData instance
};
#pragma pack (pop)
// raw binary
fnd::MemoryBlob mBinaryBlob;
fnd::Vec<byte_t> mRawBinary;
// variables
uint32_t mVersion;
fnd::List<FsAccessFlag> mFsaRights;
struct sSection
{
size_t offset;
size_t size;
} mContentOwnerIdPos, mSaveDataOwnerIdPos;
fnd::List<fac::FsAccessFlag> mFsaRights;
sSection mContentOwnerIdPos;
sSection mSaveDataOwnerIdPos;
void calculateOffsets();
bool isEqual(const FacHeader& other) const;
void copyFrom(const FacHeader& other);
};
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,9 +1,6 @@
#pragma once
#include <string>
#include <fnd/types.h>
#include <crypto/aes.h>
#include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h>
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\ContentMetaBinary.h" />
<ClInclude Include="include\nx\elf.h" />
<ClInclude Include="include\nx\fac.h" />
<ClInclude Include="include\nx\FacBinary.h" />
<ClInclude Include="include\nx\FacHeader.h" />
<ClInclude Include="include\nx\HandleTableSizeEntry.h" />

View file

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

View file

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

View file

@ -2,33 +2,21 @@
using namespace nx;
void AciHeader::calculateSectionOffsets()
AciHeader::AciHeader()
{
mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize);
mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize);
mKc.offset = mSac.offset + align(mSac.size, aci::kAciAlignSize);
clear();
}
bool AciHeader::isEqual(const AciHeader & other) const
AciHeader::AciHeader(const AciHeader & other)
{
return (mHeaderOffset == other.mHeaderOffset) \
&& (mType == other.mType) \
&& (mIsProduction == other.mIsProduction) \
&& (mIsUnqualifiedApproval == other.mIsUnqualifiedApproval) \
&& (mAcidSize == other.mAcidSize) \
&& (mProgramIdMin == other.mProgramIdMin) \
&& (mProgramIdMax == other.mProgramIdMax) \
&& (mProgramId == other.mProgramId) \
&& (mFac == other.mFac) \
&& (mSac == other.mSac) \
&& (mKc == other.mKc);
*this = other;
}
void AciHeader::copyFrom(const AciHeader & other)
void AciHeader::operator=(const AciHeader & other)
{
if (other.getSize())
if (other.getBytes().size())
{
importBinary(other.getBytes(), other.getSize());
fromBytes(other.getBytes().data(), other.getBytes().size());
}
else
{
@ -46,50 +34,30 @@ void AciHeader::copyFrom(const AciHeader & other)
}
}
AciHeader::AciHeader()
{
clear();
}
AciHeader::AciHeader(const AciHeader & other)
{
importBinary(other.getBytes(), other.getSize());
}
AciHeader::AciHeader(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool AciHeader::operator==(const AciHeader & other) const
{
return isEqual(other);
return (mHeaderOffset == other.mHeaderOffset) \
&& (mType == other.mType) \
&& (mIsProduction == other.mIsProduction) \
&& (mIsUnqualifiedApproval == other.mIsUnqualifiedApproval) \
&& (mAcidSize == other.mAcidSize) \
&& (mProgramIdMin == other.mProgramIdMin) \
&& (mProgramIdMax == other.mProgramIdMax) \
&& (mProgramId == other.mProgramId) \
&& (mFac == other.mFac) \
&& (mSac == other.mSac) \
&& (mKc == other.mKc);
}
bool AciHeader::operator!=(const AciHeader & other) const
{
return !isEqual(other);
return !(*this == other);
}
void AciHeader::operator=(const AciHeader & other)
void AciHeader::toBytes()
{
this->importBinary(other.getBytes(), other.getSize());
}
const byte_t * AciHeader::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t AciHeader::getSize() const
{
return mBinaryBlob.getSize();
}
void AciHeader::exportBinary()
{
mBinaryBlob.alloc(sizeof(sAciHeader));
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
mRawBinary.alloc(sizeof(sAciHeader));
sAciHeader* hdr = (sAciHeader*)mRawBinary.data();
// set type
switch (mType)
@ -135,7 +103,7 @@ void AciHeader::exportBinary()
}
}
void AciHeader::importBinary(const byte_t * bytes, size_t len)
void AciHeader::fromBytes(const byte_t * bytes, size_t len)
{
if (len < sizeof(sAciHeader))
{
@ -144,10 +112,10 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
clear();
mBinaryBlob.alloc(sizeof(sAciHeader));
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sAciHeader));
mRawBinary.alloc(sizeof(sAciHeader));
memcpy(mRawBinary.data(), bytes, sizeof(sAciHeader));
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
sAciHeader* hdr = (sAciHeader*)mRawBinary.data();
switch (hdr->signature.get())
{
@ -192,9 +160,14 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
mKc.size = hdr->kc.size.get();
}
const fnd::Vec<byte_t>& AciHeader::getBytes() const
{
return mRawBinary;
}
void nx::AciHeader::clear()
{
mBinaryBlob.clear();
mRawBinary.clear();
mHeaderOffset = 0;
mType = TYPE_ACI0;
mProgramId = 0;
@ -322,3 +295,10 @@ void AciHeader::setKcSize(size_t size)
{
mKc.size = size;
}
void AciHeader::calculateSectionOffsets()
{
mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize);
mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize);
mKc.offset = mSac.offset + align(mSac.size, aci::kAciAlignSize);
}

View file

@ -1,7 +1,5 @@
#include <nx/AcidBinary.h>
nx::AcidBinary::AcidBinary()
{
clear();
@ -9,17 +7,106 @@ nx::AcidBinary::AcidBinary()
nx::AcidBinary::AcidBinary(const AcidBinary & other)
{
copyFrom(other);
*this = other;
}
nx::AcidBinary::AcidBinary(const byte_t * bytes, size_t len)
bool nx::AcidBinary::operator==(const AcidBinary & other) const
{
importBinary(bytes, len);
return AciBinary::operator==(other) \
&& (mEmbeddedPublicKey == other.mEmbeddedPublicKey);
}
bool nx::AcidBinary::operator!=(const AcidBinary & other) const
{
return !(*this == other);
}
void nx::AcidBinary::operator=(const AcidBinary & other)
{
if (other.getBytes().size())
{
importBinary(other.getBytes().data(), other.getBytes().size());
}
else
{
AciBinary::operator=(other);
mEmbeddedPublicKey = other.mEmbeddedPublicKey;
}
}
void nx::AcidBinary::toBytes()
{
AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature
AciBinary::exportBinary();
mRawBinary.alloc(AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2);
memcpy(mRawBinary.data() + crypto::rsa::kRsa2048Size, mEmbeddedPublicKey.modulus, crypto::rsa::kRsa2048Size);
memcpy(mRawBinary.data() + crypto::rsa::kRsa2048Size * 2, AciBinary::getBytes().data(), AciBinary::getBytes().size());
}
void nx::AcidBinary::signBinary(const crypto::rsa::sRsa2048Key & key)
{
if (mRawBinary.size() == 0)
{
exportBinary();
}
byte_t hash[crypto::sha::kSha256HashLen];
crypto::sha::Sha256(mRawBinary.data() + crypto::rsa::kRsa2048Size, mRawBinary.size() - crypto::rsa::kRsa2048Size, hash);
if (crypto::rsa::pkcs::rsaSign(key, crypto::sha::HASH_SHA256, hash, mRawBinary.data()) != 0)
{
throw fnd::Exception(kModuleName, "Failed to sign ACID");
}
}
void nx::AcidBinary::fromBytes(const byte_t * bytes, size_t len)
{
if (len <= crypto::rsa::kRsa2048Size*2)
{
throw fnd::Exception(kModuleName, "ACID binary too small");
}
// import aci binary past sig + pubkey
AciBinary::importBinary(bytes + crypto::rsa::kRsa2048Size * 2, len - crypto::rsa::kRsa2048Size * 2);
// save internal copy
size_t acid_size = AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2;
if (acid_size > len)
{
throw fnd::Exception(kModuleName, "ACID binary too small");
}
mRawBinary.alloc(acid_size);
memcpy(mRawBinary.data(), bytes, mRawBinary.size());
memcpy(mEmbeddedPublicKey.modulus, bytes + crypto::rsa::kRsa2048Size, crypto::rsa::kRsa2048Size);
}
void nx::AcidBinary::verifyBinary(const crypto::rsa::sRsa2048Key & key) const
{
if (mRawBinary.size() == 0)
{
throw fnd::Exception(kModuleName, "No ACID binary exists to verify");
}
byte_t hash[crypto::sha::kSha256HashLen];
crypto::sha::Sha256(mRawBinary.data() + crypto::rsa::kRsa2048Size, mRawBinary.size() - crypto::rsa::kRsa2048Size, hash);
if (crypto::rsa::pss::rsaVerify(key, crypto::sha::HASH_SHA256, hash, mRawBinary.data()) != 0)
{
throw fnd::Exception(kModuleName, "Failed to verify ACID");
}
}
const fnd::Vec<byte_t>& nx::AcidBinary::getBytes() const
{
return mRawBinary;
}
void nx::AcidBinary::clear()
{
AciBinary::clear();
mRawBinary.clear();
mEmbeddedPublicKey = crypto::rsa::sRsa2048Key();
}
@ -32,111 +119,3 @@ void nx::AcidBinary::setNcaHeader2RsaKey(const crypto::rsa::sRsa2048Key & key)
{
mEmbeddedPublicKey = key;
}
bool nx::AcidBinary::isEqual(const AcidBinary & other) const
{
return AciBinary::operator==(other) \
&& (mEmbeddedPublicKey == other.mEmbeddedPublicKey);
}
void nx::AcidBinary::copyFrom(const AcidBinary & other)
{
if (other.getSize())
{
importBinary(other.getBytes(), other.getSize());
}
else
{
AciBinary::operator=(other);
mEmbeddedPublicKey = other.mEmbeddedPublicKey;
}
}
bool nx::AcidBinary::operator==(const AcidBinary & other) const
{
return isEqual(other);
}
bool nx::AcidBinary::operator!=(const AcidBinary & other) const
{
return !isEqual(other);
}
void nx::AcidBinary::operator=(const AcidBinary & other)
{
copyFrom(other);
}
const byte_t * nx::AcidBinary::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t nx::AcidBinary::getSize() const
{
return mBinaryBlob.getSize();
}
void nx::AcidBinary::exportBinary()
{
AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature
AciBinary::exportBinary();
mBinaryBlob.alloc(AciBinary::getSize() + crypto::rsa::kRsa2048Size * 2);
memcpy(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mEmbeddedPublicKey.modulus, crypto::rsa::kRsa2048Size);
memcpy(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size * 2, AciBinary::getBytes(), AciBinary::getSize());
}
void nx::AcidBinary::signBinary(const crypto::rsa::sRsa2048Key & key)
{
if (mBinaryBlob.getSize() == 0)
{
exportBinary();
}
byte_t hash[crypto::sha::kSha256HashLen];
crypto::sha::Sha256(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mBinaryBlob.getSize() - crypto::rsa::kRsa2048Size, hash);
if (crypto::rsa::pkcs::rsaSign(key, crypto::sha::HASH_SHA256, hash, mBinaryBlob.getBytes()) != 0)
{
throw fnd::Exception(kModuleName, "Failed to sign ACID");
}
}
void nx::AcidBinary::importBinary(const byte_t * bytes, size_t len)
{
if (len <= crypto::rsa::kRsa2048Size*2)
{
throw fnd::Exception(kModuleName, "ACID binary too small");
}
// import aci binary past sig + pubkey
AciBinary::importBinary(bytes + crypto::rsa::kRsa2048Size * 2, len - crypto::rsa::kRsa2048Size * 2);
// save internal copy
size_t acid_size = AciBinary::getSize() + crypto::rsa::kRsa2048Size * 2;
if (acid_size > len)
{
throw fnd::Exception(kModuleName, "ACID binary too small");
}
mBinaryBlob.alloc(acid_size);
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
memcpy(mEmbeddedPublicKey.modulus, bytes + crypto::rsa::kRsa2048Size, crypto::rsa::kRsa2048Size);
}
void nx::AcidBinary::verifyBinary(const crypto::rsa::sRsa2048Key & key) const
{
if (mBinaryBlob.getSize() == 0)
{
throw fnd::Exception(kModuleName, "No ACID binary exists to verify");
}
byte_t hash[crypto::sha::kSha256HashLen];
crypto::sha::Sha256(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mBinaryBlob.getSize() - crypto::rsa::kRsa2048Size, hash);
if (crypto::rsa::pss::rsaVerify(key, crypto::sha::HASH_SHA256, hash, mBinaryBlob.getBytes()) != 0)
{
throw fnd::Exception(kModuleName, "Failed to verify ACID");
}
}

View file

@ -7,17 +7,92 @@ nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary()
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other)
{
copyFrom(other);
*this = other;
}
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const byte_t* bytes, size_t len)
void nx::ApplicationControlPropertyBinary::operator=(const ApplicationControlPropertyBinary& other)
{
importBinary(bytes, len);
clear();
mTitle = other.mTitle;
mIsbn = other.mIsbn;
mStartupUserAccount = other.mStartupUserAccount;
mTouchScreenUsageMode = other.mTouchScreenUsageMode;
mAocRegistrationType = other.mAocRegistrationType;
mAttributeFlag = other.mAttributeFlag;
mParentalControlFlag = other.mParentalControlFlag;
mScreenshotMode = other.mScreenshotMode;
mVideoCaptureMode = other.mVideoCaptureMode;
mDataLossConfirmation = other.mDataLossConfirmation;
mPlayLogPolicy = other.mPlayLogPolicy;
mPresenceGroupId = other.mPresenceGroupId;
mRatingAge = other.mRatingAge;
mDisplayVersion = other.mDisplayVersion;
mAocBaseId = other.mAocBaseId;
mSaveDatawOwnerId = other.mSaveDatawOwnerId;
mUserAccountSaveDataSize = other.mUserAccountSaveDataSize;
mDeviceSaveDataSize = other.mDeviceSaveDataSize;
mBcatDeliveryCacheStorageSize = other.mBcatDeliveryCacheStorageSize;
mApplicationErrorCodeCategory = other.mApplicationErrorCodeCategory;
mLocalCommunicationId = other.mLocalCommunicationId;
mLogoType = other.mLogoType;
mLogoHandling = other.mLogoHandling;
mRuntimeAocInstallMode = other.mRuntimeAocInstallMode;
mCrashReportMode = other.mCrashReportMode;
mHdcp = other.mHdcp;
mSeedForPsuedoDeviceId = other.mSeedForPsuedoDeviceId;
mBcatPassphase = other.mBcatPassphase;
mUserAccountSaveDataMax = other.mUserAccountSaveDataMax;
mDeviceSaveDataMax = other.mDeviceSaveDataMax;
mTemporaryStorageSize = other.mTemporaryStorageSize;
mCacheStorageSize = other.mCacheStorageSize;
mCacheStorageDataAndJournalSizeMax = other.mCacheStorageDataAndJournalSizeMax;
mCacheStorageIndex = other.mCacheStorageIndex;
mPlayLogQueryableApplicationId = other.mPlayLogQueryableApplicationId;
mPlayLogQueryCapability = other.mPlayLogQueryCapability;
mRepairFlag = other.mRepairFlag;
mProgramIndex = other.mProgramIndex;
}
bool nx::ApplicationControlPropertyBinary::operator==(const ApplicationControlPropertyBinary& other) const
{
return isEqual(other);
return (mTitle == other.mTitle) \
&& (mIsbn == other.mIsbn) \
&& (mStartupUserAccount == other.mStartupUserAccount) \
&& (mTouchScreenUsageMode == other.mTouchScreenUsageMode) \
&& (mAocRegistrationType == other.mAocRegistrationType) \
&& (mAttributeFlag == other.mAttributeFlag) \
&& (mParentalControlFlag == other.mParentalControlFlag) \
&& (mScreenshotMode == other.mScreenshotMode) \
&& (mVideoCaptureMode == other.mVideoCaptureMode) \
&& (mDataLossConfirmation == other.mDataLossConfirmation) \
&& (mPlayLogPolicy == other.mPlayLogPolicy) \
&& (mPresenceGroupId == other.mPresenceGroupId) \
&& (mRatingAge == other.mRatingAge) \
&& (mDisplayVersion == other.mDisplayVersion) \
&& (mAocBaseId == other.mAocBaseId) \
&& (mSaveDatawOwnerId == other.mSaveDatawOwnerId) \
&& (mUserAccountSaveDataSize == other.mUserAccountSaveDataSize) \
&& (mDeviceSaveDataSize == other.mDeviceSaveDataSize) \
&& (mBcatDeliveryCacheStorageSize == other.mBcatDeliveryCacheStorageSize) \
&& (mApplicationErrorCodeCategory == other.mApplicationErrorCodeCategory) \
&& (mLocalCommunicationId == other.mLocalCommunicationId) \
&& (mLogoType == other.mLogoType) \
&& (mLogoHandling == other.mLogoHandling) \
&& (mRuntimeAocInstallMode == other.mRuntimeAocInstallMode) \
&& (mCrashReportMode == other.mCrashReportMode) \
&& (mHdcp == other.mHdcp) \
&& (mSeedForPsuedoDeviceId == other.mSeedForPsuedoDeviceId) \
&& (mBcatPassphase == other.mBcatPassphase) \
&& (mUserAccountSaveDataMax == other.mUserAccountSaveDataMax) \
&& (mDeviceSaveDataMax == other.mDeviceSaveDataMax) \
&& (mTemporaryStorageSize == other.mTemporaryStorageSize) \
&& (mCacheStorageSize == other.mCacheStorageSize) \
&& (mCacheStorageDataAndJournalSizeMax == other.mCacheStorageDataAndJournalSizeMax) \
&& (mCacheStorageIndex == other.mCacheStorageIndex) \
&& (mPlayLogQueryableApplicationId == other.mPlayLogQueryableApplicationId) \
&& (mPlayLogQueryCapability == other.mPlayLogQueryCapability) \
&& (mRepairFlag == other.mRepairFlag) \
&& (mProgramIndex == other.mProgramIndex);
}
bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPropertyBinary& other) const
@ -25,30 +100,15 @@ bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPr
return !(*this == other);
}
void nx::ApplicationControlPropertyBinary::operator=(const ApplicationControlPropertyBinary& other)
void nx::ApplicationControlPropertyBinary::toBytes()
{
copyFrom(other);
}
mRawBinary.alloc(sizeof(nx::sApplicationControlProperty));
const byte_t* nx::ApplicationControlPropertyBinary::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t nx::ApplicationControlPropertyBinary::getSize() const
{
return mBinaryBlob.getSize();
}
void nx::ApplicationControlPropertyBinary::exportBinary()
{
mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty));
sApplicationControlProperty* data = (sApplicationControlProperty*)mBinaryBlob.getBytes();
sApplicationControlProperty* data = (sApplicationControlProperty*)mRawBinary.data();
// strings
uint32_t supported_langs = 0;
for (size_t i = 0; i < mTitle.getSize(); i++)
for (size_t i = 0; i < mTitle.size(); i++)
{
supported_langs = _BIT(mTitle[i].language);
strncpy(data->title[mTitle[i].language].name, mTitle[i].name.c_str(), nacp::kNameLength);
@ -82,18 +142,18 @@ void nx::ApplicationControlPropertyBinary::exportBinary()
// misc params
data->presence_group_id = mPresenceGroupId;
memset(data->rating_age, nacp::kUnusedAgeRating, nacp::kRatingAgeCount); // clear ratings
for (size_t i = 0; i < mRatingAge.getSize(); i++)
for (size_t i = 0; i < mRatingAge.size(); i++)
{
data->rating_age[mRatingAge[i].organisation] = mRatingAge[i].age;
}
data->add_on_content_base_id = mAocBaseId;
data->save_data_owner_id = mSaveDatawOwnerId;
for (size_t i = 0; i < mLocalCommunicationId.getSize() && i < nacp::kLocalCommunicationIdCount; i++)
for (size_t i = 0; i < mLocalCommunicationId.size() && i < nacp::kLocalCommunicationIdCount; i++)
{
data->local_communication_id[i] = mLocalCommunicationId[i];
}
data->seed_for_pseudo_device_id = mSeedForPsuedoDeviceId;
for (size_t i = 0; i < mPlayLogQueryableApplicationId.getSize() && i < nacp::kPlayLogQueryableApplicationIdCount; i++)
for (size_t i = 0; i < mPlayLogQueryableApplicationId.size() && i < nacp::kPlayLogQueryableApplicationIdCount; i++)
{
data->play_log_queryable_application_id[i] = mPlayLogQueryableApplicationId[i];
}
@ -116,7 +176,7 @@ void nx::ApplicationControlPropertyBinary::exportBinary()
data->cache_storage_data_and_journal_size_max = mCacheStorageDataAndJournalSizeMax;
}
void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, size_t len)
void nx::ApplicationControlPropertyBinary::fromBytes(const byte_t* bytes, size_t len)
{
if (len < sizeof(nx::sApplicationControlProperty))
{
@ -125,10 +185,10 @@ void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, siz
clear();
mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
mRawBinary.alloc(sizeof(nx::sApplicationControlProperty));
memcpy(mRawBinary.data(), bytes, mRawBinary.size());
const sApplicationControlProperty* data = (const sApplicationControlProperty*)mBinaryBlob.getBytes();
const sApplicationControlProperty* data = (const sApplicationControlProperty*)mRawBinary.data();
// strings
for (size_t i = 0; i < nacp::kMaxLanguageCount; i++)
@ -204,9 +264,14 @@ void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, siz
mCacheStorageDataAndJournalSizeMax = (int64_t)data->cache_storage_data_and_journal_size_max.get();
}
const fnd::Vec<byte_t>& nx::ApplicationControlPropertyBinary::getBytes() const
{
return mRawBinary;
}
void nx::ApplicationControlPropertyBinary::clear()
{
mBinaryBlob.clear();
mRawBinary.clear();
mTitle.clear();
mIsbn.clear();
mStartupUserAccount = nacp::USER_None;
@ -625,89 +690,4 @@ byte_t nx::ApplicationControlPropertyBinary::getProgramIndex() const
void nx::ApplicationControlPropertyBinary::setProgramIndex(byte_t var)
{
mProgramIndex = var;
}
bool nx::ApplicationControlPropertyBinary::isEqual(const ApplicationControlPropertyBinary& other) const
{
return (mTitle == other.mTitle) \
&& (mIsbn == other.mIsbn) \
&& (mStartupUserAccount == other.mStartupUserAccount) \
&& (mTouchScreenUsageMode == other.mTouchScreenUsageMode) \
&& (mAocRegistrationType == other.mAocRegistrationType) \
&& (mAttributeFlag == other.mAttributeFlag) \
&& (mParentalControlFlag == other.mParentalControlFlag) \
&& (mScreenshotMode == other.mScreenshotMode) \
&& (mVideoCaptureMode == other.mVideoCaptureMode) \
&& (mDataLossConfirmation == other.mDataLossConfirmation) \
&& (mPlayLogPolicy == other.mPlayLogPolicy) \
&& (mPresenceGroupId == other.mPresenceGroupId) \
&& (mRatingAge == other.mRatingAge) \
&& (mDisplayVersion == other.mDisplayVersion) \
&& (mAocBaseId == other.mAocBaseId) \
&& (mSaveDatawOwnerId == other.mSaveDatawOwnerId) \
&& (mUserAccountSaveDataSize == other.mUserAccountSaveDataSize) \
&& (mDeviceSaveDataSize == other.mDeviceSaveDataSize) \
&& (mBcatDeliveryCacheStorageSize == other.mBcatDeliveryCacheStorageSize) \
&& (mApplicationErrorCodeCategory == other.mApplicationErrorCodeCategory) \
&& (mLocalCommunicationId == other.mLocalCommunicationId) \
&& (mLogoType == other.mLogoType) \
&& (mLogoHandling == other.mLogoHandling) \
&& (mRuntimeAocInstallMode == other.mRuntimeAocInstallMode) \
&& (mCrashReportMode == other.mCrashReportMode) \
&& (mHdcp == other.mHdcp) \
&& (mSeedForPsuedoDeviceId == other.mSeedForPsuedoDeviceId) \
&& (mBcatPassphase == other.mBcatPassphase) \
&& (mUserAccountSaveDataMax == other.mUserAccountSaveDataMax) \
&& (mDeviceSaveDataMax == other.mDeviceSaveDataMax) \
&& (mTemporaryStorageSize == other.mTemporaryStorageSize) \
&& (mCacheStorageSize == other.mCacheStorageSize) \
&& (mCacheStorageDataAndJournalSizeMax == other.mCacheStorageDataAndJournalSizeMax) \
&& (mCacheStorageIndex == other.mCacheStorageIndex) \
&& (mPlayLogQueryableApplicationId == other.mPlayLogQueryableApplicationId) \
&& (mPlayLogQueryCapability == other.mPlayLogQueryCapability) \
&& (mRepairFlag == other.mRepairFlag) \
&& (mProgramIndex == other.mProgramIndex);
}
void nx::ApplicationControlPropertyBinary::copyFrom(const ApplicationControlPropertyBinary& other)
{
clear();
mTitle = other.mTitle;
mIsbn = other.mIsbn;
mStartupUserAccount = other.mStartupUserAccount;
mTouchScreenUsageMode = other.mTouchScreenUsageMode;
mAocRegistrationType = other.mAocRegistrationType;
mAttributeFlag = other.mAttributeFlag;
mParentalControlFlag = other.mParentalControlFlag;
mScreenshotMode = other.mScreenshotMode;
mVideoCaptureMode = other.mVideoCaptureMode;
mDataLossConfirmation = other.mDataLossConfirmation;
mPlayLogPolicy = other.mPlayLogPolicy;
mPresenceGroupId = other.mPresenceGroupId;
mRatingAge = other.mRatingAge;
mDisplayVersion = other.mDisplayVersion;
mAocBaseId = other.mAocBaseId;
mSaveDatawOwnerId = other.mSaveDatawOwnerId;
mUserAccountSaveDataSize = other.mUserAccountSaveDataSize;
mDeviceSaveDataSize = other.mDeviceSaveDataSize;
mBcatDeliveryCacheStorageSize = other.mBcatDeliveryCacheStorageSize;
mApplicationErrorCodeCategory = other.mApplicationErrorCodeCategory;
mLocalCommunicationId = other.mLocalCommunicationId;
mLogoType = other.mLogoType;
mLogoHandling = other.mLogoHandling;
mRuntimeAocInstallMode = other.mRuntimeAocInstallMode;
mCrashReportMode = other.mCrashReportMode;
mHdcp = other.mHdcp;
mSeedForPsuedoDeviceId = other.mSeedForPsuedoDeviceId;
mBcatPassphase = other.mBcatPassphase;
mUserAccountSaveDataMax = other.mUserAccountSaveDataMax;
mDeviceSaveDataMax = other.mDeviceSaveDataMax;
mTemporaryStorageSize = other.mTemporaryStorageSize;
mCacheStorageSize = other.mCacheStorageSize;
mCacheStorageDataAndJournalSizeMax = other.mCacheStorageDataAndJournalSizeMax;
mCacheStorageIndex = other.mCacheStorageIndex;
mPlayLogQueryableApplicationId = other.mPlayLogQueryableApplicationId;
mPlayLogQueryCapability = other.mPlayLogQueryCapability;
mRepairFlag = other.mRepairFlag;
mProgramIndex = other.mProgramIndex;
}
}

View file

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

View file

@ -1,118 +1,100 @@
#include <nx/FacBinary.h>
nx::FacBinary::FacBinary()
{}
{
clear();
}
nx::FacBinary::FacBinary(const FacBinary & other)
{
copyFrom(other);
}
nx::FacBinary::FacBinary(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool nx::FacBinary::operator==(const FacBinary & other) const
{
return isEqual(other);
}
bool nx::FacBinary::operator!=(const FacBinary & other) const
{
return !isEqual(other);
*this = other;
}
void nx::FacBinary::operator=(const FacBinary & other)
{
copyFrom(other);
}
const byte_t * nx::FacBinary::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t nx::FacBinary::getSize() const
{
return mBinaryBlob.getSize();
}
void nx::FacBinary::exportBinary()
{
FacHeader::setContentOwnerIdSize(mContentOwnerIdList.getSize() * sizeof(uint32_t));
FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.getSize() * sizeof(uint32_t));
FacHeader::exportBinary();
mBinaryBlob.alloc(getFacSize());
memcpy(mBinaryBlob.getBytes(), FacHeader::getBytes(), FacHeader::getSize());
uint32_t* rawContentOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getContentOwnerIdOffset());
for (size_t i = 0; i < mContentOwnerIdList.getSize(); i++)
if (other.getBytes().size())
{
rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]);
}
uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getSaveDataOwnerIdOffset());
for (size_t i = 0; i < mSaveDataOwnerIdList.getSize(); i++)
{
rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]);
}
}
void nx::FacBinary::importBinary(const byte_t * bytes, size_t len)
{
clear();
FacHeader::importBinary(bytes, len);
if (FacHeader::getFacSize() > len)
{
throw fnd::Exception(kModuleName, "FAC binary too small");
}
mBinaryBlob.alloc(FacHeader::getFacSize());
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
uint32_t* rawContentOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getContentOwnerIdOffset());
size_t rawContentOwnerIdNum = FacHeader::getContentOwnerIdSize() / sizeof(uint32_t);
for (size_t i = 0; i < rawContentOwnerIdNum; i++)
{
mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i]));
}
uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getSaveDataOwnerIdOffset());
size_t rawSaveDataOwnerIdNum = FacHeader::getSaveDataOwnerIdSize() / sizeof(uint32_t);
for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++)
{
mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i]));
}
}
bool nx::FacBinary::isEqual(const FacBinary & other) const
{
return (FacHeader::operator==(other)) \
&& (mContentOwnerIdList == other.mContentOwnerIdList) \
&& (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList);
}
void nx::FacBinary::copyFrom(const FacBinary & other)
{
if (other.getSize())
{
importBinary(other.getBytes(), other.getSize());
fromBytes(other.getBytes().data(), other.getBytes().size());
}
else
{
clear();
FacHeader::operator=(other);
mContentOwnerIdList = other.mContentOwnerIdList;
mSaveDataOwnerIdList = other.mSaveDataOwnerIdList;
}
}
bool nx::FacBinary::operator==(const FacBinary & other) const
{
return (FacHeader::operator==(other)) \
&& (mContentOwnerIdList == other.mContentOwnerIdList) \
&& (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList);
}
bool nx::FacBinary::operator!=(const FacBinary & other) const
{
return !(*this == other);
}
void nx::FacBinary::toBytes()
{
FacHeader::setContentOwnerIdSize(mContentOwnerIdList.size() * sizeof(uint32_t));
FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.size() * sizeof(uint32_t));
FacHeader::toBytes();
mRawBinary.alloc(getFacSize());
memcpy(mRawBinary.data(), FacHeader::getBytes().data(), FacHeader::getBytes().size());
uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getContentOwnerIdPos().offset);
for (size_t i = 0; i < mContentOwnerIdList.size(); i++)
{
rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]);
}
uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getSaveDataOwnerIdPos().offset);
for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++)
{
rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]);
}
}
void nx::FacBinary::fromBytes(const byte_t* data, size_t len)
{
clear();
FacHeader::fromBytes(data, len);
if (FacHeader::getFacSize() > len)
{
throw fnd::Exception(kModuleName, "FAC binary too small");
}
mRawBinary.alloc(FacHeader::getFacSize());
memcpy(mRawBinary.data(), data, mRawBinary.size());
uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getContentOwnerIdPos().offset);
size_t rawContentOwnerIdNum = FacHeader::getContentOwnerIdPos().size / sizeof(uint32_t);
for (size_t i = 0; i < rawContentOwnerIdNum; i++)
{
mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i]));
}
uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getSaveDataOwnerIdPos().offset);
size_t rawSaveDataOwnerIdNum = FacHeader::getSaveDataOwnerIdPos().size / sizeof(uint32_t);
for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++)
{
mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i]));
}
}
const fnd::Vec<byte_t>& nx::FacBinary::getBytes() const
{
return mRawBinary;
}
void nx::FacBinary::clear()
{
FacHeader::clear();
mRawBinary.clear();
mContentOwnerIdList.clear();
mSaveDataOwnerIdList.clear();
}

View file

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

View file

@ -8,45 +8,40 @@ nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader()
nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader & other)
{
copyFrom(other);
}
nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool nx::HierarchicalIntegrityHeader::operator==(const HierarchicalIntegrityHeader & other) const
{
return isEqual(other);
}
bool nx::HierarchicalIntegrityHeader::operator!=(const HierarchicalIntegrityHeader & other) const
{
return !isEqual(other);
*this = other;
}
void nx::HierarchicalIntegrityHeader::operator=(const HierarchicalIntegrityHeader & other)
{
copyFrom(other);
if (other.getBytes().size() != 0)
{
fromBytes(other.getBytes().data(), other.getBytes().size());
}
else
{
clear();
mLayerInfo = other.mLayerInfo;
mMasterHashList = other.mMasterHashList;
}
}
const byte_t * nx::HierarchicalIntegrityHeader::getBytes() const
bool nx::HierarchicalIntegrityHeader::operator==(const HierarchicalIntegrityHeader & other) const
{
return mBinaryBlob.getBytes();
return (mLayerInfo == other.mLayerInfo) \
&& (mMasterHashList == other.mMasterHashList);
}
size_t nx::HierarchicalIntegrityHeader::getSize() const
bool nx::HierarchicalIntegrityHeader::operator!=(const HierarchicalIntegrityHeader & other) const
{
return mBinaryBlob.getSize();
return !(*this == other);
}
void nx::HierarchicalIntegrityHeader::exportBinary()
void nx::HierarchicalIntegrityHeader::toBytes()
{
throw fnd::Exception(kModuleName, "exportBinary() not implemented");
}
void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t len)
void nx::HierarchicalIntegrityHeader::fromBytes(const byte_t* data, size_t len)
{
std::stringstream error_str;
@ -56,7 +51,7 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t
throw fnd::Exception(kModuleName, "Header too small");
}
const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)bytes;
const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)data;
// Validate Header Sig "IVFC"
if (hdr->signature.get() != hierarchicalintegrity::kStructSig)
@ -92,24 +87,29 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t
}
// copy to internal storage
mBinaryBlob.alloc(total_size);
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
mRawBinary.alloc(total_size);
memcpy(mRawBinary.data(), data, mRawBinary.size());
// save layer info
const nx::sHierarchicalIntegrityLayerInfo* layer_info = (const nx::sHierarchicalIntegrityLayerInfo*)(mBinaryBlob.getBytes() + sizeof(nx::sHierarchicalIntegrityHeader));
const nx::sHierarchicalIntegrityLayerInfo* layer_info = (const nx::sHierarchicalIntegrityLayerInfo*)(mRawBinary.data() + sizeof(nx::sHierarchicalIntegrityHeader));
for (size_t i = 0; i < hierarchicalintegrity::kDefaultLayerNum; i++)
{
mLayerInfo.addElement({layer_info[i].offset.get(), layer_info[i].size.get(), layer_info[i].block_size.get()});
}
// save hash list
const crypto::sha::sSha256Hash* hash_list = (const crypto::sha::sSha256Hash*)(mBinaryBlob.getBytes() + master_hash_offset);
const crypto::sha::sSha256Hash* hash_list = (const crypto::sha::sSha256Hash*)(mRawBinary.data() + master_hash_offset);
for (size_t i = 0; i < hdr->master_hash_size.get()/sizeof(crypto::sha::sSha256Hash); i++)
{
mMasterHashList.addElement(hash_list[i]);
}
}
const fnd::Vec<byte_t>& nx::HierarchicalIntegrityHeader::getBytes() const
{
return mRawBinary;
}
void nx::HierarchicalIntegrityHeader::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)
{
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 <nx/HierarchicalSha256Header.h>
nx::HierarchicalSha256Header::HierarchicalSha256Header()
{
clear();
@ -9,45 +8,41 @@ nx::HierarchicalSha256Header::HierarchicalSha256Header()
nx::HierarchicalSha256Header::HierarchicalSha256Header(const HierarchicalSha256Header & other)
{
copyFrom(other);
}
nx::HierarchicalSha256Header::HierarchicalSha256Header(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool nx::HierarchicalSha256Header::operator==(const HierarchicalSha256Header & other) const
{
return isEqual(other);
}
bool nx::HierarchicalSha256Header::operator!=(const HierarchicalSha256Header & other) const
{
return !isEqual(other);
*this = other;
}
void nx::HierarchicalSha256Header::operator=(const HierarchicalSha256Header & other)
{
copyFrom(other);
if (other.getBytes().size() != 0)
{
fromBytes(other.getBytes().data(), other.getBytes().size());
}
else
{
mMasterHash = other.mMasterHash;
mHashBlockSize = other.mHashBlockSize;
mLayerInfo = other.mLayerInfo;
}
}
const byte_t * nx::HierarchicalSha256Header::getBytes() const
bool nx::HierarchicalSha256Header::operator==(const HierarchicalSha256Header & other) const
{
return mBinaryBlob.getBytes();
return (mMasterHash == other.mMasterHash) \
&& (mHashBlockSize == other.mHashBlockSize) \
&& (mLayerInfo == other.mLayerInfo);
}
size_t nx::HierarchicalSha256Header::getSize() const
bool nx::HierarchicalSha256Header::operator!=(const HierarchicalSha256Header & other) const
{
return mBinaryBlob.getSize();
return !(*this == other);
}
void nx::HierarchicalSha256Header::exportBinary()
void nx::HierarchicalSha256Header::toBytes()
{
throw fnd::Exception(kModuleName, "exportBinary() not implemented");
}
void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len)
void nx::HierarchicalSha256Header::fromBytes(const byte_t* data, size_t len)
{
std::stringstream error_str;
@ -56,7 +51,7 @@ void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len
throw fnd::Exception(kModuleName, "Header too small");
}
const nx::sHierarchicalSha256Header* hdr = (const nx::sHierarchicalSha256Header*)bytes;
const nx::sHierarchicalSha256Header* hdr = (const nx::sHierarchicalSha256Header*)data;
if (hdr->layer_num.get() != nx::hierarchicalsha256::kDefaultLayerNum)
{
@ -74,6 +69,11 @@ void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len
}
}
const fnd::Vec<byte_t>& nx::HierarchicalSha256Header::getBytes() const
{
return mRawBinary;
}
void nx::HierarchicalSha256Header::clear()
{
memset(mMasterHash.bytes, 0, sizeof(crypto::sha::sSha256Hash));
@ -109,25 +109,4 @@ const fnd::List<nx::HierarchicalSha256Header::sLayer>& nx::HierarchicalSha256Hea
void nx::HierarchicalSha256Header::setLayerInfo(const fnd::List<sLayer>& 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>
nx::KcBinary::KcBinary()
{}
nx::KcBinary::KcBinary(const KcBinary & other)
{
copyFrom(other);
}
nx::KcBinary::KcBinary(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool nx::KcBinary::operator==(const KcBinary & other) const
{
return isEqual(other);
}
bool nx::KcBinary::operator!=(const KcBinary & other) const
{
return !isEqual(other);
*this = other;
}
void nx::KcBinary::operator=(const KcBinary & other)
{
copyFrom(other);
clear();
mThreadInfo = other.mThreadInfo;
mSystemCalls = other.mSystemCalls;
mMemoryMap = other.mMemoryMap;
mInterupts = other.mInterupts;
mMiscParams = other.mMiscParams;
mKernelVersion = other.mKernelVersion;
mHandleTableSize = other.mHandleTableSize;
mMiscFlags = other.mMiscFlags;
}
const byte_t * nx::KcBinary::getBytes() const
bool nx::KcBinary::operator==(const KcBinary & other) const
{
return mBinaryBlob.getBytes();
return (mThreadInfo == other.mThreadInfo) \
&& (mSystemCalls == other.mSystemCalls) \
&& (mMemoryMap == other.mMemoryMap) \
&& (mInterupts == other.mInterupts) \
&& (mMiscParams == other.mMiscParams) \
&& (mKernelVersion == other.mKernelVersion) \
&& (mHandleTableSize == other.mHandleTableSize) \
&& (mMiscFlags == other.mMiscFlags);
}
size_t nx::KcBinary::getSize() const
bool nx::KcBinary::operator!=(const KcBinary & other) const
{
return mBinaryBlob.getSize();
return !(*this == other);
}
void nx::KcBinary::exportBinary()
void nx::KcBinary::toBytes()
{
fnd::List<KernelCapability> caps;
@ -55,23 +53,27 @@ void nx::KcBinary::exportBinary()
mMiscFlags.exportKernelCapabilityList(caps);
// allocate memory
mBinaryBlob.alloc(caps.getSize() * sizeof(uint32_t));
mRawBinary.alloc(caps.size() * sizeof(uint32_t));
// write to binary
uint32_t* raw_caps = (uint32_t*)mBinaryBlob.getBytes();
for (size_t i = 0; i < caps.getSize(); i++)
uint32_t* raw_caps = (uint32_t*)mRawBinary.data();
for (size_t i = 0; i < caps.size(); i++)
{
raw_caps[i] = le_word(caps[i].getCap());
}
}
void nx::KcBinary::importBinary(const byte_t * bytes, size_t len)
void nx::KcBinary::fromBytes(const byte_t * data, size_t len)
{
if ((len % sizeof(uint32_t)) != 0)
{
throw fnd::Exception(kModuleName, "KernelCapability list must be aligned to 4 bytes");
}
// save copy of KcBinary
mRawBinary.alloc(len);
memcpy(mRawBinary.data(), data, len);
fnd::List<KernelCapability> threadInfoCaps;
fnd::List<KernelCapability> systemCallCaps;
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> miscFlagsCaps;
const uint32_t* raw_caps = (const uint32_t*)bytes;
size_t cap_num = len / sizeof(uint32_t);
const uint32_t* raw_caps = (const uint32_t*)mRawBinary.data();
size_t cap_num = mRawBinary.size() / sizeof(uint32_t);
KernelCapability cap;
for (size_t i = 0; i < cap_num; i++)
{
@ -129,9 +131,14 @@ void nx::KcBinary::importBinary(const byte_t * bytes, size_t len)
mMiscFlags.importKernelCapabilityList(miscFlagsCaps);
}
const fnd::Vec<byte_t>& nx::KcBinary::getBytes() const
{
return mRawBinary;
}
void nx::KcBinary::clear()
{
mBinaryBlob.clear();
mRawBinary.clear();
mThreadInfo.clear();
mSystemCalls.clear();
mMemoryMap.clear();
@ -220,28 +227,4 @@ const nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags() const
nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags()
{
return mMiscFlags;
}
bool nx::KcBinary::isEqual(const KcBinary & other) const
{
return (mThreadInfo == other.mThreadInfo) \
&& (mSystemCalls == other.mSystemCalls) \
&& (mMemoryMap == other.mMemoryMap) \
&& (mInterupts == other.mInterupts) \
&& (mMiscParams == other.mMiscParams) \
&& (mKernelVersion == other.mKernelVersion) \
&& (mHandleTableSize == other.mHandleTableSize) \
&& (mMiscFlags == other.mMiscFlags);
}
void nx::KcBinary::copyFrom(const KcBinary & other)
{
mThreadInfo = other.mThreadInfo;
mSystemCalls = other.mSystemCalls;
mMemoryMap = other.mMemoryMap;
mInterupts = other.mInterupts;
mMiscParams = other.mMiscParams;
mKernelVersion = other.mKernelVersion;
mHandleTableSize = other.mHandleTableSize;
mMiscFlags = other.mMiscFlags;
}
}

View file

@ -2,11 +2,61 @@
using namespace nx;
void NcaHeader::exportBinary()
NcaHeader::NcaHeader()
{
mBinaryBlob.alloc(sizeof(sNcaHeader));
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
clear();
}
NcaHeader::NcaHeader(const NcaHeader & other)
{
*this = other;
}
bool NcaHeader::operator==(const NcaHeader & other) const
{
return (mDistributionType == other.mDistributionType) \
&& (mContentType == other.mContentType) \
&& (mKeyGeneration == other.mKeyGeneration) \
&& (mKaekIndex == other.mKaekIndex) \
&& (mContentSize == other.mContentSize) \
&& (mProgramId == other.mProgramId) \
&& (mContentIndex == other.mContentIndex) \
&& (mSdkAddonVersion == other.mSdkAddonVersion) \
&& (mPartitions == other.mPartitions) \
&& (mEncAesKeys == other.mEncAesKeys);
}
bool NcaHeader::operator!=(const NcaHeader & other) const
{
return !(*this == other);
}
void NcaHeader::operator=(const NcaHeader & other)
{
if (other.getBytes().size())
{
fromBytes(other.getBytes().data(), other.getBytes().size());
}
else
{
mRawBinary.clear();
mDistributionType = other.mDistributionType;
mContentType = other.mContentType;
mKeyGeneration = other.mKeyGeneration;
mKaekIndex = other.mKaekIndex;
mContentSize = other.mContentSize;
mProgramId = other.mProgramId;
mContentIndex = other.mContentIndex;
mSdkAddonVersion = other.mSdkAddonVersion;
mPartitions = other.mPartitions;
mEncAesKeys = other.mEncAesKeys;
}
}
void NcaHeader::toBytes()
{
mRawBinary.alloc(sizeof(sNcaHeader));
sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data();
switch(mFormatVersion)
@ -41,7 +91,7 @@ void NcaHeader::exportBinary()
memcpy(hdr->rights_id, mRightsId, nca::kRightsIdLen);
// TODO: properly reconstruct NCA layout? atm in hands of user
for (size_t i = 0; i < mPartitions.getSize(); i++)
for (size_t i = 0; i < mPartitions.size(); i++)
{
// determine partition index
byte_t idx = mPartitions[i].index;
@ -60,7 +110,7 @@ void NcaHeader::exportBinary()
}
}
void NcaHeader::importBinary(const byte_t * bytes, size_t len)
void NcaHeader::fromBytes(const byte_t * data, size_t len)
{
if (len < sizeof(sNcaHeader))
{
@ -69,10 +119,10 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len)
clear();
mBinaryBlob.alloc(sizeof(sNcaHeader));
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sNcaHeader));
mRawBinary.alloc(sizeof(sNcaHeader));
memcpy(mRawBinary.data(), data, sizeof(sNcaHeader));
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data();
switch(hdr->signature.get())
{
@ -110,6 +160,11 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len)
}
}
const fnd::Vec<byte_t>& NcaHeader::getBytes() const
{
return mRawBinary;
}
void nx::NcaHeader::clear()
{
mFormatVersion = NCA3_FORMAT;
@ -247,7 +302,7 @@ const fnd::List<NcaHeader::sPartition>& NcaHeader::getPartitions() const
void NcaHeader::setPartitions(const fnd::List<NcaHeader::sPartition>& partitions)
{
mPartitions = partitions;
if (mPartitions.getSize() >= nca::kPartitionNum)
if (mPartitions.size() >= nca::kPartitionNum)
{
throw fnd::Exception(kModuleName, "Too many NCA partitions");
}
@ -271,80 +326,4 @@ uint64_t NcaHeader::blockNumToSize(uint32_t block_num) const
uint32_t NcaHeader::sizeToBlockNum(uint64_t real_size) const
{
return (uint32_t)(align(real_size, nca::kSectorSize) / nca::kSectorSize);
}
bool NcaHeader::isEqual(const NcaHeader & other) const
{
return (mDistributionType == other.mDistributionType) \
&& (mContentType == other.mContentType) \
&& (mKeyGeneration == other.mKeyGeneration) \
&& (mKaekIndex == other.mKaekIndex) \
&& (mContentSize == other.mContentSize) \
&& (mProgramId == other.mProgramId) \
&& (mContentIndex == other.mContentIndex) \
&& (mSdkAddonVersion == other.mSdkAddonVersion) \
&& (mPartitions == other.mPartitions) \
&& (mEncAesKeys == other.mEncAesKeys);
}
void NcaHeader::copyFrom(const NcaHeader & other)
{
if (other.getSize())
{
importBinary(other.getBytes(), other.getSize());
}
else
{
mBinaryBlob.clear();
mDistributionType = other.mDistributionType;
mContentType = other.mContentType;
mKeyGeneration = other.mKeyGeneration;
mKaekIndex = other.mKaekIndex;
mContentSize = other.mContentSize;
mProgramId = other.mProgramId;
mContentIndex = other.mContentIndex;
mSdkAddonVersion = other.mSdkAddonVersion;
mPartitions = other.mPartitions;
mEncAesKeys = other.mEncAesKeys;
}
}
NcaHeader::NcaHeader()
{
clear();
}
NcaHeader::NcaHeader(const NcaHeader & other)
{
copyFrom(other);
}
NcaHeader::NcaHeader(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool NcaHeader::operator==(const NcaHeader & other) const
{
return isEqual(other);
}
bool NcaHeader::operator!=(const NcaHeader & other) const
{
return !isEqual(other);
}
void NcaHeader::operator=(const NcaHeader & other)
{
this->importBinary(other.getBytes(), other.getSize());
}
const byte_t * NcaHeader::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t NcaHeader::getSize() const
{
return mBinaryBlob.getSize();
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,39 +1,16 @@
#include <nx/XciHeader.h>
bool nx::XciHeader::isEqual(const XciHeader& other) const
nx::XciHeader::XciHeader()
{
return ( mRomAreaStartPage == other.mRomAreaStartPage \
&& mBackupAreaStartPage == other.mBackupAreaStartPage \
&& mKekIndex == other.mKekIndex \
&& mTitleKeyDecIndex == other.mTitleKeyDecIndex \
&& mRomSize == other.mRomSize \
&& mCardHeaderVersion == other.mCardHeaderVersion \
&& mFlags == other.mFlags \
&& mPackageId == other.mPackageId \
&& mValidDataEndPage == other.mValidDataEndPage \
&& mAesCbcIv == other.mAesCbcIv \
&& mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress \
&& mPartitionFsHeaderSize == other.mPartitionFsHeaderSize \
&& mPartitionFsHeaderHash == other.mPartitionFsHeaderHash \
&& mInitialDataHash == other.mInitialDataHash \
&& mSelSec == other.mSelSec \
&& mSelT1Key == other.mSelT1Key \
&& mSelKey == other.mSelKey \
&& mLimAreaPage == other.mLimAreaPage \
&& mFwVersion[0] == other.mFwVersion[0] \
&& mFwVersion[1] == other.mFwVersion[1] \
&& mAccCtrl1 == other.mAccCtrl1 \
&& mWait1TimeRead == other.mWait1TimeRead \
&& mWait2TimeRead == other.mWait2TimeRead \
&& mWait1TimeWrite == other.mWait1TimeWrite \
&& mWait2TimeWrite == other.mWait2TimeWrite \
&& mFwMode == other.mFwMode \
&& mUppVersion == other.mUppVersion \
&& memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) \
&& mUppId == other.mUppId );
clear();
}
void nx::XciHeader::copyFrom(const XciHeader& other)
nx::XciHeader::XciHeader(const XciHeader& other)
{
*this = other;
}
void nx::XciHeader::operator=(const XciHeader& other)
{
mRomAreaStartPage = other.mRomAreaStartPage;
mBackupAreaStartPage = other.mBackupAreaStartPage;
@ -66,51 +43,50 @@ void nx::XciHeader::copyFrom(const XciHeader& other)
mUppId = other.mUppId;
}
nx::XciHeader::XciHeader()
{
}
nx::XciHeader::XciHeader(const XciHeader& other)
{
importBinary(other.getBytes(), other.getSize());
}
nx::XciHeader::XciHeader(const byte_t* bytes, size_t len)
{
importBinary(bytes, len);
}
bool nx::XciHeader::operator==(const XciHeader& other) const
{
return isEqual(other);
return (mRomAreaStartPage == other.mRomAreaStartPage \
&& mBackupAreaStartPage == other.mBackupAreaStartPage \
&& mKekIndex == other.mKekIndex \
&& mTitleKeyDecIndex == other.mTitleKeyDecIndex \
&& mRomSize == other.mRomSize \
&& mCardHeaderVersion == other.mCardHeaderVersion \
&& mFlags == other.mFlags \
&& mPackageId == other.mPackageId \
&& mValidDataEndPage == other.mValidDataEndPage \
&& mAesCbcIv == other.mAesCbcIv \
&& mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress \
&& mPartitionFsHeaderSize == other.mPartitionFsHeaderSize \
&& mPartitionFsHeaderHash == other.mPartitionFsHeaderHash \
&& mInitialDataHash == other.mInitialDataHash \
&& mSelSec == other.mSelSec \
&& mSelT1Key == other.mSelT1Key \
&& mSelKey == other.mSelKey \
&& mLimAreaPage == other.mLimAreaPage \
&& mFwVersion[0] == other.mFwVersion[0] \
&& mFwVersion[1] == other.mFwVersion[1] \
&& mAccCtrl1 == other.mAccCtrl1 \
&& mWait1TimeRead == other.mWait1TimeRead \
&& mWait2TimeRead == other.mWait2TimeRead \
&& mWait1TimeWrite == other.mWait1TimeWrite \
&& mWait2TimeWrite == other.mWait2TimeWrite \
&& mFwMode == other.mFwMode \
&& mUppVersion == other.mUppVersion \
&& memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) \
&& mUppId == other.mUppId);
}
bool nx::XciHeader::operator!=(const XciHeader& other) const
{
return isEqual(other) == false;
}
void nx::XciHeader::operator=(const XciHeader& other)
{
copyFrom(other);
return !(*this == other);
}
// to be used after export
const byte_t* nx::XciHeader::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t nx::XciHeader::getSize() const
{
return mBinaryBlob.getSize();
}
// export/import binary
void nx::XciHeader::exportBinary()
void nx::XciHeader::toBytes()
{
fnd::Exception(kModuleName, "exportBinary() not implemented");
}
void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
void nx::XciHeader::fromBytes(const byte_t* data, size_t len)
{
// check input data size
if (len < sizeof(sXciHeader))
@ -122,11 +98,11 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
clear();
// allocate internal local binary copy
mBinaryBlob.alloc(sizeof(sXciHeader));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
mRawBinary.alloc(sizeof(sXciHeader));
memcpy(mRawBinary.data(), data, mRawBinary.size());
// get sXciHeader ptr
const nx::sXciHeader* hdr = (const nx::sXciHeader*)mBinaryBlob.getBytes();
const nx::sXciHeader* hdr = (const nx::sXciHeader*)mRawBinary.data();
// check XCI signature
if (hdr->signature.get() != xci::kXciSig)
@ -172,6 +148,11 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
}
const fnd::Vec<byte_t>& nx::XciHeader::getBytes() const
{
return mRawBinary;
}
// variables
void nx::XciHeader::clear()
{