mirror of
https://github.com/jakcron/nstool
synced 2024-11-15 02:06:40 +00:00
Merge pull request #34 from jakcron/master
Bring across changes to nstool-esfiletypes branch
This commit is contained in:
commit
2f9cba6d40
15 changed files with 249 additions and 131 deletions
|
@ -11,6 +11,29 @@ namespace nx
|
||||||
class FileSystemAccessControlBinary : public fnd::ISerialisable
|
class FileSystemAccessControlBinary : public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct sSaveDataOwnerId
|
||||||
|
{
|
||||||
|
nx::fac::SaveDataOwnerIdAccessType access_type;
|
||||||
|
uint64_t id;
|
||||||
|
|
||||||
|
void operator=(const sSaveDataOwnerId& other)
|
||||||
|
{
|
||||||
|
access_type = other.access_type;
|
||||||
|
id = other.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const sSaveDataOwnerId& other) const
|
||||||
|
{
|
||||||
|
return (access_type == other.access_type) \
|
||||||
|
&& (id == other.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const sSaveDataOwnerId& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
FileSystemAccessControlBinary();
|
FileSystemAccessControlBinary();
|
||||||
FileSystemAccessControlBinary(const FileSystemAccessControlBinary& other);
|
FileSystemAccessControlBinary(const FileSystemAccessControlBinary& other);
|
||||||
|
|
||||||
|
@ -32,11 +55,11 @@ namespace nx
|
||||||
const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const;
|
const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const;
|
||||||
void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list);
|
void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list);
|
||||||
|
|
||||||
const fnd::List<uint32_t>& getContentOwnerIdList() const;
|
const fnd::List<uint64_t>& getContentOwnerIdList() const;
|
||||||
void setContentOwnerIdList(const fnd::List<uint32_t>& list);
|
void setContentOwnerIdList(const fnd::List<uint64_t>& list);
|
||||||
|
|
||||||
const fnd::List<uint32_t>& getSaveDataOwnerIdList() const;
|
const fnd::List<sSaveDataOwnerId>& getSaveDataOwnerIdList() const;
|
||||||
void setSaveDataOwnerIdList(const fnd::List<uint32_t>& list);
|
void setSaveDataOwnerIdList(const fnd::List<sSaveDataOwnerId>& list);
|
||||||
private:
|
private:
|
||||||
const std::string kModuleName = "FILE_SYSTEM_ACCESS_CONTROL_BINARY";
|
const std::string kModuleName = "FILE_SYSTEM_ACCESS_CONTROL_BINARY";
|
||||||
|
|
||||||
|
@ -46,7 +69,7 @@ namespace nx
|
||||||
// variables
|
// variables
|
||||||
uint32_t mVersion;
|
uint32_t mVersion;
|
||||||
fnd::List<fac::FsAccessFlag> mFsaRights;
|
fnd::List<fac::FsAccessFlag> mFsaRights;
|
||||||
fnd::List<uint32_t> mContentOwnerIdList;
|
fnd::List<uint64_t> mContentOwnerIdList;
|
||||||
fnd::List<uint32_t> mSaveDataOwnerIdList;
|
fnd::List<sSaveDataOwnerId> mSaveDataOwnerIdList;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -33,6 +33,13 @@ namespace nx
|
||||||
FSA_DEBUG = 62,
|
FSA_DEBUG = 62,
|
||||||
FSA_FULL_PERMISSION = 63,
|
FSA_FULL_PERMISSION = 63,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SaveDataOwnerIdAccessType
|
||||||
|
{
|
||||||
|
SDO_READ = 1,
|
||||||
|
SDO_WRITE,
|
||||||
|
SDO_READWRITE
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
|
@ -42,8 +49,8 @@ namespace nx
|
||||||
le_uint64_t fac_flags;
|
le_uint64_t fac_flags;
|
||||||
struct sFacSection
|
struct sFacSection
|
||||||
{
|
{
|
||||||
le_uint32_t start;
|
le_uint32_t offset;
|
||||||
le_uint32_t end;
|
le_uint32_t size;
|
||||||
} content_owner_ids, save_data_owner_ids; // the data for these follow later in binary. start/end relative to base of FacData instance
|
} 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)
|
#pragma pack(pop)
|
||||||
|
|
|
@ -48,11 +48,11 @@ void nx::AccessControlInfoBinary::toBytes()
|
||||||
uint32_t offset, size;
|
uint32_t offset, size;
|
||||||
} fac, sac, kc;
|
} fac, sac, kc;
|
||||||
|
|
||||||
fac.offset = align(sizeof(sAciHeader), aci::kSectionAlignSize);
|
fac.offset = (uint32_t)align(sizeof(sAciHeader), aci::kSectionAlignSize);
|
||||||
fac.size = (uint32_t)mFileSystemAccessControl.getBytes().size();
|
fac.size = (uint32_t)mFileSystemAccessControl.getBytes().size();
|
||||||
sac.offset = align(fac.offset + fac.size, aci::kSectionAlignSize);
|
sac.offset = (uint32_t)align(fac.offset + fac.size, aci::kSectionAlignSize);
|
||||||
sac.size = (uint32_t)mServiceAccessControl.getBytes().size();
|
sac.size = (uint32_t)mServiceAccessControl.getBytes().size();
|
||||||
kc.offset = align(sac.offset + sac.size, aci::kSectionAlignSize);
|
kc.offset = (uint32_t)align(sac.offset + sac.size, aci::kSectionAlignSize);
|
||||||
kc.size = (uint32_t)mKernelCapabilities.getBytes().size();
|
kc.size = (uint32_t)mKernelCapabilities.getBytes().size();
|
||||||
|
|
||||||
// get total size
|
// get total size
|
||||||
|
|
|
@ -52,11 +52,11 @@ void nx::AccessControlInfoDescBinary::toBytes()
|
||||||
uint32_t offset, size;
|
uint32_t offset, size;
|
||||||
} fac, sac, kc;
|
} fac, sac, kc;
|
||||||
|
|
||||||
fac.offset = align(sizeof(sAciDescHeader), aci::kSectionAlignSize);
|
fac.offset = (uint32_t)align(sizeof(sAciDescHeader), aci::kSectionAlignSize);
|
||||||
fac.size = (uint32_t)mFileSystemAccessControl.getBytes().size();
|
fac.size = (uint32_t)mFileSystemAccessControl.getBytes().size();
|
||||||
sac.offset = align(fac.offset + fac.size, aci::kSectionAlignSize);
|
sac.offset = (uint32_t)align(fac.offset + fac.size, aci::kSectionAlignSize);
|
||||||
sac.size = (uint32_t)mServiceAccessControl.getBytes().size();
|
sac.size = (uint32_t)mServiceAccessControl.getBytes().size();
|
||||||
kc.offset = align(sac.offset + sac.size, aci::kSectionAlignSize);
|
kc.offset = (uint32_t)align(sac.offset + sac.size, aci::kSectionAlignSize);
|
||||||
kc.size = (uint32_t)mKernelCapabilities.getBytes().size();
|
kc.size = (uint32_t)mKernelCapabilities.getBytes().size();
|
||||||
|
|
||||||
// get total size
|
// get total size
|
||||||
|
@ -72,7 +72,7 @@ void nx::AccessControlInfoDescBinary::toBytes()
|
||||||
hdr->st_magic = aci::kAciDescStructMagic;
|
hdr->st_magic = aci::kAciDescStructMagic;
|
||||||
|
|
||||||
// set "acid size"
|
// set "acid size"
|
||||||
hdr->signed_size = total_size - crypto::rsa::kRsa2048Size;
|
hdr->signed_size = (uint32_t)(total_size - crypto::rsa::kRsa2048Size);
|
||||||
|
|
||||||
// set flags
|
// set flags
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
|
|
|
@ -41,10 +41,10 @@ void nx::FileSystemAccessControlBinary::toBytes()
|
||||||
uint32_t offset, size;
|
uint32_t offset, size;
|
||||||
} content, savedata;
|
} content, savedata;
|
||||||
|
|
||||||
content.offset = align(sizeof(sFacHeader), fac::kSectionAlignSize);
|
content.offset = (uint32_t)align(sizeof(sFacHeader), fac::kSectionAlignSize);
|
||||||
content.size = (uint32_t)(mContentOwnerIdList.size() * sizeof(uint32_t));
|
content.size = (uint32_t)(sizeof(uint32_t) + mContentOwnerIdList.size() * sizeof(uint64_t));
|
||||||
savedata.offset = content.offset + align(content.size, fac::kSectionAlignSize);
|
savedata.offset = (uint32_t)(content.offset + (content.size > 0 ? align(content.size, fac::kSectionAlignSize) : 0));
|
||||||
savedata.size = (uint32_t)(mSaveDataOwnerIdList.size() * sizeof(uint32_t));
|
savedata.size = (uint32_t)(sizeof(uint32_t) + align(mSaveDataOwnerIdList.size(), fac::kSectionAlignSize) + mSaveDataOwnerIdList.size() * sizeof(uint64_t));
|
||||||
|
|
||||||
// get total size
|
// get total size
|
||||||
size_t total_size = _MAX(_MAX(content.offset + content.size, savedata.offset + savedata.size), align(sizeof(sFacHeader), fac::kSectionAlignSize));
|
size_t total_size = _MAX(_MAX(content.offset + content.size, savedata.offset + savedata.size), align(sizeof(sFacHeader), fac::kSectionAlignSize));
|
||||||
|
@ -64,24 +64,30 @@ void nx::FileSystemAccessControlBinary::toBytes()
|
||||||
hdr->fac_flags = flag;
|
hdr->fac_flags = flag;
|
||||||
|
|
||||||
// set offset/size
|
// set offset/size
|
||||||
hdr->content_owner_ids.start = content.offset;
|
hdr->content_owner_ids.offset = content.offset;
|
||||||
if (content.size > 0)
|
if (content.size > 0)
|
||||||
hdr->content_owner_ids.end = content.offset + content.size;
|
hdr->content_owner_ids.size = content.size;
|
||||||
hdr->save_data_owner_ids.start = savedata.offset;
|
hdr->save_data_owner_ids.offset = savedata.offset;
|
||||||
if (savedata.size > 0)
|
if (savedata.size > 0)
|
||||||
hdr->save_data_owner_ids.end = savedata.offset + savedata.size;
|
hdr->save_data_owner_ids.size = savedata.size;
|
||||||
|
|
||||||
// set ids
|
// set ids
|
||||||
le_uint32_t* content_owner_ids = (le_uint32_t*)(mRawBinary.data() + content.offset);
|
le_uint32_t* content_owner_id_num = (le_uint32_t*)(mRawBinary.data() + content.offset);
|
||||||
|
le_uint64_t* content_owner_ids = (le_uint64_t*)(mRawBinary.data() + content.offset + sizeof(uint32_t));
|
||||||
|
content_owner_id_num->set((uint32_t)mContentOwnerIdList.size());
|
||||||
for (size_t i = 0; i < mContentOwnerIdList.size(); i++)
|
for (size_t i = 0; i < mContentOwnerIdList.size(); i++)
|
||||||
{
|
{
|
||||||
content_owner_ids[i] = mContentOwnerIdList[i];
|
content_owner_ids[i] = mContentOwnerIdList[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
le_uint32_t* save_data_owner_ids = (le_uint32_t*)(mRawBinary.data() + savedata.offset);
|
le_uint32_t* save_data_owner_id_num = (le_uint32_t*)(mRawBinary.data() + savedata.offset);
|
||||||
|
byte_t* save_data_owner_id_accessibility_array = (mRawBinary.data() + savedata.offset + sizeof(uint32_t));
|
||||||
|
le_uint64_t* save_data_owner_ids = (le_uint64_t*)(mRawBinary.data() + savedata.offset + sizeof(uint32_t) + align(mSaveDataOwnerIdList.size(), sizeof(uint32_t)));
|
||||||
|
save_data_owner_id_num->set((uint32_t)mSaveDataOwnerIdList.size());
|
||||||
for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++)
|
for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++)
|
||||||
{
|
{
|
||||||
save_data_owner_ids[i] = mSaveDataOwnerIdList[i];
|
save_data_owner_id_accessibility_array[i] = mSaveDataOwnerIdList[i].access_type;
|
||||||
|
save_data_owner_ids[i] = mSaveDataOwnerIdList[i].id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +113,7 @@ void nx::FileSystemAccessControlBinary::fromBytes(const byte_t* data, size_t len
|
||||||
}
|
}
|
||||||
|
|
||||||
// get total size
|
// get total size
|
||||||
size_t total_size = _MAX(_MAX(hdr.content_owner_ids.end.get(), hdr.save_data_owner_ids.end.get()), align(sizeof(sFacHeader), fac::kSectionAlignSize));
|
size_t total_size = _MAX(_MAX(hdr.content_owner_ids.offset.get() + hdr.content_owner_ids.size.get(), hdr.save_data_owner_ids.offset.get() + hdr.save_data_owner_ids.size.get()), align(sizeof(sFacHeader), fac::kSectionAlignSize));
|
||||||
|
|
||||||
// validate binary size
|
// validate binary size
|
||||||
if (len < total_size)
|
if (len < total_size)
|
||||||
|
@ -130,22 +136,23 @@ void nx::FileSystemAccessControlBinary::fromBytes(const byte_t* data, size_t len
|
||||||
}
|
}
|
||||||
|
|
||||||
// save ids
|
// save ids
|
||||||
if (hdr.content_owner_ids.end.get() > hdr.content_owner_ids.start.get())
|
if (hdr.content_owner_ids.size.get() > 0)
|
||||||
{
|
{
|
||||||
le_uint32_t* content_owner_ids = (le_uint32_t*)(mRawBinary.data() + hdr.content_owner_ids.start.get());
|
size_t content_owner_id_num = ((le_uint32_t*)(mRawBinary.data() + hdr.content_owner_ids.offset.get()))->get();
|
||||||
size_t content_owner_id_num = (hdr.content_owner_ids.end.get() - hdr.content_owner_ids.start.get()) / sizeof(uint32_t);
|
le_uint64_t* content_owner_ids = (le_uint64_t*)(mRawBinary.data() + hdr.content_owner_ids.offset.get() + sizeof(uint32_t));
|
||||||
for (size_t i = 0; i < content_owner_id_num; i++)
|
for (size_t i = 0; i < content_owner_id_num; i++)
|
||||||
{
|
{
|
||||||
mContentOwnerIdList.addElement(content_owner_ids[i].get());
|
mContentOwnerIdList.addElement(content_owner_ids[i].get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hdr.save_data_owner_ids.end.get() > hdr.save_data_owner_ids.start.get())
|
if (hdr.save_data_owner_ids.size.get() > 0)
|
||||||
{
|
{
|
||||||
le_uint32_t* save_data_owner_ids = (le_uint32_t*)(mRawBinary.data() + hdr.save_data_owner_ids.start.get());
|
size_t save_data_owner_id_num = ((le_uint32_t*)(mRawBinary.data() + hdr.save_data_owner_ids.offset.get()))->get();
|
||||||
size_t save_data_owner_id_num = (hdr.save_data_owner_ids.end.get() - hdr.save_data_owner_ids.start.get()) / sizeof(uint32_t);
|
byte_t* save_data_owner_id_accessibility_array = (mRawBinary.data() + hdr.save_data_owner_ids.offset.get() + sizeof(uint32_t));
|
||||||
|
le_uint64_t* save_data_owner_ids = (le_uint64_t*)(mRawBinary.data() + hdr.save_data_owner_ids.offset.get() + sizeof(uint32_t) + align(save_data_owner_id_num, fac::kSectionAlignSize));
|
||||||
for (size_t i = 0; i < save_data_owner_id_num; i++)
|
for (size_t i = 0; i < save_data_owner_id_num; i++)
|
||||||
{
|
{
|
||||||
mSaveDataOwnerIdList.addElement(save_data_owner_ids[i].get());
|
mSaveDataOwnerIdList.addElement({ (fac::SaveDataOwnerIdAccessType)save_data_owner_id_accessibility_array[i], save_data_owner_ids[i].get() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,22 +191,22 @@ void nx::FileSystemAccessControlBinary::setFsaRightsList(const fnd::List<fac::Fs
|
||||||
mFsaRights = list;
|
mFsaRights = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fnd::List<uint32_t>& nx::FileSystemAccessControlBinary::getContentOwnerIdList() const
|
const fnd::List<uint64_t>& nx::FileSystemAccessControlBinary::getContentOwnerIdList() const
|
||||||
{
|
{
|
||||||
return mContentOwnerIdList;
|
return mContentOwnerIdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::FileSystemAccessControlBinary::setContentOwnerIdList(const fnd::List<uint32_t>& list)
|
void nx::FileSystemAccessControlBinary::setContentOwnerIdList(const fnd::List<uint64_t>& list)
|
||||||
{
|
{
|
||||||
mContentOwnerIdList = list;
|
mContentOwnerIdList = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fnd::List<uint32_t>& nx::FileSystemAccessControlBinary::getSaveDataOwnerIdList() const
|
const fnd::List<nx::FileSystemAccessControlBinary::sSaveDataOwnerId>& nx::FileSystemAccessControlBinary::getSaveDataOwnerIdList() const
|
||||||
{
|
{
|
||||||
return mSaveDataOwnerIdList;
|
return mSaveDataOwnerIdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::FileSystemAccessControlBinary::setSaveDataOwnerIdList(const fnd::List<uint32_t>& list)
|
void nx::FileSystemAccessControlBinary::setSaveDataOwnerIdList(const fnd::List<sSaveDataOwnerId>& list)
|
||||||
{
|
{
|
||||||
mSaveDataOwnerIdList = list;
|
mSaveDataOwnerIdList = list;
|
||||||
}
|
}
|
|
@ -61,9 +61,9 @@ void nx::NpdmBinary::toBytes()
|
||||||
uint32_t offset, size;
|
uint32_t offset, size;
|
||||||
} acid, aci;
|
} acid, aci;
|
||||||
|
|
||||||
acid.offset = align(sizeof(sNpdmHeader), npdm::kSectionAlignSize);
|
acid.offset = (uint32_t)align(sizeof(sNpdmHeader), npdm::kSectionAlignSize);
|
||||||
acid.size = (uint32_t)mAcid.getBytes().size();
|
acid.size = (uint32_t)mAcid.getBytes().size();
|
||||||
aci.offset = acid.offset + align(acid.size, npdm::kSectionAlignSize);
|
aci.offset = (uint32_t)(acid.offset + align(acid.size, npdm::kSectionAlignSize));
|
||||||
aci.size = (uint32_t)mAci.getBytes().size();
|
aci.size = (uint32_t)mAci.getBytes().size();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,15 @@ const std::string kFsaFlag[64] =
|
||||||
"Debug",
|
"Debug",
|
||||||
"FullPermission"
|
"FullPermission"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::string kSaveDataOwnerAccessMode[4] =
|
||||||
|
{
|
||||||
|
"IllegalAccessCondition",
|
||||||
|
"Read",
|
||||||
|
"Write",
|
||||||
|
"ReadWrite"
|
||||||
|
};
|
||||||
|
|
||||||
const std::string kSysCall[0x80] =
|
const std::string kSysCall[0x80] =
|
||||||
{
|
{
|
||||||
"svc00",
|
"svc00",
|
||||||
|
@ -378,7 +387,7 @@ void NpdmProcess::validateAciFromAcid(const nx::AccessControlInfoBinary& aci, co
|
||||||
if (rightFound == false)
|
if (rightFound == false)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("[WARNING] ACI/FAC ContentOwnerId: FAIL (%08x not permitted)\n", aci.getFileSystemAccessControl().getContentOwnerIdList()[i]);
|
printf("[WARNING] ACI/FAC ContentOwnerId: FAIL (%016" PRIx64 " not permitted)\n", aci.getFileSystemAccessControl().getContentOwnerIdList()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +403,7 @@ void NpdmProcess::validateAciFromAcid(const nx::AccessControlInfoBinary& aci, co
|
||||||
if (rightFound == false)
|
if (rightFound == false)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("[WARNING] ACI/FAC ContentOwnerId: FAIL (%08x not permitted)\n", aci.getFileSystemAccessControl().getSaveDataOwnerIdList()[i]);
|
printf("[WARNING] ACI/FAC ContentOwnerId: FAIL (%016" PRIx64 "(%d) not permitted)\n", aci.getFileSystemAccessControl().getSaveDataOwnerIdList()[i].id, aci.getFileSystemAccessControl().getSaveDataOwnerIdList()[i].access_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,25 +599,22 @@ void NpdmProcess::displayFac(const nx::FileSystemAccessControlBinary& fac)
|
||||||
printf("%s", fac.getFsaRightsList()[i] != fac.getFsaRightsList().atBack() ? ", " : "\n");
|
printf("%s", fac.getFsaRightsList()[i] != fac.getFsaRightsList().atBack() ? ", " : "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(" FS Rights: NONE\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fac.getContentOwnerIdList().size())
|
if (fac.getContentOwnerIdList().size())
|
||||||
{
|
{
|
||||||
printf(" Content Owner IDs:\n");
|
printf(" Content Owner IDs:\n");
|
||||||
for (size_t i = 0; i < fac.getContentOwnerIdList().size(); i++)
|
for (size_t i = 0; i < fac.getContentOwnerIdList().size(); i++)
|
||||||
{
|
{
|
||||||
printf(" 0x%08x\n", fac.getContentOwnerIdList()[i]);
|
printf(" 0x%016" PRIx64 "\n", fac.getContentOwnerIdList()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fac.getSaveDataOwnerIdList().size())
|
if (fac.getSaveDataOwnerIdList().size())
|
||||||
{
|
{
|
||||||
printf(" Save Data Owner IDs:\n");
|
printf(" Save Data Owner IDs:\n");
|
||||||
for (size_t i = 0; i < fac.getSaveDataOwnerIdList().size(); i++)
|
for (size_t i = 0; i < fac.getSaveDataOwnerIdList().size(); i++)
|
||||||
{
|
{
|
||||||
printf(" 0x%08x\n", fac.getSaveDataOwnerIdList()[i]);
|
printf(" 0x%016" PRIx64 " (%s)\n", fac.getSaveDataOwnerIdList()[i].id, kSaveDataOwnerAccessMode[fac.getSaveDataOwnerIdList()[i].access_type].c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,11 @@ void NroProcess::setAssetRomfsExtractPath(const std::string& path)
|
||||||
mAssetProc.setRomfsExtractPath(path);
|
mAssetProc.setRomfsExtractPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RoMetadataProcess& NroProcess::getRoMetadataProcess() const
|
||||||
|
{
|
||||||
|
return mRoMeta;
|
||||||
|
}
|
||||||
|
|
||||||
void NroProcess::importHeader()
|
void NroProcess::importHeader()
|
||||||
{
|
{
|
||||||
fnd::Vec<byte_t> scratch;
|
fnd::Vec<byte_t> scratch;
|
||||||
|
|
|
@ -31,6 +31,8 @@ public:
|
||||||
void setAssetIconExtractPath(const std::string& path);
|
void setAssetIconExtractPath(const std::string& path);
|
||||||
void setAssetNacpExtractPath(const std::string& path);
|
void setAssetNacpExtractPath(const std::string& path);
|
||||||
void setAssetRomfsExtractPath(const std::string& path);
|
void setAssetRomfsExtractPath(const std::string& path);
|
||||||
|
|
||||||
|
const RoMetadataProcess& getRoMetadataProcess() const;
|
||||||
private:
|
private:
|
||||||
const std::string kModuleName = "NroProcess";
|
const std::string kModuleName = "NroProcess";
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,11 @@ void NsoProcess::setListSymbols(bool listSymbols)
|
||||||
mRoMeta.setListSymbols(listSymbols);
|
mRoMeta.setListSymbols(listSymbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RoMetadataProcess& NsoProcess::getRoMetadataProcess() const
|
||||||
|
{
|
||||||
|
return mRoMeta;
|
||||||
|
}
|
||||||
|
|
||||||
void NsoProcess::importHeader()
|
void NsoProcess::importHeader()
|
||||||
{
|
{
|
||||||
fnd::Vec<byte_t> scratch;
|
fnd::Vec<byte_t> scratch;
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
void setInstructionType(nx::npdm::InstructionType type);
|
void setInstructionType(nx::npdm::InstructionType type);
|
||||||
void setListApi(bool listApi);
|
void setListApi(bool listApi);
|
||||||
void setListSymbols(bool listSymbols);
|
void setListSymbols(bool listSymbols);
|
||||||
|
|
||||||
|
const RoMetadataProcess& getRoMetadataProcess() const;
|
||||||
private:
|
private:
|
||||||
const std::string kModuleName = "NsoProcess";
|
const std::string kModuleName = "NsoProcess";
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,31 @@ void RoMetadataProcess::setListSymbols(bool listSymbols)
|
||||||
mListSymbols = listSymbols;
|
mListSymbols = listSymbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<SdkApiString>& RoMetadataProcess::getSdkVerApiList() const
|
||||||
|
{
|
||||||
|
return mSdkVerApiList;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<SdkApiString>& RoMetadataProcess::getPublicApiList() const
|
||||||
|
{
|
||||||
|
return mPublicApiList;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<SdkApiString>& RoMetadataProcess::getDebugApiList() const
|
||||||
|
{
|
||||||
|
return mDebugApiList;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<SdkApiString>& RoMetadataProcess::getPrivateApiList() const
|
||||||
|
{
|
||||||
|
return mPrivateApiList;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::List<ElfSymbolParser::sElfSymbol>& RoMetadataProcess::getSymbolList() const
|
||||||
|
{
|
||||||
|
return mSymbolList.getSymbolList();
|
||||||
|
}
|
||||||
|
|
||||||
void RoMetadataProcess::importApiList()
|
void RoMetadataProcess::importApiList()
|
||||||
{
|
{
|
||||||
if (mApiInfo.size > 0)
|
if (mApiInfo.size > 0)
|
||||||
|
|
|
@ -27,6 +27,12 @@ public:
|
||||||
void setInstructionType(nx::npdm::InstructionType type);
|
void setInstructionType(nx::npdm::InstructionType type);
|
||||||
void setListApi(bool listApi);
|
void setListApi(bool listApi);
|
||||||
void setListSymbols(bool listSymbols);
|
void setListSymbols(bool listSymbols);
|
||||||
|
|
||||||
|
const std::vector<SdkApiString>& getSdkVerApiList() const;
|
||||||
|
const std::vector<SdkApiString>& getPublicApiList() const;
|
||||||
|
const std::vector<SdkApiString>& getDebugApiList() const;
|
||||||
|
const std::vector<SdkApiString>& getPrivateApiList() const;
|
||||||
|
const fnd::List<ElfSymbolParser::sElfSymbol>& getSymbolList() const;
|
||||||
private:
|
private:
|
||||||
const std::string kModuleName = "RoMetadataProcess";
|
const std::string kModuleName = "RoMetadataProcess";
|
||||||
|
|
||||||
|
|
|
@ -90,76 +90,38 @@ void XciProcess::setListFs(bool list_fs)
|
||||||
mListFs = list_fs;
|
mListFs = list_fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char* getBoolStr(bool isTrue)
|
|
||||||
{
|
|
||||||
return isTrue? "TRUE" : "FALSE";
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char* getRomSizeStr(byte_t rom_size)
|
|
||||||
{
|
|
||||||
const char* str = "unknown";
|
|
||||||
switch (rom_size)
|
|
||||||
{
|
|
||||||
case (nx::xci::ROM_SIZE_1GB) :
|
|
||||||
str = "1GB";
|
|
||||||
break;
|
|
||||||
case (nx::xci::ROM_SIZE_2GB) :
|
|
||||||
str = "2GB";
|
|
||||||
break;
|
|
||||||
case (nx::xci::ROM_SIZE_4GB) :
|
|
||||||
str = "4GB";
|
|
||||||
break;
|
|
||||||
case (nx::xci::ROM_SIZE_8GB) :
|
|
||||||
str = "8GB";
|
|
||||||
break;
|
|
||||||
case (nx::xci::ROM_SIZE_16GB) :
|
|
||||||
str = "16GB";
|
|
||||||
break;
|
|
||||||
case (nx::xci::ROM_SIZE_32GB) :
|
|
||||||
str = "32GB";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char* getCardClockRate(uint32_t acc_ctrl_1)
|
|
||||||
{
|
|
||||||
const char* str = "unknown";
|
|
||||||
switch (acc_ctrl_1)
|
|
||||||
{
|
|
||||||
case (nx::xci::CLOCK_RATE_25) :
|
|
||||||
str = "20 MHz";
|
|
||||||
break;
|
|
||||||
case (nx::xci::CLOCK_RATE_50) :
|
|
||||||
str = "50 MHz";
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void XciProcess::displayHeader()
|
void XciProcess::displayHeader()
|
||||||
{
|
{
|
||||||
printf("[XCI Header]\n");
|
printf("[XCI Header]\n");
|
||||||
printf(" Magic: HEAD\n");
|
|
||||||
printf(" KekIndex: %d\n", mHdr.getKekIndex());
|
|
||||||
printf(" TitleKeyDecIndex: %d\n", mHdr.getTitleKeyDecIndex());
|
|
||||||
printf(" RomSize: 0x%x (%s)\n", mHdr.getRomSizeType(), getRomSizeStr(mHdr.getRomSizeType()));
|
|
||||||
printf(" CardHeaderVersion: %d\n", mHdr.getCardHeaderVersion());
|
printf(" CardHeaderVersion: %d\n", mHdr.getCardHeaderVersion());
|
||||||
printf(" Flags: 0x%x\n", mHdr.getFlags());
|
printf(" RomSize: %s", getRomSizeStr(mHdr.getRomSizeType()));
|
||||||
printf(" AutoBoot: %s\n", getBoolStr(_HAS_BIT(mHdr.getFlags(), nx::xci::FLAG_AUTOBOOT)));
|
|
||||||
printf(" HistoryErase: %s\n", getBoolStr(_HAS_BIT(mHdr.getFlags(), nx::xci::FLAG_HISTORY_ERASE)));
|
|
||||||
printf(" RepairTool: %s\n", getBoolStr(_HAS_BIT(mHdr.getFlags(), nx::xci::FLAG_REPAIR_TOOL)));
|
|
||||||
printf(" PackageId: 0x%" PRIx64 "\n", mHdr.getPackageId());
|
|
||||||
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
|
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
|
||||||
|
printf(" (0x%x)", mHdr.getRomSizeType());
|
||||||
|
printf("\n");
|
||||||
|
printf(" PackageId: 0x%" PRIx64 "\n", mHdr.getPackageId());
|
||||||
|
printf(" Flags: 0x%x\n", mHdr.getFlags());
|
||||||
|
if (mHdr.getFlags() != 0)
|
||||||
{
|
{
|
||||||
printf(" InitialDataHash: \n");
|
for (uint32_t i = 0; i < 8; i++)
|
||||||
fnd::SimpleTextOutput::hexDump(mHdr.getInitialDataHash().bytes, sizeof(mHdr.getInitialDataHash().bytes));
|
{
|
||||||
|
if (_HAS_BIT(mHdr.getFlags(), i))
|
||||||
|
{
|
||||||
|
printf(" %s\n", getHeaderFlagStr(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
|
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
|
||||||
{
|
{
|
||||||
printf(" Enc Header AES-IV: ");
|
printf(" InitialData:\n");
|
||||||
fnd::SimpleTextOutput::hexDump(mHdr.getAesCbcIv().iv, sizeof(mHdr.getAesCbcIv().iv));
|
printf(" KekIndex: %d\n", mHdr.getKekIndex());
|
||||||
|
printf(" TitleKeyDecIndex: %d\n", mHdr.getTitleKeyDecIndex());
|
||||||
|
printf(" Hash:\n");
|
||||||
|
fnd::SimpleTextOutput::hexDump(mHdr.getInitialDataHash().bytes, sizeof(mHdr.getInitialDataHash().bytes), 0x10, 6);
|
||||||
|
}
|
||||||
|
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
|
||||||
|
{
|
||||||
|
printf(" Enc Header AES-IV:\n");
|
||||||
|
fnd::SimpleTextOutput::hexDump(mHdr.getAesCbcIv().iv, sizeof(mHdr.getAesCbcIv().iv), 0x10, 4);
|
||||||
}
|
}
|
||||||
printf(" SelSec: 0x%x\n", mHdr.getSelSec());
|
printf(" SelSec: 0x%x\n", mHdr.getSelSec());
|
||||||
printf(" SelT1Key: 0x%x\n", mHdr.getSelT1Key());
|
printf(" SelT1Key: 0x%x\n", mHdr.getSelT1Key());
|
||||||
|
@ -187,34 +149,35 @@ void XciProcess::displayHeader()
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf(" PartitionFs Header:\n");
|
printf(" PartitionFs Header:\n");
|
||||||
printf(" Offset: 0x%" PRIx64 "\n", mHdr.getPartitionFsAddress());
|
printf(" Offset: 0x%" PRIx64 "\n", mHdr.getPartitionFsAddress());
|
||||||
printf(" Size: 0x%" PRIx64 "\n", mHdr.getPartitionFsSize());
|
printf(" Size: 0x%" PRIx64 "\n", mHdr.getPartitionFsSize());
|
||||||
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
|
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
|
||||||
{
|
{
|
||||||
printf(" Hash: ");
|
printf(" Hash:\n");
|
||||||
fnd::SimpleTextOutput::hexDump(mHdr.getPartitionFsHash().bytes, sizeof(mHdr.getPartitionFsHash().bytes));
|
fnd::SimpleTextOutput::hexDump(mHdr.getPartitionFsHash().bytes, sizeof(mHdr.getPartitionFsHash().bytes), 0x10, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[XCI Extended Header]\n");
|
|
||||||
printf(" FwVersion: v%d.%d\n", mHdr.getFwVerMajor(), mHdr.getFwVerMinor());
|
if (mHdr.getFwVerMinor() != 0)
|
||||||
printf(" AccCtrl1: 0x%x\n", mHdr.getAccCtrl1());
|
{
|
||||||
printf(" CardClockRate: %s\n", getCardClockRate(mHdr.getAccCtrl1()));
|
printf("[XCI Extended Header]\n");
|
||||||
printf(" Wait1TimeRead: 0x%x\n", mHdr.getWait1TimeRead());
|
printf(" FwVersion: v%d.%d\n", mHdr.getFwVerMajor(), mHdr.getFwVerMinor());
|
||||||
printf(" Wait2TimeRead: 0x%x\n", mHdr.getWait2TimeRead());
|
printf(" AccCtrl1: 0x%x\n", mHdr.getAccCtrl1());
|
||||||
printf(" Wait1TimeWrite: 0x%x\n", mHdr.getWait1TimeWrite());
|
printf(" CardClockRate: %s\n", getCardClockRate(mHdr.getAccCtrl1()));
|
||||||
printf(" Wait2TimeWrite: 0x%x\n", mHdr.getWait2TimeWrite());
|
printf(" Wait1TimeRead: 0x%x\n", mHdr.getWait1TimeRead());
|
||||||
printf(" FwMode: 0x%x\n", mHdr.getFwMode());
|
printf(" Wait2TimeRead: 0x%x\n", mHdr.getWait2TimeRead());
|
||||||
printf(" Update Partition Info:\n");
|
printf(" Wait1TimeWrite: 0x%x\n", mHdr.getWait1TimeWrite());
|
||||||
|
printf(" Wait2TimeWrite: 0x%x\n", mHdr.getWait2TimeWrite());
|
||||||
|
printf(" FwMode: 0x%x\n", mHdr.getFwMode());
|
||||||
|
printf(" Update Partition Info:\n");
|
||||||
#define _SPLIT_VER(ver) ( (ver>>26) & 0x3f), ( (ver>>20) & 0x3f), ( (ver>>16) & 0xf), (ver & 0xffff)
|
#define _SPLIT_VER(ver) ( (ver>>26) & 0x3f), ( (ver>>20) & 0x3f), ( (ver>>16) & 0xf), (ver & 0xffff)
|
||||||
printf(" CUP Version: v%" PRId32 " (%d.%d.%d.%d)\n", mHdr.getUppVersion(), _SPLIT_VER(mHdr.getUppVersion()));
|
printf(" CUP Version: v%" PRId32 " (%d.%d.%d.%d)\n", mHdr.getUppVersion(), _SPLIT_VER(mHdr.getUppVersion()));
|
||||||
#undef _SPLIT_VER
|
#undef _SPLIT_VER
|
||||||
printf(" CUP TitleId: %016" PRIx64 "\n", mHdr.getUppId());
|
printf(" CUP TitleId: %016" PRIx64 "\n", mHdr.getUppId());
|
||||||
printf(" Partition Hash: ");
|
printf(" Partition Hash: ");
|
||||||
fnd::SimpleTextOutput::hexDump(mHdr.getUppHash(), 8);
|
fnd::SimpleTextOutput::hexDump(mHdr.getUppHash(), 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash)
|
bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash)
|
||||||
|
@ -274,3 +237,65 @@ void XciProcess::processPartitionPfs()
|
||||||
tmp.process();
|
tmp.process();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* XciProcess::getRomSizeStr(byte_t rom_size) const
|
||||||
|
{
|
||||||
|
const char* str = "unknown";
|
||||||
|
switch (rom_size)
|
||||||
|
{
|
||||||
|
case (nx::xci::ROM_SIZE_1GB):
|
||||||
|
str = "1GB";
|
||||||
|
break;
|
||||||
|
case (nx::xci::ROM_SIZE_2GB):
|
||||||
|
str = "2GB";
|
||||||
|
break;
|
||||||
|
case (nx::xci::ROM_SIZE_4GB):
|
||||||
|
str = "4GB";
|
||||||
|
break;
|
||||||
|
case (nx::xci::ROM_SIZE_8GB):
|
||||||
|
str = "8GB";
|
||||||
|
break;
|
||||||
|
case (nx::xci::ROM_SIZE_16GB):
|
||||||
|
str = "16GB";
|
||||||
|
break;
|
||||||
|
case (nx::xci::ROM_SIZE_32GB):
|
||||||
|
str = "32GB";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* XciProcess::getHeaderFlagStr(byte_t flag) const
|
||||||
|
{
|
||||||
|
const char* str = "unknown";
|
||||||
|
switch (flag)
|
||||||
|
{
|
||||||
|
case (nx::xci::FLAG_AUTOBOOT):
|
||||||
|
str = "AutoBoot";
|
||||||
|
break;
|
||||||
|
case (nx::xci::FLAG_HISTORY_ERASE):
|
||||||
|
str = "HistoryErase";
|
||||||
|
break;
|
||||||
|
case (nx::xci::FLAG_REPAIR_TOOL):
|
||||||
|
str = "RepairTool";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* XciProcess::getCardClockRate(uint32_t acc_ctrl_1) const
|
||||||
|
{
|
||||||
|
const char* str = "unknown";
|
||||||
|
switch (acc_ctrl_1)
|
||||||
|
{
|
||||||
|
case (nx::xci::CLOCK_RATE_25):
|
||||||
|
str = "20 MHz";
|
||||||
|
break;
|
||||||
|
case (nx::xci::CLOCK_RATE_50):
|
||||||
|
str = "50 MHz";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
|
@ -67,4 +67,9 @@ private:
|
||||||
void validateXciSignature();
|
void validateXciSignature();
|
||||||
void processRootPfs();
|
void processRootPfs();
|
||||||
void processPartitionPfs();
|
void processPartitionPfs();
|
||||||
|
|
||||||
|
// strings
|
||||||
|
const char* getRomSizeStr(byte_t rom_size) const;
|
||||||
|
const char* getHeaderFlagStr(byte_t flag) const;
|
||||||
|
const char* getCardClockRate(uint32_t acc_ctrl_1) const;
|
||||||
};
|
};
|
Loading…
Reference in a new issue