mirror of
https://github.com/jakcron/nstool.git
synced 2024-12-22 18:55:29 +00:00
Merge pull request #8 from jakcron/npdm-development
[nx|nstool] Updated npdm->aci flag information. Also corrected some bugs
This commit is contained in:
commit
2b11b434b6
|
@ -78,6 +78,8 @@ namespace nx
|
|||
void setAciType(AciType type);
|
||||
bool isProduction() const;
|
||||
void setIsProduction(bool isProduction);
|
||||
bool isUnqualifiedApproval() const;
|
||||
void setIsUnqualifiedApproval(bool isUnqualifiedApproval);
|
||||
const sSection& getFacPos() const;
|
||||
void setFacSize(size_t size);
|
||||
const sSection& getSacPos() const;
|
||||
|
@ -103,6 +105,7 @@ namespace nx
|
|||
size_t mHeaderOffset;
|
||||
AciType mType;
|
||||
bool mIsProduction;
|
||||
bool mIsUnqualifiedApproval;
|
||||
sSection mFac, mSac, mKc;
|
||||
|
||||
void calculateSectionOffsets();
|
||||
|
|
|
@ -12,56 +12,34 @@ namespace nx
|
|||
const std::string kAciStructSig = "ACI0";
|
||||
const std::string kAciDescStructSig = "ACID";
|
||||
static const size_t kAciAlignSize = 0x10;
|
||||
|
||||
enum Flags
|
||||
{
|
||||
FLAG_PRODUCTION,
|
||||
FLAG_UNQUALIFIED_APPROVAL
|
||||
};
|
||||
}
|
||||
#pragma pack(push,1)
|
||||
struct sAciHeader
|
||||
{
|
||||
private:
|
||||
byte_t signature_[4];
|
||||
uint32_t size_; // includes prefacing signature, set only in ACID made by SDK (it enables easy resigning)
|
||||
char signature[4];
|
||||
le_uint32_t size; // includes prefacing signature, set only in ACID made by SDK (it enables easy resigning)
|
||||
byte_t reserved_0[4];
|
||||
uint32_t flags_; // set in ACID only
|
||||
uint64_t program_id_; // set only in ACI0 (since ACID is generic)
|
||||
uint64_t program_id_max_;
|
||||
le_uint32_t flags; // set in ACID only
|
||||
union uProgramIdInfo
|
||||
{
|
||||
struct sRestrictProgramId
|
||||
{
|
||||
le_uint64_t min;
|
||||
le_uint64_t max;
|
||||
} program_id_restrict;
|
||||
le_uint64_t program_id;
|
||||
} program_id_info;
|
||||
struct sAciSection
|
||||
{
|
||||
private:
|
||||
uint32_t offset_; // aligned by 0x10 from the last one
|
||||
uint32_t size_;
|
||||
public:
|
||||
uint32_t offset() const { return le_word(offset_); }
|
||||
void set_offset(uint32_t offset) { offset_ = le_word(offset); }
|
||||
|
||||
uint32_t size() const { return le_word(size_); }
|
||||
void set_size(uint32_t size) { size_ = le_word(size); }
|
||||
} fac_, sac_, kc_;
|
||||
public:
|
||||
const char* signature() const { return (const char*)signature_; }
|
||||
void set_signature(const char* signature) { memcpy(signature_, signature, 4); }
|
||||
|
||||
uint32_t size() const { return le_word(size_); }
|
||||
void set_size(uint32_t size) { size_ = le_word(size); }
|
||||
|
||||
uint32_t flags() const { return le_word(flags_); }
|
||||
void set_flags(uint32_t flags) { flags_ = le_word(flags); }
|
||||
|
||||
uint64_t program_id() const { return le_dword(program_id_); }
|
||||
void set_program_id(uint64_t program_id) { program_id_ = le_dword(program_id); }
|
||||
|
||||
uint64_t program_id_min() const { return program_id(); }
|
||||
void set_program_id_min(uint64_t program_id) { set_program_id(program_id); }
|
||||
|
||||
uint64_t program_id_max() const { return le_dword(program_id_max_); }
|
||||
void set_program_id_max(uint64_t program_id) { program_id_max_ = le_dword(program_id); }
|
||||
|
||||
const sAciSection& fac() const { return fac_; }
|
||||
sAciSection& fac() { return fac_; }
|
||||
|
||||
const sAciSection& sac() const { return sac_; }
|
||||
sAciSection& sac() { return sac_; }
|
||||
|
||||
const sAciSection& kc() const { return kc_; }
|
||||
sAciSection& kc() { return kc_; }
|
||||
le_uint32_t offset; // aligned by 0x10 from the last one
|
||||
le_uint32_t size;
|
||||
} fac, sac, kc;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
|
@ -13,7 +13,11 @@ bool AciHeader::isEqual(const AciHeader & other) const
|
|||
{
|
||||
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) \
|
||||
|
@ -30,7 +34,11 @@ void AciHeader::copyFrom(const AciHeader & other)
|
|||
{
|
||||
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;
|
||||
|
@ -87,10 +95,10 @@ void AciHeader::exportBinary()
|
|||
switch (mType)
|
||||
{
|
||||
case (TYPE_ACI0):
|
||||
hdr->set_signature(aci::kAciStructSig.c_str());
|
||||
memcpy(hdr->signature, aci::kAciStructSig.c_str(), 4);
|
||||
break;
|
||||
case (TYPE_ACID):
|
||||
hdr->set_signature(aci::kAciDescStructSig.c_str());
|
||||
memcpy(hdr->signature, aci::kAciDescStructSig.c_str(), 4);
|
||||
break;
|
||||
default:
|
||||
throw fnd::Exception(kModuleName, "Unexpected ACI type");
|
||||
|
@ -98,30 +106,32 @@ void AciHeader::exportBinary()
|
|||
|
||||
// set offset/size
|
||||
calculateSectionOffsets();
|
||||
hdr->fac().set_offset(mFac.offset);
|
||||
hdr->fac().set_size(mFac.size);
|
||||
hdr->sac().set_offset(mSac.offset);
|
||||
hdr->sac().set_size(mSac.size);
|
||||
hdr->kc().set_offset(mKc.offset);
|
||||
hdr->kc().set_size(mKc.size);
|
||||
hdr->fac.offset = mFac.offset;
|
||||
hdr->fac.size = mFac.size;
|
||||
hdr->sac.offset = mSac.offset;
|
||||
hdr->sac.size = mSac.size;
|
||||
hdr->kc.offset = mKc.offset;
|
||||
hdr->kc.size = mKc.size;
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (mIsProduction)
|
||||
flags |= BIT(0);
|
||||
flags |= _BIT(aci::FLAG_PRODUCTION);
|
||||
if (mIsProduction)
|
||||
flags |= _BIT(aci::FLAG_UNQUALIFIED_APPROVAL);
|
||||
|
||||
hdr->set_flags(flags);
|
||||
hdr->flags = flags;
|
||||
|
||||
if (mType == TYPE_ACI0)
|
||||
{
|
||||
// set program
|
||||
hdr->set_program_id(mProgramId);
|
||||
hdr->program_id_info.program_id = mProgramId;
|
||||
}
|
||||
else if (mType == TYPE_ACID)
|
||||
{
|
||||
mAcidSize = getAciSize();
|
||||
hdr->set_size(mAcidSize);
|
||||
hdr->set_program_id_min(mProgramIdMin);
|
||||
hdr->set_program_id_max(mProgramIdMax);
|
||||
hdr->size = mAcidSize;
|
||||
hdr->program_id_info.program_id_restrict.min = mProgramIdMin;
|
||||
hdr->program_id_info.program_id_restrict.max = mProgramIdMax;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,11 +149,11 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
|
|||
|
||||
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
|
||||
|
||||
if (memcmp(hdr->signature(), aci::kAciStructSig.c_str(), 4) == 0)
|
||||
if (std::string(hdr->signature, 4) == aci::kAciStructSig)
|
||||
{
|
||||
mType = TYPE_ACI0;
|
||||
}
|
||||
else if (memcmp(hdr->signature(), aci::kAciDescStructSig.c_str(), 4) == 0)
|
||||
else if (std::string(hdr->signature, 4) == aci::kAciDescStructSig)
|
||||
{
|
||||
mType = TYPE_ACID;
|
||||
}
|
||||
|
@ -155,8 +165,9 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
|
|||
|
||||
if (mType == TYPE_ACI0)
|
||||
{
|
||||
mProgramId = hdr->program_id();
|
||||
mProgramId = hdr->program_id_info.program_id.get();
|
||||
mIsProduction = false;
|
||||
mIsUnqualifiedApproval = false;
|
||||
mAcidSize = 0;
|
||||
mProgramIdMin = 0;
|
||||
mProgramIdMax = 0;
|
||||
|
@ -164,21 +175,22 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
|
|||
else if (mType == TYPE_ACID)
|
||||
{
|
||||
mProgramId = 0;
|
||||
mIsProduction = (hdr->flags() & BIT(0)) == BIT(0);
|
||||
mAcidSize = hdr->size();
|
||||
mProgramIdMin = hdr->program_id_min();
|
||||
mProgramIdMax = hdr->program_id_max();
|
||||
mIsProduction = _HAS_BIT(hdr->flags.get(), aci::FLAG_PRODUCTION);
|
||||
mIsUnqualifiedApproval = _HAS_BIT(hdr->flags.get(), aci::FLAG_UNQUALIFIED_APPROVAL);
|
||||
mAcidSize = hdr->size.get();
|
||||
mProgramIdMin = hdr->program_id_info.program_id_restrict.min.get();
|
||||
mProgramIdMax = hdr->program_id_info.program_id_restrict.max.get();
|
||||
}
|
||||
|
||||
// the header offset is the MIN(sac.offset, fac.offset, kc.offset) - sizeof(sHeader)
|
||||
mHeaderOffset = MAX(MIN(hdr->sac().offset(), MIN(hdr->fac().offset(), hdr->kc().offset())), align(sizeof(sAciHeader), aci::kAciAlignSize)) - align(sizeof(sAciHeader), aci::kAciAlignSize);
|
||||
mHeaderOffset = MAX(MIN(hdr->sac.offset.get(), MIN(hdr->fac.offset.get(), hdr->kc.offset.get())), align(sizeof(sAciHeader), aci::kAciAlignSize)) - align(sizeof(sAciHeader), aci::kAciAlignSize);
|
||||
|
||||
mFac.offset = hdr->fac().offset() - mHeaderOffset;
|
||||
mFac.size = hdr->fac().size();
|
||||
mSac.offset = hdr->sac().offset() - mHeaderOffset;
|
||||
mSac.size = hdr->sac().size();
|
||||
mKc.offset = hdr->kc().offset() - mHeaderOffset;
|
||||
mKc.size = hdr->kc().size();
|
||||
mFac.offset = hdr->fac.offset.get() - mHeaderOffset;
|
||||
mFac.size = hdr->fac.size.get();
|
||||
mSac.offset = hdr->sac.offset.get() - mHeaderOffset;
|
||||
mSac.size = hdr->sac.size.get();
|
||||
mKc.offset = hdr->kc.offset.get() - mHeaderOffset;
|
||||
mKc.size = hdr->kc.size.get();
|
||||
}
|
||||
|
||||
void nx::AciHeader::clear()
|
||||
|
@ -191,6 +203,7 @@ void nx::AciHeader::clear()
|
|||
mProgramIdMax = 0;
|
||||
mAcidSize = 0;
|
||||
mIsProduction = false;
|
||||
mIsUnqualifiedApproval = false;
|
||||
mFac.offset = 0;
|
||||
mFac.size = 0;
|
||||
mSac.offset = 0;
|
||||
|
@ -261,6 +274,16 @@ void nx::AciHeader::setIsProduction(bool isProduction)
|
|||
mIsProduction = isProduction;
|
||||
}
|
||||
|
||||
bool nx::AciHeader::isUnqualifiedApproval() const
|
||||
{
|
||||
return mIsUnqualifiedApproval;
|
||||
}
|
||||
|
||||
void nx::AciHeader::setIsUnqualifiedApproval(bool isUnqualifiedApproval)
|
||||
{
|
||||
mIsUnqualifiedApproval = isUnqualifiedApproval;
|
||||
}
|
||||
|
||||
uint64_t AciHeader::getProgramId() const
|
||||
{
|
||||
return mProgramId;
|
||||
|
|
|
@ -465,7 +465,9 @@ void NpdmProcess::displayAciHdr(const nx::AciHeader& aci)
|
|||
{
|
||||
|
||||
printf(" ACID Size: %" PRIx64 "\n", aci.getAcidSize());
|
||||
printf(" Target: %s\n", kAcidTarget[aci.isProduction()].c_str());
|
||||
printf(" Flags: \n");
|
||||
printf(" Production: %s\n", aci.isProduction() ? "TRUE" : "FALSE");
|
||||
printf(" UnqualifiedApproval: %s\n", aci.isUnqualifiedApproval() ? "TRUE" : "FALSE");
|
||||
printf(" ProgramID Restriction\n");
|
||||
printf(" Min: %016" PRIx64 "\n", aci.getProgramIdMin());
|
||||
printf(" Max: %016" PRIx64 "\n", aci.getProgramIdMax());
|
||||
|
|
Loading…
Reference in a new issue