Use ISerialiseablePrimative types in NcaHeader

This commit is contained in:
jakcron 2018-03-17 20:01:19 +08:00
parent c5c71873b9
commit e293b322c0
2 changed files with 50 additions and 90 deletions

View file

@ -13,6 +13,12 @@ namespace nx
public fnd::ISerialiseableBinary public fnd::ISerialiseableBinary
{ {
public: public:
enum FormatVersion
{
NCA2_FORMAT,
NCA3_FORMAT
};
enum DistributionType enum DistributionType
{ {
DIST_DOWNLOAD, DIST_DOWNLOAD,
@ -133,72 +139,26 @@ namespace nx
struct sNcaHeader struct sNcaHeader
{ {
private: char signature[4];
u8 signature_[4]; byte_t distribution_type;
u8 distribution_type_; byte_t content_type;
u8 content_type_; byte_t key_generation;
u8 key_generation_; byte_t key_area_encryption_key_index;
u8 key_area_encryption_key_index_; le_uint64_t nca_size;
u64 nca_size_; le_uint64_t program_id;
u64 program_id_; le_uint32_t content_index;
u32 content_index_; le_uint32_t sdk_addon_version;
u32 sdk_addon_version_; byte_t reserved_2[0x20];
u8 reserved_2[0x20];
struct sNcaSection struct sNcaSection
{ {
private: le_uint32_t start; // block units
u32 start_; // block units le_uint32_t end; // block units
u32 end_; // block units byte_t enabled;
u8 enabled_; byte_t reserved[7];
u8 reserved[7]; } section[kSectionNum];
public: crypto::sha::sSha256Hash section_hash[kSectionNum];
u32 start() const { return le_word(start_); } crypto::aes::sAes128Key enc_aes_key[kAesKeyNum];
void set_start(u32 offset) { start_ = le_word(offset); }
u32 end() const { return le_word(end_); }
void set_end(u32 offset) { end_ = le_word(offset); }
u8 enabled() const { return enabled_; }
void set_enabled(u8 is_enabled) { enabled_ = is_enabled; }
} section_[kSectionNum];
crypto::sha::sSha256Hash section_hash_[kSectionNum];
crypto::aes::sAes128Key enc_aes_keys_[kAesKeyNum];
public:
const char* signature() const { return (const char*)signature_; }
void set_signature(const char* signature) { memcpy(signature_, signature, 4); }
u8 distribution_type() const { return distribution_type_; }
void set_distribution_type(u8 type) { distribution_type_ = type; }
u8 content_type() const { return content_type_; }
void set_content_type(u8 type) { content_type_ = type; }
u8 key_generation() const { return key_generation_; }
void set_key_generation(u8 type) { key_generation_ = type; }
u8 key_area_encryption_key_index() const { return key_area_encryption_key_index_; }
void set_key_area_encryption_key_index(u8 index) { key_area_encryption_key_index_ = index; }
u64 nca_size() const { return le_dword(nca_size_); }
void set_nca_size(u64 nca_size) { nca_size_ = le_dword(nca_size); }
u64 program_id() const { return le_dword(program_id_); }
void set_program_id(u64 program_id) { program_id_ = le_dword(program_id); }
u32 content_index() const { return le_word(content_index_); }
void set_content_index(u32 index) { content_index_ = le_word(index); }
u32 sdk_addon_version() const { return le_word(sdk_addon_version_); }
void set_sdk_addon_version(u32 version) { sdk_addon_version_ = le_word(version); }
const sNcaSection& section(u8 index) const { return section_[index%kSectionNum]; }
sNcaSection& section(u8 index) { return section_[index%kSectionNum]; }
const crypto::sha::sSha256Hash& section_hash(u8 index) const { return section_hash_[index%kSectionNum]; }
crypto::sha::sSha256Hash& section_hash(u8 index) { return section_hash_[index%kSectionNum]; }
const crypto::aes::sAes128Key& enc_aes_key(u8 index) const { return enc_aes_keys_[index%kAesKeyNum]; }
crypto::aes::sAes128Key& enc_aes_key(u8 index) { return enc_aes_keys_[index%kAesKeyNum]; }
}; };
#pragma pack (pop) #pragma pack (pop)

View file

@ -8,15 +8,15 @@ void NcaHeader::exportBinary()
mBinaryBlob.alloc(sizeof(sNcaHeader)); mBinaryBlob.alloc(sizeof(sNcaHeader));
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes(); sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
hdr->set_signature(kNcaSig.c_str()); strncpy(hdr->signature, kNcaSig.c_str(), 4);
hdr->set_distribution_type(mDistributionType); hdr->distribution_type = mDistributionType;
hdr->set_content_type(mContentType); hdr->content_type = mContentType;
hdr->set_key_generation(mEncryptionType); hdr->key_generation = mEncryptionType;
hdr->set_key_area_encryption_key_index(mKeyIndex); hdr->key_area_encryption_key_index = mKeyIndex;
hdr->set_nca_size(mNcaSize); hdr->nca_size = mNcaSize;
hdr->set_program_id(mProgramId); hdr->program_id = mProgramId;
hdr->set_content_index(mContentIndex); hdr->content_index = mContentIndex;
hdr->set_sdk_addon_version(mSdkAddonVersion); hdr->sdk_addon_version = mSdkAddonVersion;
// TODO: properly reconstruct NCA layout? atm in hands of user // TODO: properly reconstruct NCA layout? atm in hands of user
@ -25,15 +25,15 @@ void NcaHeader::exportBinary()
// determine section index // determine section index
u8 section = mSections.getSize() - 1 - i; u8 section = mSections.getSize() - 1 - i;
hdr->section(section).set_start(sizeToBlockNum(mSections[i].offset)); hdr->section[section].start = sizeToBlockNum(mSections[i].offset);
hdr->section(section).set_end(sizeToBlockNum(mSections[i].offset) + sizeToBlockNum(mSections[i].size)); hdr->section[section].end = (sizeToBlockNum(mSections[i].offset) + sizeToBlockNum(mSections[i].size));
hdr->section(section).set_enabled(1); hdr->section[section].enabled = true;
hdr->section_hash(section) = mSections[i].hash; hdr->section_hash[section] = mSections[i].hash;
} }
for (size_t i = 0; i < kAesKeyNum; i++) for (size_t i = 0; i < kAesKeyNum; i++)
{ {
hdr->enc_aes_key(i) = mEncAesKeys[i]; hdr->enc_aes_key[i] = mEncAesKeys[i];
} }
} }
@ -51,19 +51,19 @@ void NcaHeader::importBinary(const u8 * bytes, size_t len)
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes(); sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
if (memcmp(hdr->signature(), kNcaSig.c_str(), 4) != 0) if (memcmp(hdr->signature, kNcaSig.c_str(), 4) != 0)
{ {
throw fnd::Exception(kModuleName, "NCA header corrupt"); throw fnd::Exception(kModuleName, "NCA header corrupt");
} }
mDistributionType = (DistributionType)hdr->distribution_type(); mDistributionType = (DistributionType)hdr->distribution_type;
mContentType = (ContentType)hdr->content_type(); mContentType = (ContentType)hdr->content_type;
mEncryptionType = (EncryptionType)hdr->key_generation(); mEncryptionType = (EncryptionType)hdr->key_generation;
mKeyIndex = (EncryptionKeyIndex)hdr->key_area_encryption_key_index(); mKeyIndex = (EncryptionKeyIndex)hdr->key_area_encryption_key_index;
mNcaSize = hdr->nca_size(); mNcaSize = *hdr->nca_size;
mProgramId = hdr->program_id(); mProgramId = *hdr->program_id;
mContentIndex = hdr->content_index(); mContentIndex = *hdr->content_index;
mSdkAddonVersion = hdr->sdk_addon_version(); mSdkAddonVersion = *hdr->sdk_addon_version;
for (size_t i = 0; i < kSectionNum; i++) for (size_t i = 0; i < kSectionNum; i++)
{ {
@ -71,7 +71,7 @@ void NcaHeader::importBinary(const u8 * bytes, size_t len)
u8 section = kSectionNum - 1 - i; u8 section = kSectionNum - 1 - i;
// skip sections that don't exist // skip sections that don't exist
if (hdr->section(section).start() == 0 && hdr->section(section).end() == 0) continue; if (*hdr->section[section].start == 0 && *hdr->section[section].end == 0) continue;
EncryptionType encType = mEncryptionType; EncryptionType encType = mEncryptionType;
if (encType == CRYPT_AUTO) if (encType == CRYPT_AUTO)
@ -87,12 +87,12 @@ void NcaHeader::importBinary(const u8 * bytes, size_t len)
} }
// add high level struct // add high level struct
mSections.addElement({ blockNumToSize(hdr->section(section).start()), blockNumToSize(hdr->section(section).end() - hdr->section(section).start()), encType, hdr->section_hash(section) }); mSections.addElement({ blockNumToSize(*hdr->section[section].start), blockNumToSize(hdr->section[section].end.get() - hdr->section[section].start.get()), encType, hdr->section_hash[section] });
} }
for (size_t i = 0; i < kAesKeyNum; i++) for (size_t i = 0; i < kAesKeyNum; i++)
{ {
mEncAesKeys.addElement(hdr->enc_aes_key(i)); mEncAesKeys.addElement(hdr->enc_aes_key[i]);
} }
} }