Merge pull request #67 from jakcron/v1.2-stable

Update NSTool to v1.2.0
This commit is contained in:
Jack 2020-02-29 16:08:53 +08:00 committed by GitHub
commit 513efc618d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 230 additions and 2196 deletions

View file

@ -22,7 +22,7 @@
<VCProjectVersion>15.0</VCProjectVersion> <VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{775EF5EB-CA49-4994-8AC4-47B4A5385266}</ProjectGuid> <ProjectGuid>{775EF5EB-CA49-4994-8AC4-47B4A5385266}</ProjectGuid>
<RootNamespace>nstool</RootNamespace> <RootNamespace>nstool</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

2
deps/libfnd vendored

@ -1 +1 @@
Subproject commit a3da67f8bcbf794e3689b0496695a249e323b6e8 Subproject commit 98a6f623361781e5bf4efbec0477efa9729de2cd

2
deps/liblz4 vendored

@ -1 +1 @@
Subproject commit 1dbb4a7988f91f0dbe854cb841b4ad5cdaff912e Subproject commit 0e5a8c29295a9046fff4ad5371a8ea682c7e0cb3

2
deps/libnintendo-es vendored

@ -1 +1 @@
Subproject commit 5b46763f7c35111bc67406ecadb4381436aa62b8 Subproject commit ba3036e08dc0d58662c3fc38a3dbee46371e399a

@ -1 +1 @@
Subproject commit 71f5f5d9488bf24ee3c9196911880c5ecda7c0cc Subproject commit 112f9b59a3914dcc06a2713de8c7cd67112c57bb

@ -1 +1 @@
Subproject commit dc434e4605476c40f584e6e98f54fdd980eba2eb Subproject commit e7f773bf883c6f5db700df32a286aa110849d863

@ -1 +1 @@
Subproject commit 509300a121626a9221f2d8af42a06723481ebf33 Subproject commit ca228576350a7ea3922ddc87ca43d68376d16fb2

2
deps/libpolarssl vendored

@ -1 +1 @@
Subproject commit 6573a1bd54a6a13bd468c6e17e631332eaff4449 Subproject commit 7cf5ebe575b5330b946160bad05c6be917340ae9

View file

@ -1,8 +1,12 @@
#include "CnmtProcess.h"
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <fnd/OffsetAdjustedIFile.h> #include <fnd/OffsetAdjustedIFile.h>
#include "CnmtProcess.h"
#include <nn/hac/ContentMetaUtil.h>
CnmtProcess::CnmtProcess() : CnmtProcess::CnmtProcess() :
mFile(), mFile(),
@ -61,10 +65,18 @@ void CnmtProcess::displayCnmt()
std::cout << "[ContentMeta]" << std::endl; std::cout << "[ContentMeta]" << std::endl;
std::cout << " TitleId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mCnmt.getTitleId() << std::endl; std::cout << " TitleId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mCnmt.getTitleId() << std::endl;
std::cout << " Version: v" << std::dec << mCnmt.getTitleVersion() << " (" << _SPLIT_VER(mCnmt.getTitleVersion()) << ")"<< std::endl; std::cout << " Version: v" << std::dec << mCnmt.getTitleVersion() << " (" << _SPLIT_VER(mCnmt.getTitleVersion()) << ")"<< std::endl;
std::cout << " Type: " << getContentMetaTypeStr(mCnmt.getContentMetaType()) << " (" << std::dec << mCnmt.getContentMetaType() << ")" << std::endl; std::cout << " Type: " << nn::hac::ContentMetaUtil::getContentMetaTypeAsString(mCnmt.getContentMetaType()) << " (" << std::dec << mCnmt.getContentMetaType() << ")" << std::endl;
std::cout << " Attributes: 0x" << std::hex << (uint32_t)mCnmt.getAttributes() << std::endl; std::cout << " Attributes: 0x" << std::hex << (uint32_t)mCnmt.getAttributes() << std::endl;
std::cout << " IncludesExFatDriver: " << getBoolStr(_HAS_BIT(mCnmt.getAttributes(), nn::hac::cnmt::ATTRIBUTE_INCLUDES_EX_FAT_DRIVER)) << std::endl; if (mCnmt.getAttributes() != 0)
std::cout << " Rebootless: " << getBoolStr(_HAS_BIT(mCnmt.getAttributes(), nn::hac::cnmt::ATTRIBUTE_REBOOTLESS)) << std::endl; {
for (size_t bit = 0; bit < (sizeof(byte_t)*8); bit++)
{
if (_HAS_BIT(mCnmt.getAttributes(), bit))
{
std::cout << " > " << nn::hac::ContentMetaUtil::getContentMetaAttributeAsString((nn::hac::cnmt::ContentMetaAttribute)bit) << std::endl;
}
}
}
std::cout << " RequiredDownloadSystemVersion: v" << mCnmt.getRequiredDownloadSystemVersion() << " (" << _SPLIT_VER(mCnmt.getRequiredDownloadSystemVersion()) << ")"<< std::endl; std::cout << " RequiredDownloadSystemVersion: v" << mCnmt.getRequiredDownloadSystemVersion() << " (" << _SPLIT_VER(mCnmt.getRequiredDownloadSystemVersion()) << ")"<< std::endl;
switch(mCnmt.getContentMetaType()) switch(mCnmt.getContentMetaType())
{ {
@ -97,7 +109,7 @@ void CnmtProcess::displayCnmt()
{ {
const nn::hac::ContentInfo& info = mCnmt.getContentInfo()[i]; const nn::hac::ContentInfo& info = mCnmt.getContentInfo()[i];
std::cout << " " << std::dec << i << std::endl; std::cout << " " << std::dec << i << std::endl;
std::cout << " Type: " << getContentTypeStr(info.getContentType()) << " (" << std::dec << info.getContentType() << ")" << std::endl; std::cout << " Type: " << nn::hac::ContentMetaUtil::getContentTypeAsString(info.getContentType()) << " (" << std::dec << info.getContentType() << ")" << std::endl;
std::cout << " Id: " << fnd::SimpleTextOutput::arrayToString(info.getContentId().data, nn::hac::cnmt::kContentIdLen, false, "") << std::endl; std::cout << " Id: " << fnd::SimpleTextOutput::arrayToString(info.getContentId().data, nn::hac::cnmt::kContentIdLen, false, "") << std::endl;
std::cout << " Size: 0x" << std::hex << info.getContentSize() << std::endl; std::cout << " Size: 0x" << std::hex << info.getContentSize() << std::endl;
std::cout << " Hash: " << fnd::SimpleTextOutput::arrayToString(info.getContentHash().bytes, sizeof(info.getContentHash()), false, "") << std::endl; std::cout << " Hash: " << fnd::SimpleTextOutput::arrayToString(info.getContentHash().bytes, sizeof(info.getContentHash()), false, "") << std::endl;
@ -112,10 +124,18 @@ void CnmtProcess::displayCnmt()
std::cout << " " << std::dec << i << std::endl; std::cout << " " << std::dec << i << std::endl;
std::cout << " Id: 0x" << std::hex << std::setw(16) << std::setfill('0') << info.getTitleId() << std::endl; std::cout << " Id: 0x" << std::hex << std::setw(16) << std::setfill('0') << info.getTitleId() << std::endl;
std::cout << " Version: v" << std::dec << info.getTitleVersion() << " (" << _SPLIT_VER(info.getTitleVersion()) << ")"<< std::endl; std::cout << " Version: v" << std::dec << info.getTitleVersion() << " (" << _SPLIT_VER(info.getTitleVersion()) << ")"<< std::endl;
std::cout << " Type: " << getContentMetaTypeStr(info.getContentMetaType()) << " (" << std::dec << info.getContentMetaType() << ")" << std::endl; std::cout << " Type: " << nn::hac::ContentMetaUtil::getContentMetaTypeAsString(info.getContentMetaType()) << " (" << std::dec << info.getContentMetaType() << ")" << std::endl;
std::cout << " Attributes: 0x" << std::hex << (uint32_t)info.getAttributes() << std::endl; std::cout << " Attributes: 0x" << std::hex << (uint32_t)info.getAttributes() << std::endl;
std::cout << " IncludesExFatDriver: " << getBoolStr(_HAS_BIT(info.getAttributes(), nn::hac::cnmt::ATTRIBUTE_INCLUDES_EX_FAT_DRIVER)) << std::endl; if (info.getAttributes() != 0)
std::cout << " Rebootless: " << getBoolStr(_HAS_BIT(info.getAttributes(), nn::hac::cnmt::ATTRIBUTE_REBOOTLESS)) << std::endl; {
for (size_t bit = 0; bit < (sizeof(byte_t)*8); bit++)
{
if (_HAS_BIT(info.getAttributes(), bit))
{
std::cout << " > " << nn::hac::ContentMetaUtil::getContentMetaAttributeAsString((nn::hac::cnmt::ContentMetaAttribute)bit) << std::endl;
}
}
}
} }
} }
@ -127,123 +147,4 @@ void CnmtProcess::displayCnmt()
const char* CnmtProcess::getBoolStr(bool state) const const char* CnmtProcess::getBoolStr(bool state) const
{ {
return state? "TRUE" : "FALSE"; return state? "TRUE" : "FALSE";
} }
const char* CnmtProcess::getContentTypeStr(nn::hac::cnmt::ContentType type) const
{
const char* str = nullptr;
switch (type)
{
case (nn::hac::cnmt::TYPE_META):
str = "Meta";
break;
case (nn::hac::cnmt::TYPE_PROGRAM):
str = "Program";
break;
case (nn::hac::cnmt::TYPE_DATA):
str = "Data";
break;
case (nn::hac::cnmt::TYPE_CONTROL):
str = "Control";
break;
case (nn::hac::cnmt::TYPE_HTML_DOCUMENT):
str = "HtmlDocument";
break;
case (nn::hac::cnmt::TYPE_LEGAL_INFORMATION):
str = "LegalInformation";
break;
case (nn::hac::cnmt::TYPE_DELTA_FRAGMENT):
str = "DeltaFragment";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* CnmtProcess::getContentMetaTypeStr(nn::hac::cnmt::ContentMetaType type) const
{
const char* str = nullptr;
switch (type)
{
case (nn::hac::cnmt::METATYPE_SYSTEM_PROGRAM):
str = "SystemProgram";
break;
case (nn::hac::cnmt::METATYPE_SYSTEM_DATA):
str = "SystemData";
break;
case (nn::hac::cnmt::METATYPE_SYSTEM_UPDATE):
str = "SystemUpdate";
break;
case (nn::hac::cnmt::METATYPE_BOOT_IMAGE_PACKAGE):
str = "BootImagePackage";
break;
case (nn::hac::cnmt::METATYPE_BOOT_IMAGE_PACKAGE_SAFE):
str = "BootImagePackageSafe";
break;
case (nn::hac::cnmt::METATYPE_APPLICATION):
str = "Application";
break;
case (nn::hac::cnmt::METATYPE_PATCH):
str = "Patch";
break;
case (nn::hac::cnmt::METATYPE_ADD_ON_CONTENT):
str = "AddOnContent";
break;
case (nn::hac::cnmt::METATYPE_DELTA):
str = "Delta";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* CnmtProcess::getUpdateTypeStr(nn::hac::cnmt::UpdateType type) const
{
const char* str = nullptr;
switch (type)
{
case (nn::hac::cnmt::UPDATETYPE_APPLY_AS_DELTA):
str = "ApplyAsDelta";
break;
case (nn::hac::cnmt::UPDATETYPE_OVERWRITE):
str = "Overwrite";
break;
case (nn::hac::cnmt::UPDATETYPE_CREATE):
str = "Create";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* CnmtProcess::getContentMetaAttrStr(nn::hac::cnmt::ContentMetaAttribute attr) const
{
const char* str = nullptr;
switch (attr)
{
case (nn::hac::cnmt::ATTRIBUTE_INCLUDES_EX_FAT_DRIVER):
str = "IncludesExFatDriver";
break;
case (nn::hac::cnmt::ATTRIBUTE_REBOOTLESS):
str = "Rebootless";
break;
default:
str = "Unknown";
break;
}
return str;
}

View file

@ -33,8 +33,4 @@ private:
void displayCnmt(); void displayCnmt();
const char* getBoolStr(bool state) const; const char* getBoolStr(bool state) const;
const char* getContentTypeStr(nn::hac::cnmt::ContentType type) const;
const char* getContentMetaTypeStr(nn::hac::cnmt::ContentMetaType type) const;
const char* getUpdateTypeStr(nn::hac::cnmt::UpdateType type) const;
const char* getContentMetaAttrStr(nn::hac::cnmt::ContentMetaAttribute attr) const;
}; };

View file

@ -2,7 +2,7 @@
#include <iomanip> #include <iomanip>
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <fnd/OffsetAdjustedIFile.h> #include <fnd/OffsetAdjustedIFile.h>
#include <nn/hac/GameCardUtils.h> #include <nn/hac/GameCardUtil.h>
#include "GameCardProcess.h" #include "GameCardProcess.h"
GameCardProcess::GameCardProcess() : GameCardProcess::GameCardProcess() :
@ -10,6 +10,7 @@ GameCardProcess::GameCardProcess() :
mCliOutputMode(_BIT(OUTPUT_BASIC)), mCliOutputMode(_BIT(OUTPUT_BASIC)),
mVerify(false), mVerify(false),
mListFs(false), mListFs(false),
mProccessExtendedHeader(false),
mRootPfs(), mRootPfs(),
mExtractInfo() mExtractInfo()
{ {
@ -73,25 +74,53 @@ void GameCardProcess::importHeader()
throw fnd::Exception(kModuleName, "No file reader set."); throw fnd::Exception(kModuleName, "No file reader set.");
} }
// read header page // allocate memory for header
(*mFile)->read((byte_t*)&mHdrPage, 0, sizeof(nn::hac::sGcHeaderPage)); scratch.alloc(sizeof(nn::hac::sSdkGcHeader));
// allocate memory for and decrypt sXciHeader // read header region
scratch.alloc(sizeof(nn::hac::sGcHeader)); (*mFile)->read((byte_t*)scratch.data(), 0, sizeof(nn::hac::sSdkGcHeader));
// determine if this is a SDK XCI or a "Community" XCI
if (((nn::hac::sSdkGcHeader*)scratch.data())->signed_header.header.st_magic.get() == nn::hac::gc::kGcHeaderStructMagic)
{
mIsTrueSdkXci = true;
mGcHeaderOffset = sizeof(nn::hac::sGcKeyDataRegion);
}
else if (((nn::hac::sGcHeader_Rsa2048Signed*)scratch.data())->header.st_magic.get() == nn::hac::gc::kGcHeaderStructMagic)
{
mIsTrueSdkXci = false;
mGcHeaderOffset = 0;
}
else
{
throw fnd::Exception(kModuleName, "GameCard image did not have expected magic bytes");
}
nn::hac::sGcHeader_Rsa2048Signed* hdr_ptr = (nn::hac::sGcHeader_Rsa2048Signed*)(scratch.data() + mGcHeaderOffset);
// generate hash of raw header
fnd::sha::Sha256((byte_t*)&hdr_ptr->header, sizeof(nn::hac::sGcHeader), mHdrHash.bytes);
// save the signature
memcpy(mHdrSignature, hdr_ptr->signature, fnd::rsa::kRsa2048Size);
// decrypt extended header
fnd::aes::sAes128Key header_key; fnd::aes::sAes128Key header_key;
mKeyCfg.getXciHeaderKey(header_key); if (mKeyCfg.getXciHeaderKey(header_key))
nn::hac::GameCardUtils::decryptXciHeader((const byte_t*)&mHdrPage.header, scratch.data(), header_key.key); {
nn::hac::GameCardUtil::decryptXciHeader(&hdr_ptr->header, header_key.key);
mProccessExtendedHeader = true;
}
// deserialise header // deserialise header
mHdr.fromBytes(scratch.data(), scratch.size()); mHdr.fromBytes((byte_t*)&hdr_ptr->header, sizeof(nn::hac::sGcHeader));
} }
void GameCardProcess::displayHeader() void GameCardProcess::displayHeader()
{ {
std::cout << "[GameCard Header]" << std::endl; std::cout << "[GameCard Header]" << std::endl;
std::cout << " CardHeaderVersion: " << std::dec << (uint32_t)mHdr.getCardHeaderVersion() << std::endl; std::cout << " CardHeaderVersion: " << std::dec << (uint32_t)mHdr.getCardHeaderVersion() << std::endl;
std::cout << " RomSize: " << getRomSizeStr(mHdr.getRomSizeType()); std::cout << " RomSize: " << nn::hac::GameCardUtil::getRomSizeAsString((nn::hac::gc::RomSize)mHdr.getRomSizeType());
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
std::cout << " (0x" << std::hex << (uint32_t)mHdr.getRomSizeType() << ")"; std::cout << " (0x" << std::hex << (uint32_t)mHdr.getRomSizeType() << ")";
std::cout << std::endl; std::cout << std::endl;
@ -103,14 +132,14 @@ void GameCardProcess::displayHeader()
{ {
if (_HAS_BIT(mHdr.getFlags(), i)) if (_HAS_BIT(mHdr.getFlags(), i))
{ {
std::cout << " " << getHeaderFlagStr(i) << std::endl; std::cout << " " << nn::hac::GameCardUtil::getHeaderFlagsAsString((nn::hac::gc::HeaderFlags)i) << std::endl;
} }
} }
} }
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
{ {
std::cout << " InitialData:" << std::endl; std::cout << " InitialData:" << std::endl;
std::cout << " KekIndex: " << std::dec << (uint32_t)mHdr.getKekIndex() << std::endl; std::cout << " KekIndex: " << nn::hac::GameCardUtil::getKekIndexAsString((nn::hac::gc::KekIndex)mHdr.getKekIndex()) << "(" << std::dec << (uint32_t)mHdr.getKekIndex() << ")" << std::endl;
std::cout << " TitleKeyDecIndex: " << std::dec << (uint32_t)mHdr.getTitleKeyDecIndex() << std::endl; std::cout << " TitleKeyDecIndex: " << std::dec << (uint32_t)mHdr.getTitleKeyDecIndex() << std::endl;
std::cout << " Hash:" << std::endl; std::cout << " Hash:" << std::endl;
std::cout << " " << fnd::SimpleTextOutput::arrayToString(mHdr.getInitialDataHash().bytes, 0x10, true, ":") << std::endl; std::cout << " " << fnd::SimpleTextOutput::arrayToString(mHdr.getInitialDataHash().bytes, 0x10, true, ":") << std::endl;
@ -128,22 +157,22 @@ void GameCardProcess::displayHeader()
{ {
std::cout << " RomAreaStartPage: 0x" << std::hex << mHdr.getRomAreaStartPage(); std::cout << " RomAreaStartPage: 0x" << std::hex << mHdr.getRomAreaStartPage();
if (mHdr.getRomAreaStartPage() != (uint32_t)(-1)) if (mHdr.getRomAreaStartPage() != (uint32_t)(-1))
std::cout << " (0x" << std::hex << nn::hac::GameCardUtils::blockToAddr(mHdr.getRomAreaStartPage()) << ")"; std::cout << " (0x" << std::hex << nn::hac::GameCardUtil::blockToAddr(mHdr.getRomAreaStartPage()) << ")";
std::cout << std::endl; std::cout << std::endl;
std::cout << " BackupAreaStartPage: 0x" << std::hex << mHdr.getBackupAreaStartPage(); std::cout << " BackupAreaStartPage: 0x" << std::hex << mHdr.getBackupAreaStartPage();
if (mHdr.getBackupAreaStartPage() != (uint32_t)(-1)) if (mHdr.getBackupAreaStartPage() != (uint32_t)(-1))
std::cout << " (0x" << std::hex << nn::hac::GameCardUtils::blockToAddr(mHdr.getBackupAreaStartPage()) << ")"; std::cout << " (0x" << std::hex << nn::hac::GameCardUtil::blockToAddr(mHdr.getBackupAreaStartPage()) << ")";
std::cout << std::endl; std::cout << std::endl;
std::cout << " ValidDataEndPage: 0x" << std::hex << mHdr.getValidDataEndPage(); std::cout << " ValidDataEndPage: 0x" << std::hex << mHdr.getValidDataEndPage();
if (mHdr.getValidDataEndPage() != (uint32_t)(-1)) if (mHdr.getValidDataEndPage() != (uint32_t)(-1))
std::cout << " (0x" << std::hex << nn::hac::GameCardUtils::blockToAddr(mHdr.getValidDataEndPage()) << ")"; std::cout << " (0x" << std::hex << nn::hac::GameCardUtil::blockToAddr(mHdr.getValidDataEndPage()) << ")";
std::cout << std::endl; std::cout << std::endl;
std::cout << " LimArea: 0x" << std::hex << mHdr.getLimAreaPage(); std::cout << " LimArea: 0x" << std::hex << mHdr.getLimAreaPage();
if (mHdr.getLimAreaPage() != (uint32_t)(-1)) if (mHdr.getLimAreaPage() != (uint32_t)(-1))
std::cout << " (0x" << std::hex << nn::hac::GameCardUtils::blockToAddr(mHdr.getLimAreaPage()) << ")"; std::cout << " (0x" << std::hex << nn::hac::GameCardUtil::blockToAddr(mHdr.getLimAreaPage()) << ")";
std::cout << std::endl; std::cout << std::endl;
std::cout << " PartitionFs Header:" << std::endl; std::cout << " PartitionFs Header:" << std::endl;
@ -158,23 +187,24 @@ void GameCardProcess::displayHeader()
} }
if (mHdr.getFwVerMinor() != 0) if (mProccessExtendedHeader)
{ {
std::cout << "[GameCard Extended Header]" << std::endl; std::cout << "[GameCard Extended Header]" << std::endl;
std::cout << " FwVersion: v" << std::dec << mHdr.getFwVerMajor() << "." << mHdr.getFwVerMinor() << std::endl; std::cout << " FwVersion: v" << std::dec << mHdr.getFwVersion() << "(" << nn::hac::GameCardUtil::getCardFwVersionDescriptionAsString((nn::hac::gc::FwVersion)mHdr.getFwVersion()) << ")" << std::endl;
std::cout << " AccCtrl1: 0x" << std::hex << mHdr.getAccCtrl1() << std::endl; std::cout << " AccCtrl1: 0x" << std::hex << mHdr.getAccCtrl1() << std::endl;
std::cout << " CardClockRate: " << getCardClockRate(mHdr.getAccCtrl1()) << std::endl; std::cout << " CardClockRate: " << nn::hac::GameCardUtil::getCardClockRateAsString((nn::hac::gc::CardClockRate)mHdr.getAccCtrl1()) << std::endl;
std::cout << " Wait1TimeRead: 0x" << std::hex << mHdr.getWait1TimeRead() << std::endl; std::cout << " Wait1TimeRead: 0x" << std::hex << mHdr.getWait1TimeRead() << std::endl;
std::cout << " Wait2TimeRead: 0x" << std::hex << mHdr.getWait2TimeRead() << std::endl; std::cout << " Wait2TimeRead: 0x" << std::hex << mHdr.getWait2TimeRead() << std::endl;
std::cout << " Wait1TimeWrite: 0x" << std::hex << mHdr.getWait1TimeWrite() << std::endl; std::cout << " Wait1TimeWrite: 0x" << std::hex << mHdr.getWait1TimeWrite() << std::endl;
std::cout << " Wait2TimeWrite: 0x" << std::hex << mHdr.getWait2TimeWrite() << std::endl; std::cout << " Wait2TimeWrite: 0x" << std::hex << mHdr.getWait2TimeWrite() << std::endl;
std::cout << " FwMode: 0x" << std::hex << mHdr.getFwMode() << std::endl; std::cout << " FwMode: 0x" << std::hex << mHdr.getFwMode() << std::endl;
std::cout << " CompatibilityType: " << nn::hac::GameCardUtil::getCompatibilityTypeAsString((nn::hac::gc::CompatibilityType)mHdr.getCompatibilityType()) << "(" << std::dec << mHdr.getCompatibilityType() << ")" << std::endl;
std::cout << " Update Partition Info:" << std::endl; std::cout << " Update Partition Info:" << std::endl;
#define _SPLIT_VER(ver) std::dec << ((ver>>26) & 0x3f) << "." << ((ver>>20) & 0x3f) << "." << ((ver>>16) & 0xf) << "." << (ver & 0xffff) #define _SPLIT_VER(ver) std::dec << ((ver>>26) & 0x3f) << "." << ((ver>>20) & 0x3f) << "." << ((ver>>16) & 0xf) << "." << (ver & 0xffff)
std::cout << " CUP Version: v" << std::dec << mHdr.getUppVersion() << " (" << _SPLIT_VER(mHdr.getUppVersion()) << ")" << std::endl; std::cout << " CUP Version: v" << std::dec << mHdr.getUppVersion() << " (" << _SPLIT_VER(mHdr.getUppVersion()) << ")" << std::endl;
#undef _SPLIT_VER #undef _SPLIT_VER
std::cout << " CUP TitleId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mHdr.getUppId() << std::endl; std::cout << " CUP TitleId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mHdr.getUppId() << std::endl;
std::cout << " Partition Hash: " << fnd::SimpleTextOutput::arrayToString(mHdr.getUppHash(), 8, true, ":") << std::endl; std::cout << " CUP Digest: " << fnd::SimpleTextOutput::arrayToString(mHdr.getUppHash(), 8, true, ":") << std::endl;
} }
} }
@ -191,10 +221,9 @@ bool GameCardProcess::validateRegionOfFile(size_t offset, size_t len, const byte
void GameCardProcess::validateXciSignature() void GameCardProcess::validateXciSignature()
{ {
fnd::rsa::sRsa2048Key header_sign_key; fnd::rsa::sRsa2048Key header_sign_key;
fnd::sha::sSha256Hash calc_hash;
fnd::sha::Sha256((byte_t*)&mHdrPage.header, sizeof(nn::hac::sGcHeader), calc_hash.bytes);
mKeyCfg.getXciHeaderSignKey(header_sign_key); mKeyCfg.getXciHeaderSignKey(header_sign_key);
if (fnd::rsa::pkcs::rsaVerify(header_sign_key, fnd::sha::HASH_SHA256, calc_hash.bytes, mHdrPage.signature) != 0) if (fnd::rsa::pkcs::rsaVerify(header_sign_key, fnd::sha::HASH_SHA256, mHdrHash.bytes, mHdrSignature) != 0)
{ {
std::cout << "[WARNING] GameCard Header Signature: FAIL" << std::endl; std::cout << "[WARNING] GameCard Header Signature: FAIL" << std::endl;
} }
@ -236,80 +265,4 @@ void GameCardProcess::processPartitionPfs()
tmp.process(); tmp.process();
} }
} }
const char* GameCardProcess::getRomSizeStr(byte_t rom_size) const
{
const char* str = nullptr;
switch (rom_size)
{
case (nn::hac::gc::ROM_SIZE_1GB):
str = "1GB";
break;
case (nn::hac::gc::ROM_SIZE_2GB):
str = "2GB";
break;
case (nn::hac::gc::ROM_SIZE_4GB):
str = "4GB";
break;
case (nn::hac::gc::ROM_SIZE_8GB):
str = "8GB";
break;
case (nn::hac::gc::ROM_SIZE_16GB):
str = "16GB";
break;
case (nn::hac::gc::ROM_SIZE_32GB):
str = "32GB";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* GameCardProcess::getHeaderFlagStr(byte_t flag) const
{
const char* str = nullptr;
switch (flag)
{
case (nn::hac::gc::FLAG_AUTOBOOT):
str = "AutoBoot";
break;
case (nn::hac::gc::FLAG_HISTORY_ERASE):
str = "HistoryErase";
break;
case (nn::hac::gc::FLAG_REPAIR_TOOL):
str = "RepairTool";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* GameCardProcess::getCardClockRate(uint32_t acc_ctrl_1) const
{
const char* str = nullptr;
switch (acc_ctrl_1)
{
case (nn::hac::gc::CLOCK_RATE_25):
str = "20 MHz";
break;
case (nn::hac::gc::CLOCK_RATE_50):
str = "50 MHz";
break;
default:
str = "Unknown";
break;
}
return str;
}

View file

@ -35,6 +35,7 @@ private:
KeyConfiguration mKeyCfg; KeyConfiguration mKeyCfg;
CliOutputMode mCliOutputMode; CliOutputMode mCliOutputMode;
bool mVerify; bool mVerify;
bool mListFs;
struct sExtractInfo struct sExtractInfo
{ {
@ -53,10 +54,16 @@ private:
} }
}; };
bool mListFs;
nn::hac::sGcHeaderPage mHdrPage; bool mIsTrueSdkXci;
bool mIsSdkXciEncrypted;
size_t mGcHeaderOffset;
bool mProccessExtendedHeader;
byte_t mHdrSignature[fnd::rsa::kRsa2048Size];
fnd::sha::sSha256Hash mHdrHash;
nn::hac::GameCardHeader mHdr; nn::hac::GameCardHeader mHdr;
PfsProcess mRootPfs; PfsProcess mRootPfs;
fnd::List<sExtractInfo> mExtractInfo; fnd::List<sExtractInfo> mExtractInfo;
@ -66,9 +73,4 @@ 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;
}; };

View file

@ -2,7 +2,6 @@
#include <fnd/ResourceFileReader.h> #include <fnd/ResourceFileReader.h>
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <nn/hac/AesKeygen.h> #include <nn/hac/AesKeygen.h>
#include <nn/hac/ContentArchiveUtils.h>
KeyConfiguration::KeyConfiguration() KeyConfiguration::KeyConfiguration()
{ {
@ -211,7 +210,7 @@ void KeyConfiguration::clearGeneralKeyConfiguration()
for (size_t j = 0; j < kNcaKeakNum; j++) for (size_t j = 0; j < kNcaKeakNum; j++)
{ {
mNcaKeyAreaEncryptionKey[j][i] = kNullAesKey; mNcaKeyAreaEncryptionKey[j][i] = kNullAesKey;
mNcaKeyAreaEncryptionKey[j][i] = kNullAesKey; mNcaKeyAreaEncryptionKeyHw[j][i] = kNullAesKey;
} }
} }
} }

View file

@ -1,9 +1,15 @@
#include "KipProcess.h"
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <fnd/OffsetAdjustedIFile.h> #include <fnd/OffsetAdjustedIFile.h>
#include <fnd/Vec.h> #include <fnd/Vec.h>
#include "KipProcess.h"
#include <nn/hac/KernelCapabilityUtil.h>
#include <nn/hac/KernelInitialProcessUtil.h>
KipProcess::KipProcess(): KipProcess::KipProcess():
mFile(), mFile(),
@ -141,7 +147,7 @@ void KipProcess::displayHeader()
std::cout << " Meta:" << std::endl; std::cout << " Meta:" << std::endl;
std::cout << " Name: " << mHdr.getName() << std::endl; std::cout << " Name: " << mHdr.getName() << std::endl;
std::cout << " TitleId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mHdr.getTitleId() << std::endl; std::cout << " TitleId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mHdr.getTitleId() << std::endl;
std::cout << " ProcessCategory: " << getProcessCategoryStr(mHdr.getProcessCategory()) << std::endl; std::cout << " ProcessCategory: " << nn::hac::KernelInitialProcessUtil::getProcessCategoryAsString(mHdr.getProcessCategory()) << std::endl;
std::cout << " InstructionType: " << getInstructionTypeStr(mHdr.getFlagList().hasElement(nn::hac::kip::FLAG_INSTRUCTION_64BIT)) << std::endl; std::cout << " InstructionType: " << getInstructionTypeStr(mHdr.getFlagList().hasElement(nn::hac::kip::FLAG_INSTRUCTION_64BIT)) << std::endl;
std::cout << " AddrSpaceWidth: " << getAddressSpaceStr(mHdr.getFlagList().hasElement(nn::hac::kip::FLAG_ADDR_SPACE_64BIT)) << std::endl; std::cout << " AddrSpaceWidth: " << getAddressSpaceStr(mHdr.getFlagList().hasElement(nn::hac::kip::FLAG_ADDR_SPACE_64BIT)) << std::endl;
std::cout << " MemoryPool: " << getMemoryPoolStr(mHdr.getFlagList().hasElement(nn::hac::kip::FLAG_USE_SYSTEM_POOL_PARTITION)) << std::endl; std::cout << " MemoryPool: " << getMemoryPoolStr(mHdr.getFlagList().hasElement(nn::hac::kip::FLAG_USE_SYSTEM_POOL_PARTITION)) << std::endl;
@ -191,7 +197,7 @@ void KipProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
if (kern.getSystemCalls().isSet()) if (kern.getSystemCalls().isSet())
{ {
fnd::List<uint8_t> syscalls = kern.getSystemCalls().getSystemCalls(); fnd::List<nn::hac::kc::SystemCall> syscalls = kern.getSystemCalls().getSystemCalls();
std::cout << " SystemCalls:" << std::endl; std::cout << " SystemCalls:" << std::endl;
std::cout << " "; std::cout << " ";
size_t lineLen = 0; size_t lineLen = 0;
@ -203,10 +209,11 @@ void KipProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
std::cout << std::endl; std::cout << std::endl;
std::cout << " "; std::cout << " ";
} }
std::cout << getSystemCallStr(syscalls[i]); std::string syscall_string = nn::hac::KernelCapabilityUtil::getSystemCallAsString(syscalls[i]);
std::cout << syscall_string;
if (syscalls[i] != syscalls.atBack()) if (syscalls[i] != syscalls.atBack())
std::cout << ", "; std::cout << ", ";
lineLen += strlen(getSystemCallStr(syscalls[i])); lineLen += syscall_string.length();
} }
std::cout << std::endl; std::cout << std::endl;
} }
@ -218,12 +225,12 @@ void KipProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
std::cout << " MemoryMaps:" << std::endl; std::cout << " MemoryMaps:" << std::endl;
for (size_t i = 0; i < maps.size(); i++) for (size_t i = 0; i < maps.size(); i++)
{ {
std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)maps[i].addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(maps[i].addr + maps[i].size) << 12) - 1) << " (perm=" << getMemMapPermStr(maps[i].perm) << ") (type=" << getMemMapTypeStr(maps[i].type) << ")" << std::endl; std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)maps[i].addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(maps[i].addr + maps[i].size) << 12) - 1) << " (perm=" << nn::hac::KernelCapabilityUtil::getMemMapPermAsString(maps[i].perm) << ") (type=" << nn::hac::KernelCapabilityUtil::getMemMapTypeAsString(maps[i].type) << ")" << std::endl;
} }
//std::cout << " IoMaps:" << std::endl; //std::cout << " IoMaps:" << std::endl;
for (size_t i = 0; i < ioMaps.size(); i++) for (size_t i = 0; i < ioMaps.size(); i++)
{ {
std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)ioMaps[i].addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(ioMaps[i].addr + ioMaps[i].size) << 12) - 1) << " (perm=" << getMemMapPermStr(ioMaps[i].perm) << ") (type=" << getMemMapTypeStr(ioMaps[i].type) << ")" << std::endl; std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)ioMaps[i].addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(ioMaps[i].addr + ioMaps[i].size) << 12) - 1) << " (perm=" << nn::hac::KernelCapabilityUtil::getMemMapPermAsString(ioMaps[i].perm) << ") (type=" << nn::hac::KernelCapabilityUtil::getMemMapTypeAsString(ioMaps[i].type) << ")" << std::endl;
} }
} }
if (kern.getInterupts().isSet()) if (kern.getInterupts().isSet())
@ -258,7 +265,7 @@ void KipProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
} }
if (kern.getMiscFlags().isSet()) if (kern.getMiscFlags().isSet())
{ {
fnd::List<nn::hac::MiscFlagsHandler::Flags> flagList = kern.getMiscFlags().getFlagList(); fnd::List<nn::hac::kc::MiscFlags> flagList = kern.getMiscFlags().getFlagList();
std::cout << " Misc Flags:" << std::endl; std::cout << " Misc Flags:" << std::endl;
for (uint32_t i = 0; i < flagList.size(); i++) for (uint32_t i = 0; i < flagList.size(); i++)
@ -269,7 +276,7 @@ void KipProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
std::cout << std::endl; std::cout << std::endl;
std::cout << " "; std::cout << " ";
} }
std::cout << getMiscFlagStr(flagList[i]); std::cout << nn::hac::KernelCapabilityUtil::getMiscFlagAsString(flagList[i]);
if (flagList[i] != flagList.atBack()) if (flagList[i] != flagList.atBack())
std::cout << ", "; std::cout << ", ";
std::cout << std::endl; std::cout << std::endl;
@ -277,25 +284,6 @@ void KipProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
} }
} }
const char* KipProcess::getProcessCategoryStr(nn::hac::kip::ProcessCategory var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::kip::PROCCAT_REGULAR):
str = "NormalProcess";
break;
case (nn::hac::kip::PROCCAT_KERNAL_KIP):
str = "KernelInitalProcess";
break;
default:
str = "Unknown";
}
return str;
}
const char* KipProcess::getInstructionTypeStr(bool is64Bit) const const char* KipProcess::getInstructionTypeStr(bool is64Bit) const
{ {
return is64Bit? "64Bit" : "32Bit"; return is64Bit? "64Bit" : "32Bit";
@ -309,459 +297,4 @@ const char* KipProcess::getAddressSpaceStr(bool is64Bit) const
const char* KipProcess::getMemoryPoolStr(bool isSystemPool) const const char* KipProcess::getMemoryPoolStr(bool isSystemPool) const
{ {
return isSystemPool? "System" : "Application"; return isSystemPool? "System" : "Application";
}
const char* KipProcess::getMiscFlagStr(nn::hac::MiscFlagsHandler::Flags flag) const
{
const char* str = nullptr;
switch(flag)
{
case (nn::hac::MiscFlagsHandler::FLAG_ENABLE_DEBUG):
str = "EnableDebug";
break;
case (nn::hac::MiscFlagsHandler::FLAG_FORCE_DEBUG):
str = "ForceDebug";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* KipProcess::getSystemCallStr(byte_t syscall_id) const
{
const char* str = nullptr;
switch(syscall_id)
{
case (0x01):
str = "SetHeapSize";
break;
case (0x02):
str = "SetMemoryPermission";
break;
case (0x03):
str = "SetMemoryAttribute";
break;
case (0x04):
str = "MapMemory";
break;
case (0x05):
str = "UnmapMemory";
break;
case (0x06):
str = "QueryMemory";
break;
case (0x07):
str = "ExitProcess";
break;
case (0x08):
str = "CreateThread";
break;
case (0x09):
str = "StartThread";
break;
case (0x0a):
str = "ExitThread";
break;
case (0x0b):
str = "SleepThread";
break;
case (0x0c):
str = "GetThreadPriority";
break;
case (0x0d):
str = "SetThreadPriority";
break;
case (0x0e):
str = "GetThreadCoreMask";
break;
case (0x0f):
str = "SetThreadCoreMask";
break;
case (0x10):
str = "GetCurrentProcessorNumber";
break;
case (0x11):
str = "SignalEvent";
break;
case (0x12):
str = "ClearEvent";
break;
case (0x13):
str = "MapSharedMemory";
break;
case (0x14):
str = "UnmapSharedMemory";
break;
case (0x15):
str = "CreateTransferMemory";
break;
case (0x16):
str = "CloseHandle";
break;
case (0x17):
str = "ResetSignal";
break;
case (0x18):
str = "WaitSynchronization";
break;
case (0x19):
str = "CancelSynchronization";
break;
case (0x1a):
str = "ArbitrateLock";
break;
case (0x1b):
str = "ArbitrateUnlock";
break;
case (0x1c):
str = "WaitProcessWideKeyAtomic";
break;
case (0x1d):
str = "SignalProcessWideKey";
break;
case (0x1e):
str = "GetSystemTick";
break;
case (0x1f):
str = "ConnectToNamedPort";
break;
case (0x20):
str = "SendSyncRequestLight";
break;
case (0x21):
str = "SendSyncRequest";
break;
case (0x22):
str = "SendSyncRequestWithUserBuffer";
break;
case (0x23):
str = "SendAsyncRequestWithUserBuffer";
break;
case (0x24):
str = "GetProcessId";
break;
case (0x25):
str = "GetThreadId";
break;
case (0x26):
str = "Break";
break;
case (0x27):
str = "OutputDebugString";
break;
case (0x28):
str = "ReturnFromException";
break;
case (0x29):
str = "GetInfo";
break;
case (0x2a):
str = "FlushEntireDataCache";
break;
case (0x2b):
str = "FlushDataCache";
break;
case (0x2c):
str = "MapPhysicalMemory";
break;
case (0x2d):
str = "UnmapPhysicalMemory";
break;
case (0x2e):
str = "GetFutureThreadInfo";
break;
case (0x2f):
str = "GetLastThreadInfo";
break;
case (0x30):
str = "GetResourceLimitLimitValue";
break;
case (0x31):
str = "GetResourceLimitCurrentValue";
break;
case (0x32):
str = "SetThreadActivity";
break;
case (0x33):
str = "GetThreadContext3";
break;
case (0x34):
str = "WaitForAddress";
break;
case (0x35):
str = "SignalToAddress";
break;
case (0x36):
str = "svc36";
break;
case (0x37):
str = "svc37";
break;
case (0x38):
str = "svc38";
break;
case (0x39):
str = "svc39";
break;
case (0x3a):
str = "svc3A";
break;
case (0x3b):
str = "svc3B";
break;
case (0x3c):
str = "DumpInfo";
break;
case (0x3d):
str = "DumpInfoNew";
break;
case (0x3e):
str = "svc3E";
break;
case (0x3f):
str = "svc3F";
break;
case (0x40):
str = "CreateSession";
break;
case (0x41):
str = "AcceptSession";
break;
case (0x42):
str = "ReplyAndReceiveLight";
break;
case (0x43):
str = "ReplyAndReceive";
break;
case (0x44):
str = "ReplyAndReceiveWithUserBuffer";
break;
case (0x45):
str = "CreateEvent";
break;
case (0x46):
str = "svc46";
break;
case (0x47):
str = "svc47";
break;
case (0x48):
str = "MapPhysicalMemoryUnsafe";
break;
case (0x49):
str = "UnmapPhysicalMemoryUnsafe";
break;
case (0x4a):
str = "SetUnsafeLimit";
break;
case (0x4b):
str = "CreateCodeMemory";
break;
case (0x4c):
str = "ControlCodeMemory";
break;
case (0x4d):
str = "SleepSystem";
break;
case (0x4e):
str = "ReadWriteRegister";
break;
case (0x4f):
str = "SetProcessActivity";
break;
case (0x50):
str = "CreateSharedMemory";
break;
case (0x51):
str = "MapTransferMemory";
break;
case (0x52):
str = "UnmapTransferMemory";
break;
case (0x53):
str = "CreateInterruptEvent";
break;
case (0x54):
str = "QueryPhysicalAddress";
break;
case (0x55):
str = "QueryIoMapping";
break;
case (0x56):
str = "CreateDeviceAddressSpace";
break;
case (0x57):
str = "AttachDeviceAddressSpace";
break;
case (0x58):
str = "DetachDeviceAddressSpace";
break;
case (0x59):
str = "MapDeviceAddressSpaceByForce";
break;
case (0x5a):
str = "MapDeviceAddressSpaceAligned";
break;
case (0x5b):
str = "MapDeviceAddressSpace";
break;
case (0x5c):
str = "UnmapDeviceAddressSpace";
break;
case (0x5d):
str = "InvalidateProcessDataCache";
break;
case (0x5e):
str = "StoreProcessDataCache";
break;
case (0x5f):
str = "FlushProcessDataCache";
break;
case (0x60):
str = "DebugActiveProcess";
break;
case (0x61):
str = "BreakDebugProcess";
break;
case (0x62):
str = "TerminateDebugProcess";
break;
case (0x63):
str = "GetDebugEvent";
break;
case (0x64):
str = "ContinueDebugEvent";
break;
case (0x65):
str = "GetProcessList";
break;
case (0x66):
str = "GetThreadList";
break;
case (0x67):
str = "GetDebugThreadContext";
break;
case (0x68):
str = "SetDebugThreadContext";
break;
case (0x69):
str = "QueryDebugProcessMemory";
break;
case (0x6a):
str = "ReadDebugProcessMemory";
break;
case (0x6b):
str = "WriteDebugProcessMemory";
break;
case (0x6c):
str = "SetHardwareBreakPoint";
break;
case (0x6d):
str = "GetDebugThreadParam";
break;
case (0x6e):
str = "svc6E";
break;
case (0x6f):
str = "GetSystemInfo";
break;
case (0x70):
str = "CreatePort";
break;
case (0x71):
str = "ManageNamedPort";
break;
case (0x72):
str = "ConnectToPort";
break;
case (0x73):
str = "SetProcessMemoryPermission";
break;
case (0x74):
str = "MapProcessMemory";
break;
case (0x75):
str = "UnmapProcessMemory";
break;
case (0x76):
str = "QueryProcessMemory";
break;
case (0x77):
str = "MapProcessCodeMemory";
break;
case (0x78):
str = "UnmapProcessCodeMemory";
break;
case (0x79):
str = "CreateProcess";
break;
case (0x7a):
str = "StartProcess";
break;
case (0x7b):
str = "TerminateProcess";
break;
case (0x7c):
str = "GetProcessInfo";
break;
case (0x7d):
str = "CreateResourceLimit";
break;
case (0x7e):
str = "SetResourceLimitLimitValue";
break;
case (0x7f):
str = "CallSecureMonitor";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* KipProcess::getMemMapPermStr(nn::hac::MemoryMappingHandler::MemoryPerm type) const
{
const char* str = nullptr;
switch(type)
{
case (nn::hac::MemoryMappingHandler::MEM_RW):
str = "RW";
break;
case (nn::hac::MemoryMappingHandler::MEM_RO):
str = "RO";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* KipProcess::getMemMapTypeStr(nn::hac::MemoryMappingHandler::MappingType type) const
{
const char* str = nullptr;
switch(type)
{
case (nn::hac::MemoryMappingHandler::MAP_IO):
str = "Io";
break;
case (nn::hac::MemoryMappingHandler::MAP_STATIC):
str = "Static";
break;
default:
str = "Unknown";
break;
}
return str;
} }

View file

@ -33,12 +33,7 @@ private:
void displayHeader(); void displayHeader();
void displayKernelCap(const nn::hac::KernelCapabilityControl& kern); void displayKernelCap(const nn::hac::KernelCapabilityControl& kern);
const char* getProcessCategoryStr(nn::hac::kip::ProcessCategory var) const;
const char* getInstructionTypeStr(bool is64Bit) const; const char* getInstructionTypeStr(bool is64Bit) const;
const char* getAddressSpaceStr(bool is64Bit) const; const char* getAddressSpaceStr(bool is64Bit) const;
const char* getMemoryPoolStr(bool isSystemPool) const; const char* getMemoryPoolStr(bool isSystemPool) const;
const char* getMiscFlagStr(nn::hac::MiscFlagsHandler::Flags flag) const;
const char* getSystemCallStr(byte_t syscall_id) const;
const char* getMemMapPermStr(nn::hac::MemoryMappingHandler::MemoryPerm type) const;
const char* getMemMapTypeStr(nn::hac::MemoryMappingHandler::MappingType type) const;
}; };

View file

@ -1,6 +1,12 @@
#include "MetaProcess.h"
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include "MetaProcess.h"
#include <nn/hac/AccessControlInfoUtil.h>
#include <nn/hac/FileSystemAccessUtil.h>
#include <nn/hac/KernelCapabilityUtil.h>
#include <nn/hac/MetaUtil.h>
MetaProcess::MetaProcess() : MetaProcess::MetaProcess() :
mFile(), mFile(),
@ -120,7 +126,7 @@ void MetaProcess::validateAciFromAcid(const nn::hac::AccessControlInfo& aci, con
if (fsaRightFound == false) if (fsaRightFound == false)
{ {
std::cout << "[WARNING] ACI/FAC FsaRights: FAIL (" << getFsaRightStr(aci.getFileSystemAccessControl().getFsaRightsList()[i]) << " not permitted)" << std::endl; std::cout << "[WARNING] ACI/FAC FsaRights: FAIL (" << nn::hac::FileSystemAccessUtil::getFsaRightAsString(aci.getFileSystemAccessControl().getFsaRightsList()[i]) << " not permitted)" << std::endl;
} }
} }
@ -202,7 +208,7 @@ void MetaProcess::validateAciFromAcid(const nn::hac::AccessControlInfo& aci, con
if (rightFound == false) if (rightFound == false)
{ {
std::cout << "[WARNING] ACI/KC SystemCallList: FAIL (" << getSystemCallStr(aci.getKernelCapabilities().getSystemCalls().getSystemCalls()[i]) << " not permitted)" << std::endl; std::cout << "[WARNING] ACI/KC SystemCallList: FAIL (" << nn::hac::KernelCapabilityUtil::getSystemCallAsString(aci.getKernelCapabilities().getSystemCalls().getSystemCalls()[i]) << " not permitted)" << std::endl;
} }
} }
// check memory maps // check memory maps
@ -219,7 +225,7 @@ void MetaProcess::validateAciFromAcid(const nn::hac::AccessControlInfo& aci, con
{ {
const nn::hac::MemoryMappingHandler::sMemoryMapping& map = aci.getKernelCapabilities().getMemoryMaps().getMemoryMaps()[i]; const nn::hac::MemoryMappingHandler::sMemoryMapping& map = aci.getKernelCapabilities().getMemoryMaps().getMemoryMaps()[i];
std::cout << "[WARNING] ACI/KC MemoryMap: FAIL (0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)map.addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(map.addr + map.size) << 12) - 1) << " (perm=" << getMemMapPermStr(map.perm) << ") (type=" << getMemMapTypeStr(map.type) << ") not permitted)" << std::endl; std::cout << "[WARNING] ACI/KC MemoryMap: FAIL (0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)map.addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(map.addr + map.size) << 12) - 1) << " (perm=" << nn::hac::KernelCapabilityUtil::getMemMapPermAsString(map.perm) << ") (type=" << nn::hac::KernelCapabilityUtil::getMemMapTypeAsString(map.type) << ") not permitted)" << std::endl;
} }
} }
for (size_t i = 0; i < aci.getKernelCapabilities().getMemoryMaps().getIoMemoryMaps().size(); i++) for (size_t i = 0; i < aci.getKernelCapabilities().getMemoryMaps().getIoMemoryMaps().size(); i++)
@ -235,7 +241,7 @@ void MetaProcess::validateAciFromAcid(const nn::hac::AccessControlInfo& aci, con
{ {
const nn::hac::MemoryMappingHandler::sMemoryMapping& map = aci.getKernelCapabilities().getMemoryMaps().getIoMemoryMaps()[i]; const nn::hac::MemoryMappingHandler::sMemoryMapping& map = aci.getKernelCapabilities().getMemoryMaps().getIoMemoryMaps()[i];
std::cout << "[WARNING] ACI/KC IoMemoryMap: FAIL (0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)map.addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(map.addr + map.size) << 12) - 1) << " (perm=" << getMemMapPermStr(map.perm) << ") (type=" << getMemMapTypeStr(map.type) << ") not permitted)" << std::endl; std::cout << "[WARNING] ACI/KC IoMemoryMap: FAIL (0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)map.addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(map.addr + map.size) << 12) - 1) << " (perm=" << nn::hac::KernelCapabilityUtil::getMemMapPermAsString(map.perm) << ") (type=" << nn::hac::KernelCapabilityUtil::getMemMapTypeAsString(map.type) << ") not permitted)" << std::endl;
} }
} }
// check interupts // check interupts
@ -282,7 +288,7 @@ void MetaProcess::validateAciFromAcid(const nn::hac::AccessControlInfo& aci, con
if (rightFound == false) if (rightFound == false)
{ {
std::cout << "[WARNING] ACI/KC MiscFlag: FAIL (" << getMiscFlagStr(aci.getKernelCapabilities().getMiscFlags().getFlagList()[i]) << " not permitted)" << std::endl; std::cout << "[WARNING] ACI/KC MiscFlag: FAIL (" << nn::hac::KernelCapabilityUtil::getMiscFlagAsString(aci.getKernelCapabilities().getMiscFlags().getFlagList()[i]) << " not permitted)" << std::endl;
} }
} }
} }
@ -290,9 +296,10 @@ void MetaProcess::validateAciFromAcid(const nn::hac::AccessControlInfo& aci, con
void MetaProcess::displayMetaHeader(const nn::hac::Meta& hdr) void MetaProcess::displayMetaHeader(const nn::hac::Meta& hdr)
{ {
std::cout << "[Meta Header]" << std::endl; std::cout << "[Meta Header]" << std::endl;
std::cout << " ACID KeyGeneration: " << std::dec << hdr.getAcidKeyGeneration() << std::endl;
std::cout << " Process Architecture Params:" << std::endl; std::cout << " Process Architecture Params:" << std::endl;
std::cout << " Ins. Type: " << getInstructionTypeStr(hdr.getInstructionType()) << std::endl; std::cout << " Ins. Type: " << nn::hac::MetaUtil::getInstructionTypeAsString(hdr.getInstructionType()) << std::endl;
std::cout << " Addr Space: " << getProcAddressSpaceTypeStr(hdr.getProcAddressSpaceType()) << std::endl; std::cout << " Addr Space: " << nn::hac::MetaUtil::getProcAddressSpaceTypeAsString(hdr.getProcAddressSpaceType()) << std::endl;
std::cout << " Main Thread Params:" << std::endl; std::cout << " Main Thread Params:" << std::endl;
std::cout << " Priority: " << std::dec << (uint32_t)hdr.getMainThreadPriority() << std::endl; std::cout << " Priority: " << std::dec << (uint32_t)hdr.getMainThreadPriority() << std::endl;
std::cout << " CpuId: " << std::dec << (uint32_t)hdr.getMainThreadCpuId() << std::endl; std::cout << " CpuId: " << std::dec << (uint32_t)hdr.getMainThreadCpuId() << std::endl;
@ -320,9 +327,10 @@ void MetaProcess::displayAciDescHdr(const nn::hac::AccessControlInfoDesc& acid)
std::cout << " Flags: " << std::endl; std::cout << " Flags: " << std::endl;
for (size_t i = 0; i < acid.getFlagList().size(); i++) for (size_t i = 0; i < acid.getFlagList().size(); i++)
{ {
std::cout << " " << getAcidFlagStr(acid.getFlagList()[i]) << " (" << std::dec << (uint32_t)acid.getFlagList()[i] << ")" << std::endl; std::cout << " " << nn::hac::AccessControlInfoUtil::getAcidFlagAsString(acid.getFlagList()[i]) << " (" << std::dec << (uint32_t)acid.getFlagList()[i] << ")" << std::endl;
} }
} }
std::cout << " Memory Region: " << nn::hac::AccessControlInfoUtil::getMemoryRegionAsString(acid.getMemoryRegion()) << " (" << std::dec << (uint32_t)acid.getMemoryRegion() << ")" << std::endl;
std::cout << " ProgramID Restriction" << std::endl; std::cout << " ProgramID Restriction" << std::endl;
std::cout << " Min: 0x" << std::hex << std::setw(16) << std::setfill('0') << acid.getProgramIdRestrict().min << std::endl; std::cout << " Min: 0x" << std::hex << std::setw(16) << std::setfill('0') << acid.getProgramIdRestrict().min << std::endl;
std::cout << " Max: 0x" << std::hex << std::setw(16) << std::setfill('0') << acid.getProgramIdRestrict().max << std::endl; std::cout << " Max: 0x" << std::hex << std::setw(16) << std::setfill('0') << acid.getProgramIdRestrict().max << std::endl;
@ -344,7 +352,7 @@ void MetaProcess::displayFac(const nn::hac::FileSystemAccessControl& fac)
std::cout << std::endl; std::cout << std::endl;
std::cout << " "; std::cout << " ";
} }
std::cout << getFsaRightStr(fac.getFsaRightsList()[i]); std::cout << nn::hac::FileSystemAccessUtil::getFsaRightAsString(fac.getFsaRightsList()[i]);
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
std::cout << " (bit " << std::dec << (uint32_t)fac.getFsaRightsList()[i] << ")"; std::cout << " (bit " << std::dec << (uint32_t)fac.getFsaRightsList()[i] << ")";
if (fac.getFsaRightsList()[i] != fac.getFsaRightsList().atBack()) if (fac.getFsaRightsList()[i] != fac.getFsaRightsList().atBack())
@ -367,7 +375,7 @@ void MetaProcess::displayFac(const nn::hac::FileSystemAccessControl& fac)
std::cout << " Save Data Owner IDs:" << std::endl; std::cout << " Save Data Owner IDs:" << std::endl;
for (size_t i = 0; i < fac.getSaveDataOwnerIdList().size(); i++) for (size_t i = 0; i < fac.getSaveDataOwnerIdList().size(); i++)
{ {
std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << fac.getSaveDataOwnerIdList()[i].id << " (" << getSaveDataOwnerAccessModeStr(fac.getSaveDataOwnerIdList()[i].access_type) << ")" << std::endl; std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << fac.getSaveDataOwnerIdList()[i].id << " (" << nn::hac::FileSystemAccessUtil::getSaveDataOwnerAccessModeAsString(fac.getSaveDataOwnerIdList()[i].access_type) << ")" << std::endl;
} }
} }
@ -410,7 +418,7 @@ void MetaProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
if (kern.getSystemCalls().isSet()) if (kern.getSystemCalls().isSet())
{ {
fnd::List<uint8_t> syscalls = kern.getSystemCalls().getSystemCalls(); fnd::List<nn::hac::kc::SystemCall> syscalls = kern.getSystemCalls().getSystemCalls();
std::cout << " SystemCalls:" << std::endl; std::cout << " SystemCalls:" << std::endl;
std::cout << " "; std::cout << " ";
size_t lineLen = 0; size_t lineLen = 0;
@ -422,10 +430,11 @@ void MetaProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
std::cout << std::endl; std::cout << std::endl;
std::cout << " "; std::cout << " ";
} }
std::cout << getSystemCallStr(syscalls[i]); std::string syscall_name = nn::hac::KernelCapabilityUtil::getSystemCallAsString(syscalls[i]);
std::cout << syscall_name;
if (syscalls[i] != syscalls.atBack()) if (syscalls[i] != syscalls.atBack())
std::cout << ", "; std::cout << ", ";
lineLen += strlen(getSystemCallStr(syscalls[i])); lineLen += syscall_name.length();
} }
std::cout << std::endl; std::cout << std::endl;
} }
@ -437,12 +446,12 @@ void MetaProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
std::cout << " MemoryMaps:" << std::endl; std::cout << " MemoryMaps:" << std::endl;
for (size_t i = 0; i < maps.size(); i++) for (size_t i = 0; i < maps.size(); i++)
{ {
std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)maps[i].addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(maps[i].addr + maps[i].size) << 12) - 1) << " (perm=" << getMemMapPermStr(maps[i].perm) << ") (type=" << getMemMapTypeStr(maps[i].type) << ")" << std::endl; std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)maps[i].addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(maps[i].addr + maps[i].size) << 12) - 1) << " (perm=" << nn::hac::KernelCapabilityUtil::getMemMapPermAsString(maps[i].perm) << ") (type=" << nn::hac::KernelCapabilityUtil::getMemMapTypeAsString(maps[i].type) << ")" << std::endl;
} }
//std::cout << " IoMaps:" << std::endl; //std::cout << " IoMaps:" << std::endl;
for (size_t i = 0; i < ioMaps.size(); i++) for (size_t i = 0; i < ioMaps.size(); i++)
{ {
std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)ioMaps[i].addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(ioMaps[i].addr + ioMaps[i].size) << 12) - 1) << " (perm=" << getMemMapPermStr(ioMaps[i].perm) << ") (type=" << getMemMapTypeStr(ioMaps[i].type) << ")" << std::endl; std::cout << " 0x" << std::hex << std::setw(16) << std::setfill('0') << ((uint64_t)ioMaps[i].addr << 12) << " - 0x" << std::hex << std::setw(16) << std::setfill('0') << (((uint64_t)(ioMaps[i].addr + ioMaps[i].size) << 12) - 1) << " (perm=" << nn::hac::KernelCapabilityUtil::getMemMapPermAsString(ioMaps[i].perm) << ") (type=" << nn::hac::KernelCapabilityUtil::getMemMapTypeAsString(ioMaps[i].type) << ")" << std::endl;
} }
} }
if (kern.getInterupts().isSet()) if (kern.getInterupts().isSet())
@ -477,7 +486,7 @@ void MetaProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
} }
if (kern.getMiscFlags().isSet()) if (kern.getMiscFlags().isSet())
{ {
fnd::List<nn::hac::MiscFlagsHandler::Flags> flagList = kern.getMiscFlags().getFlagList(); fnd::List<nn::hac::kc::MiscFlags> flagList = kern.getMiscFlags().getFlagList();
std::cout << " Misc Flags:" << std::endl; std::cout << " Misc Flags:" << std::endl;
for (uint32_t i = 0; i < flagList.size(); i++) for (uint32_t i = 0; i < flagList.size(); i++)
@ -488,631 +497,10 @@ void MetaProcess::displayKernelCap(const nn::hac::KernelCapabilityControl& kern)
std::cout << std::endl; std::cout << std::endl;
std::cout << " "; std::cout << " ";
} }
std::cout << getMiscFlagStr(flagList[i]); std::cout << nn::hac::KernelCapabilityUtil::getMiscFlagAsString(flagList[i]);
if (flagList[i] != flagList.atBack()) if (flagList[i] != flagList.atBack())
std::cout << ", "; std::cout << ", ";
std::cout << std::endl; std::cout << std::endl;
} }
} }
}
const char* MetaProcess::getInstructionTypeStr(nn::hac::meta::InstructionType type) const
{
const char* str = nullptr;
switch(type)
{
case (nn::hac::meta::INSTR_32BIT):
str = "32Bit";
break;
case (nn::hac::meta::INSTR_64BIT):
str = "64Bit";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* MetaProcess::getProcAddressSpaceTypeStr(nn::hac::meta::ProcAddrSpaceType type) const
{
const char* str = nullptr;
switch(type)
{
case (nn::hac::meta::ADDR_SPACE_64BIT):
str = "64Bit";
break;
case (nn::hac::meta::ADDR_SPACE_32BIT):
str = "32Bit";
break;
case (nn::hac::meta::ADDR_SPACE_32BIT_NO_RESERVED):
str = "32Bit no reserved";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* MetaProcess::getAcidFlagStr(nn::hac::aci::Flag flag) const
{
const char* str = nullptr;
switch(flag)
{
case (nn::hac::aci::FLAG_PRODUCTION):
str = "Production";
break;
case (nn::hac::aci::FLAG_UNQUALIFIED_APPROVAL):
str = "UnqualifiedApproval";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* MetaProcess::getMiscFlagStr(nn::hac::MiscFlagsHandler::Flags flag) const
{
const char* str = nullptr;
switch(flag)
{
case (nn::hac::MiscFlagsHandler::FLAG_ENABLE_DEBUG):
str = "EnableDebug";
break;
case (nn::hac::MiscFlagsHandler::FLAG_FORCE_DEBUG):
str = "ForceDebug";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* MetaProcess::getFsaRightStr(nn::hac::fac::FsAccessFlag flag) const
{
const char* str = nullptr;
switch(flag)
{
case (nn::hac::fac::FSA_APPLICATION_INFO):
str = "ApplicationInfo";
break;
case (nn::hac::fac::FSA_BOOT_MODE_CONTROL):
str = "BootModeControl";
break;
case (nn::hac::fac::FSA_CALIBRATION):
str = "Calibration";
break;
case (nn::hac::fac::FSA_SYSTEM_SAVE_DATA):
str = "SystemSaveData";
break;
case (nn::hac::fac::FSA_GAME_CARD):
str = "GameCard";
break;
case (nn::hac::fac::FSA_SAVE_DATA_BACKUP):
str = "SaveDataBackUp";
break;
case (nn::hac::fac::FSA_SAVE_DATA_MANAGEMENT):
str = "SaveDataManagement";
break;
case (nn::hac::fac::FSA_BIS_ALL_RAW):
str = "BisAllRaw";
break;
case (nn::hac::fac::FSA_GAME_CARD_RAW):
str = "GameCardRaw";
break;
case (nn::hac::fac::FSA_GAME_CARD_PRIVATE):
str = "GameCardPrivate";
break;
case (nn::hac::fac::FSA_SET_TIME):
str = "SetTime";
break;
case (nn::hac::fac::FSA_CONTENT_MANAGER):
str = "ContentManager";
break;
case (nn::hac::fac::FSA_IMAGE_MANAGER):
str = "ImageManager";
break;
case (nn::hac::fac::FSA_CREATE_SAVE_DATA):
str = "CreateSaveData";
break;
case (nn::hac::fac::FSA_SYSTEM_SAVE_DATA_MANAGEMENT):
str = "SystemSaveDataManagement";
break;
case (nn::hac::fac::FSA_BIS_FILE_SYSTEM):
str = "BisFileSystem";
break;
case (nn::hac::fac::FSA_SYSTEM_UPDATE):
str = "SystemUpdate";
break;
case (nn::hac::fac::FSA_SAVE_DATA_META):
str = "SaveDataMeta";
break;
case (nn::hac::fac::FSA_DEVICE_SAVE_CONTROL):
str = "DeviceSaveData";
break;
case (nn::hac::fac::FSA_SETTINGS_CONTROL):
str = "SettingsControl";
break;
case (nn::hac::fac::FSA_DEBUG):
str = "Debug";
break;
case (nn::hac::fac::FSA_FULL_PERMISSION):
str = "FullPermission";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* MetaProcess::getSaveDataOwnerAccessModeStr(nn::hac::fac::SaveDataOwnerIdAccessType type) const
{
const char* str = nullptr;
switch(type)
{
case (nn::hac::fac::SDO_READ):
str = "Read";
break;
case (nn::hac::fac::SDO_WRITE):
str = "Write";
break;
case (nn::hac::fac::SDO_READWRITE):
str = "ReadWrite";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* MetaProcess::getSystemCallStr(byte_t syscall_id) const
{
const char* str = nullptr;
switch(syscall_id)
{
case (0x01):
str = "SetHeapSize";
break;
case (0x02):
str = "SetMemoryPermission";
break;
case (0x03):
str = "SetMemoryAttribute";
break;
case (0x04):
str = "MapMemory";
break;
case (0x05):
str = "UnmapMemory";
break;
case (0x06):
str = "QueryMemory";
break;
case (0x07):
str = "ExitProcess";
break;
case (0x08):
str = "CreateThread";
break;
case (0x09):
str = "StartThread";
break;
case (0x0a):
str = "ExitThread";
break;
case (0x0b):
str = "SleepThread";
break;
case (0x0c):
str = "GetThreadPriority";
break;
case (0x0d):
str = "SetThreadPriority";
break;
case (0x0e):
str = "GetThreadCoreMask";
break;
case (0x0f):
str = "SetThreadCoreMask";
break;
case (0x10):
str = "GetCurrentProcessorNumber";
break;
case (0x11):
str = "SignalEvent";
break;
case (0x12):
str = "ClearEvent";
break;
case (0x13):
str = "MapSharedMemory";
break;
case (0x14):
str = "UnmapSharedMemory";
break;
case (0x15):
str = "CreateTransferMemory";
break;
case (0x16):
str = "CloseHandle";
break;
case (0x17):
str = "ResetSignal";
break;
case (0x18):
str = "WaitSynchronization";
break;
case (0x19):
str = "CancelSynchronization";
break;
case (0x1a):
str = "ArbitrateLock";
break;
case (0x1b):
str = "ArbitrateUnlock";
break;
case (0x1c):
str = "WaitProcessWideKeyAtomic";
break;
case (0x1d):
str = "SignalProcessWideKey";
break;
case (0x1e):
str = "GetSystemTick";
break;
case (0x1f):
str = "ConnectToNamedPort";
break;
case (0x20):
str = "SendSyncRequestLight";
break;
case (0x21):
str = "SendSyncRequest";
break;
case (0x22):
str = "SendSyncRequestWithUserBuffer";
break;
case (0x23):
str = "SendAsyncRequestWithUserBuffer";
break;
case (0x24):
str = "GetProcessId";
break;
case (0x25):
str = "GetThreadId";
break;
case (0x26):
str = "Break";
break;
case (0x27):
str = "OutputDebugString";
break;
case (0x28):
str = "ReturnFromException";
break;
case (0x29):
str = "GetInfo";
break;
case (0x2a):
str = "FlushEntireDataCache";
break;
case (0x2b):
str = "FlushDataCache";
break;
case (0x2c):
str = "MapPhysicalMemory";
break;
case (0x2d):
str = "UnmapPhysicalMemory";
break;
case (0x2e):
str = "GetFutureThreadInfo";
break;
case (0x2f):
str = "GetLastThreadInfo";
break;
case (0x30):
str = "GetResourceLimitLimitValue";
break;
case (0x31):
str = "GetResourceLimitCurrentValue";
break;
case (0x32):
str = "SetThreadActivity";
break;
case (0x33):
str = "GetThreadContext3";
break;
case (0x34):
str = "WaitForAddress";
break;
case (0x35):
str = "SignalToAddress";
break;
case (0x36):
str = "svc36";
break;
case (0x37):
str = "svc37";
break;
case (0x38):
str = "svc38";
break;
case (0x39):
str = "svc39";
break;
case (0x3a):
str = "svc3A";
break;
case (0x3b):
str = "svc3B";
break;
case (0x3c):
str = "DumpInfo";
break;
case (0x3d):
str = "DumpInfoNew";
break;
case (0x3e):
str = "svc3E";
break;
case (0x3f):
str = "svc3F";
break;
case (0x40):
str = "CreateSession";
break;
case (0x41):
str = "AcceptSession";
break;
case (0x42):
str = "ReplyAndReceiveLight";
break;
case (0x43):
str = "ReplyAndReceive";
break;
case (0x44):
str = "ReplyAndReceiveWithUserBuffer";
break;
case (0x45):
str = "CreateEvent";
break;
case (0x46):
str = "svc46";
break;
case (0x47):
str = "svc47";
break;
case (0x48):
str = "MapPhysicalMemoryUnsafe";
break;
case (0x49):
str = "UnmapPhysicalMemoryUnsafe";
break;
case (0x4a):
str = "SetUnsafeLimit";
break;
case (0x4b):
str = "CreateCodeMemory";
break;
case (0x4c):
str = "ControlCodeMemory";
break;
case (0x4d):
str = "SleepSystem";
break;
case (0x4e):
str = "ReadWriteRegister";
break;
case (0x4f):
str = "SetProcessActivity";
break;
case (0x50):
str = "CreateSharedMemory";
break;
case (0x51):
str = "MapTransferMemory";
break;
case (0x52):
str = "UnmapTransferMemory";
break;
case (0x53):
str = "CreateInterruptEvent";
break;
case (0x54):
str = "QueryPhysicalAddress";
break;
case (0x55):
str = "QueryIoMapping";
break;
case (0x56):
str = "CreateDeviceAddressSpace";
break;
case (0x57):
str = "AttachDeviceAddressSpace";
break;
case (0x58):
str = "DetachDeviceAddressSpace";
break;
case (0x59):
str = "MapDeviceAddressSpaceByForce";
break;
case (0x5a):
str = "MapDeviceAddressSpaceAligned";
break;
case (0x5b):
str = "MapDeviceAddressSpace";
break;
case (0x5c):
str = "UnmapDeviceAddressSpace";
break;
case (0x5d):
str = "InvalidateProcessDataCache";
break;
case (0x5e):
str = "StoreProcessDataCache";
break;
case (0x5f):
str = "FlushProcessDataCache";
break;
case (0x60):
str = "DebugActiveProcess";
break;
case (0x61):
str = "BreakDebugProcess";
break;
case (0x62):
str = "TerminateDebugProcess";
break;
case (0x63):
str = "GetDebugEvent";
break;
case (0x64):
str = "ContinueDebugEvent";
break;
case (0x65):
str = "GetProcessList";
break;
case (0x66):
str = "GetThreadList";
break;
case (0x67):
str = "GetDebugThreadContext";
break;
case (0x68):
str = "SetDebugThreadContext";
break;
case (0x69):
str = "QueryDebugProcessMemory";
break;
case (0x6a):
str = "ReadDebugProcessMemory";
break;
case (0x6b):
str = "WriteDebugProcessMemory";
break;
case (0x6c):
str = "SetHardwareBreakPoint";
break;
case (0x6d):
str = "GetDebugThreadParam";
break;
case (0x6e):
str = "svc6E";
break;
case (0x6f):
str = "GetSystemInfo";
break;
case (0x70):
str = "CreatePort";
break;
case (0x71):
str = "ManageNamedPort";
break;
case (0x72):
str = "ConnectToPort";
break;
case (0x73):
str = "SetProcessMemoryPermission";
break;
case (0x74):
str = "MapProcessMemory";
break;
case (0x75):
str = "UnmapProcessMemory";
break;
case (0x76):
str = "QueryProcessMemory";
break;
case (0x77):
str = "MapProcessCodeMemory";
break;
case (0x78):
str = "UnmapProcessCodeMemory";
break;
case (0x79):
str = "CreateProcess";
break;
case (0x7a):
str = "StartProcess";
break;
case (0x7b):
str = "TerminateProcess";
break;
case (0x7c):
str = "GetProcessInfo";
break;
case (0x7d):
str = "CreateResourceLimit";
break;
case (0x7e):
str = "SetResourceLimitLimitValue";
break;
case (0x7f):
str = "CallSecureMonitor";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* MetaProcess::getMemMapPermStr(nn::hac::MemoryMappingHandler::MemoryPerm type) const
{
const char* str = nullptr;
switch(type)
{
case (nn::hac::MemoryMappingHandler::MEM_RW):
str = "RW";
break;
case (nn::hac::MemoryMappingHandler::MEM_RO):
str = "RO";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* MetaProcess::getMemMapTypeStr(nn::hac::MemoryMappingHandler::MappingType type) const
{
const char* str = nullptr;
switch(type)
{
case (nn::hac::MemoryMappingHandler::MAP_IO):
str = "Io";
break;
case (nn::hac::MemoryMappingHandler::MAP_STATIC):
str = "Static";
break;
default:
str = "Unknown";
break;
}
return str;
} }

View file

@ -43,14 +43,4 @@ private:
void displayFac(const nn::hac::FileSystemAccessControl& fac); void displayFac(const nn::hac::FileSystemAccessControl& fac);
void displaySac(const nn::hac::ServiceAccessControl& sac); void displaySac(const nn::hac::ServiceAccessControl& sac);
void displayKernelCap(const nn::hac::KernelCapabilityControl& kern); void displayKernelCap(const nn::hac::KernelCapabilityControl& kern);
const char* getInstructionTypeStr(nn::hac::meta::InstructionType type) const;
const char* getProcAddressSpaceTypeStr(nn::hac::meta::ProcAddrSpaceType type) const;
const char* getAcidFlagStr(nn::hac::aci::Flag flag) const;
const char* getMiscFlagStr(nn::hac::MiscFlagsHandler::Flags flag) const;
const char* getFsaRightStr(nn::hac::fac::FsAccessFlag flag) const;
const char* getSaveDataOwnerAccessModeStr(nn::hac::fac::SaveDataOwnerIdAccessType type) const;
const char* getSystemCallStr(byte_t syscall_id) const;
const char* getMemMapPermStr(nn::hac::MemoryMappingHandler::MemoryPerm type) const;
const char* getMemMapTypeStr(nn::hac::MemoryMappingHandler::MappingType type) const;
}; };

View file

@ -1,9 +1,13 @@
#include "NacpProcess.h"
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <fnd/OffsetAdjustedIFile.h> #include <fnd/OffsetAdjustedIFile.h>
#include "NacpProcess.h"
#include <nn/hac/ApplicationControlPropertyUtil.h>
NacpProcess::NacpProcess() : NacpProcess::NacpProcess() :
mFile(), mFile(),
@ -64,20 +68,20 @@ void NacpProcess::displayNacp()
std::cout << " ISBN: " << mNacp.getIsbn() << std::endl; std::cout << " ISBN: " << mNacp.getIsbn() << std::endl;
for (size_t i = 0; i < mNacp.getTitle().size(); i++) for (size_t i = 0; i < mNacp.getTitle().size(); i++)
{ {
std::cout << " " << getLanguageStr(mNacp.getTitle()[i].language) << " Title:" << std::endl; std::cout << " " << nn::hac::ApplicationControlPropertyUtil::getLanguageAsString(mNacp.getTitle()[i].language) << " Title:" << std::endl;
std::cout << " Name: " << mNacp.getTitle()[i].name << std::endl; std::cout << " Name: " << mNacp.getTitle()[i].name << std::endl;
std::cout << " Publisher: " << mNacp.getTitle()[i].publisher << std::endl; std::cout << " Publisher: " << mNacp.getTitle()[i].publisher << std::endl;
} }
std::cout << " Logo:" << std::endl; std::cout << " Logo:" << std::endl;
std::cout << " Type: " << getLogoTypeStr(mNacp.getLogoType()) << std::endl; std::cout << " Type: " << nn::hac::ApplicationControlPropertyUtil::getLogoTypeAsString(mNacp.getLogoType()) << std::endl;
std::cout << " Handling: " << getLogoHandlingStr(mNacp.getLogoHandling()) << std::endl; std::cout << " Handling: " << nn::hac::ApplicationControlPropertyUtil::getLogoHandlingAsString(mNacp.getLogoHandling()) << std::endl;
std::cout << " AddOnContent:" << std::endl; std::cout << " AddOnContent:" << std::endl;
std::cout << " BaseId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mNacp.getAocBaseId() << std::endl; std::cout << " BaseId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mNacp.getAocBaseId() << std::endl;
std::cout << " RegistrationType: " << getAocRegistrationTypeStr(mNacp.getAocRegistrationType()) << std::endl; std::cout << " RegistrationType: " << nn::hac::ApplicationControlPropertyUtil::getAocRegistrationTypeAsString(mNacp.getAocRegistrationType()) << std::endl;
std::cout << " RuntimeInstallMode: " << getRuntimeAocInstallModeStr(mNacp.getRuntimeAocInstallMode()) << std::endl; std::cout << " RuntimeInstallMode: " << nn::hac::ApplicationControlPropertyUtil::getRuntimeAocInstallModeAsString(mNacp.getRuntimeAocInstallMode()) << std::endl;
std::cout << " Play Log:" << std::endl; std::cout << " Play Log:" << std::endl;
std::cout << " PlayLogPolicy: " << getPlayLogPolicyStr(mNacp.getPlayLogPolicy()) << std::endl; std::cout << " PlayLogPolicy: " << nn::hac::ApplicationControlPropertyUtil::getPlayLogPolicyAsString(mNacp.getPlayLogPolicy()) << std::endl;
std::cout << " PlayLogQueryCapability: " << getPlayLogQueryCapabilityStr(mNacp.getPlayLogQueryCapability()) << std::endl; std::cout << " PlayLogQueryCapability: " << nn::hac::ApplicationControlPropertyUtil::getPlayLogQueryCapabilityAsString(mNacp.getPlayLogQueryCapability()) << std::endl;
if (mNacp.getPlayLogQueryableApplicationId().size() > 0) if (mNacp.getPlayLogQueryableApplicationId().size() > 0)
{ {
std::cout << " PlayLogQueryableApplicationId:" << std::endl; std::cout << " PlayLogQueryableApplicationId:" << std::endl;
@ -87,11 +91,11 @@ void NacpProcess::displayNacp()
} }
} }
std::cout << " Parental Controls:" << std::endl; std::cout << " Parental Controls:" << std::endl;
std::cout << " ParentalControlFlag: " << getParentalControlFlagStr(mNacp.getParentalControlFlag()) << std::endl; std::cout << " ParentalControlFlag: " << nn::hac::ApplicationControlPropertyUtil::getParentalControlFlagAsString(mNacp.getParentalControlFlag()) << std::endl;
for (size_t i = 0; i < mNacp.getRatingAge().size(); i++) for (size_t i = 0; i < mNacp.getRatingAge().size(); i++)
{ {
std::cout << " Age Restriction:" << std::endl; std::cout << " Age Restriction:" << std::endl;
std::cout << " Agency: " << getOrganisationStr(mNacp.getRatingAge()[i].organisation) << std::endl; std::cout << " Agency: " << nn::hac::ApplicationControlPropertyUtil::getOrganisationAsString(mNacp.getRatingAge()[i].organisation) << std::endl;
std::cout << " Age: " << std::dec << (uint32_t)mNacp.getRatingAge()[i].age << std::endl; std::cout << " Age: " << std::dec << (uint32_t)mNacp.getRatingAge()[i].age << std::endl;
} }
@ -115,51 +119,51 @@ void NacpProcess::displayNacp()
if (mNacp.getUserAccountSaveDataSize().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getUserAccountSaveDataSize().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
{ {
std::cout << " UserAccountSaveData:" << std::endl; std::cout << " UserAccountSaveData:" << std::endl;
std::cout << " Size: " << getSaveDataSizeStr(mNacp.getUserAccountSaveDataSize().size) << std::endl; std::cout << " Size: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getUserAccountSaveDataSize().size) << std::endl;
std::cout << " JournalSize: " << getSaveDataSizeStr(mNacp.getUserAccountSaveDataSize().journal_size) << std::endl; std::cout << " JournalSize: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getUserAccountSaveDataSize().journal_size) << std::endl;
} }
if (mNacp.getDeviceSaveDataSize().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getDeviceSaveDataSize().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
{ {
std::cout << " DeviceSaveData:" << std::endl; std::cout << " DeviceSaveData:" << std::endl;
std::cout << " Size: " << getSaveDataSizeStr(mNacp.getDeviceSaveDataSize().size) << std::endl; std::cout << " Size: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getDeviceSaveDataSize().size) << std::endl;
std::cout << " JournalSize: " << getSaveDataSizeStr(mNacp.getDeviceSaveDataSize().journal_size) << std::endl; std::cout << " JournalSize: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getDeviceSaveDataSize().journal_size) << std::endl;
} }
if (mNacp.getUserAccountSaveDataMax().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getUserAccountSaveDataMax().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
{ {
std::cout << " UserAccountSaveDataMax:" << std::endl; std::cout << " UserAccountSaveDataMax:" << std::endl;
std::cout << " Size: " << getSaveDataSizeStr(mNacp.getUserAccountSaveDataMax().size) << std::endl; std::cout << " Size: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getUserAccountSaveDataMax().size) << std::endl;
std::cout << " JournalSize: " << getSaveDataSizeStr(mNacp.getUserAccountSaveDataMax().journal_size) << std::endl; std::cout << " JournalSize: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getUserAccountSaveDataMax().journal_size) << std::endl;
} }
if (mNacp.getDeviceSaveDataMax().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getDeviceSaveDataMax().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
{ {
std::cout << " DeviceSaveDataMax:" << std::endl; std::cout << " DeviceSaveDataMax:" << std::endl;
std::cout << " Size: " << getSaveDataSizeStr(mNacp.getDeviceSaveDataMax().size) << std::endl; std::cout << " Size: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getDeviceSaveDataMax().size) << std::endl;
std::cout << " JournalSize: " << getSaveDataSizeStr(mNacp.getDeviceSaveDataMax().journal_size) << std::endl; std::cout << " JournalSize: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getDeviceSaveDataMax().journal_size) << std::endl;
} }
if (mNacp.getTemporaryStorageSize() > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getTemporaryStorageSize() > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
{ {
std::cout << " TemporaryStorageSize: " << getSaveDataSizeStr(mNacp.getTemporaryStorageSize()) << std::endl; std::cout << " TemporaryStorageSize: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getTemporaryStorageSize()) << std::endl;
} }
if (mNacp.getCacheStorageSize().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getCacheStorageSize().journal_size > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
{ {
std::cout << " CacheStorage:" << std::endl; std::cout << " CacheStorage:" << std::endl;
std::cout << " Size: " << getSaveDataSizeStr(mNacp.getCacheStorageSize().size) << std::endl; std::cout << " Size: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getCacheStorageSize().size) << std::endl;
std::cout << " JournalSize: " << getSaveDataSizeStr(mNacp.getCacheStorageSize().journal_size) << std::endl; std::cout << " JournalSize: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getCacheStorageSize().journal_size) << std::endl;
std::cout << " MaxDataAndJournalSize: " << getSaveDataSizeStr(mNacp.getCacheStorageDataAndJournalSizeMax()) << std::endl; std::cout << " MaxDataAndJournalSize: " << nn::hac::ApplicationControlPropertyUtil::getSaveDataSizeAsString(mNacp.getCacheStorageDataAndJournalSizeMax()) << std::endl;
std::cout << " StorageIndexMax: 0x" << std::hex << mNacp.getCacheStorageIndexMax() << std::endl; std::cout << " StorageIndexMax: 0x" << std::hex << mNacp.getCacheStorageIndexMax() << std::endl;
} }
std::cout << " Other Flags:" << std::endl; std::cout << " Other Flags:" << std::endl;
std::cout << " StartupUserAccount: " << getStartupUserAccountStr(mNacp.getStartupUserAccount()) << std::endl; std::cout << " StartupUserAccount: " << nn::hac::ApplicationControlPropertyUtil::getStartupUserAccountAsString(mNacp.getStartupUserAccount()) << std::endl;
std::cout << " UserAccountSwitchLock: " << getUserAccountSwitchLockValueStr(mNacp.getUserAccountSwitchLockValue()) << std::endl; std::cout << " UserAccountSwitchLock: " << nn::hac::ApplicationControlPropertyUtil::getUserAccountSwitchLockValueAsString(mNacp.getUserAccountSwitchLockValue()) << std::endl;
std::cout << " AttributeFlag: " << getAttributeFlagStr(mNacp.getAttributeFlag()) << std::endl; std::cout << " AttributeFlag: " << nn::hac::ApplicationControlPropertyUtil::getAttributeFlagAsString(mNacp.getAttributeFlag()) << std::endl;
std::cout << " CrashReportMode: " << getCrashReportModeStr(mNacp.getCrashReportMode()) << std::endl; std::cout << " CrashReportMode: " << nn::hac::ApplicationControlPropertyUtil::getCrashReportModeAsString(mNacp.getCrashReportMode()) << std::endl;
std::cout << " HDCP: " << getHdcpStr(mNacp.getHdcp()) << std::endl; std::cout << " HDCP: " << nn::hac::ApplicationControlPropertyUtil::getHdcpAsString(mNacp.getHdcp()) << std::endl;
std::cout << " ScreenshotMode: " << getScreenshotModeStr(mNacp.getScreenshotMode()) << std::endl; std::cout << " ScreenshotMode: " << nn::hac::ApplicationControlPropertyUtil::getScreenshotModeAsString(mNacp.getScreenshotMode()) << std::endl;
std::cout << " VideoCaptureMode: " << getVideoCaptureModeStr(mNacp.getVideoCaptureMode()) << std::endl; std::cout << " VideoCaptureMode: " << nn::hac::ApplicationControlPropertyUtil::getVideoCaptureModeAsString(mNacp.getVideoCaptureMode()) << std::endl;
std::cout << " DataLossConfirmation: " << getDataLossConfirmationStr(mNacp.getDataLossConfirmation()) << std::endl; std::cout << " DataLossConfirmation: " << nn::hac::ApplicationControlPropertyUtil::getDataLossConfirmationAsString(mNacp.getDataLossConfirmation()) << std::endl;
std::cout << " RepairFlag: " << getRepairFlagStr(mNacp.getRepairFlag()) << std::endl; std::cout << " RepairFlag: " << nn::hac::ApplicationControlPropertyUtil::getRepairFlagAsString(mNacp.getRepairFlag()) << std::endl;
std::cout << " ProgramIndex: 0x" << std::hex << std::setw(2) << std::setfill('0') << (uint32_t)mNacp.getProgramIndex() << std::endl; std::cout << " ProgramIndex: 0x" << std::hex << std::setw(2) << std::setfill('0') << (uint32_t)mNacp.getProgramIndex() << std::endl;
std::cout << " Req NetworkLicenseOnLaunch: " << getRequiredNetworkServiceLicenseOnLaunchValueStr(mNacp.getRequiredNetworkServiceLicenseOnLaunchValue()) << std::endl; std::cout << " Req NetworkLicenseOnLaunch: " << nn::hac::ApplicationControlPropertyUtil::getRequiredNetworkServiceLicenseOnLaunchValueAsString(mNacp.getRequiredNetworkServiceLicenseOnLaunchValue()) << std::endl;
if (mNacp.getApplicationErrorCodeCategory().empty() == false || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getApplicationErrorCodeCategory().empty() == false || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
{ {
std::cout << " ApplicationErrorCodeCategory: " << mNacp.getApplicationErrorCodeCategory() << std::endl; std::cout << " ApplicationErrorCodeCategory: " << mNacp.getApplicationErrorCodeCategory() << std::endl;
@ -172,498 +176,4 @@ void NacpProcess::displayNacp()
if (mNacp.getPresenceGroupId() > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getPresenceGroupId() > 0 || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
std::cout << " PresenceGroupId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mNacp.getPresenceGroupId() << std::endl; std::cout << " PresenceGroupId: 0x" << std::hex << std::setw(16) << std::setfill('0') << mNacp.getPresenceGroupId() << std::endl;
} }
}
const char* NacpProcess::getLanguageStr(nn::hac::nacp::Language var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::LANG_AmericanEnglish):
str = "AmericanEnglish";
break;
case (nn::hac::nacp::LANG_BritishEnglish):
str = "BritishEnglish";
break;
case (nn::hac::nacp::LANG_Japanese):
str = "Japanese";
break;
case (nn::hac::nacp::LANG_French):
str = "French";
break;
case (nn::hac::nacp::LANG_German):
str = "German";
break;
case (nn::hac::nacp::LANG_LatinAmericanSpanish):
str = "LatinAmericanSpanish";
break;
case (nn::hac::nacp::LANG_Spanish):
str = "Spanish";
break;
case (nn::hac::nacp::LANG_Italian):
str = "Italian";
break;
case (nn::hac::nacp::LANG_Dutch):
str = "Dutch";
break;
case (nn::hac::nacp::LANG_CanadianFrench):
str = "CanadianFrench";
break;
case (nn::hac::nacp::LANG_Portuguese):
str = "Portuguese";
break;
case (nn::hac::nacp::LANG_Russian):
str = "Russian";
break;
case (nn::hac::nacp::LANG_Korean):
str = "Korean";
break;
case (nn::hac::nacp::LANG_TraditionalChinese):
str = "TraditionalChinese";
break;
case (nn::hac::nacp::LANG_SimplifiedChinese):
str = "SimplifiedChinese";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getStartupUserAccountStr(nn::hac::nacp::StartupUserAccount var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::USER_None):
str = "None";
break;
case (nn::hac::nacp::USER_Required):
str = "Required";
break;
case (nn::hac::nacp::USER_RequiredWithNetworkServiceAccountAvailable):
str = "RequiredWithNetworkServiceAccountAvailable";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getTouchScreenUsageModeStr(nn::hac::nacp::TouchScreenUsageMode var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::TOUCH_None):
str = "None";
break;
case (nn::hac::nacp::TOUCH_Supported):
str = "Supported";
break;
case (nn::hac::nacp::TOUCH_Required):
str = "Required";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getUserAccountSwitchLockValueStr(nn::hac::nacp::UserAccountSwitchLockValue var) const
{
const char* str = nullptr;
switch (var)
{
case (nn::hac::nacp::UASL_Disable):
str = "Disable";
break;
case (nn::hac::nacp::UASL_Enable):
str = "Enable";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getAocRegistrationTypeStr(nn::hac::nacp::AocRegistrationType var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::AOC_AllOnLaunch):
str = "AllOnLaunch";
break;
case (nn::hac::nacp::AOC_OnDemand):
str = "OnDemand";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getAttributeFlagStr(nn::hac::nacp::AttributeFlag var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::ATTR_None):
str = "None";
break;
case (nn::hac::nacp::ATTR_Demo):
str = "Demo";
break;
case (nn::hac::nacp::ATTR_RetailInteractiveDisplay):
str = "RetailInteractiveDisplay";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getParentalControlFlagStr(nn::hac::nacp::ParentalControlFlag var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::PC_None):
str = "None";
break;
case (nn::hac::nacp::PC_FreeCommunication):
str = "FreeCommunication";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getScreenshotModeStr(nn::hac::nacp::ScreenshotMode var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::SCRN_Allow):
str = "Allow";
break;
case (nn::hac::nacp::SCRN_Deny):
str = "Deny";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getVideoCaptureModeStr(nn::hac::nacp::VideoCaptureMode var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::VCAP_Disable):
str = "Disable";
break;
case (nn::hac::nacp::VCAP_Manual):
str = "Manual";
break;
case (nn::hac::nacp::VCAP_Enable):
str = "Enable";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getDataLossConfirmationStr(nn::hac::nacp::DataLossConfirmation var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::DLOSS_None):
str = "None";
break;
case (nn::hac::nacp::DLOSS_Required):
str = "Required";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getPlayLogPolicyStr(nn::hac::nacp::PlayLogPolicy var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::PLP_All):
str = "All";
break;
case (nn::hac::nacp::PLP_LogOnly):
str = "LogOnly";
break;
case (nn::hac::nacp::PLP_None):
str = "None";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getOrganisationStr(nn::hac::nacp::Organisation var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::ORGN_CERO):
str = "CERO";
break;
case (nn::hac::nacp::ORGN_GRACGCRB):
str = "GRACGCRB";
break;
case (nn::hac::nacp::ORGN_GSRMR):
str = "GSRMR";
break;
case (nn::hac::nacp::ORGN_ESRB):
str = "ESRB";
break;
case (nn::hac::nacp::ORGN_ClassInd):
str = "ClassInd";
break;
case (nn::hac::nacp::ORGN_USK):
str = "USK";
break;
case (nn::hac::nacp::ORGN_PEGI):
str = "PEGI";
break;
case (nn::hac::nacp::ORGN_PEGIPortugal):
str = "PEGIPortugal";
break;
case (nn::hac::nacp::ORGN_PEGIBBFC):
str = "PEGIBBFC";
break;
case (nn::hac::nacp::ORGN_Russian):
str = "Russian";
break;
case (nn::hac::nacp::ORGN_ACB):
str = "ACB";
break;
case (nn::hac::nacp::ORGN_OFLC):
str = "OFLC";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getLogoTypeStr(nn::hac::nacp::LogoType var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::LOGO_LicensedByNintendo):
str = "LicensedByNintendo";
break;
case (nn::hac::nacp::LOGO_DistributedByNintendo):
str = "DistributedByNintendo";
break;
case (nn::hac::nacp::LOGO_Nintendo):
str = "Nintendo";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getLogoHandlingStr(nn::hac::nacp::LogoHandling var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::LHND_Auto):
str = "Auto";
break;
case (nn::hac::nacp::LHND_None):
str = "None";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getRuntimeAocInstallModeStr(nn::hac::nacp::RuntimeAocInstallMode var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::RTAOC_Deny):
str = "Deny";
break;
case (nn::hac::nacp::RTAOC_AllowAppend):
str = "AllowAppend";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getCrashReportModeStr(nn::hac::nacp::CrashReportMode var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::CREP_Deny):
str = "Deny";
break;
case (nn::hac::nacp::CREP_Allow):
str = "Allow";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getHdcpStr(nn::hac::nacp::Hdcp var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::HDCP_None):
str = "None";
break;
case (nn::hac::nacp::HDCP_Required):
str = "Required";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getPlayLogQueryCapabilityStr(nn::hac::nacp::PlayLogQueryCapability var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::PLQC_None):
str = "None";
break;
case (nn::hac::nacp::PLQC_Whitelist):
str = "Whitelist";
break;
case (nn::hac::nacp::PLQC_All):
str = "All";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getRepairFlagStr(nn::hac::nacp::RepairFlag var) const
{
const char* str = nullptr;
switch(var)
{
case (nn::hac::nacp::REPF_None):
str = "None";
break;
case (nn::hac::nacp::REPF_SuppressGameCardAccess):
str = "SuppressGameCardAccess";
break;
default:
str = "Unknown";
}
return str;
}
const char* NacpProcess::getRequiredNetworkServiceLicenseOnLaunchValueStr(nn::hac::nacp::RequiredNetworkServiceLicenseOnLaunchValue var) const
{
const char* str = nullptr;
switch (var)
{
case (nn::hac::nacp::REQNETLIC_None):
str = "None";
break;
case (nn::hac::nacp::REQNETLIC_Common):
str = "Common";
break;
default:
str = "Unknown";
}
return str;
}
std::string NacpProcess::getSaveDataSizeStr(int64_t size) const
{
static const int64_t kKiloByte = 1024;
static const int64_t kMegaByte = 1024 * 1024;
std::stringstream sstr;
if (size < kKiloByte)
{
sstr << size << " B";
}
else if (size < kMegaByte)
{
sstr << (size/kKiloByte) << " KB";
}
else
{
sstr << (size/kMegaByte) << " MB";
}
return sstr.str();
} }

View file

@ -31,25 +31,4 @@ private:
void importNacp(); void importNacp();
void displayNacp(); void displayNacp();
const char* getLanguageStr(nn::hac::nacp::Language var) const;
const char* getStartupUserAccountStr(nn::hac::nacp::StartupUserAccount var) const;
const char* getUserAccountSwitchLockValueStr(nn::hac::nacp::UserAccountSwitchLockValue var) const;
const char* getTouchScreenUsageModeStr(nn::hac::nacp::TouchScreenUsageMode var) const;
const char* getAocRegistrationTypeStr(nn::hac::nacp::AocRegistrationType var) const;
const char* getAttributeFlagStr(nn::hac::nacp::AttributeFlag var) const;
const char* getParentalControlFlagStr(nn::hac::nacp::ParentalControlFlag var) const;
const char* getScreenshotModeStr(nn::hac::nacp::ScreenshotMode var) const;
const char* getVideoCaptureModeStr(nn::hac::nacp::VideoCaptureMode var) const;
const char* getDataLossConfirmationStr(nn::hac::nacp::DataLossConfirmation var) const;
const char* getPlayLogPolicyStr(nn::hac::nacp::PlayLogPolicy var) const;
const char* getOrganisationStr(nn::hac::nacp::Organisation var) const;
const char* getLogoTypeStr(nn::hac::nacp::LogoType var) const;
const char* getLogoHandlingStr(nn::hac::nacp::LogoHandling var) const;
const char* getRuntimeAocInstallModeStr(nn::hac::nacp::RuntimeAocInstallMode var) const;
const char* getCrashReportModeStr(nn::hac::nacp::CrashReportMode var) const;
const char* getHdcpStr(nn::hac::nacp::Hdcp var) const;
const char* getPlayLogQueryCapabilityStr(nn::hac::nacp::PlayLogQueryCapability var) const;
const char* getRepairFlagStr(nn::hac::nacp::RepairFlag var) const;
const char* getRequiredNetworkServiceLicenseOnLaunchValueStr(nn::hac::nacp::RequiredNetworkServiceLicenseOnLaunchValue var) const;
std::string getSaveDataSizeStr(int64_t size) const;
}; };

View file

@ -1,19 +1,22 @@
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fnd/SimpleTextOutput.h>
#include <fnd/OffsetAdjustedIFile.h>
#include <fnd/AesCtrWrappedIFile.h>
#include <fnd/LayeredIntegrityWrappedIFile.h>
#include <nn/hac/ContentArchiveUtils.h>
#include <nn/hac/AesKeygen.h>
#include <nn/hac/HierarchicalSha256Header.h>
#include <nn/hac/HierarchicalIntegrityHeader.h>
#include "NcaProcess.h" #include "NcaProcess.h"
#include "PfsProcess.h" #include "PfsProcess.h"
#include "RomfsProcess.h" #include "RomfsProcess.h"
#include "MetaProcess.h" #include "MetaProcess.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fnd/SimpleTextOutput.h>
#include <fnd/OffsetAdjustedIFile.h>
#include <fnd/AesCtrWrappedIFile.h>
#include <fnd/LayeredIntegrityWrappedIFile.h>
#include <nn/hac/ContentArchiveUtil.h>
#include <nn/hac/AesKeygen.h>
#include <nn/hac/HierarchicalSha256Header.h>
#include <nn/hac/HierarchicalIntegrityHeader.h>
NcaProcess::NcaProcess() : NcaProcess::NcaProcess() :
mFile(), mFile(),
@ -112,7 +115,7 @@ void NcaProcess::importHeader()
// decrypt header block // decrypt header block
fnd::aes::sAesXts128Key header_key; fnd::aes::sAesXts128Key header_key;
mKeyCfg.getContentArchiveHeaderKey(header_key); mKeyCfg.getContentArchiveHeaderKey(header_key);
nn::hac::ContentArchiveUtils::decryptContentArchiveHeader((byte_t*)&mHdrBlock, (byte_t*)&mHdrBlock, header_key); nn::hac::ContentArchiveUtil::decryptContentArchiveHeader((byte_t*)&mHdrBlock, (byte_t*)&mHdrBlock, header_key);
// generate header hash // generate header hash
fnd::sha::Sha256((byte_t*)&mHdrBlock.header, sizeof(nn::hac::sContentArchiveHeader), mHdrHash.bytes); fnd::sha::Sha256((byte_t*)&mHdrBlock.header, sizeof(nn::hac::sContentArchiveHeader), mHdrHash.bytes);
@ -128,7 +131,7 @@ void NcaProcess::generateNcaBodyEncryptionKeys()
memset(zero_aesctr_key.key, 0, sizeof(zero_aesctr_key)); memset(zero_aesctr_key.key, 0, sizeof(zero_aesctr_key));
// get key data from header // get key data from header
byte_t masterkey_rev = nn::hac::ContentArchiveUtils::getMasterKeyRevisionFromKeyGeneration(mHdr.getKeyGeneration()); byte_t masterkey_rev = nn::hac::ContentArchiveUtil::getMasterKeyRevisionFromKeyGeneration(mHdr.getKeyGeneration());
byte_t keak_index = mHdr.getKeyAreaEncryptionKeyIndex(); byte_t keak_index = mHdr.getKeyAreaEncryptionKeyIndex();
// process key area // process key area
@ -253,7 +256,7 @@ void NcaProcess::generatePartitionConfiguration()
} }
// setup AES-CTR // setup AES-CTR
nn::hac::ContentArchiveUtils::getNcaPartitionAesCtr(&fs_header, info.aes_ctr.iv); nn::hac::ContentArchiveUtil::getNcaPartitionAesCtr(&fs_header, info.aes_ctr.iv);
// save partition config // save partition config
info.reader = nullptr; info.reader = nullptr;
@ -356,7 +359,7 @@ void NcaProcess::generatePartitionConfiguration()
else if (info.enc_type == nn::hac::nca::CRYPT_AESXTS || info.enc_type == nn::hac::nca::CRYPT_AESCTREX) else if (info.enc_type == nn::hac::nca::CRYPT_AESXTS || info.enc_type == nn::hac::nca::CRYPT_AESCTREX)
{ {
error.clear(); error.clear();
error << "EncryptionType(" << getEncryptionTypeStr(info.enc_type) << "): UNSUPPORTED"; error << "EncryptionType(" << nn::hac::ContentArchiveUtil::getEncryptionTypeAsString(info.enc_type) << "): UNSUPPORTED";
throw fnd::Exception(kModuleName, error.str()); throw fnd::Exception(kModuleName, error.str());
} }
else else
@ -443,11 +446,11 @@ void NcaProcess::validateNcaSignatures()
void NcaProcess::displayHeader() void NcaProcess::displayHeader()
{ {
std::cout << "[NCA Header]" << std::endl; std::cout << "[NCA Header]" << std::endl;
std::cout << " Format Type: " << getFormatVersionStr(mHdr.getFormatVersion()) << std::endl; std::cout << " Format Type: " << nn::hac::ContentArchiveUtil::getFormatVersionAsString((nn::hac::nca::HeaderFormatVersion)mHdr.getFormatVersion()) << std::endl;
std::cout << " Dist. Type: " << getDistributionTypeStr(mHdr.getDistributionType()) << std::endl; std::cout << " Dist. Type: " << nn::hac::ContentArchiveUtil::getDistributionTypeAsString(mHdr.getDistributionType()) << std::endl;
std::cout << " Content Type: " << getContentTypeStr(mHdr.getContentType()) << std::endl; std::cout << " Content Type: " << nn::hac::ContentArchiveUtil::getContentTypeAsString(mHdr.getContentType()) << std::endl;
std::cout << " Key Generation: " << std::dec << (uint32_t)mHdr.getKeyGeneration() << std::endl; std::cout << " Key Generation: " << std::dec << (uint32_t)mHdr.getKeyGeneration() << std::endl;
std::cout << " Kaek Index: " << getKaekIndexStr((nn::hac::nca::KeyAreaEncryptionKeyIndex)mHdr.getKeyAreaEncryptionKeyIndex()) << " (" << std::dec << (uint32_t)mHdr.getKeyAreaEncryptionKeyIndex() << ")" << std::endl; std::cout << " Kaek Index: " << nn::hac::ContentArchiveUtil::getKeyAreaEncryptionKeyIndexAsString((nn::hac::nca::KeyAreaEncryptionKeyIndex)mHdr.getKeyAreaEncryptionKeyIndex()) << " (" << std::dec << (uint32_t)mHdr.getKeyAreaEncryptionKeyIndex() << ")" << std::endl;
std::cout << " Size: 0x" << std::hex << mHdr.getContentSize() << std::endl; std::cout << " Size: 0x" << std::hex << mHdr.getContentSize() << std::endl;
std::cout << " ProgID: 0x" << std::hex << std::setw(16) << std::setfill('0') << mHdr.getProgramId() << std::endl; std::cout << " ProgID: 0x" << std::hex << std::setw(16) << std::setfill('0') << mHdr.getProgramId() << std::endl;
std::cout << " Content Index: " << std::dec << mHdr.getContentIndex() << std::endl; std::cout << " Content Index: " << std::dec << mHdr.getContentIndex() << std::endl;
@ -494,9 +497,9 @@ void NcaProcess::displayHeader()
std::cout << " " << std::dec << index << ":" << std::endl; std::cout << " " << std::dec << index << ":" << std::endl;
std::cout << " Offset: 0x" << std::hex << (uint64_t)info.offset << std::endl; std::cout << " Offset: 0x" << std::hex << (uint64_t)info.offset << std::endl;
std::cout << " Size: 0x" << std::hex << (uint64_t)info.size << std::endl; std::cout << " Size: 0x" << std::hex << (uint64_t)info.size << std::endl;
std::cout << " Format Type: " << getFormatTypeStr(info.format_type) << std::endl; std::cout << " Format Type: " << nn::hac::ContentArchiveUtil::getFormatTypeAsString(info.format_type) << std::endl;
std::cout << " Hash Type: " << getHashTypeStr(info.hash_type) << std::endl; std::cout << " Hash Type: " << nn::hac::ContentArchiveUtil::getHashTypeAsString(info.hash_type) << std::endl;
std::cout << " Enc. Type: " << getEncryptionTypeStr(info.enc_type) << std::endl; std::cout << " Enc. Type: " << nn::hac::ContentArchiveUtil::getEncryptionTypeAsString(info.enc_type) << std::endl;
if (info.enc_type == nn::hac::nca::CRYPT_AESCTR) if (info.enc_type == nn::hac::nca::CRYPT_AESCTR)
{ {
fnd::aes::sAesIvCtr ctr; fnd::aes::sAesIvCtr ctr;
@ -574,7 +577,7 @@ void NcaProcess::processPartitions()
pfs.setListFs(mListFs); pfs.setListFs(mListFs);
if (mHdr.getContentType() == nn::hac::nca::TYPE_PROGRAM) if (mHdr.getContentType() == nn::hac::nca::TYPE_PROGRAM)
{ {
pfs.setMountPointName(std::string(getContentTypeForMountStr(mHdr.getContentType())) + ":/" + std::string(getProgramPartitionNameStr(index))); pfs.setMountPointName(std::string(getContentTypeForMountStr(mHdr.getContentType())) + ":/" + nn::hac::ContentArchiveUtil::getProgramContentParititionIndexAsString((nn::hac::nca::ProgramContentPartitionIndex)index));
} }
else else
{ {
@ -593,7 +596,7 @@ void NcaProcess::processPartitions()
romfs.setListFs(mListFs); romfs.setListFs(mListFs);
if (mHdr.getContentType() == nn::hac::nca::TYPE_PROGRAM) if (mHdr.getContentType() == nn::hac::nca::TYPE_PROGRAM)
{ {
romfs.setMountPointName(std::string(getContentTypeForMountStr(mHdr.getContentType())) + ":/" + std::string(getProgramPartitionNameStr(index))); romfs.setMountPointName(std::string(getContentTypeForMountStr(mHdr.getContentType())) + ":/" + nn::hac::ContentArchiveUtil::getProgramContentParititionIndexAsString((nn::hac::nca::ProgramContentPartitionIndex)index));
} }
else else
{ {
@ -607,177 +610,6 @@ void NcaProcess::processPartitions()
} }
} }
const char* NcaProcess::getFormatVersionStr(byte_t format_ver) const
{
const char* str = nullptr;
switch (format_ver)
{
case (nn::hac::nca::FORMAT_NCA2):
str = "NCA2";
break;
case (nn::hac::nca::FORMAT_NCA3):
str = "NCA3";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* NcaProcess::getDistributionTypeStr(nn::hac::nca::DistributionType dist_type) const
{
const char* str = nullptr;
switch (dist_type)
{
case (nn::hac::nca::DIST_DOWNLOAD):
str = "Download";
break;
case (nn::hac::nca::DIST_GAME_CARD):
str = "Game Card";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* NcaProcess::getContentTypeStr(nn::hac::nca::ContentType cont_type) const
{
const char* str = nullptr;
switch (cont_type)
{
case (nn::hac::nca::TYPE_PROGRAM):
str = "Program";
break;
case (nn::hac::nca::TYPE_META):
str = "Meta";
break;
case (nn::hac::nca::TYPE_CONTROL):
str = "Control";
break;
case (nn::hac::nca::TYPE_MANUAL):
str = "Manual";
break;
case (nn::hac::nca::TYPE_DATA):
str = "Data";
break;
case (nn::hac::nca::TYPE_PUBLIC_DATA):
str = "PublicData";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* NcaProcess::getEncryptionTypeStr(nn::hac::nca::EncryptionType enc_type) const
{
const char* str = nullptr;
switch (enc_type)
{
case (nn::hac::nca::CRYPT_AUTO):
str = "Auto";
break;
case (nn::hac::nca::CRYPT_NONE):
str = "None";
break;
case (nn::hac::nca::CRYPT_AESXTS):
str = "AesXts";
break;
case (nn::hac::nca::CRYPT_AESCTR):
str = "AesCtr";
break;
case (nn::hac::nca::CRYPT_AESCTREX):
str = "AesCtrEx";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* NcaProcess::getHashTypeStr(nn::hac::nca::HashType hash_type) const
{
const char* str = nullptr;
switch (hash_type)
{
case (nn::hac::nca::HASH_AUTO):
str = "Auto";
break;
case (nn::hac::nca::HASH_NONE):
str = "None";
break;
case (nn::hac::nca::HASH_HIERARCHICAL_SHA256):
str = "HierarchicalSha256";
break;
case (nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY):
str = "HierarchicalIntegrity";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* NcaProcess::getFormatTypeStr(nn::hac::nca::FormatType format_type) const
{
const char* str = nullptr;
switch (format_type)
{
case (nn::hac::nca::FORMAT_ROMFS):
str = "RomFs";
break;
case (nn::hac::nca::FORMAT_PFS0):
str = "PartitionFs";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* NcaProcess::getKaekIndexStr(nn::hac::nca::KeyAreaEncryptionKeyIndex keak_index) const
{
const char* str = nullptr;
switch (keak_index)
{
case (nn::hac::nca::KAEK_IDX_APPLICATION):
str = "Application";
break;
case (nn::hac::nca::KAEK_IDX_OCEAN):
str = "Ocean";
break;
case (nn::hac::nca::KAEK_IDX_SYSTEM):
str = "System";
break;
default:
str = "Unknown";
break;
}
return str;
}
const char* NcaProcess::getContentTypeForMountStr(nn::hac::nca::ContentType cont_type) const const char* NcaProcess::getContentTypeForMountStr(nn::hac::nca::ContentType cont_type) const
{ {
const char* str = nullptr; const char* str = nullptr;
@ -807,28 +639,5 @@ const char* NcaProcess::getContentTypeForMountStr(nn::hac::nca::ContentType cont
break; break;
} }
return str;
}
const char* NcaProcess::getProgramPartitionNameStr(size_t i) const
{
const char* str = nullptr;
switch (i)
{
case (nn::hac::nca::PARTITION_CODE):
str = "code";
break;
case (nn::hac::nca::PARTITION_DATA):
str = "data";
break;
case (nn::hac::nca::PARTITION_LOGO):
str = "logo";
break;
default:
str = "";
break;
}
return str; return str;
} }

View file

@ -111,13 +111,5 @@ private:
void displayHeader(); void displayHeader();
void processPartitions(); void processPartitions();
const char* getFormatVersionStr(byte_t format_ver) const;
const char* getDistributionTypeStr(nn::hac::nca::DistributionType dist_type) const;
const char* getContentTypeStr(nn::hac::nca::ContentType cont_type) const;
const char* getEncryptionTypeStr(nn::hac::nca::EncryptionType enc_type) const;
const char* getHashTypeStr(nn::hac::nca::HashType hash_type) const;
const char* getFormatTypeStr(nn::hac::nca::FormatType format_type) const;
const char* getKaekIndexStr(nn::hac::nca::KeyAreaEncryptionKeyIndex keak_index) const;
const char* getContentTypeForMountStr(nn::hac::nca::ContentType cont_type) const; const char* getContentTypeForMountStr(nn::hac::nca::ContentType cont_type) const;
const char* getProgramPartitionNameStr(size_t i) const;
}; };

View file

@ -128,7 +128,9 @@ void NroProcess::importCodeSegments()
void NroProcess::displayHeader() void NroProcess::displayHeader()
{ {
std::cout << "[NRO Header]" << std::endl; std::cout << "[NRO Header]" << std::endl;
std::cout << " RoCrt: " << fnd::SimpleTextOutput::arrayToString(mHdr.getRoCrt().data, nn::hac::nro::kRoCrtSize, false, "") << std::endl; std::cout << " RoCrt: " << std::endl;
std::cout << " EntryPoint: 0x" << std::hex << mHdr.getRoCrtEntryPoint() << std::endl;
std::cout << " ModOffset: 0x" << std::hex << mHdr.getRoCrtModOffset() << std::endl;
std::cout << " ModuleId: " << fnd::SimpleTextOutput::arrayToString(mHdr.getModuleId().data, nn::hac::nro::kModuleIdSize, false, "") << std::endl; std::cout << " ModuleId: " << fnd::SimpleTextOutput::arrayToString(mHdr.getModuleId().data, nn::hac::nro::kModuleIdSize, false, "") << std::endl;
std::cout << " NroSize: 0x" << std::hex << mHdr.getNroSize() << std::endl; std::cout << " NroSize: 0x" << std::hex << mHdr.getNroSize() << std::endl;
std::cout << " Program Sections:" << std::endl; std::cout << " Program Sections:" << std::endl;

View file

@ -1,8 +1,13 @@
#include "PfsProcess.h"
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <fnd/SimpleFile.h> #include <fnd/SimpleFile.h>
#include <fnd/io.h> #include <fnd/io.h>
#include "PfsProcess.h"
#include <nn/hac/PartitionFsUtil.h>
PfsProcess::PfsProcess() : PfsProcess::PfsProcess() :
mFile(), mFile(),
@ -95,7 +100,7 @@ void PfsProcess::importHeader()
void PfsProcess::displayHeader() void PfsProcess::displayHeader()
{ {
std::cout << "[PartitionFS]" << std::endl; std::cout << "[PartitionFS]" << std::endl;
std::cout << " Type: " << getFsTypeStr(mPfs.getFsType()) << std::endl; std::cout << " Type: " << nn::hac::PartitionFsUtil::getFsTypeAsString(mPfs.getFsType()) << std::endl;
std::cout << " FileNum: " << std::dec << mPfs.getFileList().size() << std::endl; std::cout << " FileNum: " << std::dec << mPfs.getFileList().size() << std::endl;
if (mMountName.empty() == false) if (mMountName.empty() == false)
{ {
@ -191,24 +196,4 @@ void PfsProcess::extractFs()
} }
outFile.close(); outFile.close();
} }
}
const char* PfsProcess::getFsTypeStr(nn::hac::PartitionFsHeader::FsType type) const
{
const char* str = nullptr;
switch (type)
{
case (nn::hac::PartitionFsHeader::TYPE_PFS0):
str = "PFS0";
break;
case (nn::hac::PartitionFsHeader::TYPE_HFS0):
str = "HFS0";
break;
default:
str = "Unknown";
break;
}
return str;
} }

View file

@ -50,6 +50,4 @@ private:
bool validateHeaderMagic(const nn::hac::sPfsHeader* hdr); bool validateHeaderMagic(const nn::hac::sPfsHeader* hdr);
void validateHfs(); void validateHfs();
void extractFs(); void extractFs();
const char* getFsTypeStr(nn::hac::PartitionFsHeader::FsType type) const;
}; };

View file

@ -13,7 +13,7 @@
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <fnd/Vec.h> #include <fnd/Vec.h>
#include <fnd/ResourceFileReader.h> #include <fnd/ResourceFileReader.h>
#include <nn/hac/ContentArchiveUtils.h> #include <nn/hac/ContentArchiveUtil.h>
#include <nn/hac/AesKeygen.h> #include <nn/hac/AesKeygen.h>
#include <nn/hac/define/gc.h> #include <nn/hac/define/gc.h>
#include <nn/hac/define/pfs.h> #include <nn/hac/define/pfs.h>
@ -522,7 +522,7 @@ void UserSettings::populateKeyset(sCmdArgs& args)
fnd::aes::sAes128Key enc_title_key; fnd::aes::sAes128Key enc_title_key;
memcpy(enc_title_key.key, tik.getBody().getEncTitleKey(), 16); memcpy(enc_title_key.key, tik.getBody().getEncTitleKey(), 16);
fnd::aes::sAes128Key common_key, external_content_key; fnd::aes::sAes128Key common_key, external_content_key;
if (mKeyCfg.getETicketCommonKey(nn::hac::ContentArchiveUtils::getMasterKeyRevisionFromKeyGeneration(tik.getBody().getCommonKeyId()), common_key) == true) if (mKeyCfg.getETicketCommonKey(nn::hac::ContentArchiveUtil::getMasterKeyRevisionFromKeyGeneration(tik.getBody().getCommonKeyId()), common_key) == true)
{ {
nn::hac::AesKeygen::generateKey(external_content_key.key, tik.getBody().getEncTitleKey(), common_key.key); nn::hac::AesKeygen::generateKey(external_content_key.key, tik.getBody().getEncTitleKey(), common_key.key);
mKeyCfg.addNcaExternalContentKey(tik.getBody().getRightsId(), external_content_key); mKeyCfg.addNcaExternalContentKey(tik.getBody().getRightsId(), external_content_key);
@ -609,7 +609,7 @@ FileType UserSettings::getFileTypeFromString(const std::string& type_str)
FileType type; FileType type;
if (str == "gc" || str == "gamecard" || str == "xci") if (str == "gc" || str == "gamecard" || str == "xci")
type = FILE_GC; type = FILE_GAMECARD;
else if (str == "nsp") else if (str == "nsp")
type = FILE_NSP; type = FILE_NSP;
else if (str == "partitionfs" || str == "hashedpartitionfs" \ else if (str == "partitionfs" || str == "hashedpartitionfs" \
@ -666,9 +666,11 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
#define _TYPE_PTR(st) ((st*)(scratch.data())) #define _TYPE_PTR(st) ((st*)(scratch.data()))
#define _ASSERT_SIZE(sz) (scratch.size() >= (sz)) #define _ASSERT_SIZE(sz) (scratch.size() >= (sz))
// test npdm // test gamecard
if (_ASSERT_SIZE(sizeof(nn::hac::sGcHeaderPage)) && _TYPE_PTR(nn::hac::sGcHeaderPage)->header.st_magic.get() == nn::hac::gc::kGcHeaderStructMagic) if (_ASSERT_SIZE(sizeof(nn::hac::sGcHeader_Rsa2048Signed)) && _TYPE_PTR(nn::hac::sGcHeader_Rsa2048Signed)->header.st_magic.get() == nn::hac::gc::kGcHeaderStructMagic)
file_type = FILE_GC; file_type = FILE_GAMECARD;
else if (_ASSERT_SIZE(sizeof(nn::hac::sSdkGcHeader)) && _TYPE_PTR(nn::hac::sSdkGcHeader)->signed_header.header.st_magic.get() == nn::hac::gc::kGcHeaderStructMagic)
file_type = FILE_GAMECARD;
// test pfs0 // test pfs0
else if (_ASSERT_SIZE(sizeof(nn::hac::sPfsHeader)) && _TYPE_PTR(nn::hac::sPfsHeader)->st_magic.get() == nn::hac::pfs::kPfsStructMagic) else if (_ASSERT_SIZE(sizeof(nn::hac::sPfsHeader)) && _TYPE_PTR(nn::hac::sPfsHeader)->st_magic.get() == nn::hac::pfs::kPfsStructMagic)
file_type = FILE_PARTITIONFS; file_type = FILE_PARTITIONFS;
@ -729,14 +731,14 @@ bool UserSettings::determineValidNcaFromSample(const fnd::Vec<byte_t>& sample) c
{ {
// prepare decrypted NCA data // prepare decrypted NCA data
byte_t nca_raw[nn::hac::nca::kHeaderSize]; byte_t nca_raw[nn::hac::nca::kHeaderSize];
nn::hac::sContentArchiveHeader* nca_header = (nn::hac::sContentArchiveHeader*)(nca_raw + nn::hac::ContentArchiveUtils::sectorToOffset(1)); nn::hac::sContentArchiveHeader* nca_header = (nn::hac::sContentArchiveHeader*)(nca_raw + nn::hac::ContentArchiveUtil::sectorToOffset(1));
if (sample.size() < nn::hac::nca::kHeaderSize) if (sample.size() < nn::hac::nca::kHeaderSize)
return false; return false;
fnd::aes::sAesXts128Key header_key; fnd::aes::sAesXts128Key header_key;
mKeyCfg.getContentArchiveHeaderKey(header_key); mKeyCfg.getContentArchiveHeaderKey(header_key);
nn::hac::ContentArchiveUtils::decryptContentArchiveHeader(sample.data(), nca_raw, header_key); nn::hac::ContentArchiveUtil::decryptContentArchiveHeader(sample.data(), nca_raw, header_key);
if (nca_header->st_magic.get() != nn::hac::nca::kNca2StructMagic && nca_header->st_magic.get() != nn::hac::nca::kNca3StructMagic) if (nca_header->st_magic.get() != nn::hac::nca::kNca2StructMagic && nca_header->st_magic.get() != nn::hac::nca::kNca3StructMagic)
return false; return false;

View file

@ -10,7 +10,7 @@ static const size_t kNcaKeakNum = nn::hac::nca::kKeyAreaEncryptionKeyNum;
enum FileType enum FileType
{ {
FILE_GC, FILE_GAMECARD,
FILE_NSP, FILE_NSP,
FILE_PARTITIONFS, FILE_PARTITIONFS,
FILE_ROMFS, FILE_ROMFS,

View file

@ -40,7 +40,7 @@ int main(int argc, char** argv)
fnd::SharedPtr<fnd::IFile> inputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read)); fnd::SharedPtr<fnd::IFile> inputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read));
if (user_set.getFileType() == FILE_GC) if (user_set.getFileType() == FILE_GAMECARD)
{ {
GameCardProcess obj; GameCardProcess obj;

View file

@ -2,6 +2,6 @@
#define APP_NAME "NSTool" #define APP_NAME "NSTool"
#define BIN_NAME "nstool" #define BIN_NAME "nstool"
#define VER_MAJOR 1 #define VER_MAJOR 1
#define VER_MINOR 1 #define VER_MINOR 2
#define VER_PATCH 0 #define VER_PATCH 0
#define AUTHORS "jakcron" #define AUTHORS "jakcron"