mirror of
https://github.com/jakcron/nstool
synced 2024-12-25 14:11:14 +00:00
[nstool] Prototype reading NSO header.
This commit is contained in:
parent
a8863ca9c3
commit
7f27f344bd
5 changed files with 184 additions and 0 deletions
137
programs/nstool/source/NsoProcess.cpp
Normal file
137
programs/nstool/source/NsoProcess.cpp
Normal 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
|
||||
}
|
||||
|
32
programs/nstool/source/NsoProcess.h
Normal file
32
programs/nstool/source/NsoProcess.h
Normal 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();
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -19,6 +19,7 @@ enum FileType
|
|||
FILE_NCA,
|
||||
FILE_NPDM,
|
||||
FILE_CNMT,
|
||||
FILE_NSO,
|
||||
FILE_INVALID = -1,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue