This commit is contained in:
Jack 2023-01-21 20:03:21 +08:00
parent af41275c80
commit 605b5c70f9
3 changed files with 22 additions and 13 deletions

View file

@ -49,9 +49,9 @@ void nstool::NcaProcess::setInputFile(const std::shared_ptr<tc::io::IStream>& fi
mFile = file; mFile = file;
} }
void nstool::NcaProcess::setBaseNCAPath(const tc::Optional<tc::io::Path>& baseNCA) void nstool::NcaProcess::setBaseNcaPath(const tc::Optional<tc::io::Path>& nca_path)
{ {
baseNcaPath = baseNCA; mBaseNcaPath = nca_path;
} }
void nstool::NcaProcess::setKeyCfg(const KeyBag& keycfg) void nstool::NcaProcess::setKeyCfg(const KeyBag& keycfg)
@ -217,12 +217,16 @@ void nstool::NcaProcess::generateNcaBodyEncryptionKeys()
} }
} }
nstool::NcaProcess nstool::NcaProcess::readBaseNCA() { nstool::NcaProcess nstool::NcaProcess::readBaseNCA()
if (baseNcaPath.isNull()) { {
// open base nca stream
if (mBaseNcaPath.isNull())
{
throw tc::Exception(mModuleName, "Base NCA not supplied. Necessary for update NCA."); throw tc::Exception(mModuleName, "Base NCA not supplied. Necessary for update NCA.");
} }
std::shared_ptr<tc::io::IStream> base_stream = std::make_shared<tc::io::FileStream>(tc::io::FileStream(baseNcaPath.get(), tc::io::FileMode::Open, tc::io::FileAccess::Read)); std::shared_ptr<tc::io::IStream> base_stream = std::make_shared<tc::io::FileStream>(tc::io::FileStream(mBaseNcaPath.get(), tc::io::FileMode::Open, tc::io::FileAccess::Read));
// process base nca with output suppressed
NcaProcess obj; NcaProcess obj;
nstool::CliOutputMode cliOutput; nstool::CliOutputMode cliOutput;
cliOutput.show_basic_info = false; cliOutput.show_basic_info = false;
@ -234,6 +238,8 @@ nstool::NcaProcess nstool::NcaProcess::readBaseNCA() {
obj.setKeyCfg(mKeyCfg); obj.setKeyCfg(mKeyCfg);
obj.setInputFile(base_stream); obj.setInputFile(base_stream);
obj.process(); obj.process();
// return processed base nca
return obj; return obj;
} }
@ -310,11 +316,10 @@ void nstool::NcaProcess::generatePartitionConfiguration()
// get partition counter // get partition counter
pie::hac::detail::aes_iv_t partition_ctr = info.aes_ctr; pie::hac::detail::aes_iv_t partition_ctr = info.aes_ctr;
tc::crypto::IncrementCounterAes128Ctr(partition_ctr.data(), info.offset>>4); tc::crypto::IncrementCounterAes128Ctr(partition_ctr.data(), info.offset >> 4);
// create decryption stream // create decryption stream
info.decrypt_reader = std::make_shared<tc::crypto::Aes128CtrEncryptedStream>(tc::crypto::Aes128CtrEncryptedStream(info.raw_reader, partition_key, partition_ctr)); info.decrypt_reader = std::make_shared<tc::crypto::Aes128CtrEncryptedStream>(tc::crypto::Aes128CtrEncryptedStream(info.raw_reader, partition_key, partition_ctr));
} }
else if (info.enc_type == pie::hac::nca::EncryptionType_AesCtrEx) else if (info.enc_type == pie::hac::nca::EncryptionType_AesCtrEx)
{ {
@ -329,17 +334,21 @@ void nstool::NcaProcess::generatePartitionConfiguration()
tc::crypto::IncrementCounterAes128Ctr(partition_ctr.data(), info.offset >> 4); tc::crypto::IncrementCounterAes128Ctr(partition_ctr.data(), info.offset >> 4);
NcaProcess nca_base = readBaseNCA(); NcaProcess nca_base = readBaseNCA();
if (nca_base.mHdr.getProgramId() != mHdr.getProgramId()) { if (nca_base.mHdr.getProgramId() != mHdr.getProgramId())
{
throw tc::Exception(mModuleName, "Invalid base nca. ProgramID diferent."); throw tc::Exception(mModuleName, "Invalid base nca. ProgramID diferent.");
} }
std::shared_ptr<tc::io::IStream> base_reader; std::shared_ptr<tc::io::IStream> base_reader;
for (auto& partition_base : nca_base.mPartitions) { for (auto& partition_base : nca_base.mPartitions)
{
if (partition_base.format_type == pie::hac::nca::FormatType::FormatType_RomFs && partition_base.raw_reader != nullptr) if (partition_base.format_type == pie::hac::nca::FormatType::FormatType_RomFs && partition_base.raw_reader != nullptr)
{ {
base_reader = partition_base.decrypt_reader; base_reader = partition_base.decrypt_reader;
} }
} }
if (base_reader == nullptr) { if (base_reader == nullptr)
{
throw tc::Exception(mModuleName, "Cannot determine RomFs from base nca."); throw tc::Exception(mModuleName, "Cannot determine RomFs from base nca.");
} }

View file

@ -21,7 +21,7 @@ public:
void setKeyCfg(const KeyBag& keycfg); void setKeyCfg(const KeyBag& keycfg);
void setCliOutputMode(CliOutputMode type); void setCliOutputMode(CliOutputMode type);
void setVerifyMode(bool verify); void setVerifyMode(bool verify);
void setBaseNCAPath(const tc::Optional<tc::io::Path>& keycfg); void setBaseNcaPath(const tc::Optional<tc::io::Path>& nca_path);
// fs specific // fs specific
@ -41,7 +41,7 @@ private:
KeyBag mKeyCfg; KeyBag mKeyCfg;
CliOutputMode mCliOutputMode; CliOutputMode mCliOutputMode;
bool mVerify; bool mVerify;
tc::Optional<tc::io::Path> baseNcaPath; tc::Optional<tc::io::Path> mBaseNcaPath;
// fs processing // fs processing
std::shared_ptr<tc::io::IFileSystem> mFileSystem; std::shared_ptr<tc::io::IFileSystem> mFileSystem;

View file

@ -75,7 +75,7 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
nstool::NcaProcess obj; nstool::NcaProcess obj;
obj.setInputFile(infile_stream); obj.setInputFile(infile_stream);
obj.setBaseNCAPath(set.nca.base_nca_path); obj.setBaseNcaPath(set.nca.base_nca_path);
obj.setKeyCfg(set.opt.keybag); obj.setKeyCfg(set.opt.keybag);
obj.setCliOutputMode(set.opt.cli_output_mode); obj.setCliOutputMode(set.opt.cli_output_mode);
obj.setVerifyMode(set.opt.verify); obj.setVerifyMode(set.opt.verify);