mirror of
https://github.com/jakcron/nstool
synced 2024-11-15 02:06:40 +00:00
Use ISerialiseablePrimative types in NcaHeader
This commit is contained in:
parent
c5c71873b9
commit
e293b322c0
2 changed files with 50 additions and 90 deletions
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue