mirror of
https://github.com/jakcron/nstool
synced 2024-12-24 13:41:12 +00:00
[nx] Add ISerialiseableInterface, which AciHeader and NcaHeader inherit from. Also added SacEntry.
This commit is contained in:
parent
bd8a232160
commit
337a5eff25
9 changed files with 260 additions and 19 deletions
|
@ -19,20 +19,45 @@ void AciHeader::calculateSectionOffsets()
|
|||
mKc.offset = mSac.offset + align(mSac.size, kAciAlignSize);
|
||||
}
|
||||
|
||||
AciHeader::AciHeader()
|
||||
{
|
||||
clearVariables();
|
||||
}
|
||||
|
||||
AciHeader::AciHeader(const AciHeader & other)
|
||||
{
|
||||
importBinary(other.getBytes(), other.getSize());
|
||||
}
|
||||
|
||||
AciHeader::AciHeader(const u8 * bytes)
|
||||
{
|
||||
importBinary(bytes);
|
||||
}
|
||||
|
||||
bool AciHeader::operator==(const AciHeader & other)
|
||||
{
|
||||
return memcmp(this->getBytes(), other.getBytes(), this->getSize());
|
||||
}
|
||||
|
||||
void AciHeader::operator=(const AciHeader & other)
|
||||
{
|
||||
this->importBinary(other.getBytes(), other.getSize());
|
||||
}
|
||||
|
||||
const u8 * AciHeader::getBytes() const
|
||||
{
|
||||
return mBinaryBlob.data();
|
||||
return mBinaryBlob.getBytes();
|
||||
}
|
||||
|
||||
size_t AciHeader::getSize() const
|
||||
{
|
||||
return mBinaryBlob.size();
|
||||
return mBinaryBlob.getSize();
|
||||
}
|
||||
|
||||
void AciHeader::exportBinary()
|
||||
{
|
||||
mBinaryBlob.alloc(sizeof(sAciHeader));
|
||||
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.data();
|
||||
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
|
||||
|
||||
// set type
|
||||
switch (mType)
|
||||
|
@ -65,9 +90,9 @@ void AciHeader::importBinary(const u8 * bytes)
|
|||
clearVariables();
|
||||
|
||||
mBinaryBlob.alloc(sizeof(sAciHeader));
|
||||
memcpy(mBinaryBlob.data(), bytes, sizeof(sAciHeader));
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sAciHeader));
|
||||
|
||||
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.data();
|
||||
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
|
||||
|
||||
if (memcmp(hdr->signature(), kAciStructSig.c_str(), 4) == 0)
|
||||
{
|
||||
|
@ -91,6 +116,15 @@ void AciHeader::importBinary(const u8 * bytes)
|
|||
mKc.size = hdr->kc().size();
|
||||
}
|
||||
|
||||
void AciHeader::importBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
if (len < sizeof(sAciHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "ACI header too small");
|
||||
}
|
||||
importBinary(bytes);
|
||||
}
|
||||
|
||||
AciHeader::AciType AciHeader::getAciType() const
|
||||
{
|
||||
return mType;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/memory_blob.h>
|
||||
#include <string>
|
||||
#include <nx/ISerialiseableBinary.h>
|
||||
|
||||
class AciHeader
|
||||
class AciHeader : public ISerialiseableBinary
|
||||
{
|
||||
public:
|
||||
enum AciType
|
||||
|
@ -18,6 +19,13 @@ public:
|
|||
size_t size;
|
||||
};
|
||||
|
||||
AciHeader();
|
||||
AciHeader(const AciHeader& other);
|
||||
AciHeader(const u8* bytes);
|
||||
|
||||
bool operator==(const AciHeader& other);
|
||||
void operator=(const AciHeader& other);
|
||||
|
||||
// to be used after export
|
||||
const u8* getBytes() const;
|
||||
size_t getSize() const;
|
||||
|
@ -25,6 +33,7 @@ public:
|
|||
// export/import binary
|
||||
void exportBinary();
|
||||
void importBinary(const u8* bytes);
|
||||
void importBinary(const u8* bytes, size_t len);
|
||||
|
||||
// variables
|
||||
AciType getAciType() const;
|
||||
|
@ -56,13 +65,13 @@ private:
|
|||
{
|
||||
private:
|
||||
u32 offset_; // aligned by 0x10 from the last one
|
||||
u32 size_;
|
||||
u32 mSize;
|
||||
public:
|
||||
u32 offset() const { return le_word(offset_); }
|
||||
void set_offset(u32 offset) { offset_ = le_word(offset); }
|
||||
|
||||
u32 size() const { return le_word(size_); }
|
||||
void set_size(u32 size) { size_ = le_word(size); }
|
||||
u32 size() const { return le_word(mSize); }
|
||||
void set_size(u32 size) { mSize = le_word(size); }
|
||||
} fac_, sac_, kc_;
|
||||
u8 reserved_3[8];
|
||||
public:
|
||||
|
|
17
lib/nx/ISerialiseableBinary.h
Normal file
17
lib/nx/ISerialiseableBinary.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include <fnd/types.h>
|
||||
|
||||
class ISerialiseableBinary
|
||||
{
|
||||
public:
|
||||
virtual bool operator==(const ISerialiseableBinary& other) = 0;
|
||||
virtual void operator=(const ISerialiseableBinary& other) = 0;
|
||||
|
||||
virtual const u8* getBytes() const = 0;
|
||||
virtual size_t getSize() const = 0;
|
||||
|
||||
virtual void exportBinary() = 0;
|
||||
virtual void importBinary(const u8* bytes) = 0;
|
||||
virtual void importBinary(const u8* bytes, size_t len) = 0;
|
||||
};
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
void NcaHeader::exportBinary()
|
||||
{
|
||||
mBinaryBlob.alloc(sizeof(sNcaHeader));
|
||||
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.data();
|
||||
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
|
||||
|
||||
hdr->set_signature(kNcaSig.c_str());
|
||||
hdr->set_block_size(kDefaultBlockSize);
|
||||
|
@ -36,9 +36,9 @@ void NcaHeader::importBinary(const u8 * bytes)
|
|||
clearVariables();
|
||||
|
||||
mBinaryBlob.alloc(sizeof(sNcaHeader));
|
||||
memcpy(mBinaryBlob.data(), bytes, sizeof(sNcaHeader));
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sNcaHeader));
|
||||
|
||||
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.data();
|
||||
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
|
||||
|
||||
if (memcmp(hdr->signature(), kNcaSig.c_str(), 4) != 0)
|
||||
{
|
||||
|
@ -68,6 +68,15 @@ void NcaHeader::importBinary(const u8 * bytes)
|
|||
}
|
||||
}
|
||||
|
||||
void NcaHeader::importBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
if (len < sizeof(sNcaHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NCA header size is too small");
|
||||
}
|
||||
importBinary(bytes);
|
||||
}
|
||||
|
||||
u64 NcaHeader::getNcaSize() const
|
||||
{
|
||||
return mNcaSize;
|
||||
|
@ -157,12 +166,22 @@ NcaHeader::NcaHeader(const u8 * bytes)
|
|||
importBinary(bytes);
|
||||
}
|
||||
|
||||
bool NcaHeader::operator==(const NcaHeader & other)
|
||||
{
|
||||
return memcmp(this->getBytes(), other.getBytes(), this->getSize()) == 0;
|
||||
}
|
||||
|
||||
void NcaHeader::operator=(const NcaHeader & other)
|
||||
{
|
||||
this->importBinary(other.getBytes(), other.getSize());
|
||||
}
|
||||
|
||||
const u8 * NcaHeader::getBytes() const
|
||||
{
|
||||
return mBinaryBlob.data();
|
||||
return mBinaryBlob.getBytes();
|
||||
}
|
||||
|
||||
size_t NcaHeader::getSize() const
|
||||
{
|
||||
return mBinaryBlob.size();
|
||||
return mBinaryBlob.getSize();
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/memory_blob.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <nx/ISerialiseableBinary.h>
|
||||
|
||||
class NcaHeader
|
||||
class NcaHeader : public ISerialiseableBinary
|
||||
{
|
||||
public:
|
||||
struct sSection
|
||||
|
@ -19,10 +20,15 @@ public:
|
|||
crypto::sha::sSha256Hash hash;
|
||||
};
|
||||
|
||||
static const size_t kDefaultBlockSize = 0x200;
|
||||
|
||||
NcaHeader();
|
||||
NcaHeader(const NcaHeader& other);
|
||||
NcaHeader(const u8* bytes);
|
||||
|
||||
bool operator==(const NcaHeader& other);
|
||||
void operator=(const NcaHeader& other);
|
||||
|
||||
// to be used after export
|
||||
const u8* getBytes() const;
|
||||
size_t getSize() const;
|
||||
|
@ -30,6 +36,7 @@ public:
|
|||
// export/import binary
|
||||
void exportBinary();
|
||||
void importBinary(const u8* bytes);
|
||||
void importBinary(const u8* bytes, size_t len);
|
||||
|
||||
// variables
|
||||
u64 getNcaSize() const;
|
||||
|
@ -45,7 +52,6 @@ public:
|
|||
private:
|
||||
const std::string kModuleName = "NCA_HEADER";
|
||||
const std::string kNcaSig = "NCA2";
|
||||
static const size_t kDefaultBlockSize = 0x200;
|
||||
static const size_t kSectionNum = 4;
|
||||
static const size_t kAesKeyNum = 4;
|
||||
|
||||
|
|
101
lib/nx/SacEntry.cpp
Normal file
101
lib/nx/SacEntry.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "SacEntry.h"
|
||||
|
||||
SacEntry::SacEntry() :
|
||||
mIsServer(false),
|
||||
mName("")
|
||||
{
|
||||
}
|
||||
|
||||
SacEntry::SacEntry(const SacEntry & other)
|
||||
{
|
||||
importBinary(other.getBytes(), other.getSize());
|
||||
}
|
||||
|
||||
SacEntry::SacEntry(const u8 * bytes)
|
||||
{
|
||||
importBinary(bytes);
|
||||
}
|
||||
|
||||
const u8 * SacEntry::getBytes() const
|
||||
{
|
||||
return mBinaryBlob.getBytes();
|
||||
}
|
||||
|
||||
size_t SacEntry::getSize() const
|
||||
{
|
||||
return mBinaryBlob.getSize();
|
||||
}
|
||||
|
||||
void SacEntry::exportBinary()
|
||||
{
|
||||
try {
|
||||
mBinaryBlob.alloc(mName.size() + 1);
|
||||
}
|
||||
catch (const fnd::Exception& e)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Failed to allocate memory for SacEntry: " + std::string(e.what()));
|
||||
}
|
||||
|
||||
if (mName.length() > kMaxServiceNameLen)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Service name string too long (max 8 chars)");
|
||||
}
|
||||
|
||||
// copy data into binary blob
|
||||
mBinaryBlob[0] = (mIsServer ? SAC_IS_SERVER : 0) | (mName.length() & SAC_NAME_LEN_MASK);
|
||||
memcpy(mBinaryBlob.getBytes() + 1, mName.c_str(), mName.length());
|
||||
}
|
||||
|
||||
void SacEntry::importBinary(const u8 * bytes)
|
||||
{
|
||||
bool isServer = (bytes[0] & SAC_IS_SERVER) == SAC_IS_SERVER;
|
||||
size_t nameLen = (bytes[0] & SAC_NAME_LEN_MASK);
|
||||
if (nameLen == 0)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "SAC entry has no service name");
|
||||
}
|
||||
else if (nameLen > kMaxServiceNameLen)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Service name string too long (max 8 chars)");
|
||||
}
|
||||
|
||||
mBinaryBlob.alloc(nameLen + 1);
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||
|
||||
mIsServer = isServer;
|
||||
mName = std::string((const char*)(mBinaryBlob.getBytes() + 1), nameLen);
|
||||
}
|
||||
|
||||
void SacEntry::importBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
importBinary(bytes);
|
||||
if (getSize() != len)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "SAC Entry has unexpected size");
|
||||
}
|
||||
}
|
||||
|
||||
bool SacEntry::isServer() const
|
||||
{
|
||||
return mIsServer;
|
||||
}
|
||||
|
||||
void SacEntry::setIsServer(bool isServer)
|
||||
{
|
||||
mIsServer = isServer;
|
||||
}
|
||||
|
||||
const std::string & SacEntry::getName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
void SacEntry::setName(const std::string & name)
|
||||
{
|
||||
if (name.length() > kMaxServiceNameLen)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Service name string too long (max 8 chars)");
|
||||
}
|
||||
|
||||
mName = name;
|
||||
}
|
43
lib/nx/SacEntry.h
Normal file
43
lib/nx/SacEntry.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/memory_blob.h>
|
||||
#include <nx/ISerialiseableBinary.h>
|
||||
|
||||
class SacEntry : public ISerialiseableBinary
|
||||
{
|
||||
SacEntry();
|
||||
SacEntry(const SacEntry& other);
|
||||
SacEntry(const u8* bytes);
|
||||
|
||||
// to be used after export
|
||||
const u8* getBytes() const;
|
||||
size_t getSize() const;
|
||||
|
||||
// export/import binary
|
||||
void exportBinary();
|
||||
void importBinary(const u8* bytes);
|
||||
void importBinary(const u8* bytes, size_t len);
|
||||
|
||||
// variables
|
||||
bool isServer() const;
|
||||
void setIsServer(bool isServer);
|
||||
const std::string& getName() const;
|
||||
void setName(const std::string& name);
|
||||
private:
|
||||
const std::string kModuleName = "SAC_ENTRY";
|
||||
static const size_t kMaxServiceNameLen = 8;
|
||||
|
||||
enum SacEntryFlag
|
||||
{
|
||||
SAC_IS_SERVER = BIT(7),
|
||||
SAC_NAME_LEN_MASK = BIT(7)-1
|
||||
};
|
||||
|
||||
// raw binary
|
||||
fnd::MemoryBlob mBinaryBlob;
|
||||
|
||||
// variables
|
||||
bool mIsServer;
|
||||
std::string mName;
|
||||
};
|
|
@ -20,12 +20,15 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AciHeader.h" />
|
||||
<ClInclude Include="ISerialiseableBinary.h" />
|
||||
<ClInclude Include="NcaHeader.h" />
|
||||
<ClInclude Include="NXCrypto.h" />
|
||||
<ClInclude Include="SacEntry.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AciHeader.cpp" />
|
||||
<ClCompile Include="NcaHeader.cpp" />
|
||||
<ClCompile Include="SacEntry.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
<ClInclude Include="AciHeader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SacEntry.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ISerialiseableBinary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="NcaHeader.cpp">
|
||||
|
@ -32,5 +38,8 @@
|
|||
<ClCompile Include="AciHeader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SacEntry.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in a new issue