From a8f39b721d23e1b3ad3427f97e45717400b06f91 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sun, 3 Jun 2018 15:10:47 +0800 Subject: [PATCH] [nx|nstool] Added support for xci logo partition. --- lib/libnx/include/nx/xci.h | 5 +++ programs/nstool/source/NsoProcess.h | 1 + programs/nstool/source/UserSettings.cpp | 59 +++++++++++++++---------- programs/nstool/source/UserSettings.h | 55 ++++++++--------------- programs/nstool/source/XciProcess.cpp | 37 +++++----------- programs/nstool/source/XciProcess.h | 15 +++---- programs/nstool/source/main.cpp | 31 ++++++------- programs/nstool/source/nstool.h | 1 + 8 files changed, 93 insertions(+), 111 deletions(-) diff --git a/lib/libnx/include/nx/xci.h b/lib/libnx/include/nx/xci.h index 751e71d..08b35e4 100644 --- a/lib/libnx/include/nx/xci.h +++ b/lib/libnx/include/nx/xci.h @@ -23,6 +23,11 @@ namespace nx static const uint32_t kCertAreaPageCount = 64; static const uint32_t kNormalAreaStartPageAddress = kReservedAreaPageCount + kCertAreaPageCount + kCardHeaderPageCount + kCardKeyAreaPageCount; + const std::string kUpdatePartitionStr = "update"; + const std::string kNormalPartitionStr = "normal"; + const std::string kSecurePartitionStr = "secure"; + const std::string kLogoPartitionStr = "logo"; + enum KekIndex { diff --git a/programs/nstool/source/NsoProcess.h b/programs/nstool/source/NsoProcess.h index a1ab964..0a34c75 100644 --- a/programs/nstool/source/NsoProcess.h +++ b/programs/nstool/source/NsoProcess.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "nstool.h" diff --git a/programs/nstool/source/UserSettings.cpp b/programs/nstool/source/UserSettings.cpp index 977b4ed..1aeb524 100644 --- a/programs/nstool/source/UserSettings.cpp +++ b/programs/nstool/source/UserSettings.cpp @@ -48,6 +48,7 @@ void UserSettings::showHelp() printf(" --listfs Print file system in embedded partitions\n"); printf(" --update Extract \"update\" partition to directory\n"); printf(" --normal Extract \"normal\" partition to directory\n"); + printf(" --logo Extract \"logo\" partition to directory\n"); printf(" --secure Extract \"secure\" partition to directory\n"); printf("\n PFS0/HFS0 (PartitionFs), RomFs, NSP (Ninendo Submission Package)\n"); printf(" nstool [--listfs] [--fsdir ] \n"); @@ -103,19 +104,24 @@ const sOptional& UserSettings::getArchType() const return mArchType; } -const sOptional& UserSettings::getUpdatePath() const +const sOptional& UserSettings::getXciUpdatePath() const { - return mUpdatePath; + return mXciUpdatePath; } -const sOptional& UserSettings::getNormalPath() const +const sOptional& UserSettings::getXciNormalPath() const { - return mNormalPath; + return mXciNormalPath; } -const sOptional& UserSettings::getSecurePath() const +const sOptional& UserSettings::getXciSecurePath() const { - return mSecurePath; + return mXciSecurePath; +} + +const sOptional& UserSettings::getXciLogoPath() const +{ + return mXciLogoPath; } const sOptional& UserSettings::getFsPath() const @@ -123,24 +129,24 @@ const sOptional& UserSettings::getFsPath() const return mFsPath; } -const sOptional& UserSettings::getPart0Path() const +const sOptional& UserSettings::getNcaPart0Path() const { - return mPart0Path; + return mNcaPart0Path; } -const sOptional& UserSettings::getPart1Path() const +const sOptional& UserSettings::getNcaPart1Path() const { - return mPart1Path; + return mNcaPart1Path; } -const sOptional& UserSettings::getPart2Path() const +const sOptional& UserSettings::getNcaPart2Path() const { - return mPart2Path; + return mNcaPart2Path; } -const sOptional& UserSettings::getPart3Path() const +const sOptional& UserSettings::getNcaPart3Path() const { - return mPart3Path; + return mNcaPart3Path; } @@ -160,7 +166,6 @@ void UserSettings::populateCmdArgs(int argc, char** argv, sCmdArgs& cmd_args) throw fnd::Exception(kModuleName, "Not enough arguments."); } - cmd_args.clear(); cmd_args.input_path = args.back(); for (size_t i = 1; i < args.size(); i++) @@ -236,6 +241,12 @@ void UserSettings::populateCmdArgs(int argc, char** argv, sCmdArgs& cmd_args) cmd_args.secure_path = args[i+1]; } + else if (args[i] == "--logo") + { + if (!hasParamter) throw fnd::Exception(kModuleName, args[i] + " requries a parameter."); + cmd_args.logo_path = args[i+1]; + } + else if (args[i] == "--fsdir") { if (!hasParamter) throw fnd::Exception(kModuleName, args[i] + " requries a parameter."); @@ -530,20 +541,20 @@ void UserSettings::populateUserSettings(sCmdArgs& args) mInputPath = *args.input_path; mVerifyFile = args.verify_file.isSet; mListFs = args.list_fs.isSet; - mUpdatePath = args.update_path; - mNormalPath = args.normal_path; - mSecurePath = args.secure_path; + mXciUpdatePath = args.update_path; + mXciNormalPath = args.normal_path; + mXciSecurePath = args.secure_path; + mXciLogoPath = args.logo_path; + mFsPath = args.fs_path; - mPart0Path = args.part0_path; - mPart1Path = args.part1_path; - mPart2Path = args.part2_path; - mPart3Path = args.part3_path; + mNcaPart0Path = args.part0_path; + mNcaPart1Path = args.part1_path; + mNcaPart2Path = args.part2_path; + mNcaPart3Path = args.part3_path; // determine the architecture type for NSO if (args.arch_type.isSet) mArchType = getInstructionTypeFromString(*args.arch_type); - else - mArchType.isSet = false; // determine output path if (args.verbose_output.isSet) diff --git a/programs/nstool/source/UserSettings.h b/programs/nstool/source/UserSettings.h index 8d508d8..2177e67 100644 --- a/programs/nstool/source/UserSettings.h +++ b/programs/nstool/source/UserSettings.h @@ -24,20 +24,22 @@ public: const sOptional& getArchType() const; // specialised paths - const sOptional& getUpdatePath() const; - const sOptional& getNormalPath() const; - const sOptional& getSecurePath() const; + const sOptional& getXciUpdatePath() const; + const sOptional& getXciNormalPath() const; + const sOptional& getXciSecurePath() const; + const sOptional& getXciLogoPath() const; const sOptional& getFsPath() const; - const sOptional& getPart0Path() const; - const sOptional& getPart1Path() const; - const sOptional& getPart2Path() const; - const sOptional& getPart3Path() const; + const sOptional& getNcaPart0Path() const; + const sOptional& getNcaPart1Path() const; + const sOptional& getNcaPart2Path() const; + const sOptional& getNcaPart3Path() const; private: const std::string kModuleName = "UserSettings"; struct sCmdArgs { + sCmdArgs() {} sOptional input_path; sOptional devkit_keys; sOptional keyset_path; @@ -49,6 +51,7 @@ private: sOptional update_path; sOptional normal_path; sOptional secure_path; + sOptional logo_path; sOptional fs_path; sOptional nca_titlekey; sOptional nca_bodykey; @@ -57,29 +60,6 @@ private: sOptional part2_path; sOptional part3_path; sOptional arch_type; - - void clear() - { - input_path.isSet = false; - devkit_keys.isSet = false; - keyset_path.isSet = false; - file_type.isSet = false; - verify_file.isSet = false; - verbose_output.isSet = false; - minimal_output.isSet = false; - list_fs.isSet = false; - update_path.isSet = false; - normal_path.isSet = false; - secure_path.isSet = false; - fs_path.isSet = false; - nca_titlekey.isSet = false; - nca_bodykey.isSet = false; - part0_path.isSet = false; - part1_path.isSet = false; - part2_path.isSet = false; - part3_path.isSet = false; - arch_type.isSet = false; - } }; std::string mInputPath; @@ -89,15 +69,16 @@ private: CliOutputType mOutputType; bool mListFs; - sOptional mUpdatePath; - sOptional mNormalPath; - sOptional mSecurePath; + sOptional mXciUpdatePath; + sOptional mXciNormalPath; + sOptional mXciSecurePath; + sOptional mXciLogoPath; sOptional mFsPath; - sOptional mPart0Path; - sOptional mPart1Path; - sOptional mPart2Path; - sOptional mPart3Path; + sOptional mNcaPart0Path; + sOptional mNcaPart1Path; + sOptional mNcaPart2Path; + sOptional mNcaPart3Path; sOptional mArchType; diff --git a/programs/nstool/source/XciProcess.cpp b/programs/nstool/source/XciProcess.cpp index e7a2788..0082be9 100644 --- a/programs/nstool/source/XciProcess.cpp +++ b/programs/nstool/source/XciProcess.cpp @@ -163,12 +163,13 @@ void XciProcess::processPartitionPfs() tmp.setVerifyMode(mVerify); tmp.setCliOutputMode(mCliOutputType); tmp.setMountPointName(kXciMountPointName + rootPartitions[i].name); - if (mUpdatePath.doExtract && rootPartitions[i].name == "update") - tmp.setExtractPath(mUpdatePath.path); - if (mNormalPath.doExtract && rootPartitions[i].name == "normal") - tmp.setExtractPath(mNormalPath.path); - if (mSecurePath.doExtract && rootPartitions[i].name == "secure") - tmp.setExtractPath(mSecurePath.path); + for (size_t j = 0; j < mExtractInfo.size(); j++) + { + if (mExtractInfo[j].partition_name == rootPartitions[i].name) + { + tmp.setExtractPath(mExtractInfo[j].extract_path); + } + } tmp.process(); } } @@ -180,13 +181,8 @@ XciProcess::XciProcess() : mVerify(false), mListFs(false), mRootPfs(), - mUpdatePfs(), - mNormalPfs(), - mSecurePfs() + mExtractInfo() { - mUpdatePath.doExtract = false; - mNormalPath.doExtract = false; - mSecurePath.doExtract = false; } XciProcess::~XciProcess() @@ -255,22 +251,9 @@ void XciProcess::setVerifyMode(bool verify) mVerify = verify; } -void XciProcess::setUpdateExtractPath(const std::string& path) +void XciProcess::setPartitionForExtract(const std::string& partition_name, const std::string& extract_path) { - mUpdatePath.path = path; - mUpdatePath.doExtract = true; -} - -void XciProcess::setNormalExtractPath(const std::string& path) -{ - mNormalPath.path = path; - mNormalPath.doExtract = true; -} - -void XciProcess::setSecureExtractPath(const std::string& path) -{ - mSecurePath.path = path; - mSecurePath.doExtract = true; + mExtractInfo.push_back({partition_name, extract_path}); } void XciProcess::setListFs(bool list_fs) diff --git a/programs/nstool/source/XciProcess.h b/programs/nstool/source/XciProcess.h index 3f6acd3..c66fc76 100644 --- a/programs/nstool/source/XciProcess.h +++ b/programs/nstool/source/XciProcess.h @@ -24,9 +24,7 @@ public: void setVerifyMode(bool verify); // xci specific - void setUpdateExtractPath(const std::string& path); - void setNormalExtractPath(const std::string& path); - void setSecureExtractPath(const std::string& path); + void setPartitionForExtract(const std::string& partition_name, const std::string& extract_path); void setListFs(bool list_fs); private: @@ -39,17 +37,18 @@ private: CliOutputType mCliOutputType; bool mVerify; - struct sExtract + struct sExtractInfo { - std::string path; - bool doExtract; - } mUpdatePath, mNormalPath, mSecurePath; + std::string partition_name; + std::string extract_path; + }; bool mListFs; nx::sXciHeaderPage mHdrPage; nx::XciHeader mHdr; - PfsProcess mRootPfs, mUpdatePfs, mNormalPfs, mSecurePfs; + PfsProcess mRootPfs; + std::vector mExtractInfo; void displayHeader(); bool validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash); diff --git a/programs/nstool/source/main.cpp b/programs/nstool/source/main.cpp index 0ef0f57..8e85a7f 100644 --- a/programs/nstool/source/main.cpp +++ b/programs/nstool/source/main.cpp @@ -9,7 +9,6 @@ #include "CnmtProcess.h" #include "NsoProcess.h" - int main(int argc, char** argv) { UserSettings user_set; @@ -29,12 +28,14 @@ int main(int argc, char** argv) xci.setCliOutputMode(user_set.getCliOutputType()); xci.setVerifyMode(user_set.isVerifyFile()); - if (user_set.getUpdatePath().isSet) - xci.setUpdateExtractPath(user_set.getUpdatePath().var); - if (user_set.getNormalPath().isSet) - xci.setNormalExtractPath(user_set.getNormalPath().var); - if (user_set.getSecurePath().isSet) - xci.setSecureExtractPath(user_set.getSecurePath().var); + if (user_set.getXciUpdatePath().isSet) + xci.setPartitionForExtract(nx::xci::kUpdatePartitionStr, user_set.getXciUpdatePath().var); + if (user_set.getXciNormalPath().isSet) + xci.setPartitionForExtract(nx::xci::kNormalPartitionStr, user_set.getXciNormalPath().var); + if (user_set.getXciSecurePath().isSet) + xci.setPartitionForExtract(nx::xci::kSecurePartitionStr, user_set.getXciSecurePath().var); + if (user_set.getXciLogoPath().isSet) + xci.setPartitionForExtract(nx::xci::kLogoPartitionStr, user_set.getXciLogoPath().var); xci.setListFs(user_set.isListFs()); xci.process(); @@ -77,14 +78,14 @@ int main(int argc, char** argv) nca.setVerifyMode(user_set.isVerifyFile()); - if (user_set.getPart0Path().isSet) - nca.setPartition0ExtractPath(user_set.getPart0Path().var); - if (user_set.getPart1Path().isSet) - nca.setPartition1ExtractPath(user_set.getPart1Path().var); - if (user_set.getPart2Path().isSet) - nca.setPartition2ExtractPath(user_set.getPart2Path().var); - if (user_set.getPart3Path().isSet) - nca.setPartition3ExtractPath(user_set.getPart3Path().var); + if (user_set.getNcaPart0Path().isSet) + nca.setPartition0ExtractPath(user_set.getNcaPart0Path().var); + if (user_set.getNcaPart1Path().isSet) + nca.setPartition1ExtractPath(user_set.getNcaPart1Path().var); + if (user_set.getNcaPart2Path().isSet) + nca.setPartition2ExtractPath(user_set.getNcaPart2Path().var); + if (user_set.getNcaPart3Path().isSet) + nca.setPartition3ExtractPath(user_set.getNcaPart3Path().var); nca.setListFs(user_set.isListFs()); nca.process(); diff --git a/programs/nstool/source/nstool.h b/programs/nstool/source/nstool.h index 5325918..c8d1d5d 100644 --- a/programs/nstool/source/nstool.h +++ b/programs/nstool/source/nstool.h @@ -35,6 +35,7 @@ struct sOptional { bool isSet; T var; + inline sOptional() : isSet(false) {} inline const T& operator=(const T& other) { isSet = true; var = other; return var; } inline const sOptional& operator=(const sOptional& other) {