[nx|nstool] Updated FacBinary design.

This commit is contained in:
jakcron 2018-06-24 23:56:55 +08:00
parent 48ac29f3ce
commit c4c2610417
3 changed files with 51 additions and 34 deletions

View file

@ -1,13 +1,13 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <nx/FacHeader.h> #include <nx/fac.h>
namespace nx namespace nx
{ {
class FacBinary : class FacBinary :
public FacHeader public fnd::ISerialisable
{ {
public: public:
FacBinary(); FacBinary();
@ -25,6 +25,9 @@ namespace nx
// variables // variables
void clear(); void clear();
const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const;
void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list);
const fnd::List<uint32_t>& getContentOwnerIdList() const; const fnd::List<uint32_t>& getContentOwnerIdList() const;
void setContentOwnerIdList(const fnd::List<uint32_t>& list); void setContentOwnerIdList(const fnd::List<uint32_t>& list);
@ -33,12 +36,12 @@ namespace nx
private: private:
const std::string kModuleName = "FAC_BINARY"; const std::string kModuleName = "FAC_BINARY";
static const uint32_t kFacFormatVersion = 1;
// raw binary // raw binary
fnd::Vec<byte_t> mRawBinary; fnd::Vec<byte_t> mRawBinary;
// variables // variables
fnd::List<fac::FsAccessFlag> mFsaRights;
fnd::List<uint32_t> mContentOwnerIdList; fnd::List<uint32_t> mContentOwnerIdList;
fnd::List<uint32_t> mSaveDataOwnerIdList; fnd::List<uint32_t> mSaveDataOwnerIdList;
}; };

View file

@ -1,4 +1,5 @@
#include <nx/FacBinary.h> #include <nx/FacBinary.h>
#include <nx/FacHeader.h>
nx::FacBinary::FacBinary() nx::FacBinary::FacBinary()
{ {
@ -19,7 +20,7 @@ void nx::FacBinary::operator=(const FacBinary & other)
else else
{ {
clear(); clear();
FacHeader::operator=(other); mFsaRights = other.mFsaRights;
mContentOwnerIdList = other.mContentOwnerIdList; mContentOwnerIdList = other.mContentOwnerIdList;
mSaveDataOwnerIdList = other.mSaveDataOwnerIdList; mSaveDataOwnerIdList = other.mSaveDataOwnerIdList;
} }
@ -27,7 +28,7 @@ void nx::FacBinary::operator=(const FacBinary & other)
bool nx::FacBinary::operator==(const FacBinary & other) const bool nx::FacBinary::operator==(const FacBinary & other) const
{ {
return (FacHeader::operator==(other)) \ return (mFsaRights == other.mFsaRights) \
&& (mContentOwnerIdList == other.mContentOwnerIdList) \ && (mContentOwnerIdList == other.mContentOwnerIdList) \
&& (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList); && (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList);
} }
@ -39,20 +40,24 @@ bool nx::FacBinary::operator!=(const FacBinary & other) const
void nx::FacBinary::toBytes() void nx::FacBinary::toBytes()
{ {
FacHeader::setContentOwnerIdSize(mContentOwnerIdList.size() * sizeof(uint32_t)); FacHeader hdr;
FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.size() * sizeof(uint32_t));
FacHeader::toBytes();
mRawBinary.alloc(getFacSize()); hdr.setFormatVersion(fac::kFacFormatVersion);
memcpy(mRawBinary.data(), FacHeader::getBytes().data(), FacHeader::getBytes().size()); hdr.setFsaRightsList(mFsaRights);
hdr.setContentOwnerIdSize(mContentOwnerIdList.size() * sizeof(uint32_t));
hdr.setSaveDataOwnerIdSize(mSaveDataOwnerIdList.size() * sizeof(uint32_t));
hdr.toBytes();
uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getContentOwnerIdPos().offset); mRawBinary.alloc(hdr.getFacSize());
memcpy(mRawBinary.data(), hdr.getBytes().data(), hdr.getBytes().size());
uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + hdr.getContentOwnerIdPos().offset);
for (size_t i = 0; i < mContentOwnerIdList.size(); i++) for (size_t i = 0; i < mContentOwnerIdList.size(); i++)
{ {
rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]); rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]);
} }
uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getSaveDataOwnerIdPos().offset); uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + hdr.getSaveDataOwnerIdPos().offset);
for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++) for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++)
{ {
rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]); rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]);
@ -62,24 +67,29 @@ void nx::FacBinary::toBytes()
void nx::FacBinary::fromBytes(const byte_t* data, size_t len) void nx::FacBinary::fromBytes(const byte_t* data, size_t len)
{ {
clear(); clear();
FacHeader::fromBytes(data, len);
if (FacHeader::getFacSize() > len) FacHeader hdr;
hdr.fromBytes(data, len);
mFsaRights = hdr.getFsaRightsList();
if (hdr.getFacSize() > len)
{ {
throw fnd::Exception(kModuleName, "FAC binary too small"); throw fnd::Exception(kModuleName, "FAC binary too small");
} }
mRawBinary.alloc(FacHeader::getFacSize()); mRawBinary.alloc(hdr.getFacSize());
memcpy(mRawBinary.data(), data, mRawBinary.size()); memcpy(mRawBinary.data(), data, mRawBinary.size());
uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getContentOwnerIdPos().offset); uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + hdr.getContentOwnerIdPos().offset);
size_t rawContentOwnerIdNum = FacHeader::getContentOwnerIdPos().size / sizeof(uint32_t); size_t rawContentOwnerIdNum = hdr.getContentOwnerIdPos().size / sizeof(uint32_t);
for (size_t i = 0; i < rawContentOwnerIdNum; i++) for (size_t i = 0; i < rawContentOwnerIdNum; i++)
{ {
mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i])); mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i]));
} }
uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getSaveDataOwnerIdPos().offset); uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + hdr.getSaveDataOwnerIdPos().offset);
size_t rawSaveDataOwnerIdNum = FacHeader::getSaveDataOwnerIdPos().size / sizeof(uint32_t); size_t rawSaveDataOwnerIdNum = hdr.getSaveDataOwnerIdPos().size / sizeof(uint32_t);
for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++) for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++)
{ {
mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i])); mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i]));
@ -93,12 +103,25 @@ const fnd::Vec<byte_t>& nx::FacBinary::getBytes() const
void nx::FacBinary::clear() void nx::FacBinary::clear()
{ {
FacHeader::clear();
mRawBinary.clear(); mRawBinary.clear();
mContentOwnerIdList.clear(); mContentOwnerIdList.clear();
mSaveDataOwnerIdList.clear(); mSaveDataOwnerIdList.clear();
} }
const fnd::List<nx::fac::FsAccessFlag>& nx::FacBinary::getFsaRightsList() const
{
return mFsaRights;
}
void nx::FacBinary::setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list)
{
mFsaRights.clear();
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");
}
}
const fnd::List<uint32_t>& nx::FacBinary::getContentOwnerIdList() const const fnd::List<uint32_t>& nx::FacBinary::getContentOwnerIdList() const
{ {
return mContentOwnerIdList; return mContentOwnerIdList;

View file

@ -316,12 +316,6 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
printf("[WARNING] ACI ProgramId: FAIL (Outside Legal Range)\n"); printf("[WARNING] ACI ProgramId: FAIL (Outside Legal Range)\n");
} }
// Check FAC
if (aci.getFac().getFormatVersion() != acid.getFac().getFormatVersion())
{
printf("[WARNING] ACI/FAC FormatVersion: FAIL (%d != %d (expected))\n", aci.getFac().getFormatVersion(),acid.getFac().getFormatVersion());
}
for (size_t i = 0; i < aci.getFac().getFsaRightsList().size(); i++) for (size_t i = 0; i < aci.getFac().getFsaRightsList().size(); i++)
{ {
bool fsaRightFound = false; bool fsaRightFound = false;
@ -382,7 +376,6 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
if (rightFound == false) if (rightFound == false)
{ {
printf("[WARNING] ACI/SAC ServiceList: FAIL (%s%s not permitted)\n", aci.getSac().getServiceList()[i].getName().c_str(), aci.getSac().getServiceList()[i].isServer()? " (Server)" : ""); printf("[WARNING] ACI/SAC ServiceList: FAIL (%s%s not permitted)\n", aci.getSac().getServiceList()[i].getName().c_str(), aci.getSac().getServiceList()[i].isServer()? " (Server)" : "");
} }
} }
@ -391,19 +384,19 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
// check thread info // check thread info
if (aci.getKc().getThreadInfo().getMaxCpuId() != acid.getKc().getThreadInfo().getMaxCpuId()) if (aci.getKc().getThreadInfo().getMaxCpuId() != acid.getKc().getThreadInfo().getMaxCpuId())
{ {
printf("[WARNING] ACI/KC ThreadInfo/MaxCpuId: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMaxCpuId()); printf("[WARNING] ACI/KC ThreadInfo/MaxCpuId: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMaxCpuId());
} }
if (aci.getKc().getThreadInfo().getMinCpuId() != acid.getKc().getThreadInfo().getMinCpuId()) if (aci.getKc().getThreadInfo().getMinCpuId() != acid.getKc().getThreadInfo().getMinCpuId())
{ {
printf("[WARNING] ACI/KC ThreadInfo/MinCpuId: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinCpuId()); printf("[WARNING] ACI/KC ThreadInfo/MinCpuId: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinCpuId());
} }
if (aci.getKc().getThreadInfo().getMaxPriority() != acid.getKc().getThreadInfo().getMaxPriority()) if (aci.getKc().getThreadInfo().getMaxPriority() != acid.getKc().getThreadInfo().getMaxPriority())
{ {
printf("[WARNING] ACI/KC ThreadInfo/MaxPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMaxPriority()); printf("[WARNING] ACI/KC ThreadInfo/MaxPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMaxPriority());
} }
if (aci.getKc().getThreadInfo().getMinPriority() != acid.getKc().getThreadInfo().getMinPriority()) if (aci.getKc().getThreadInfo().getMinPriority() != acid.getKc().getThreadInfo().getMinPriority())
{ {
printf("[WARNING] ACI/KC ThreadInfo/MinPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinPriority()); printf("[WARNING] ACI/KC ThreadInfo/MinPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinPriority());
} }
// check system calls // check system calls
for (size_t i = 0; i < aci.getKc().getSystemCalls().getSystemCalls().size(); i++) for (size_t i = 0; i < aci.getKc().getSystemCalls().getSystemCalls().size(); i++)
@ -417,7 +410,6 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
if (rightFound == false) if (rightFound == false)
{ {
printf("[WARNING] ACI/KC SystemCallList: FAIL (%s not permitted)\n", kSysCall[aci.getKc().getSystemCalls().getSystemCalls()[i]].c_str()); printf("[WARNING] ACI/KC SystemCallList: FAIL (%s not permitted)\n", kSysCall[aci.getKc().getSystemCalls().getSystemCalls()[i]].c_str());
} }
} }
@ -547,7 +539,6 @@ void NpdmProcess::displayAciHdr(const nx::AciHeader& aci)
void NpdmProcess::displayFac(const nx::FacBinary& fac) void NpdmProcess::displayFac(const nx::FacBinary& fac)
{ {
printf("[FS Access Control]\n"); printf("[FS Access Control]\n");
printf(" Format Version: %d\n", fac.getFormatVersion());
if (fac.getFsaRightsList().size()) if (fac.getFsaRightsList().size())
{ {