mirror of
https://github.com/jakcron/nstool
synced 2024-12-24 21:51:14 +00:00
[nx|nstool] Encapsulated NsoHeader parsing into nx::NsoHeader
This commit is contained in:
parent
3363d9152a
commit
915bd80f6f
5 changed files with 409 additions and 56 deletions
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
#include <nx/xci.h>
|
||||
#include <nx/nso.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/List.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
|
@ -10,6 +10,81 @@ namespace nx
|
|||
public fnd::ISerialiseableBinary
|
||||
{
|
||||
public:
|
||||
struct sModuleId
|
||||
{
|
||||
byte_t data[nso::kModuleIdLen];
|
||||
|
||||
void operator=(const sModuleId& other)
|
||||
{
|
||||
memcpy(data, other.data, nso::kModuleIdLen);
|
||||
}
|
||||
|
||||
bool operator==(const sModuleId& other) const
|
||||
{
|
||||
return memcmp(data, other.data, nso::kModuleIdLen) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const sModuleId& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
struct sLayout
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
|
||||
void operator=(const sLayout& other)
|
||||
{
|
||||
offset = other.offset;
|
||||
size = other.size;
|
||||
}
|
||||
|
||||
bool operator==(const sLayout& other) const
|
||||
{
|
||||
return (offset == other.offset) \
|
||||
&& (size == other.size);
|
||||
}
|
||||
|
||||
bool operator!=(const sLayout& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
struct sCodeSegment
|
||||
{
|
||||
sLayout file_layout;
|
||||
sLayout memory_layout;
|
||||
bool is_compressed;
|
||||
bool is_hashed;
|
||||
crypto::sha::sSha256Hash hash;
|
||||
|
||||
void operator=(const sCodeSegment& other)
|
||||
{
|
||||
file_layout = other.file_layout;
|
||||
memory_layout = other.memory_layout;
|
||||
is_compressed = other.is_compressed;
|
||||
is_hashed = other.is_hashed;
|
||||
hash = other.hash;
|
||||
}
|
||||
|
||||
bool operator==(const sCodeSegment& other) const
|
||||
{
|
||||
return (file_layout == other.file_layout) \
|
||||
&& (memory_layout == other.memory_layout) \
|
||||
&& (is_compressed == other.is_compressed) \
|
||||
&& (is_hashed == other.is_hashed) \
|
||||
&& (hash == other.hash);
|
||||
}
|
||||
|
||||
bool operator!=(const sCodeSegment& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
NsoHeader();
|
||||
NsoHeader(const NsoHeader& other);
|
||||
NsoHeader(const byte_t* bytes, size_t len);
|
||||
|
@ -29,7 +104,32 @@ namespace nx
|
|||
// variables
|
||||
void clear();
|
||||
|
||||
const sModuleId& getModuleId() const;
|
||||
void setModuleId(const sModuleId& id);
|
||||
|
||||
uint32_t getBssSize() const;
|
||||
void setBssSize(uint32_t size);
|
||||
|
||||
const sCodeSegment& getTextSegmentInfo() const;
|
||||
void setTextSegmentInfo(const sCodeSegment& info);
|
||||
|
||||
const sCodeSegment& getRoSegmentInfo() const;
|
||||
void setRoSegmentInfo(const sCodeSegment& info);
|
||||
|
||||
const sCodeSegment& getDataSegmentInfo() const;
|
||||
void setDataSegmentInfo(const sCodeSegment& info);
|
||||
|
||||
const sLayout& getModuleNameInfo() const;
|
||||
void setModuleNameInfo(const sLayout& info);
|
||||
|
||||
const sLayout& getRoEmbeddedInfo() const;
|
||||
void setRoEmbeddedInfo(const sLayout& info);
|
||||
|
||||
const sLayout& getRoDynStrInfo() const;
|
||||
void setRoDynStrInfo(const sLayout& info);
|
||||
|
||||
const sLayout& getRoDynSymInfo() const;
|
||||
void setRoDynSymInfo(const sLayout& info);
|
||||
private:
|
||||
const std::string kModuleName = "NSO_HEADER";
|
||||
|
||||
|
@ -37,6 +137,15 @@ namespace nx
|
|||
fnd::MemoryBlob mBinaryBlob;
|
||||
|
||||
// data
|
||||
sModuleId mModuleId;
|
||||
uint32_t mBssSize;
|
||||
sCodeSegment mTextSegmentInfo;
|
||||
sCodeSegment mRoSegmentInfo;
|
||||
sCodeSegment mDataSegmentInfo;
|
||||
sLayout mModuleNameInfo;
|
||||
sLayout mRoEmbeddedInfo;
|
||||
sLayout mRoDynStrInfo;
|
||||
sLayout mRoDynSymInfo;
|
||||
|
||||
// helpers
|
||||
bool isEqual(const NsoHeader& other) const;
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/List.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <crypto/rsa.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
|
||||
namespace nx
|
||||
|
@ -23,6 +21,7 @@ namespace nx
|
|||
FLAG_DATA_HASH
|
||||
};
|
||||
|
||||
static const uint32_t kDefaultFormatVersion = 0;
|
||||
static const size_t kModuleIdLen = 32;
|
||||
}
|
||||
|
||||
|
@ -43,7 +42,7 @@ namespace nx
|
|||
struct sNsoHeader
|
||||
{
|
||||
char signature[4];
|
||||
le_uint32_t version;
|
||||
le_uint32_t format_version;
|
||||
byte_t reserved_1[4];
|
||||
le_uint32_t flags;
|
||||
sNsoCodeSegment text;
|
||||
|
@ -60,9 +59,9 @@ namespace nx
|
|||
sNsoSection embedded;
|
||||
sNsoSection dyn_str;
|
||||
sNsoSection dyn_sym;
|
||||
byte_t text_hash[crypto::sha::kSha256HashLen];
|
||||
byte_t ro_hash[crypto::sha::kSha256HashLen];
|
||||
byte_t data_hash[crypto::sha::kSha256HashLen];
|
||||
crypto::sha::sSha256Hash text_hash;
|
||||
crypto::sha::sSha256Hash ro_hash;
|
||||
crypto::sha::sSha256Hash data_hash;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
|
|
@ -42,24 +42,282 @@ size_t nx::NsoHeader::getSize() const
|
|||
|
||||
void nx::NsoHeader::exportBinary()
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "exportBinary() not implemented");
|
||||
mBinaryBlob.alloc(sizeof(sNsoHeader));
|
||||
nx::sNsoHeader* hdr = (nx::sNsoHeader*)mBinaryBlob.getBytes();
|
||||
|
||||
// set header identifers
|
||||
memcpy(hdr->signature, nso::kNsoSig.c_str(), 4);
|
||||
hdr->format_version = nso::kDefaultFormatVersion;
|
||||
|
||||
// variable to store flags before commiting to header
|
||||
uint32_t flags = 0;
|
||||
|
||||
// set moduleid
|
||||
memcpy(hdr->module_id, mModuleId.data, nso::kModuleIdLen);
|
||||
|
||||
// set bss size
|
||||
hdr->bss_size = mBssSize;
|
||||
|
||||
// set text segment
|
||||
hdr->text.file_offset = mTextSegmentInfo.file_layout.offset;
|
||||
hdr->text.memory_offset = mTextSegmentInfo.memory_layout.offset;
|
||||
hdr->text.size = mTextSegmentInfo.memory_layout.size;
|
||||
hdr->text_file_size = mTextSegmentInfo.file_layout.size;
|
||||
if (mTextSegmentInfo.is_compressed)
|
||||
{
|
||||
flags |= _BIT(nso::FLAG_TEXT_COMPRESS);
|
||||
}
|
||||
if (mTextSegmentInfo.is_hashed)
|
||||
{
|
||||
flags |= _BIT(nso::FLAG_TEXT_HASH);
|
||||
hdr->text_hash = mTextSegmentInfo.hash;
|
||||
}
|
||||
|
||||
// set ro segment
|
||||
hdr->ro.file_offset = mRoSegmentInfo.file_layout.offset;
|
||||
hdr->ro.memory_offset = mRoSegmentInfo.memory_layout.offset;
|
||||
hdr->ro.size = mRoSegmentInfo.memory_layout.size;
|
||||
hdr->ro_file_size = mRoSegmentInfo.file_layout.size;
|
||||
if (mRoSegmentInfo.is_compressed)
|
||||
{
|
||||
flags |= _BIT(nso::FLAG_RO_COMPRESS);
|
||||
}
|
||||
if (mRoSegmentInfo.is_hashed)
|
||||
{
|
||||
flags |= _BIT(nso::FLAG_RO_HASH);
|
||||
hdr->ro_hash = mRoSegmentInfo.hash;
|
||||
}
|
||||
|
||||
// set data segment
|
||||
hdr->data.file_offset = mDataSegmentInfo.file_layout.offset;
|
||||
hdr->data.memory_offset = mDataSegmentInfo.memory_layout.offset;
|
||||
hdr->data.size = mDataSegmentInfo.memory_layout.size;
|
||||
hdr->data_file_size = mDataSegmentInfo.file_layout.size;
|
||||
if (mDataSegmentInfo.is_compressed)
|
||||
{
|
||||
flags |= _BIT(nso::FLAG_DATA_COMPRESS);
|
||||
}
|
||||
if (mDataSegmentInfo.is_hashed)
|
||||
{
|
||||
flags |= _BIT(nso::FLAG_DATA_HASH);
|
||||
hdr->data_hash = mDataSegmentInfo.hash;
|
||||
}
|
||||
|
||||
// set module name info
|
||||
hdr->module_name_offset = mModuleNameInfo.offset;
|
||||
hdr->module_name_size = mModuleNameInfo.size;
|
||||
|
||||
// set ro embedded info
|
||||
hdr->embedded.offset = mRoEmbeddedInfo.offset;
|
||||
hdr->embedded.size = mRoEmbeddedInfo.size;
|
||||
|
||||
// set ro dyn str info
|
||||
hdr->dyn_str.offset = mRoDynStrInfo.offset;
|
||||
hdr->dyn_str.size = mRoDynStrInfo.size;
|
||||
|
||||
// set ro dyn sym info
|
||||
hdr->dyn_sym.offset = mRoDynSymInfo.offset;
|
||||
hdr->dyn_sym.size = mRoDynSymInfo.size;
|
||||
|
||||
hdr->flags = flags;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "importBinary() not implemented");
|
||||
// check input data size
|
||||
if (len < sizeof(sNsoHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO header size is too small");
|
||||
}
|
||||
|
||||
// clear internal members
|
||||
clear();
|
||||
|
||||
// allocate internal local binary copy
|
||||
mBinaryBlob.alloc(sizeof(sNsoHeader));
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||
|
||||
// get sNsoHeader ptr
|
||||
const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mBinaryBlob.getBytes();
|
||||
|
||||
// check NSO signature
|
||||
if (std::string(hdr->signature, 4) != nso::kNsoSig)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO header corrupt (unrecognised header signature)");
|
||||
}
|
||||
|
||||
// check NSO format version
|
||||
if (hdr->format_version.get() != nso::kDefaultFormatVersion)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO header corrupt (unsupported format version)");
|
||||
}
|
||||
|
||||
memcpy(mModuleId.data, hdr->module_id, nso::kModuleIdLen);
|
||||
|
||||
mBssSize = hdr->bss_size.get();
|
||||
|
||||
mTextSegmentInfo.file_layout.offset = hdr->text.file_offset.get();
|
||||
mTextSegmentInfo.file_layout.size = hdr->text_file_size.get();
|
||||
mTextSegmentInfo.memory_layout.offset = hdr->text.memory_offset.get();
|
||||
mTextSegmentInfo.memory_layout.size = hdr->text.size.get();
|
||||
mTextSegmentInfo.is_compressed = _HAS_BIT(hdr->flags.get(), nso::FLAG_TEXT_COMPRESS);
|
||||
mTextSegmentInfo.is_hashed = _HAS_BIT(hdr->flags.get(), nso::FLAG_TEXT_HASH);
|
||||
mTextSegmentInfo.hash = hdr->text_hash;
|
||||
|
||||
mRoSegmentInfo.file_layout.offset = hdr->ro.file_offset.get();
|
||||
mRoSegmentInfo.file_layout.size = hdr->ro_file_size.get();
|
||||
mRoSegmentInfo.memory_layout.offset = hdr->ro.memory_offset.get();
|
||||
mRoSegmentInfo.memory_layout.size = hdr->ro.size.get();
|
||||
mRoSegmentInfo.is_compressed = _HAS_BIT(hdr->flags.get(), nso::FLAG_RO_COMPRESS);
|
||||
mRoSegmentInfo.is_hashed = _HAS_BIT(hdr->flags.get(), nso::FLAG_RO_HASH);
|
||||
mRoSegmentInfo.hash = hdr->ro_hash;
|
||||
|
||||
mDataSegmentInfo.file_layout.offset = hdr->data.file_offset.get();
|
||||
mDataSegmentInfo.file_layout.size = hdr->data_file_size.get();
|
||||
mDataSegmentInfo.memory_layout.offset = hdr->data.memory_offset.get();
|
||||
mDataSegmentInfo.memory_layout.size = hdr->data.size.get();
|
||||
mDataSegmentInfo.is_compressed = _HAS_BIT(hdr->flags.get(), nso::FLAG_RO_COMPRESS);
|
||||
mDataSegmentInfo.is_hashed = _HAS_BIT(hdr->flags.get(), nso::FLAG_RO_HASH);
|
||||
mDataSegmentInfo.hash = hdr->data_hash;
|
||||
|
||||
mModuleNameInfo.offset = hdr->module_name_offset.get();
|
||||
mModuleNameInfo.size = hdr->module_name_size.get();
|
||||
|
||||
mRoEmbeddedInfo.offset = hdr->embedded.offset.get();
|
||||
mRoEmbeddedInfo.size = hdr->embedded.size.get();
|
||||
|
||||
mRoDynStrInfo.offset = hdr->dyn_str.offset.get();
|
||||
mRoDynStrInfo.size = hdr->dyn_str.size.get();
|
||||
|
||||
mRoDynSymInfo.offset = hdr->dyn_sym.offset.get();
|
||||
mRoDynSymInfo.size = hdr->dyn_sym.size.get();
|
||||
}
|
||||
|
||||
void nx::NsoHeader::clear()
|
||||
{
|
||||
mBinaryBlob.clear();
|
||||
memset(&mModuleId, 0, sizeof(mModuleId));
|
||||
mBssSize = 0;
|
||||
memset(&mTextSegmentInfo, 0, sizeof(mTextSegmentInfo));
|
||||
memset(&mRoSegmentInfo, 0, sizeof(mRoSegmentInfo));
|
||||
memset(&mDataSegmentInfo, 0, sizeof(mDataSegmentInfo));
|
||||
memset(&mModuleNameInfo, 0, sizeof(mModuleNameInfo));
|
||||
memset(&mRoEmbeddedInfo, 0, sizeof(mRoEmbeddedInfo));
|
||||
memset(&mRoDynStrInfo, 0, sizeof(mRoDynStrInfo));
|
||||
memset(&mRoDynSymInfo, 0, sizeof(mRoDynSymInfo));
|
||||
}
|
||||
|
||||
const nx::NsoHeader::sModuleId& nx::NsoHeader::getModuleId() const
|
||||
{
|
||||
return mModuleId;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setModuleId(const sModuleId& id)
|
||||
{
|
||||
mModuleId = id;
|
||||
}
|
||||
|
||||
uint32_t nx::NsoHeader::getBssSize() const
|
||||
{
|
||||
return mBssSize;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setBssSize(uint32_t size)
|
||||
{
|
||||
mBssSize = size;
|
||||
}
|
||||
|
||||
const nx::NsoHeader::sCodeSegment& nx::NsoHeader::getTextSegmentInfo() const
|
||||
{
|
||||
return mTextSegmentInfo;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setTextSegmentInfo(const sCodeSegment& info)
|
||||
{
|
||||
mTextSegmentInfo = info;
|
||||
}
|
||||
|
||||
const nx::NsoHeader::sCodeSegment& nx::NsoHeader::getRoSegmentInfo() const
|
||||
{
|
||||
return mRoSegmentInfo;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setRoSegmentInfo(const sCodeSegment& info)
|
||||
{
|
||||
mRoSegmentInfo = info;
|
||||
}
|
||||
|
||||
const nx::NsoHeader::sCodeSegment& nx::NsoHeader::getDataSegmentInfo() const
|
||||
{
|
||||
return mDataSegmentInfo;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setDataSegmentInfo(const sCodeSegment& info)
|
||||
{
|
||||
mDataSegmentInfo = info;
|
||||
}
|
||||
|
||||
const nx::NsoHeader::sLayout& nx::NsoHeader::getModuleNameInfo() const
|
||||
{
|
||||
return mModuleNameInfo;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setModuleNameInfo(const sLayout& info)
|
||||
{
|
||||
mModuleNameInfo = info;
|
||||
}
|
||||
|
||||
const nx::NsoHeader::sLayout& nx::NsoHeader::getRoEmbeddedInfo() const
|
||||
{
|
||||
return mRoEmbeddedInfo;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setRoEmbeddedInfo(const sLayout& info)
|
||||
{
|
||||
mRoEmbeddedInfo = info;
|
||||
}
|
||||
|
||||
const nx::NsoHeader::sLayout& nx::NsoHeader::getRoDynStrInfo() const
|
||||
{
|
||||
return mRoDynStrInfo;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setRoDynStrInfo(const sLayout& info)
|
||||
{
|
||||
mRoDynStrInfo = info;
|
||||
}
|
||||
|
||||
const nx::NsoHeader::sLayout& nx::NsoHeader::getRoDynSymInfo() const
|
||||
{
|
||||
return mRoDynSymInfo;
|
||||
}
|
||||
|
||||
void nx::NsoHeader::setRoDynSymInfo(const sLayout& info)
|
||||
{
|
||||
mRoDynSymInfo = info;
|
||||
}
|
||||
|
||||
bool nx::NsoHeader::isEqual(const NsoHeader& other) const
|
||||
{
|
||||
return false;
|
||||
return (mModuleId == other.mModuleId) \
|
||||
&& (mBssSize == other.mBssSize) \
|
||||
&& (mTextSegmentInfo == other.mTextSegmentInfo) \
|
||||
&& (mRoSegmentInfo == other.mRoSegmentInfo) \
|
||||
&& (mDataSegmentInfo == other.mDataSegmentInfo) \
|
||||
&& (mModuleNameInfo == other.mModuleNameInfo) \
|
||||
&& (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \
|
||||
&& (mRoDynStrInfo == other.mRoDynStrInfo) \
|
||||
&& (mRoDynSymInfo == other.mRoDynSymInfo);
|
||||
}
|
||||
void nx::NsoHeader::copyFrom(const NsoHeader& other)
|
||||
{
|
||||
|
||||
mModuleId = other.mModuleId;
|
||||
mBssSize = other.mBssSize;
|
||||
mTextSegmentInfo = other.mTextSegmentInfo;
|
||||
mRoSegmentInfo = other.mRoSegmentInfo;
|
||||
mDataSegmentInfo = other.mDataSegmentInfo;
|
||||
mModuleNameInfo = other.mModuleNameInfo;
|
||||
mRoEmbeddedInfo = other.mRoEmbeddedInfo;
|
||||
mRoDynStrInfo = other.mRoDynStrInfo;
|
||||
mRoDynSymInfo = other.mRoDynSymInfo;
|
||||
}
|
|
@ -41,11 +41,7 @@ void NsoProcess::process()
|
|||
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");
|
||||
}
|
||||
mHdr.importBinary(scratch.getBytes(), scratch.getSize());
|
||||
|
||||
if (mCliOutputType >= OUTPUT_NORMAL)
|
||||
{
|
||||
|
@ -73,70 +69,61 @@ 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);
|
||||
_HEXDUMP_L(mHdr.getModuleId().data, nx::nso::kModuleIdLen);
|
||||
printf("\n");
|
||||
printf(" Program Segments:\n");
|
||||
printf(" .module_id:\n");
|
||||
printf(" FileOffset: 0x%" PRIx32 "\n", mNso.module_name_offset.get());
|
||||
printf(" FileSize: 0x%" PRIx32 "\n", mNso.module_name_size.get());
|
||||
printf(" FileOffset: 0x%" PRIx32 "\n", mHdr.getModuleNameInfo().offset);
|
||||
printf(" FileSize: 0x%" PRIx32 "\n", mHdr.getModuleNameInfo().size);
|
||||
printf(" .text:\n");
|
||||
printf(" FileOffset: 0x%" PRIx32 "\n", mNso.text.file_offset.get());
|
||||
printf(" FileSize: 0x%" PRIx32 "%s\n", mNso.text_file_size.get(), _HAS_BIT(mNso.flags.get(), nx::nso::FLAG_TEXT_COMPRESS)? " (COMPRESSED)" : "");
|
||||
//printf(" Compressed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_TEXT_COMPRESS)));
|
||||
printf(" FileOffset: 0x%" PRIx32 "\n", mHdr.getTextSegmentInfo().file_layout.offset);
|
||||
printf(" FileSize: 0x%" PRIx32 "%s\n", mHdr.getTextSegmentInfo().file_layout.size, mHdr.getTextSegmentInfo().is_compressed? " (COMPRESSED)" : "");
|
||||
printf(" .ro:\n");
|
||||
printf(" FileOffset: 0x%" PRIx32 "\n", mNso.ro.file_offset.get());
|
||||
printf(" FileSize: 0x%" PRIx32 "%s\n", mNso.ro_file_size.get(), _HAS_BIT(mNso.flags.get(), nx::nso::FLAG_RO_COMPRESS)? " (COMPRESSED)" : "");
|
||||
//printf(" Compressed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_RO_COMPRESS)));
|
||||
printf(" FileOffset: 0x%" PRIx32 "\n", mHdr.getRoSegmentInfo().file_layout.offset);
|
||||
printf(" FileSize: 0x%" PRIx32 "%s\n", mHdr.getRoSegmentInfo().file_layout.size, mHdr.getRoSegmentInfo().is_compressed? " (COMPRESSED)" : "");
|
||||
printf(" .data:\n");
|
||||
printf(" FileOffset: 0x%" PRIx32 "\n", mNso.data.file_offset.get());
|
||||
printf(" FileSize: 0x%" PRIx32 "%s\n", mNso.data_file_size.get(), _HAS_BIT(mNso.flags.get(), nx::nso::FLAG_DATA_COMPRESS)? " (COMPRESSED)" : "");
|
||||
//printf(" Compressed: %s\n", getBoolStr(_HAS_BIT(mNso.flags.get(), nx::nso::FLAG_DATA_COMPRESS)));
|
||||
printf(" FileOffset: 0x%" PRIx32 "\n", mHdr.getDataSegmentInfo().file_layout.offset);
|
||||
printf(" FileSize: 0x%" PRIx32 "%s\n", mHdr.getDataSegmentInfo().file_layout.size, mHdr.getDataSegmentInfo().is_compressed? " (COMPRESSED)" : "");
|
||||
printf(" Program Sections:\n");
|
||||
printf(" .text:\n");
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.text.memory_offset.get());
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.text.size.get());
|
||||
//printf(" Hashed: %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(" MemoryOffset: 0x%" PRIx32 "\n", mHdr.getTextSegmentInfo().memory_layout.offset);
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mHdr.getTextSegmentInfo().memory_layout.size);
|
||||
if (mHdr.getTextSegmentInfo().is_hashed)
|
||||
{
|
||||
printf(" Hash: ");
|
||||
_HEXDUMP_L(mNso.text_hash, 32);
|
||||
_HEXDUMP_L(mHdr.getTextSegmentInfo().hash.bytes, 32);
|
||||
printf("\n");
|
||||
}
|
||||
printf(" .ro:\n");
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.ro.memory_offset.get());
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.ro.size.get());
|
||||
//printf(" Hashed: %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(" MemoryOffset: 0x%" PRIx32 "\n", mHdr.getRoSegmentInfo().memory_layout.offset);
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mHdr.getRoSegmentInfo().memory_layout.size);
|
||||
if (mHdr.getRoSegmentInfo().is_hashed)
|
||||
{
|
||||
printf(" Hash: ");
|
||||
_HEXDUMP_L(mNso.ro_hash, 32);
|
||||
_HEXDUMP_L(mHdr.getRoSegmentInfo().hash.bytes, 32);
|
||||
printf("\n");
|
||||
}
|
||||
printf(" .api_info:\n");
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.ro.memory_offset.get() + mNso.embedded.offset.get());
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.embedded.size.get());
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mHdr.getRoSegmentInfo().memory_layout.offset + mHdr.getRoEmbeddedInfo().offset);
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mHdr.getRoEmbeddedInfo().size);
|
||||
printf(" .dynstr:\n");
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.ro.memory_offset.get() + mNso.dyn_str.offset.get());
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.dyn_str.size.get());
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mHdr.getRoSegmentInfo().memory_layout.offset + mHdr.getRoDynStrInfo().offset);
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mHdr.getRoDynStrInfo().size);
|
||||
printf(" .dynsym:\n");
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.ro.memory_offset.get() + mNso.dyn_sym.offset.get());
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.dyn_sym.size.get());
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mHdr.getRoSegmentInfo().memory_layout.offset + mHdr.getRoDynSymInfo().offset);
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mHdr.getRoDynSymInfo().size);
|
||||
printf(" .data:\n");
|
||||
printf(" MemoryOffset: 0x%" PRIx32 "\n", mNso.data.memory_offset.get());
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.data.size.get());
|
||||
//printf(" Hashed: %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(" MemoryOffset: 0x%" PRIx32 "\n", mHdr.getDataSegmentInfo().memory_layout.offset);
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mHdr.getDataSegmentInfo().memory_layout.size);
|
||||
if (mHdr.getDataSegmentInfo().is_hashed)
|
||||
{
|
||||
printf(" Hash: ");
|
||||
_HEXDUMP_L(mNso.data_hash, 32);
|
||||
_HEXDUMP_L(mHdr.getDataSegmentInfo().hash.bytes, 32);
|
||||
printf("\n");
|
||||
}
|
||||
printf(" .bss:\n");
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mNso.bss_size.get());
|
||||
printf(" MemorySize: 0x%" PRIx32 "\n", mHdr.getBssSize());
|
||||
|
||||
#undef _HEXDUMP_L
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <nx/nso.h>
|
||||
#include <nx/NsoHeader.h>
|
||||
|
||||
#include "nstool.h"
|
||||
|
||||
|
@ -26,7 +26,7 @@ private:
|
|||
CliOutputType mCliOutputType;
|
||||
bool mVerify;
|
||||
|
||||
nx::sNsoHeader mNso;
|
||||
nx::NsoHeader mHdr;
|
||||
|
||||
void displayHeader();
|
||||
};
|
Loading…
Reference in a new issue