mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-03 00:39:14 +00:00
[ctrtool] Honour -p flag when processing CIA files.
This commit is contained in:
+15
-36
@@ -1,4 +1,5 @@
|
|||||||
#include "CiaProcess.h"
|
#include "CiaProcess.h"
|
||||||
|
#include "util.h"
|
||||||
#include <tc/io.h>
|
#include <tc/io.h>
|
||||||
#include <tc/cli.h>
|
#include <tc/cli.h>
|
||||||
#include <tc/crypto.h>
|
#include <tc/crypto.h>
|
||||||
@@ -15,6 +16,7 @@ ctrtool::CiaProcess::CiaProcess() :
|
|||||||
mShowHeaderInfo(false),
|
mShowHeaderInfo(false),
|
||||||
mVerbose(false),
|
mVerbose(false),
|
||||||
mVerify(false),
|
mVerify(false),
|
||||||
|
mPlain(false),
|
||||||
mCertExtractPath(),
|
mCertExtractPath(),
|
||||||
mTikExtractPath(),
|
mTikExtractPath(),
|
||||||
mTmdExtractPath(),
|
mTmdExtractPath(),
|
||||||
@@ -103,6 +105,7 @@ void ctrtool::CiaProcess::setRawMode(bool raw)
|
|||||||
|
|
||||||
void ctrtool::CiaProcess::setPlainMode(bool plain)
|
void ctrtool::CiaProcess::setPlainMode(bool plain)
|
||||||
{
|
{
|
||||||
|
mPlain = plain;
|
||||||
mNcchProcess.setPlainMode(plain);
|
mNcchProcess.setPlainMode(plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,7 +518,7 @@ void ctrtool::CiaProcess::verifyContent()
|
|||||||
|
|
||||||
content_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, itr->second.offset, itr->second.size));
|
content_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, itr->second.offset, itr->second.size));
|
||||||
|
|
||||||
if (itr->second.is_encrypted && mDecryptedTitleKey.isSet())
|
if (!mPlain && itr->second.is_encrypted && mDecryptedTitleKey.isSet())
|
||||||
{
|
{
|
||||||
tc::crypto::Aes128CbcEncryptedStream::iv_t content_iv;
|
tc::crypto::Aes128CbcEncryptedStream::iv_t content_iv;
|
||||||
createContentIv(content_iv, itr->second.cindex);
|
createContentIv(content_iv, itr->second.cindex);
|
||||||
@@ -691,23 +694,22 @@ void ctrtool::CiaProcess::printHeader()
|
|||||||
|
|
||||||
void ctrtool::CiaProcess::extractCia()
|
void ctrtool::CiaProcess::extractCia()
|
||||||
{
|
{
|
||||||
|
tc::ByteData cache = tc::ByteData(0x10000);
|
||||||
tc::io::Path out_path;
|
tc::io::Path out_path;
|
||||||
std::shared_ptr<tc::io::IStream> in_stream;
|
std::shared_ptr<tc::io::IStream> in_stream;
|
||||||
std::shared_ptr<tc::io::IStream> out_stream;
|
|
||||||
|
|
||||||
if (mCertExtractPath.isSet() && mCertSizeInfo.size > 0)
|
if (mCertExtractPath.isSet() && mCertSizeInfo.size > 0)
|
||||||
{
|
{
|
||||||
out_path = mCertExtractPath.get();
|
out_path = mCertExtractPath.get();
|
||||||
|
|
||||||
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mCertSizeInfo.offset, mCertSizeInfo.size));
|
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mCertSizeInfo.offset, mCertSizeInfo.size));
|
||||||
out_stream = std::shared_ptr<tc::io::FileStream>(new tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write));
|
|
||||||
|
|
||||||
if (mVerbose)
|
if (mVerbose)
|
||||||
{
|
{
|
||||||
fmt::print(stderr, "[{} LOG] Saving certs to {}...\n", mModuleLabel, out_path.to_string());
|
fmt::print(stderr, "[{} LOG] Saving certs to {}...\n", mModuleLabel, out_path.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
copyStream(in_stream, out_stream);
|
writeStreamToFile(in_stream, out_path, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTikExtractPath.isSet() && mTikSizeInfo.size > 0)
|
if (mTikExtractPath.isSet() && mTikSizeInfo.size > 0)
|
||||||
@@ -715,13 +717,13 @@ void ctrtool::CiaProcess::extractCia()
|
|||||||
out_path = mTikExtractPath.get();
|
out_path = mTikExtractPath.get();
|
||||||
|
|
||||||
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mTikSizeInfo.offset, mTikSizeInfo.size));
|
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mTikSizeInfo.offset, mTikSizeInfo.size));
|
||||||
out_stream = std::shared_ptr<tc::io::FileStream>(new tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write));
|
|
||||||
|
|
||||||
if (mVerbose)
|
if (mVerbose)
|
||||||
{
|
{
|
||||||
fmt::print(stderr, "[{} LOG] Saving tik to {}...\n", mModuleLabel, out_path.to_string());
|
fmt::print(stderr, "[{} LOG] Saving tik to {}...\n", mModuleLabel, out_path.to_string());
|
||||||
}
|
}
|
||||||
copyStream(in_stream, out_stream);
|
|
||||||
|
writeStreamToFile(in_stream, out_path, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTmdExtractPath.isSet() && mTmdSizeInfo.size > 0)
|
if (mTmdExtractPath.isSet() && mTmdSizeInfo.size > 0)
|
||||||
@@ -729,13 +731,13 @@ void ctrtool::CiaProcess::extractCia()
|
|||||||
out_path = mTmdExtractPath.get();
|
out_path = mTmdExtractPath.get();
|
||||||
|
|
||||||
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mTmdSizeInfo.offset, mTmdSizeInfo.size));
|
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mTmdSizeInfo.offset, mTmdSizeInfo.size));
|
||||||
out_stream = std::shared_ptr<tc::io::FileStream>(new tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write));
|
|
||||||
|
|
||||||
if (mVerbose)
|
if (mVerbose)
|
||||||
{
|
{
|
||||||
fmt::print(stderr, "[{} LOG] Saving tmd to {}...\n", mModuleLabel, out_path.to_string());
|
fmt::print(stderr, "[{} LOG] Saving tmd to {}...\n", mModuleLabel, out_path.to_string());
|
||||||
}
|
}
|
||||||
copyStream(in_stream, out_stream);
|
|
||||||
|
writeStreamToFile(in_stream, out_path, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFooterExtractPath.isSet() && mFooterSizeInfo.size > 0)
|
if (mFooterExtractPath.isSet() && mFooterSizeInfo.size > 0)
|
||||||
@@ -743,13 +745,13 @@ void ctrtool::CiaProcess::extractCia()
|
|||||||
out_path = mFooterExtractPath.get();
|
out_path = mFooterExtractPath.get();
|
||||||
|
|
||||||
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mFooterSizeInfo.offset, mFooterSizeInfo.size));
|
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mFooterSizeInfo.offset, mFooterSizeInfo.size));
|
||||||
out_stream = std::shared_ptr<tc::io::FileStream>(new tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write));
|
|
||||||
|
|
||||||
if (mVerbose)
|
if (mVerbose)
|
||||||
{
|
{
|
||||||
fmt::print(stderr, "[{} LOG] Saving meta to {}...\n", mModuleLabel, out_path.to_string());
|
fmt::print(stderr, "[{} LOG] Saving meta to {}...\n", mModuleLabel, out_path.to_string());
|
||||||
}
|
}
|
||||||
copyStream(in_stream, out_stream);
|
|
||||||
|
writeStreamToFile(in_stream, out_path, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mContentExtractPath.isSet() && mContentInfo.size() > 0)
|
if (mContentExtractPath.isSet() && mContentInfo.size() > 0)
|
||||||
@@ -761,7 +763,7 @@ void ctrtool::CiaProcess::extractCia()
|
|||||||
|
|
||||||
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, itr->second.offset, itr->second.size));
|
in_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, itr->second.offset, itr->second.size));
|
||||||
|
|
||||||
if (itr->second.is_encrypted && mDecryptedTitleKey.isSet())
|
if (!mPlain && itr->second.is_encrypted && mDecryptedTitleKey.isSet())
|
||||||
{
|
{
|
||||||
tc::crypto::Aes128CbcEncryptedStream::iv_t content_iv;
|
tc::crypto::Aes128CbcEncryptedStream::iv_t content_iv;
|
||||||
createContentIv(content_iv, itr->second.cindex);
|
createContentIv(content_iv, itr->second.cindex);
|
||||||
@@ -769,39 +771,16 @@ void ctrtool::CiaProcess::extractCia()
|
|||||||
in_stream = std::shared_ptr<tc::crypto::Aes128CbcEncryptedStream>(new tc::crypto::Aes128CbcEncryptedStream(in_stream, mDecryptedTitleKey.get(), content_iv));
|
in_stream = std::shared_ptr<tc::crypto::Aes128CbcEncryptedStream>(new tc::crypto::Aes128CbcEncryptedStream(in_stream, mDecryptedTitleKey.get(), content_iv));
|
||||||
}
|
}
|
||||||
|
|
||||||
out_stream = std::shared_ptr<tc::io::FileStream>(new tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write));
|
|
||||||
|
|
||||||
if (mVerbose)
|
if (mVerbose)
|
||||||
{
|
{
|
||||||
fmt::print(stderr, "[{} LOG] Saving content {:04x} to {}...\n", mModuleLabel, itr->second.cindex, out_path.to_string());
|
fmt::print(stderr, "[{} LOG] Saving content {:04x} to {}...\n", mModuleLabel, itr->second.cindex, out_path.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
copyStream(in_stream, out_stream);
|
writeStreamToFile(in_stream, out_path, cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ctrtool::CiaProcess::copyStream(const std::shared_ptr<tc::io::IStream>& in, const std::shared_ptr<tc::io::IStream>& out)
|
|
||||||
{
|
|
||||||
tc::ByteData cache = tc::ByteData(0x10000);
|
|
||||||
size_t cache_read_len;
|
|
||||||
|
|
||||||
in->seek(0, tc::io::SeekOrigin::Begin);
|
|
||||||
out->seek(0, tc::io::SeekOrigin::Begin);
|
|
||||||
for (int64_t remaining_data = in->length(); remaining_data > 0;)
|
|
||||||
{
|
|
||||||
cache_read_len = in->read(cache.data(), cache.size());
|
|
||||||
if (cache_read_len == 0)
|
|
||||||
{
|
|
||||||
throw tc::io::IOException(mModuleLabel, "Failed to read from source file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
out->write(cache.data(), cache_read_len);
|
|
||||||
|
|
||||||
remaining_data -= int64_t(cache_read_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ctrtool::CiaProcess::processContent()
|
void ctrtool::CiaProcess::processContent()
|
||||||
{
|
{
|
||||||
if (mContentIndex >= ntd::n3ds::CiaHeader::kCiaMaxContentNum)
|
if (mContentIndex >= ntd::n3ds::CiaHeader::kCiaMaxContentNum)
|
||||||
@@ -813,7 +792,7 @@ void ctrtool::CiaProcess::processContent()
|
|||||||
{
|
{
|
||||||
std::shared_ptr<tc::io::IStream> content_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mContentInfo[mContentIndex].offset, mContentInfo[mContentIndex].size));
|
std::shared_ptr<tc::io::IStream> content_stream = std::shared_ptr<tc::io::SubStream>(new tc::io::SubStream(mInputStream, mContentInfo[mContentIndex].offset, mContentInfo[mContentIndex].size));
|
||||||
|
|
||||||
if (mContentInfo[mContentIndex].is_encrypted && mDecryptedTitleKey.isSet())
|
if (!mPlain && mContentInfo[mContentIndex].is_encrypted && mDecryptedTitleKey.isSet())
|
||||||
{
|
{
|
||||||
tc::crypto::Aes128CbcEncryptedStream::iv_t content_iv;
|
tc::crypto::Aes128CbcEncryptedStream::iv_t content_iv;
|
||||||
createContentIv(content_iv, mContentInfo[mContentIndex].cindex);
|
createContentIv(content_iv, mContentInfo[mContentIndex].cindex);
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ private:
|
|||||||
bool mShowHeaderInfo;
|
bool mShowHeaderInfo;
|
||||||
bool mVerbose;
|
bool mVerbose;
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
|
bool mPlain;
|
||||||
tc::Optional<tc::io::Path> mCertExtractPath;
|
tc::Optional<tc::io::Path> mCertExtractPath;
|
||||||
tc::Optional<tc::io::Path> mTikExtractPath;
|
tc::Optional<tc::io::Path> mTikExtractPath;
|
||||||
tc::Optional<tc::io::Path> mTmdExtractPath;
|
tc::Optional<tc::io::Path> mTmdExtractPath;
|
||||||
@@ -108,7 +109,6 @@ private:
|
|||||||
void verifyContent();
|
void verifyContent();
|
||||||
void printHeader();
|
void printHeader();
|
||||||
void extractCia();
|
void extractCia();
|
||||||
void copyStream(const std::shared_ptr<tc::io::IStream>& in, const std::shared_ptr<tc::io::IStream>& out);
|
|
||||||
void processContent();
|
void processContent();
|
||||||
|
|
||||||
void createContentIv(std::array<byte_t, 16>& content_iv, uint16_t index);
|
void createContentIv(std::array<byte_t, 16>& content_iv, uint16_t index);
|
||||||
|
|||||||
Reference in New Issue
Block a user