mirror of
https://github.com/jakcron/nstool
synced 2024-12-27 15:11:12 +00:00
[nstool] Improve fnd::IFile ptr handling/sharing with fnd::SharedPtr
This commit is contained in:
parent
3b4c16d7ca
commit
f93acfad07
31 changed files with 179 additions and 357 deletions
|
@ -1,7 +1,6 @@
|
|||
#include "AesCtrWrappedIFile.h"
|
||||
|
||||
AesCtrWrappedIFile::AesCtrWrappedIFile(fnd::IFile* file, bool ownIfile, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr) :
|
||||
mOwnIFile(ownIfile),
|
||||
AesCtrWrappedIFile::AesCtrWrappedIFile(const fnd::SharedPtr<fnd::IFile>& file, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr) :
|
||||
mFile(file),
|
||||
mKey(key),
|
||||
mBaseCtr(ctr),
|
||||
|
@ -10,17 +9,9 @@ AesCtrWrappedIFile::AesCtrWrappedIFile(fnd::IFile* file, bool ownIfile, const fn
|
|||
mCache.alloc(kCacheSizeAllocSize);
|
||||
}
|
||||
|
||||
AesCtrWrappedIFile::~AesCtrWrappedIFile()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
size_t AesCtrWrappedIFile::size()
|
||||
{
|
||||
return mFile->size();
|
||||
return (*mFile)->size();
|
||||
}
|
||||
|
||||
void AesCtrWrappedIFile::seek(size_t offset)
|
||||
|
@ -44,8 +35,8 @@ void AesCtrWrappedIFile::read(byte_t* out, size_t len)
|
|||
|
||||
//printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len);
|
||||
|
||||
mFile->seek(read_pos);
|
||||
mFile->read(mCache.data(), kCacheSizeAllocSize);
|
||||
(*mFile)->seek(read_pos);
|
||||
(*mFile)->read(mCache.data(), kCacheSizeAllocSize);
|
||||
|
||||
fnd::aes::AesIncrementCounter(mBaseCtr.iv, read_pos>>4, mCurrentCtr.iv);
|
||||
fnd::aes::AesCtr(mCache.data(), kCacheSizeAllocSize, mKey.key, mCurrentCtr.iv, mCache.data());
|
||||
|
@ -81,8 +72,8 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len)
|
|||
fnd::aes::AesIncrementCounter(mBaseCtr.iv, write_pos>>4, mCurrentCtr.iv);
|
||||
fnd::aes::AesCtr(mCache.data(), kCacheSizeAllocSize, mKey.key, mCurrentCtr.iv, mCache.data());
|
||||
|
||||
mFile->seek(write_pos);
|
||||
mFile->write(mCache.data(), kCacheSizeAllocSize);
|
||||
(*mFile)->seek(write_pos);
|
||||
(*mFile)->write(mCache.data(), kCacheSizeAllocSize);
|
||||
}
|
||||
|
||||
seek(mFileOffset + len);
|
||||
|
@ -92,7 +83,7 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len)
|
|||
{
|
||||
memcpy(mScratch.data() + mBlockOffset, out + (i * kAesCtrScratchSize), kAesCtrScratchSize);
|
||||
fnd::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data());
|
||||
mFile->write(mScratch.data() + mBlockOffset, kAesCtrScratchSize);
|
||||
(*mFile)->write(mScratch.data() + mBlockOffset, kAesCtrScratchSize);
|
||||
}
|
||||
|
||||
if (len % kAesCtrScratchSize)
|
||||
|
@ -101,7 +92,7 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len)
|
|||
size_t write_pos = ((len / kAesCtrScratchSize) * kAesCtrScratchSize);
|
||||
memcpy(mScratch.data() + mBlockOffset, out + write_pos, write_len);
|
||||
fnd::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data());
|
||||
mFile->write(mScratch.data() + mBlockOffset, write_len);
|
||||
(*mFile)->write(mScratch.data() + mBlockOffset, write_len);
|
||||
}
|
||||
*/
|
||||
seek(mFileOffset + len);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <fnd/aes.h>
|
||||
|
||||
class AesCtrWrappedIFile : public fnd::IFile
|
||||
{
|
||||
public:
|
||||
AesCtrWrappedIFile(fnd::IFile* file, bool ownIfile, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr);
|
||||
~AesCtrWrappedIFile();
|
||||
AesCtrWrappedIFile(const fnd::SharedPtr<fnd::IFile>& file, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr);
|
||||
|
||||
size_t size();
|
||||
void seek(size_t offset);
|
||||
|
@ -19,8 +19,7 @@ private:
|
|||
static const size_t kCacheSize = 0x10000;
|
||||
static const size_t kCacheSizeAllocSize = kCacheSize + fnd::aes::kAesBlockSize;
|
||||
|
||||
bool mOwnIFile;
|
||||
fnd::IFile* mFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
fnd::aes::sAes128Key mKey;
|
||||
fnd::aes::sAesIvCtr mBaseCtr, mCurrentCtr;
|
||||
size_t mFileOffset;
|
||||
|
|
|
@ -7,20 +7,10 @@
|
|||
|
||||
|
||||
AssetProcess::AssetProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AssetProcess::~AssetProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetProcess::process()
|
||||
|
@ -31,10 +21,9 @@ void AssetProcess::process()
|
|||
processSections();
|
||||
}
|
||||
|
||||
void AssetProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void AssetProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void AssetProcess::setCliOutputMode(CliOutputMode type)
|
||||
|
@ -72,18 +61,18 @@ void AssetProcess::importHeader()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
if (mFile->size() < sizeof(nn::hac::sAssetHeader))
|
||||
if ((*mFile)->size() < sizeof(nn::hac::sAssetHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Corrupt ASET: file too small");
|
||||
}
|
||||
|
||||
scratch.alloc(sizeof(nn::hac::sAssetHeader));
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
|
||||
mHdr.fromBytes(scratch.data(), scratch.size());
|
||||
}
|
||||
|
@ -92,21 +81,21 @@ void AssetProcess::processSections()
|
|||
{
|
||||
if (mHdr.getIconInfo().size > 0 && mIconExtractPath.isSet)
|
||||
{
|
||||
if ((mHdr.getIconInfo().size + mHdr.getIconInfo().offset) > mFile->size())
|
||||
if ((mHdr.getIconInfo().size + mHdr.getIconInfo().offset) > (*mFile)->size())
|
||||
throw fnd::Exception(kModuleName, "ASET geometry for icon beyond file size");
|
||||
|
||||
fnd::SimpleFile outfile(mIconExtractPath.var, fnd::SimpleFile::Create);
|
||||
fnd::Vec<byte_t> cache;
|
||||
|
||||
cache.alloc(mHdr.getIconInfo().size);
|
||||
mFile->read(cache.data(), mHdr.getIconInfo().offset, cache.size());
|
||||
(*mFile)->read(cache.data(), mHdr.getIconInfo().offset, cache.size());
|
||||
outfile.write(cache.data(), cache.size());
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
if (mHdr.getNacpInfo().size > 0)
|
||||
{
|
||||
if ((mHdr.getNacpInfo().size + mHdr.getNacpInfo().offset) > mFile->size())
|
||||
if ((mHdr.getNacpInfo().size + mHdr.getNacpInfo().offset) > (*mFile)->size())
|
||||
throw fnd::Exception(kModuleName, "ASET geometry for nacp beyond file size");
|
||||
|
||||
if (mNacpExtractPath.isSet)
|
||||
|
@ -115,12 +104,12 @@ void AssetProcess::processSections()
|
|||
fnd::Vec<byte_t> cache;
|
||||
|
||||
cache.alloc(mHdr.getNacpInfo().size);
|
||||
mFile->read(cache.data(), mHdr.getNacpInfo().offset, cache.size());
|
||||
(*mFile)->read(cache.data(), mHdr.getNacpInfo().offset, cache.size());
|
||||
outfile.write(cache.data(), cache.size());
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
mNacp.setInputFile(new OffsetAdjustedIFile(mFile, false, mHdr.getNacpInfo().offset, mHdr.getNacpInfo().size), true);
|
||||
mNacp.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getNacpInfo().offset, mHdr.getNacpInfo().size));
|
||||
mNacp.setCliOutputMode(mCliOutputMode);
|
||||
mNacp.setVerifyMode(mVerify);
|
||||
|
||||
|
@ -129,10 +118,10 @@ void AssetProcess::processSections()
|
|||
|
||||
if (mHdr.getRomfsInfo().size > 0)
|
||||
{
|
||||
if ((mHdr.getRomfsInfo().size + mHdr.getRomfsInfo().offset) > mFile->size())
|
||||
if ((mHdr.getRomfsInfo().size + mHdr.getRomfsInfo().offset) > (*mFile)->size())
|
||||
throw fnd::Exception(kModuleName, "ASET geometry for romfs beyond file size");
|
||||
|
||||
mRomfs.setInputFile(new OffsetAdjustedIFile(mFile, false, mHdr.getRomfsInfo().offset, mHdr.getRomfsInfo().size), true);
|
||||
mRomfs.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getRomfsInfo().offset, mHdr.getRomfsInfo().size));
|
||||
mRomfs.setCliOutputMode(mCliOutputMode);
|
||||
mRomfs.setVerifyMode(mVerify);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <nn/hac/AssetHeader.h>
|
||||
#include "NacpProcess.h"
|
||||
#include "RomfsProcess.h"
|
||||
|
@ -12,11 +13,10 @@ class AssetProcess
|
|||
{
|
||||
public:
|
||||
AssetProcess();
|
||||
~AssetProcess();
|
||||
|
||||
void process();
|
||||
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
||||
|
@ -30,8 +30,7 @@ public:
|
|||
private:
|
||||
const std::string kModuleName = "AssetProcess";
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
||||
|
|
|
@ -5,21 +5,12 @@
|
|||
#include "CnmtProcess.h"
|
||||
|
||||
CnmtProcess::CnmtProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false)
|
||||
{
|
||||
}
|
||||
|
||||
CnmtProcess::~CnmtProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void CnmtProcess::process()
|
||||
{
|
||||
importCnmt();
|
||||
|
@ -28,10 +19,9 @@ void CnmtProcess::process()
|
|||
displayCnmt();
|
||||
}
|
||||
|
||||
void CnmtProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void CnmtProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void CnmtProcess::setCliOutputMode(CliOutputMode type)
|
||||
|
@ -53,13 +43,13 @@ void CnmtProcess::importCnmt()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
scratch.alloc(mFile->size());
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
scratch.alloc((*mFile)->size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
|
||||
mCnmt.fromBytes(scratch.data(), scratch.size());
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <nn/hac/ContentMetaBinary.h>
|
||||
|
||||
#include "common.h"
|
||||
|
@ -10,11 +11,10 @@ class CnmtProcess
|
|||
{
|
||||
public:
|
||||
CnmtProcess();
|
||||
~CnmtProcess();
|
||||
|
||||
void process();
|
||||
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
||||
|
@ -23,8 +23,7 @@ public:
|
|||
private:
|
||||
const std::string kModuleName = "CnmtProcess";
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
||||
|
|
|
@ -9,21 +9,12 @@
|
|||
|
||||
|
||||
EsTikProcess::EsTikProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false)
|
||||
{
|
||||
}
|
||||
|
||||
EsTikProcess::~EsTikProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void EsTikProcess::process()
|
||||
{
|
||||
importTicket();
|
||||
|
@ -35,10 +26,9 @@ void EsTikProcess::process()
|
|||
displayTicket();
|
||||
}
|
||||
|
||||
void EsTikProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void EsTikProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void EsTikProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||
|
@ -66,13 +56,13 @@ void EsTikProcess::importTicket()
|
|||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
scratch.alloc(mFile->size());
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
scratch.alloc((*mFile)->size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
mTik.fromBytes(scratch.data(), scratch.size());
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <nn/pki/SignedData.h>
|
||||
#include <nn/pki/CertificateBody.h>
|
||||
|
@ -13,11 +14,10 @@ class EsTikProcess
|
|||
{
|
||||
public:
|
||||
EsTikProcess();
|
||||
~EsTikProcess();
|
||||
|
||||
void process();
|
||||
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||
void setCertificateChain(const fnd::List<nn::pki::SignedData<nn::pki::CertificateBody>>& certs);
|
||||
void setCliOutputMode(CliOutputMode mode);
|
||||
|
@ -26,8 +26,7 @@ public:
|
|||
private:
|
||||
const std::string kModuleName = "EsTikProcess";
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
KeyConfiguration mKeyCfg;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
#include "HashTreeWrappedIFile.h"
|
||||
#include "OffsetAdjustedIFile.h"
|
||||
|
||||
HashTreeWrappedIFile::HashTreeWrappedIFile(fnd::IFile* file, bool ownIFile, const HashTreeMeta& hdr) :
|
||||
mOwnIFile(ownIFile),
|
||||
HashTreeWrappedIFile::HashTreeWrappedIFile(const fnd::SharedPtr<fnd::IFile>& file, const HashTreeMeta& hdr) :
|
||||
mFile(file),
|
||||
mData(nullptr),
|
||||
mDataHashLayer(),
|
||||
|
@ -12,18 +11,9 @@ HashTreeWrappedIFile::HashTreeWrappedIFile(fnd::IFile* file, bool ownIFile, cons
|
|||
initialiseDataLayer(hdr);
|
||||
}
|
||||
|
||||
HashTreeWrappedIFile::~HashTreeWrappedIFile()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
delete mData;
|
||||
}
|
||||
|
||||
size_t HashTreeWrappedIFile::size()
|
||||
{
|
||||
return mData->size();
|
||||
return (*mData)->size();
|
||||
}
|
||||
|
||||
void HashTreeWrappedIFile::seek(size_t offset)
|
||||
|
@ -118,7 +108,7 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
|
|||
cur.alloc(align(layer.size, layer.block_size));
|
||||
|
||||
// read layer
|
||||
mFile->read(cur.data(), layer.offset, layer.size);
|
||||
(*mFile)->read(cur.data(), layer.offset, layer.size);
|
||||
|
||||
// validate blocks
|
||||
size_t validate_size;
|
||||
|
@ -145,7 +135,7 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
|
|||
}
|
||||
|
||||
// generate reader for data layer
|
||||
mData = new OffsetAdjustedIFile(mFile, SHARED_IFILE, hdr.getDataLayer().offset, hdr.getDataLayer().size);
|
||||
mData = new OffsetAdjustedIFile(mFile, hdr.getDataLayer().offset, hdr.getDataLayer().size);
|
||||
mDataOffset = 0;
|
||||
mDataBlockSize = hdr.getDataLayer().block_size;
|
||||
|
||||
|
@ -160,17 +150,17 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
|
|||
|
||||
void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
|
||||
{
|
||||
mData->seek(block_offset * mDataBlockSize);
|
||||
(*mData)->seek(block_offset * mDataBlockSize);
|
||||
fnd::sha::sSha256Hash hash;
|
||||
|
||||
// determine read size
|
||||
size_t read_len = 0;
|
||||
if ((block_offset + block_num) == getBlockNum(mData->size()))
|
||||
if ((block_offset + block_num) == getBlockNum((*mData)->size()))
|
||||
{
|
||||
read_len = (block_num-1) * mDataBlockSize + getRemanderBlockReadSize(mData->size());
|
||||
read_len = (block_num-1) * mDataBlockSize + getRemanderBlockReadSize((*mData)->size());
|
||||
memset(mCache.data(), 0, block_num * mDataBlockSize);
|
||||
}
|
||||
else if ((block_offset + block_num) < getBlockNum(mData->size()))
|
||||
else if ((block_offset + block_num) < getBlockNum((*mData)->size()))
|
||||
{
|
||||
read_len = block_num * mDataBlockSize;
|
||||
}
|
||||
|
@ -180,7 +170,7 @@ void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
|
|||
}
|
||||
|
||||
// read
|
||||
mData->read(mCache.data(), block_offset * mDataBlockSize, read_len);
|
||||
(*mData)->read(mCache.data(), block_offset * mDataBlockSize, read_len);
|
||||
|
||||
if (block_num > mCacheBlockNum)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <sstream>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <fnd/sha.h>
|
||||
#include "HashTreeMeta.h"
|
||||
|
@ -9,8 +10,7 @@
|
|||
class HashTreeWrappedIFile : public fnd::IFile
|
||||
{
|
||||
public:
|
||||
HashTreeWrappedIFile(fnd::IFile* file, bool ownIFile, const HashTreeMeta& hdr);
|
||||
~HashTreeWrappedIFile();
|
||||
HashTreeWrappedIFile(const fnd::SharedPtr<fnd::IFile>& file, const HashTreeMeta& hdr);
|
||||
|
||||
size_t size();
|
||||
void seek(size_t offset);
|
||||
|
@ -23,11 +23,10 @@ private:
|
|||
static const size_t kDefaultCacheSize = 0x10000;
|
||||
std::stringstream mErrorSs;
|
||||
|
||||
bool mOwnIFile;
|
||||
fnd::IFile* mFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
|
||||
// data file
|
||||
fnd::IFile* mData;
|
||||
fnd::SharedPtr<fnd::IFile> mData;
|
||||
size_t mDataOffset;
|
||||
size_t mDataBlockSize;
|
||||
fnd::List<fnd::sha::sSha256Hash> mDataHashLayer;
|
||||
|
|
|
@ -6,21 +6,12 @@
|
|||
#include "NacpProcess.h"
|
||||
|
||||
NacpProcess::NacpProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false)
|
||||
{
|
||||
}
|
||||
|
||||
NacpProcess::~NacpProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void NacpProcess::process()
|
||||
{
|
||||
importNacp();
|
||||
|
@ -29,10 +20,9 @@ void NacpProcess::process()
|
|||
displayNacp();
|
||||
}
|
||||
|
||||
void NacpProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void NacpProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void NacpProcess::setCliOutputMode(CliOutputMode type)
|
||||
|
@ -54,13 +44,13 @@ void NacpProcess::importNacp()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
scratch.alloc(mFile->size());
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
scratch.alloc((*mFile)->size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
|
||||
mNacp.fromBytes(scratch.data(), scratch.size());
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <nn/hac/ApplicationControlPropertyBinary.h>
|
||||
|
||||
#include "common.h"
|
||||
|
@ -10,11 +11,10 @@ class NacpProcess
|
|||
{
|
||||
public:
|
||||
NacpProcess();
|
||||
~NacpProcess();
|
||||
|
||||
void process();
|
||||
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
||||
|
@ -23,8 +23,7 @@ public:
|
|||
private:
|
||||
const std::string kModuleName = "NacpProcess";
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
#include "HashTreeWrappedIFile.h"
|
||||
|
||||
NcaProcess::NcaProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false),
|
||||
mListFs(false)
|
||||
|
@ -22,23 +21,6 @@ NcaProcess::NcaProcess() :
|
|||
for (size_t i = 0; i < nn::hac::nca::kPartitionNum; i++)
|
||||
{
|
||||
mPartitionPath[i].doExtract = false;
|
||||
mPartitions[i].reader = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NcaProcess::~NcaProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nn::hac::nca::kPartitionNum; i++)
|
||||
{
|
||||
if (mPartitions[i].reader != nullptr)
|
||||
{
|
||||
delete mPartitions[i].reader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,10 +47,9 @@ void NcaProcess::process()
|
|||
processPartitions();
|
||||
}
|
||||
|
||||
void NcaProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void NcaProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void NcaProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||
|
@ -117,13 +98,13 @@ void NcaProcess::setListFs(bool list_fs)
|
|||
|
||||
void NcaProcess::importHeader()
|
||||
{
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
// read header block
|
||||
mFile->read((byte_t*)&mHdrBlock, 0, sizeof(nn::hac::sNcaHeaderBlock));
|
||||
(*mFile)->read((byte_t*)&mHdrBlock, 0, sizeof(nn::hac::sNcaHeaderBlock));
|
||||
|
||||
// decrypt header block
|
||||
fnd::aes::sAesXts128Key header_key;
|
||||
|
@ -299,13 +280,13 @@ void NcaProcess::generatePartitionConfiguration()
|
|||
// create reader based on encryption type0
|
||||
if (info.enc_type == nn::hac::nca::CRYPT_NONE)
|
||||
{
|
||||
info.reader = new OffsetAdjustedIFile(mFile, SHARED_IFILE, info.offset, info.size);
|
||||
info.reader = new OffsetAdjustedIFile(mFile, info.offset, info.size);
|
||||
}
|
||||
else if (info.enc_type == nn::hac::nca::CRYPT_AESCTR)
|
||||
{
|
||||
if (mContentKey.aes_ctr.isSet == false)
|
||||
throw fnd::Exception(kModuleName, "AES-CTR Key was not determined");
|
||||
info.reader = new OffsetAdjustedIFile(new AesCtrWrappedIFile(mFile, SHARED_IFILE, mContentKey.aes_ctr.var, info.aes_ctr), OWN_IFILE, info.offset, info.size);
|
||||
info.reader = new OffsetAdjustedIFile(new AesCtrWrappedIFile(mFile, mContentKey.aes_ctr.var, info.aes_ctr), info.offset, info.size);
|
||||
}
|
||||
else if (info.enc_type == nn::hac::nca::CRYPT_AESXTS || info.enc_type == nn::hac::nca::CRYPT_AESCTREX)
|
||||
{
|
||||
|
@ -323,9 +304,7 @@ void NcaProcess::generatePartitionConfiguration()
|
|||
// filter out unrecognised hash types, and hash based readers
|
||||
if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256 || info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY)
|
||||
{
|
||||
fnd::IFile* tmp = info.reader;
|
||||
info.reader = nullptr;
|
||||
info.reader = new HashTreeWrappedIFile(tmp, OWN_IFILE, info.hash_tree_meta);
|
||||
info.reader = new HashTreeWrappedIFile(info.reader, info.hash_tree_meta);
|
||||
}
|
||||
else if (info.hash_type != nn::hac::nca::HASH_NONE)
|
||||
{
|
||||
|
@ -337,9 +316,6 @@ void NcaProcess::generatePartitionConfiguration()
|
|||
catch (const fnd::Exception& e)
|
||||
{
|
||||
info.fail_reason = std::string(e.error());
|
||||
if (info.reader != nullptr)
|
||||
delete info.reader;
|
||||
info.reader = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -359,10 +335,10 @@ void NcaProcess::validateNcaSignatures()
|
|||
{
|
||||
if (mPartitions[nn::hac::nca::PARTITION_CODE].format_type == nn::hac::nca::FORMAT_PFS0)
|
||||
{
|
||||
if (mPartitions[nn::hac::nca::PARTITION_CODE].reader != nullptr)
|
||||
if (*mPartitions[nn::hac::nca::PARTITION_CODE].reader != nullptr)
|
||||
{
|
||||
PfsProcess exefs;
|
||||
exefs.setInputFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader, SHARED_IFILE);
|
||||
exefs.setInputFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader);
|
||||
exefs.setCliOutputMode(0);
|
||||
exefs.process();
|
||||
|
||||
|
@ -372,7 +348,7 @@ void NcaProcess::validateNcaSignatures()
|
|||
const nn::hac::PfsHeader::sFile& file = exefs.getPfsHeader().getFileList().getElement(kNpdmExefsPath);
|
||||
|
||||
NpdmProcess npdm;
|
||||
npdm.setInputFile(new OffsetAdjustedIFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader, SHARED_IFILE, file.offset, file.size), OWN_IFILE);
|
||||
npdm.setInputFile(new OffsetAdjustedIFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader, file.offset, file.size));
|
||||
npdm.setCliOutputMode(0);
|
||||
npdm.process();
|
||||
|
||||
|
@ -513,7 +489,7 @@ void NcaProcess::processPartitions()
|
|||
struct sPartitionInfo& partition = mPartitions[index];
|
||||
|
||||
// if the reader is null, skip
|
||||
if (partition.reader == nullptr)
|
||||
if (*partition.reader == nullptr)
|
||||
{
|
||||
std::cout << "[WARNING] NCA Partition " << std::dec << index << " not readable.";
|
||||
if (partition.fail_reason.empty() == false)
|
||||
|
@ -527,7 +503,7 @@ void NcaProcess::processPartitions()
|
|||
if (partition.format_type == nn::hac::nca::FORMAT_PFS0)
|
||||
{
|
||||
PfsProcess pfs;
|
||||
pfs.setInputFile(partition.reader, SHARED_IFILE);
|
||||
pfs.setInputFile(partition.reader);
|
||||
pfs.setCliOutputMode(mCliOutputMode);
|
||||
pfs.setListFs(mListFs);
|
||||
if (mHdr.getContentType() == nn::hac::nca::TYPE_PROGRAM)
|
||||
|
@ -546,7 +522,7 @@ void NcaProcess::processPartitions()
|
|||
else if (partition.format_type == nn::hac::nca::FORMAT_ROMFS)
|
||||
{
|
||||
RomfsProcess romfs;
|
||||
romfs.setInputFile(partition.reader, SHARED_IFILE);
|
||||
romfs.setInputFile(partition.reader);
|
||||
romfs.setCliOutputMode(mCliOutputMode);
|
||||
romfs.setListFs(mListFs);
|
||||
if (mHdr.getContentType() == nn::hac::nca::TYPE_PROGRAM)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/SimpleFile.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <nn/hac/NcaHeader.h>
|
||||
#include "HashTreeMeta.h"
|
||||
#include "KeyConfiguration.h"
|
||||
|
@ -13,12 +14,11 @@ class NcaProcess
|
|||
{
|
||||
public:
|
||||
NcaProcess();
|
||||
~NcaProcess();
|
||||
|
||||
void process();
|
||||
|
||||
// generic
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
@ -35,8 +35,7 @@ private:
|
|||
const std::string kNpdmExefsPath = "main.npdm";
|
||||
|
||||
// user options
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
KeyConfiguration mKeyCfg;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
@ -92,7 +91,7 @@ private:
|
|||
|
||||
struct sPartitionInfo
|
||||
{
|
||||
fnd::IFile* reader;
|
||||
fnd::SharedPtr<fnd::IFile> reader;
|
||||
std::string fail_reason;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
|
|
|
@ -3,21 +3,12 @@
|
|||
#include "NpdmProcess.h"
|
||||
|
||||
NpdmProcess::NpdmProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false)
|
||||
{
|
||||
}
|
||||
|
||||
NpdmProcess::~NpdmProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void NpdmProcess::process()
|
||||
{
|
||||
importNpdm();
|
||||
|
@ -50,10 +41,9 @@ void NpdmProcess::process()
|
|||
}
|
||||
}
|
||||
|
||||
void NpdmProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void NpdmProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void NpdmProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||
|
@ -80,13 +70,13 @@ void NpdmProcess::importNpdm()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
scratch.alloc(mFile->size());
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
scratch.alloc((*mFile)->size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
|
||||
mNpdm.fromBytes(scratch.data(), scratch.size());
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <nn/hac/NpdmBinary.h>
|
||||
#include "KeyConfiguration.h"
|
||||
|
||||
|
@ -11,11 +12,10 @@ class NpdmProcess
|
|||
{
|
||||
public:
|
||||
NpdmProcess();
|
||||
~NpdmProcess();
|
||||
|
||||
void process();
|
||||
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
@ -25,8 +25,7 @@ public:
|
|||
private:
|
||||
const std::string kModuleName = "NpdmProcess";
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
KeyConfiguration mKeyCfg;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
|
|
@ -8,21 +8,12 @@
|
|||
#include "NroProcess.h"
|
||||
|
||||
NroProcess::NroProcess():
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false)
|
||||
{
|
||||
}
|
||||
|
||||
NroProcess::~NroProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void NroProcess::process()
|
||||
{
|
||||
importHeader();
|
||||
|
@ -37,10 +28,9 @@ void NroProcess::process()
|
|||
mAssetProc.process();
|
||||
}
|
||||
|
||||
void NroProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void NroProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void NroProcess::setCliOutputMode(CliOutputMode type)
|
||||
|
@ -97,27 +87,27 @@ void NroProcess::importHeader()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
if (mFile->size() < sizeof(nn::hac::sNroHeader))
|
||||
if ((*mFile)->size() < sizeof(nn::hac::sNroHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Corrupt NRO: file too small");
|
||||
}
|
||||
|
||||
scratch.alloc(sizeof(nn::hac::sNroHeader));
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
|
||||
mHdr.fromBytes(scratch.data(), scratch.size());
|
||||
|
||||
// setup homebrew extension
|
||||
nn::hac::sNroHeader* raw_hdr = (nn::hac::sNroHeader*)scratch.data();
|
||||
if (((le_uint64_t*)raw_hdr->reserved_0)->get() == nn::hac::nro::kNroHomebrewStructMagic && mFile->size() > mHdr.getNroSize())
|
||||
if (((le_uint64_t*)raw_hdr->reserved_0)->get() == nn::hac::nro::kNroHomebrewStructMagic && (*mFile)->size() > mHdr.getNroSize())
|
||||
{
|
||||
mIsHomebrewNro = true;
|
||||
mAssetProc.setInputFile(new OffsetAdjustedIFile(mFile, false, mHdr.getNroSize(), mFile->size() - mHdr.getNroSize()), true);
|
||||
mAssetProc.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getNroSize(), (*mFile)->size() - mHdr.getNroSize()));
|
||||
mAssetProc.setCliOutputMode(mCliOutputMode);
|
||||
mAssetProc.setVerifyMode(mVerify);
|
||||
}
|
||||
|
@ -128,11 +118,11 @@ void NroProcess::importHeader()
|
|||
void NroProcess::importCodeSegments()
|
||||
{
|
||||
mTextBlob.alloc(mHdr.getTextInfo().size);
|
||||
mFile->read(mTextBlob.data(), mHdr.getTextInfo().memory_offset, mTextBlob.size());
|
||||
(*mFile)->read(mTextBlob.data(), mHdr.getTextInfo().memory_offset, mTextBlob.size());
|
||||
mRoBlob.alloc(mHdr.getRoInfo().size);
|
||||
mFile->read(mRoBlob.data(), mHdr.getRoInfo().memory_offset, mRoBlob.size());
|
||||
(*mFile)->read(mRoBlob.data(), mHdr.getRoInfo().memory_offset, mRoBlob.size());
|
||||
mDataBlob.alloc(mHdr.getDataInfo().size);
|
||||
mFile->read(mDataBlob.data(), mHdr.getDataInfo().memory_offset, mDataBlob.size());
|
||||
(*mFile)->read(mDataBlob.data(), mHdr.getDataInfo().memory_offset, mDataBlob.size());
|
||||
}
|
||||
|
||||
void NroProcess::displayHeader()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <nn/hac/npdm.h>
|
||||
#include <nn/hac/NroHeader.h>
|
||||
#include "AssetProcess.h"
|
||||
|
@ -14,11 +15,10 @@ class NroProcess
|
|||
{
|
||||
public:
|
||||
NroProcess();
|
||||
~NroProcess();
|
||||
|
||||
void process();
|
||||
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
||||
|
@ -36,9 +36,7 @@ public:
|
|||
private:
|
||||
const std::string kModuleName = "NroProcess";
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
||||
|
|
|
@ -7,21 +7,12 @@
|
|||
#include "NsoProcess.h"
|
||||
|
||||
NsoProcess::NsoProcess():
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false)
|
||||
{
|
||||
}
|
||||
|
||||
NsoProcess::~NsoProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void NsoProcess::process()
|
||||
{
|
||||
importHeader();
|
||||
|
@ -32,10 +23,9 @@ void NsoProcess::process()
|
|||
processRoMeta();
|
||||
}
|
||||
|
||||
void NsoProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void NsoProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void NsoProcess::setCliOutputMode(CliOutputMode type)
|
||||
|
@ -72,18 +62,18 @@ void NsoProcess::importHeader()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
if (mFile->size() < sizeof(nn::hac::sNsoHeader))
|
||||
if ((*mFile)->size() < sizeof(nn::hac::sNsoHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Corrupt NSO: file too small");
|
||||
}
|
||||
|
||||
scratch.alloc(sizeof(nn::hac::sNsoHeader));
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
|
||||
mHdr.fromBytes(scratch.data(), scratch.size());
|
||||
}
|
||||
|
@ -98,7 +88,7 @@ void NsoProcess::importCodeSegments()
|
|||
if (mHdr.getTextSegmentInfo().is_compressed)
|
||||
{
|
||||
scratch.alloc(mHdr.getTextSegmentInfo().file_layout.size);
|
||||
mFile->read(scratch.data(), mHdr.getTextSegmentInfo().file_layout.offset, scratch.size());
|
||||
(*mFile)->read(scratch.data(), mHdr.getTextSegmentInfo().file_layout.offset, scratch.size());
|
||||
mTextBlob.alloc(mHdr.getTextSegmentInfo().memory_layout.size);
|
||||
fnd::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mTextBlob.data(), (uint32_t)mTextBlob.size(), decompressed_len);
|
||||
if (decompressed_len != mTextBlob.size())
|
||||
|
@ -109,7 +99,7 @@ void NsoProcess::importCodeSegments()
|
|||
else
|
||||
{
|
||||
mTextBlob.alloc(mHdr.getTextSegmentInfo().file_layout.size);
|
||||
mFile->read(mTextBlob.data(), mHdr.getTextSegmentInfo().file_layout.offset, mTextBlob.size());
|
||||
(*mFile)->read(mTextBlob.data(), mHdr.getTextSegmentInfo().file_layout.offset, mTextBlob.size());
|
||||
}
|
||||
if (mHdr.getTextSegmentInfo().is_hashed)
|
||||
{
|
||||
|
@ -124,7 +114,7 @@ void NsoProcess::importCodeSegments()
|
|||
if (mHdr.getRoSegmentInfo().is_compressed)
|
||||
{
|
||||
scratch.alloc(mHdr.getRoSegmentInfo().file_layout.size);
|
||||
mFile->read(scratch.data(), mHdr.getRoSegmentInfo().file_layout.offset, scratch.size());
|
||||
(*mFile)->read(scratch.data(), mHdr.getRoSegmentInfo().file_layout.offset, scratch.size());
|
||||
mRoBlob.alloc(mHdr.getRoSegmentInfo().memory_layout.size);
|
||||
fnd::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mRoBlob.data(), (uint32_t)mRoBlob.size(), decompressed_len);
|
||||
if (decompressed_len != mRoBlob.size())
|
||||
|
@ -135,7 +125,7 @@ void NsoProcess::importCodeSegments()
|
|||
else
|
||||
{
|
||||
mRoBlob.alloc(mHdr.getRoSegmentInfo().file_layout.size);
|
||||
mFile->read(mRoBlob.data(), mHdr.getRoSegmentInfo().file_layout.offset, mRoBlob.size());
|
||||
(*mFile)->read(mRoBlob.data(), mHdr.getRoSegmentInfo().file_layout.offset, mRoBlob.size());
|
||||
}
|
||||
if (mHdr.getRoSegmentInfo().is_hashed)
|
||||
{
|
||||
|
@ -150,7 +140,7 @@ void NsoProcess::importCodeSegments()
|
|||
if (mHdr.getDataSegmentInfo().is_compressed)
|
||||
{
|
||||
scratch.alloc(mHdr.getDataSegmentInfo().file_layout.size);
|
||||
mFile->read(scratch.data(), mHdr.getDataSegmentInfo().file_layout.offset, scratch.size());
|
||||
(*mFile)->read(scratch.data(), mHdr.getDataSegmentInfo().file_layout.offset, scratch.size());
|
||||
mDataBlob.alloc(mHdr.getDataSegmentInfo().memory_layout.size);
|
||||
fnd::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mDataBlob.data(), (uint32_t)mDataBlob.size(), decompressed_len);
|
||||
if (decompressed_len != mDataBlob.size())
|
||||
|
@ -161,7 +151,7 @@ void NsoProcess::importCodeSegments()
|
|||
else
|
||||
{
|
||||
mDataBlob.alloc(mHdr.getDataSegmentInfo().file_layout.size);
|
||||
mFile->read(mDataBlob.data(), mHdr.getDataSegmentInfo().file_layout.offset, mDataBlob.size());
|
||||
(*mFile)->read(mDataBlob.data(), mHdr.getDataSegmentInfo().file_layout.offset, mDataBlob.size());
|
||||
}
|
||||
if (mHdr.getDataSegmentInfo().is_hashed)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <nn/hac/npdm.h>
|
||||
#include <nn/hac/NsoHeader.h>
|
||||
|
||||
|
@ -13,11 +14,10 @@ class NsoProcess
|
|||
{
|
||||
public:
|
||||
NsoProcess();
|
||||
~NsoProcess();
|
||||
|
||||
void process();
|
||||
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
||||
|
@ -29,9 +29,7 @@ public:
|
|||
private:
|
||||
const std::string kModuleName = "NsoProcess";
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
nn::hac::npdm::InstructionType mInstructionType;
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
#include "OffsetAdjustedIFile.h"
|
||||
|
||||
OffsetAdjustedIFile::OffsetAdjustedIFile(fnd::IFile* file, bool ownIFile, size_t offset, size_t size) :
|
||||
mOwnIFile(ownIFile),
|
||||
OffsetAdjustedIFile::OffsetAdjustedIFile(const fnd::SharedPtr<fnd::IFile>& file, size_t offset, size_t size) :
|
||||
mFile(file),
|
||||
mBaseOffset(offset),
|
||||
mCurrentOffset(0),
|
||||
mSize(size)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OffsetAdjustedIFile::~OffsetAdjustedIFile()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
size_t OffsetAdjustedIFile::size()
|
||||
|
@ -31,8 +21,8 @@ void OffsetAdjustedIFile::seek(size_t offset)
|
|||
void OffsetAdjustedIFile::read(byte_t* out, size_t len)
|
||||
{
|
||||
// assert proper position in file
|
||||
mFile->seek(mCurrentOffset + mBaseOffset);
|
||||
mFile->read(out, len);
|
||||
(*mFile)->seek(mCurrentOffset + mBaseOffset);
|
||||
(*mFile)->read(out, len);
|
||||
seek(mCurrentOffset + len);
|
||||
}
|
||||
|
||||
|
@ -45,8 +35,8 @@ void OffsetAdjustedIFile::read(byte_t* out, size_t offset, size_t len)
|
|||
void OffsetAdjustedIFile::write(const byte_t* out, size_t len)
|
||||
{
|
||||
// assert proper position in file
|
||||
mFile->seek(mCurrentOffset + mBaseOffset);
|
||||
mFile->write(out, len);
|
||||
(*mFile)->seek(mCurrentOffset + mBaseOffset);
|
||||
(*mFile)->write(out, len);
|
||||
seek(mCurrentOffset + len);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
|
||||
class OffsetAdjustedIFile : public fnd::IFile
|
||||
{
|
||||
public:
|
||||
OffsetAdjustedIFile(fnd::IFile* file, bool ownIFile, size_t offset, size_t size);
|
||||
~OffsetAdjustedIFile();
|
||||
OffsetAdjustedIFile(const fnd::SharedPtr<fnd::IFile>& file, size_t offset, size_t size);
|
||||
|
||||
size_t size();
|
||||
void seek(size_t offset);
|
||||
|
@ -13,8 +13,7 @@ public:
|
|||
void write(const byte_t* out, size_t len);
|
||||
void write(const byte_t* out, size_t offset, size_t len);
|
||||
private:
|
||||
bool mOwnIFile;
|
||||
fnd::IFile* mFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
size_t mBaseOffset, mCurrentOffset;
|
||||
size_t mSize;
|
||||
};
|
|
@ -5,8 +5,7 @@
|
|||
#include "PfsProcess.h"
|
||||
|
||||
PfsProcess::PfsProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false),
|
||||
mExtractPath(),
|
||||
|
@ -17,14 +16,6 @@ PfsProcess::PfsProcess() :
|
|||
{
|
||||
}
|
||||
|
||||
PfsProcess::~PfsProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void PfsProcess::process()
|
||||
{
|
||||
importHeader();
|
||||
|
@ -41,10 +32,9 @@ void PfsProcess::process()
|
|||
extractFs();
|
||||
}
|
||||
|
||||
void PfsProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void PfsProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void PfsProcess::setCliOutputMode(CliOutputMode type)
|
||||
|
@ -82,14 +72,14 @@ void PfsProcess::importHeader()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
// open minimum header to get full header size
|
||||
scratch.alloc(sizeof(nn::hac::sPfsHeader));
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
if (validateHeaderMagic(((nn::hac::sPfsHeader*)scratch.data())) == false)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Corrupt Header");
|
||||
|
@ -98,7 +88,7 @@ void PfsProcess::importHeader()
|
|||
|
||||
// open minimum header to get full header size
|
||||
scratch.alloc(pfsHeaderSize);
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
mPfs.fromBytes(scratch.data(), scratch.size());
|
||||
}
|
||||
|
||||
|
@ -162,7 +152,7 @@ void PfsProcess::validateHfs()
|
|||
for (size_t i = 0; i < file.size(); i++)
|
||||
{
|
||||
mCache.alloc(file[i].hash_protected_size);
|
||||
mFile->read(mCache.data(), file[i].offset, file[i].hash_protected_size);
|
||||
(*mFile)->read(mCache.data(), file[i].offset, file[i].hash_protected_size);
|
||||
fnd::sha::Sha256(mCache.data(), file[i].hash_protected_size, hash.bytes);
|
||||
if (hash != file[i].hash)
|
||||
{
|
||||
|
@ -193,10 +183,10 @@ void PfsProcess::extractFs()
|
|||
printf("extract=[%s]\n", file_path.c_str());
|
||||
|
||||
outFile.open(file_path, outFile.Create);
|
||||
mFile->seek(file[i].offset);
|
||||
(*mFile)->seek(file[i].offset);
|
||||
for (size_t j = 0; j < ((file[i].size / kCacheSize) + ((file[i].size % kCacheSize) != 0)); j++)
|
||||
{
|
||||
mFile->read(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
|
||||
(*mFile)->read(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
|
||||
outFile.write(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
|
||||
}
|
||||
outFile.close();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <nn/hac/PfsHeader.h>
|
||||
|
||||
#include "common.h"
|
||||
|
@ -10,12 +11,11 @@ class PfsProcess
|
|||
{
|
||||
public:
|
||||
PfsProcess();
|
||||
~PfsProcess();
|
||||
|
||||
void process();
|
||||
|
||||
// generic
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
||||
|
@ -30,8 +30,7 @@ private:
|
|||
const std::string kModuleName = "PfsProcess";
|
||||
static const size_t kCacheSize = 0x10000;
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
||||
|
|
|
@ -7,21 +7,12 @@
|
|||
#include "PkiValidator.h"
|
||||
|
||||
PkiCertProcess::PkiCertProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false)
|
||||
{
|
||||
}
|
||||
|
||||
PkiCertProcess::~PkiCertProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void PkiCertProcess::process()
|
||||
{
|
||||
importCerts();
|
||||
|
@ -33,10 +24,9 @@ void PkiCertProcess::process()
|
|||
displayCerts();
|
||||
}
|
||||
|
||||
void PkiCertProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void PkiCertProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void PkiCertProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||
|
@ -58,13 +48,13 @@ void PkiCertProcess::importCerts()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
scratch.alloc(mFile->size());
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
scratch.alloc((*mFile)->size());
|
||||
(*mFile)->read(scratch.data(), 0, scratch.size());
|
||||
|
||||
nn::pki::SignedData<nn::pki::CertificateBody> cert;
|
||||
for (size_t f_pos = 0; f_pos < scratch.size(); f_pos += cert.getBytes().size())
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <fnd/List.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <nn/pki/SignedData.h>
|
||||
|
@ -13,11 +14,10 @@ class PkiCertProcess
|
|||
{
|
||||
public:
|
||||
PkiCertProcess();
|
||||
~PkiCertProcess();
|
||||
|
||||
void process();
|
||||
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
@ -26,8 +26,7 @@ private:
|
|||
const std::string kModuleName = "PkiCertProcess";
|
||||
static const size_t kSmallHexDumpLen = 0x10;
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
KeyConfiguration mKeyCfg;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
#include "RomfsProcess.h"
|
||||
|
||||
RomfsProcess::RomfsProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false),
|
||||
mExtractPath(),
|
||||
|
@ -22,14 +21,6 @@ RomfsProcess::RomfsProcess() :
|
|||
mRootDir.file_list.clear();
|
||||
}
|
||||
|
||||
RomfsProcess::~RomfsProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void RomfsProcess::process()
|
||||
{
|
||||
resolveRomfs();
|
||||
|
@ -45,10 +36,9 @@ void RomfsProcess::process()
|
|||
extractFs();
|
||||
}
|
||||
|
||||
void RomfsProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void RomfsProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void RomfsProcess::setCliOutputMode(CliOutputMode type)
|
||||
|
@ -163,10 +153,10 @@ void RomfsProcess::extractDir(const std::string& path, const sDirectory& dir)
|
|||
std::cout << "extract=[" << file_path << "]" << std::endl;
|
||||
|
||||
outFile.open(file_path, outFile.Create);
|
||||
mFile->seek(dir.file_list[i].offset);
|
||||
(*mFile)->seek(dir.file_list[i].offset);
|
||||
for (size_t j = 0; j < ((dir.file_list[i].size / kCacheSize) + ((dir.file_list[i].size % kCacheSize) != 0)); j++)
|
||||
{
|
||||
mFile->read(mCache.data(), _MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize));
|
||||
(*mFile)->read(mCache.data(), _MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize));
|
||||
outFile.write(mCache.data(), _MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize));
|
||||
}
|
||||
outFile.close();
|
||||
|
@ -258,13 +248,13 @@ void RomfsProcess::importDirectory(uint32_t dir_offset, sDirectory& dir)
|
|||
|
||||
void RomfsProcess::resolveRomfs()
|
||||
{
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
// read header
|
||||
mFile->read((byte_t*)&mHdr, 0, sizeof(nn::hac::sRomfsHeader));
|
||||
(*mFile)->read((byte_t*)&mHdr, 0, sizeof(nn::hac::sRomfsHeader));
|
||||
|
||||
// logic check on the header layout
|
||||
if (validateHeaderLayout(&mHdr) == false)
|
||||
|
@ -274,13 +264,13 @@ void RomfsProcess::resolveRomfs()
|
|||
|
||||
// read directory nodes
|
||||
mDirNodes.alloc(mHdr.sections[nn::hac::romfs::DIR_NODE_TABLE].size.get());
|
||||
mFile->read(mDirNodes.data(), mHdr.sections[nn::hac::romfs::DIR_NODE_TABLE].offset.get(), mDirNodes.size());
|
||||
(*mFile)->read(mDirNodes.data(), mHdr.sections[nn::hac::romfs::DIR_NODE_TABLE].offset.get(), mDirNodes.size());
|
||||
//printf("[RAW DIR NODES]\n");
|
||||
//fnd::SimpleTextOutput::hxdStyleDump(mDirNodes.data(), mDirNodes.size());
|
||||
|
||||
// read file nodes
|
||||
mFileNodes.alloc(mHdr.sections[nn::hac::romfs::FILE_NODE_TABLE].size.get());
|
||||
mFile->read(mFileNodes.data(), mHdr.sections[nn::hac::romfs::FILE_NODE_TABLE].offset.get(), mFileNodes.size());
|
||||
(*mFile)->read(mFileNodes.data(), mHdr.sections[nn::hac::romfs::FILE_NODE_TABLE].offset.get(), mFileNodes.size());
|
||||
//printf("[RAW FILE NODES]\n");
|
||||
//fnd::SimpleTextOutput::hxdStyleDump(mFileNodes.data(), mFileNodes.size());
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <fnd/List.h>
|
||||
#include <nn/hac/romfs.h>
|
||||
|
@ -77,12 +78,11 @@ public:
|
|||
};
|
||||
|
||||
RomfsProcess();
|
||||
~RomfsProcess();
|
||||
|
||||
void process();
|
||||
|
||||
// generic
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
||||
|
@ -96,8 +96,7 @@ private:
|
|||
const std::string kModuleName = "RomfsProcess";
|
||||
static const size_t kCacheSize = 0x10000;
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
#include "XciProcess.h"
|
||||
|
||||
XciProcess::XciProcess() :
|
||||
mFile(nullptr),
|
||||
mOwnIFile(false),
|
||||
mFile(),
|
||||
mCliOutputMode(_BIT(OUTPUT_BASIC)),
|
||||
mVerify(false),
|
||||
mListFs(false),
|
||||
|
@ -16,14 +15,6 @@ XciProcess::XciProcess() :
|
|||
{
|
||||
}
|
||||
|
||||
XciProcess::~XciProcess()
|
||||
{
|
||||
if (mOwnIFile)
|
||||
{
|
||||
delete mFile;
|
||||
}
|
||||
}
|
||||
|
||||
void XciProcess::process()
|
||||
{
|
||||
importHeader();
|
||||
|
@ -43,10 +34,9 @@ void XciProcess::process()
|
|||
processPartitionPfs();
|
||||
}
|
||||
|
||||
void XciProcess::setInputFile(fnd::IFile* file, bool ownIFile)
|
||||
void XciProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
|
||||
{
|
||||
mFile = file;
|
||||
mOwnIFile = ownIFile;
|
||||
}
|
||||
|
||||
void XciProcess::setKeyCfg(const KeyConfiguration& keycfg)
|
||||
|
@ -78,13 +68,13 @@ void XciProcess::importHeader()
|
|||
{
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
if (*mFile == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No file reader set.");
|
||||
}
|
||||
|
||||
// read header page
|
||||
mFile->read((byte_t*)&mHdrPage, 0, sizeof(nn::hac::sXciHeaderPage));
|
||||
(*mFile)->read((byte_t*)&mHdrPage, 0, sizeof(nn::hac::sXciHeaderPage));
|
||||
|
||||
// allocate memory for and decrypt sXciHeader
|
||||
scratch.alloc(sizeof(nn::hac::sXciHeader));
|
||||
|
@ -193,7 +183,7 @@ bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* t
|
|||
fnd::Vec<byte_t> scratch;
|
||||
fnd::sha::sSha256Hash calc_hash;
|
||||
scratch.alloc(len);
|
||||
mFile->read(scratch.data(), offset, scratch.size());
|
||||
(*mFile)->read(scratch.data(), offset, scratch.size());
|
||||
fnd::sha::Sha256(scratch.data(), scratch.size(), calc_hash.bytes);
|
||||
return calc_hash.compare(test_hash);
|
||||
}
|
||||
|
@ -216,7 +206,7 @@ void XciProcess::processRootPfs()
|
|||
{
|
||||
std::cout << "[WARNING] XCI Root HFS0: FAIL (bad hash)" << std::endl;
|
||||
}
|
||||
mRootPfs.setInputFile(new OffsetAdjustedIFile(mFile, SHARED_IFILE, mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize()), OWN_IFILE);
|
||||
mRootPfs.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize()));
|
||||
mRootPfs.setListFs(mListFs);
|
||||
mRootPfs.setVerifyMode(false);
|
||||
mRootPfs.setCliOutputMode(mCliOutputMode);
|
||||
|
@ -236,7 +226,7 @@ void XciProcess::processPartitionPfs()
|
|||
}
|
||||
|
||||
PfsProcess tmp;
|
||||
tmp.setInputFile(new OffsetAdjustedIFile(mFile, SHARED_IFILE, mHdr.getPartitionFsAddress() + rootPartitions[i].offset, rootPartitions[i].size), OWN_IFILE);
|
||||
tmp.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress() + rootPartitions[i].offset, rootPartitions[i].size));
|
||||
tmp.setListFs(mListFs);
|
||||
tmp.setVerifyMode(mVerify);
|
||||
tmp.setCliOutputMode(mCliOutputMode);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <fnd/List.h>
|
||||
#include <nn/hac/XciHeader.h>
|
||||
#include "KeyConfiguration.h"
|
||||
|
@ -13,12 +14,11 @@ class XciProcess
|
|||
{
|
||||
public:
|
||||
XciProcess();
|
||||
~XciProcess();
|
||||
|
||||
void process();
|
||||
|
||||
// generic
|
||||
void setInputFile(fnd::IFile* file, bool ownIFile);
|
||||
void setInputFile(const fnd::SharedPtr<fnd::IFile>& file);
|
||||
void setKeyCfg(const KeyConfiguration& keycfg);
|
||||
void setCliOutputMode(CliOutputMode type);
|
||||
void setVerifyMode(bool verify);
|
||||
|
@ -31,8 +31,7 @@ private:
|
|||
const std::string kModuleName = "XciProcess";
|
||||
const std::string kXciMountPointName = "gamecard:/";
|
||||
|
||||
fnd::IFile* mFile;
|
||||
bool mOwnIFile;
|
||||
fnd::SharedPtr<fnd::IFile> mFile;
|
||||
KeyConfiguration mKeyCfg;
|
||||
CliOutputMode mCliOutputMode;
|
||||
bool mVerify;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <cstdio>
|
||||
#include <fnd/SimpleFile.h>
|
||||
#include <fnd/SharedPtr.h>
|
||||
#include <fnd/StringConv.h>
|
||||
#include "UserSettings.h"
|
||||
#include "XciProcess.h"
|
||||
|
@ -35,11 +36,13 @@ int main(int argc, char** argv)
|
|||
try {
|
||||
user_set.parseCmdArgs(args);
|
||||
|
||||
fnd::SharedPtr<fnd::IFile> inputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read));
|
||||
|
||||
if (user_set.getFileType() == FILE_XCI)
|
||||
{
|
||||
XciProcess xci;
|
||||
|
||||
xci.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
xci.setInputFile(inputFile);
|
||||
|
||||
xci.setKeyCfg(user_set.getKeyCfg());
|
||||
xci.setCliOutputMode(user_set.getCliOutputMode());
|
||||
|
@ -61,7 +64,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
PfsProcess pfs;
|
||||
|
||||
pfs.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
pfs.setInputFile(inputFile);
|
||||
pfs.setCliOutputMode(user_set.getCliOutputMode());
|
||||
pfs.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
|
@ -75,7 +78,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
RomfsProcess romfs;
|
||||
|
||||
romfs.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
romfs.setInputFile(inputFile);
|
||||
romfs.setCliOutputMode(user_set.getCliOutputMode());
|
||||
romfs.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
|
@ -89,7 +92,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
NcaProcess nca;
|
||||
|
||||
nca.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
nca.setInputFile(inputFile);
|
||||
nca.setKeyCfg(user_set.getKeyCfg());
|
||||
nca.setCliOutputMode(user_set.getCliOutputMode());
|
||||
nca.setVerifyMode(user_set.isVerifyFile());
|
||||
|
@ -111,7 +114,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
NpdmProcess npdm;
|
||||
|
||||
npdm.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
npdm.setInputFile(inputFile);
|
||||
npdm.setKeyCfg(user_set.getKeyCfg());
|
||||
npdm.setCliOutputMode(user_set.getCliOutputMode());
|
||||
npdm.setVerifyMode(user_set.isVerifyFile());
|
||||
|
@ -122,7 +125,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
CnmtProcess cnmt;
|
||||
|
||||
cnmt.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
cnmt.setInputFile(inputFile);
|
||||
cnmt.setCliOutputMode(user_set.getCliOutputMode());
|
||||
cnmt.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
|
@ -132,7 +135,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
NsoProcess obj;
|
||||
|
||||
obj.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
obj.setInputFile(inputFile);
|
||||
obj.setCliOutputMode(user_set.getCliOutputMode());
|
||||
obj.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
|
@ -146,7 +149,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
NroProcess obj;
|
||||
|
||||
obj.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
obj.setInputFile(inputFile);
|
||||
obj.setCliOutputMode(user_set.getCliOutputMode());
|
||||
obj.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
|
@ -169,7 +172,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
NacpProcess nacp;
|
||||
|
||||
nacp.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
nacp.setInputFile(inputFile);
|
||||
nacp.setCliOutputMode(user_set.getCliOutputMode());
|
||||
nacp.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
|
@ -179,7 +182,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
PkiCertProcess cert;
|
||||
|
||||
cert.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
cert.setInputFile(inputFile);
|
||||
cert.setKeyCfg(user_set.getKeyCfg());
|
||||
cert.setCliOutputMode(user_set.getCliOutputMode());
|
||||
cert.setVerifyMode(user_set.isVerifyFile());
|
||||
|
@ -190,7 +193,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
EsTikProcess tik;
|
||||
|
||||
tik.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
tik.setInputFile(inputFile);
|
||||
tik.setKeyCfg(user_set.getKeyCfg());
|
||||
tik.setCertificateChain(user_set.getCertificateChain());
|
||||
tik.setCliOutputMode(user_set.getCliOutputMode());
|
||||
|
@ -202,7 +205,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
AssetProcess obj;
|
||||
|
||||
obj.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
|
||||
obj.setInputFile(inputFile);
|
||||
obj.setCliOutputMode(user_set.getCliOutputMode());
|
||||
obj.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
|
|
Loading…
Reference in a new issue