[nstool] Prototype reading NSO header.

This commit is contained in:
jakcron 2018-05-27 20:34:10 +08:00
parent a8863ca9c3
commit 7f27f344bd
5 changed files with 184 additions and 0 deletions

View file

@ -0,0 +1,137 @@
#include <fnd/SimpleTextOutput.h>
#include <fnd/MemoryBlob.h>
#include "OffsetAdjustedIFile.h"
#include "NsoProcess.h"
inline const char* getBoolStr(bool isTrue)
{
return isTrue? "TRUE" : "FALSE";
}
NsoProcess::NsoProcess():
mReader(nullptr),
mCliOutputType(OUTPUT_NORMAL),
mVerify(false)
{
}
NsoProcess::~NsoProcess()
{
if (mReader != nullptr)
{
delete mReader;
}
}
void NsoProcess::process()
{
fnd::MemoryBlob scratch;
if (mReader == nullptr)
{
throw fnd::Exception(kModuleName, "No file reader set.");
}
if (mReader->size() < sizeof(nx::sNsoHeader))
{
throw fnd::Exception(kModuleName, "Corrupt NSO file too small");
}
scratch.alloc(sizeof(nx::sNsoHeader));
mReader->read(scratch.getBytes(), 0, scratch.getSize());
memcpy(&mNso, scratch.getBytes(), sizeof(nx::sNsoHeader));
if (std::string(mNso.signature, 4) != nx::nso::kNsoSig)
{
throw fnd::Exception(kModuleName, "Corrupt NSO header");
}
if (mCliOutputType >= OUTPUT_NORMAL)
{
displayHeader();
}
}
void NsoProcess::setInputFile(fnd::IFile* file, size_t offset, size_t size)
{
mReader = new OffsetAdjustedIFile(file, offset, size);
}
void NsoProcess::setCliOutputMode(CliOutputType type)
{
mCliOutputType = type;
}
void NsoProcess::setVerifyMode(bool verify)
{
mVerify = verify;
}
void NsoProcess::displayHeader()
{
#define _HEXDUMP_L(var, len) do { for (size_t a__a__A = 0; a__a__A < len; a__a__A++) printf("%02x", var[a__a__A]); } while(0)
printf("[NSO Header]\n");
printf(" Format Version: %" PRId32 "\n", mNso.version.get());
printf(" Flags: 0x%" PRIx32 "\n", mNso.flags.get());
printf(" ModuleId: ");
_HEXDUMP_L(mNso.module_id, 32);
printf("\n");
printf(" .text:\n");
printf(" FileOffset: 0x%" PRIx32 "\n", mNso.text.file_offset.get());
printf(" FileSize: 0x%" PRIx32 "\n", mNso.text_file_size.get());
printf(" FileCompressed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_TEXT_COMPRESS)));
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.text.memory_offset.get());
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.text.size.get());
printf(" MemBlobHashed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_TEXT_HASH)));
if (_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_TEXT_HASH))
{
printf(" MemBlobHash: ");
_HEXDUMP_L(mNso.text_hash, 32);
printf("\n");
}
printf(" .ro:\n");
printf(" FileOffset: 0x%" PRIx32 "\n", mNso.ro.file_offset.get());
printf(" FileSize: 0x%" PRIx32 "\n", mNso.ro_file_size.get());
printf(" FileCompressed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_RO_COMPRESS)));
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.ro.memory_offset.get());
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.ro.size.get());
printf(" MemBlobHashed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_RO_HASH)));
if (_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_RO_HASH))
{
printf(" MemBlobHash: ");
_HEXDUMP_L(mNso.ro_hash, 32);
printf("\n");
}
printf(" .api_info:\n");
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.embedded.offset.get());
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.embedded.size.get());
printf(" .dynstr:\n");
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.dyn_str.offset.get());
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.dyn_str.size.get());
printf(" .dynsym:\n");
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.dyn_sym.offset.get());
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.dyn_sym.size.get());
printf(" .data:\n");
printf(" FileOffset: 0x%" PRIx32 "\n", mNso.data.file_offset.get());
printf(" FileSize: 0x%" PRIx32 "\n", mNso.data_file_size.get());
printf(" FileCompressed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_DATA_COMPRESS)));
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.data.memory_offset.get());
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.data.size.get());
printf(" MemBlobHashed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_DATA_HASH)));
if (_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_DATA_HASH))
{
printf(" MemBlobHash: ");
_HEXDUMP_L(mNso.data_hash, 32);
printf("\n");
}
printf(" .bss:\n");
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.bss_size.get());
printf(" .module_id:\n");
printf(" FileOffset: 0x%" PRIx32 "\n", mNso.module_name_offset.get());
printf(" FileSize: 0x%" PRIx32 "\n", mNso.module_name_size.get());
#undef _HEXDUMP_L
}

View file

@ -0,0 +1,32 @@
#pragma once
#include <string>
#include <fnd/types.h>
#include <fnd/IFile.h>
#include <nx/nso.h>
#include "nstool.h"
class NsoProcess
{
public:
NsoProcess();
~NsoProcess();
void process();
void setInputFile(fnd::IFile* file, size_t offset, size_t size);
void setCliOutputMode(CliOutputType type);
void setVerifyMode(bool verify);
private:
const std::string kModuleName = "NsoProcess";
fnd::IFile* mReader;
CliOutputType mCliOutputType;
bool mVerify;
nx::sNsoHeader mNso;
void displayHeader();
};

View file

@ -17,6 +17,7 @@
#include <nx/nca.h>
#include <nx/npdm.h>
#include <nx/romfs.h>
#include <nx/nso.h>
UserSettings::UserSettings()
{}
@ -635,6 +636,8 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
// test npdm
else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && std::string(_QUICK_CAST(nx::sNpdmHeader, 0)->signature, 4) == nx::npdm::kNpdmStructSig)
file_type = FILE_NPDM;
else if (_ASSERT_SIZE(sizeof(nx::sNsoHeader)) && std::string(_QUICK_CAST(nx::sNsoHeader, 0)->signature, 4) == nx::nso::kNsoSig)
file_type = FILE_NSO;
// else unrecognised
else
file_type = FILE_INVALID;

View file

@ -7,6 +7,7 @@
#include "NcaProcess.h"
#include "NpdmProcess.h"
#include "CnmtProcess.h"
#include "NsoProcess.h"
int main(int argc, char** argv)
@ -109,6 +110,16 @@ int main(int argc, char** argv)
cnmt.process();
}
else if (user_set.getFileType() == FILE_NSO)
{
NsoProcess nso;
nso.setInputFile(&inputFile, 0, inputFile.size());
nso.setCliOutputMode(user_set.getCliOutputType());
nso.setVerifyMode(user_set.isVerifyFile());
nso.process();
}
}
catch (const fnd::Exception& e) {
printf("\n\n%s\n", e.what());

View file

@ -19,6 +19,7 @@ enum FileType
FILE_NCA,
FILE_NPDM,
FILE_CNMT,
FILE_NSO,
FILE_INVALID = -1,
};