[nx|es|fnd|nstool] Commit working refactor.

This commit is contained in:
jakcron 2018-06-24 23:01:16 +08:00
parent 4be0b51ddb
commit 48ac29f3ce
93 changed files with 886 additions and 938 deletions

View file

@ -19,7 +19,7 @@ namespace es
// export/import binary // export/import binary
void toBytes(); void toBytes();
void fromBytes(const byte_t* src, size_t size); void fromBytes(const byte_t* src, size_t size);
const const fnd::Vec<byte_t>& getBytes() const; const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();

View file

@ -7,7 +7,7 @@ namespace es
{ {
template <class T> template <class T>
class SignedData class SignedData
: public fnd::ISerialiseable : public fnd::ISerialisable
{ {
public: public:
SignedData(); SignedData();
@ -18,7 +18,7 @@ namespace es
bool operator!=(const SignedData& other) const; bool operator!=(const SignedData& other) const;
// export/import // export/import
const void toBytes(); void toBytes();
void fromBytes(const byte_t* src, size_t size); void fromBytes(const byte_t* src, size_t size);
const fnd::Vec<byte_t>& getBytes() const; const fnd::Vec<byte_t>& getBytes() const;
@ -42,19 +42,19 @@ namespace es
}; };
template <class T> template <class T>
inline SignedData::SignedData() inline SignedData<T>::SignedData()
{ {
clear(); clear();
} }
template <class T> template <class T>
inline SignedData::SignedData(const SignedData& other) inline SignedData<T>::SignedData(const SignedData& other)
{ {
*this = other; *this = other;
} }
template <class T> template <class T>
inline void SignedData::operator=(const SignedData& other) inline void SignedData<T>::operator=(const SignedData& other)
{ {
mRawBinary = other.mRawBinary; mRawBinary = other.mRawBinary;
mSignature = other.mSignature; mSignature = other.mSignature;
@ -62,48 +62,48 @@ namespace es
} }
template <class T> template <class T>
inline bool SignedData::operator==(const SignedData& other) const inline bool SignedData<T>::operator==(const SignedData& other) const
{ {
return (mSignature == other.mSignature) \ return (mSignature == other.mSignature) \
&& (mBody == other.mBody); && (mBody == other.mBody);
} }
template <class T> template <class T>
inline bool SignedData::operator!=(const SignedData& other) const inline bool SignedData<T>::operator!=(const SignedData& other) const
{ {
return !(*this == other); return !(*this == other);
} }
template <class T> template <class T>
inline const void SignedData::toBytes() inline void SignedData<T>::toBytes()
{ {
mSignature.toBytes(); mSignature.toBytes();
mBody.toBytes(); mBody.toBytes();
mRawBinary.alloc(mSignature.getBytes().size() + mBody.getBytes().size()); mRawBinary.alloc(mSignature.getBytes().size() + mBody.getBytes().size());
memcpy(mRawBinary.getBytes().data(), mSignature.getBytes().data(), mSignature.getBytes().size()); memcpy(mRawBinary.data(), mSignature.getBytes().data(), mSignature.getBytes().size());
memcpy(mRawBinary.getBytes().data() + mSignature.getBytes().size(), mBody.getBytes().data(), mBody.getBytes().size()); memcpy(mRawBinary.data() + mSignature.getBytes().size(), mBody.getBytes().data(), mBody.getBytes().size());
} }
template <class T> template <class T>
inline void SignedData::fromBytes(const byte_t* src, size_t size) inline void SignedData<T>::fromBytes(const byte_t* src, size_t size)
{ {
mSignature.fromBytes(src, size); mSignature.fromBytes(src, size);
mBody.fromBytes(src + mSignature.getBytes().size(), size - mSignature.getBytes().size()); mBody.fromBytes(src + mSignature.getBytes().size(), size - mSignature.getBytes().size());
mRawBinary.alloc(mSignature.getBytes().size() + mBody.getBytes().size()); mRawBinary.alloc(mSignature.getBytes().size() + mBody.getBytes().size());
memcpy(mRawBinary.getBytes().data(), src, mRawBinary.getBytes().size()); memcpy(mRawBinary.data(), src, mRawBinary.size());
} }
template <class T> template <class T>
inline const fnd::Vec<byte_t>& SignedData::getBytes() const inline const fnd::Vec<byte_t>& SignedData<T>::getBytes() const
{ {
return mRawBinary; return mRawBinary;
} }
template <class T> template <class T>
inline void SignedData::clear() inline void SignedData<T>::clear()
{ {
mRawBinary.clear(); mRawBinary.clear();
mSignature.clear(); mSignature.clear();
@ -111,25 +111,25 @@ namespace es
} }
template <class T> template <class T>
inline const es::SignatureBlock& SignedData::getSignature() const inline const es::SignatureBlock& SignedData<T>::getSignature() const
{ {
return mSignature; return mSignature;
} }
template <class T> template <class T>
inline void SignedData::setSignature(const SignatureBlock& signature) inline void SignedData<T>::setSignature(const SignatureBlock& signature)
{ {
mSignature = signature; mSignature = signature;
} }
template <class T> template <class T>
inline const T& SignedData::getBody() const inline const T& SignedData<T>::getBody() const
{ {
return mBody; return mBody;
} }
template <class T> template <class T>
inline void SignedData::setBody(const T& body) inline void SignedData<T>::setBody(const T& body)
{ {
mBody = body; mBody = body;
} }

View file

@ -181,7 +181,7 @@ const byte_t * es::TicketBody_V2::getEncTitleKey() const
void es::TicketBody_V2::setEncTitleKey(const byte_t * data, size_t len) void es::TicketBody_V2::setEncTitleKey(const byte_t * data, size_t len)
{ {
memset(mEncTitleKey, 0, ticket::kEncTitleKeySize); memset(mEncTitleKey, 0, ticket::kEncTitleKeySize);
memcpy(mEncTitleKey, data, MIN(len, ticket::kEncTitleKeySize)); memcpy(mEncTitleKey, data, _MIN(len, ticket::kEncTitleKeySize));
} }
es::ticket::TitleKeyEncType es::TicketBody_V2::getTitleKeyEncType() const es::ticket::TitleKeyEncType es::TicketBody_V2::getTitleKeyEncType() const
@ -262,7 +262,7 @@ const byte_t * es::TicketBody_V2::getReservedRegion() const
void es::TicketBody_V2::setReservedRegion(const byte_t * data, size_t len) void es::TicketBody_V2::setReservedRegion(const byte_t * data, size_t len)
{ {
memset(mReservedRegion, 0, ticket::kReservedRegionSize); memset(mReservedRegion, 0, ticket::kReservedRegionSize);
memcpy(mReservedRegion, data, MIN(len, ticket::kReservedRegionSize)); memcpy(mReservedRegion, data, _MIN(len, ticket::kReservedRegionSize));
} }
uint64_t es::TicketBody_V2::getTicketId() const uint64_t es::TicketBody_V2::getTicketId() const

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/Vec.h> #include <vector>
//#include <fnd/Vec.h>
namespace fnd namespace fnd
{ {
@ -13,7 +14,7 @@ namespace fnd
List(const List<T>& other); List(const List<T>& other);
// copy operator // copy operator
const List<T>& operator=(const List<T>& other); void operator=(const List<T>& other);
// equivalence operators // equivalence operators
bool operator==(const List<T>& other) const; bool operator==(const List<T>& other) const;
@ -43,52 +44,32 @@ namespace fnd
T& getElement(const K& key); T& getElement(const K& key);
private: private:
static const size_t kDefaultSize = 20; std::vector<T> m_Vec;
fnd::Vec<T> m_Vec;
size_t m_Num;
}; };
template<class T> template<class T>
inline List<T>::List() : inline List<T>::List() :
m_Vec(), m_Vec()
m_Num(0)
{ {
m_Vec.alloc(kDefaultSize);
} }
template<class T> template<class T>
inline List<T>::List(const List<T>& other) : inline List<T>::List(const List<T>& other) :
m_Vec(other.m_Vec), List()
m_Size(other.m_Size) {
{} *this = other;
}
template<class T> template<class T>
inline const List<T>& List<T>::operator=(const List<T>& other) inline void List<T>::operator=(const List<T>& other)
{ {
m_Vec = other.m_Vec; m_Vec = other.m_Vec;
m_Size = other.m_Size;
} }
template<class T> template<class T>
inline bool List<T>::operator==(const List<T>& other) const inline bool List<T>::operator==(const List<T>& other) const
{ {
bool isEqual = true; return m_Vec == other.m_Vec;
if (m_Num == other.m_Num)
{
for (size_t i = 0; i < m_Num && isEqual == true; i++)
{
if ((*this)[i] != other[i])
isEqual = false;
}
}
else
{
isEqual = false;
}
return isEqual;
} }
template<class T> template<class T>
@ -100,62 +81,42 @@ namespace fnd
template<class T> template<class T>
inline void List<T>::addElement(const T & element) inline void List<T>::addElement(const T & element)
{ {
(*this)[m_Num] = element; m_Vec.push_back(element);
} }
template<class T> template<class T>
inline const T & List<T>::operator[](size_t index) const inline const T & List<T>::operator[](size_t index) const
{ {
if (index >= m_Num)
{
throw fnd::Exception("List", "Out of bound read");
}
return m_Vec[index]; return m_Vec[index];
} }
template<class T> template<class T>
inline T & List<T>::operator[](size_t index) inline T & List<T>::operator[](size_t index)
{ {
if (index > m_Num)
{
throw fnd::Exception("List", "Out of bound read");
}
else if (index == m_Num)
{
if ((m_Num * 2) >= m_Vec.size())
{
m_Vec.alloc((m_Num + 1) * 2);
}
m_Num++;
}
return m_Vec[index]; return m_Vec[index];
} }
template<class T> template<class T>
inline const T & List<T>::atBack() const inline const T & List<T>::atBack() const
{ {
return m_Vec[m_Num - 1]; return m_Vec.back();
} }
template<class T> template<class T>
inline T & List<T>::atBack() inline T & List<T>::atBack()
{ {
return m_Vec[m_Num - 1]; return m_Vec.back();
} }
template<class T> template<class T>
inline size_t List<T>::size() const inline size_t List<T>::size() const
{ {
return m_Num; return m_Vec.size();
} }
template<class T> template<class T>
inline void List<T>::clear() inline void List<T>::clear()
{ {
m_Num = 0;
m_Vec.clear(); m_Vec.clear();
} }
@ -163,9 +124,9 @@ namespace fnd
template<class K> template<class K>
inline bool List<T>::hasElement(const K & key) const inline bool List<T>::hasElement(const K & key) const
{ {
for (size_t i = 0; i < m_Num; i++) for (size_t i = 0; i < m_Vec.size(); i++)
{ {
if (m_List[i] == key) if (m_Vec[i] == key)
{ {
return true; return true;
} }
@ -178,11 +139,11 @@ namespace fnd
template<class K> template<class K>
inline const T & List<T>::getElement(const K & key) const inline const T & List<T>::getElement(const K & key) const
{ {
for (size_t i = 0; i < m_Num; i++) for (size_t i = 0; i < m_Vec.size(); i++)
{ {
if (m_List[i] == key) if (m_Vec[i] == key)
{ {
return m_List[i]; return m_Vec[i];
} }
} }
@ -193,11 +154,11 @@ namespace fnd
template<class K> template<class K>
inline T & List<T>::getElement(const K & key) inline T & List<T>::getElement(const K & key)
{ {
for (size_t i = 0; i < m_Num; i++) for (size_t i = 0; i < m_Vec.size(); i++)
{ {
if (m_List[i] == key) if (m_Vec[i] == key)
{ {
return m_List[i]; return m_Vec[i];
} }
} }

View file

@ -14,7 +14,7 @@ namespace fnd
~Vec(); ~Vec();
// copy operator // copy operator
const Vec<T>& operator=(const Vec<T>& other); void operator=(const Vec<T>& other);
// equivalence operators // equivalence operators
bool operator==(const Vec<T>& other) const; bool operator==(const Vec<T>& other) const;
@ -34,10 +34,13 @@ namespace fnd
// allocate vector // allocate vector
void alloc(size_t new_size); void alloc(size_t new_size);
// resize vector
void resize(size_t new_size);
// clear vector // clear vector
void clear(); void clear();
private: private:
T * m_Vec; T* m_Vec;
size_t m_Size; size_t m_Size;
void copyFrom(const T * array, size_t num); void copyFrom(const T * array, size_t num);
@ -70,7 +73,7 @@ namespace fnd
} }
template<class T> template<class T>
inline const Vec<T>& Vec<T>::operator=(const Vec<T>& other) inline void Vec<T>::operator=(const Vec<T>& other)
{ {
copyFrom(other.data(), other.size()); copyFrom(other.data(), other.size());
} }
@ -136,6 +139,18 @@ namespace fnd
template<class T> template<class T>
inline void Vec<T>::alloc(size_t new_size) inline void Vec<T>::alloc(size_t new_size)
{
clear();
m_Vec = new T[new_size];
if (m_Vec == nullptr)
{
fnd::Exception("Vec", "Failed to allocate memory for vector");
}
m_Size = new_size;
}
template<class T>
inline void Vec<T>::resize(size_t new_size)
{ {
if (m_Vec != nullptr) if (m_Vec != nullptr)
{ {
@ -145,7 +160,7 @@ namespace fnd
fnd::Exception("Vec", "Failed to allocate memory for vector"); fnd::Exception("Vec", "Failed to allocate memory for vector");
} }
for (size_t i = 0; i < MIN(m_Size, new_size); i++) for (size_t i = 0; i < _MIN(m_Size, new_size); i++)
{ {
new_vec[i] = m_Vec[i]; new_vec[i] = m_Vec[i];
} }
@ -155,12 +170,7 @@ namespace fnd
} }
else else
{ {
m_Vec = new T[new_size]; alloc(new_size);
if (m_Vec == nullptr)
{
fnd::Exception("Vec", "Failed to allocate memory for vector");
}
m_Size = new_size;
} }
} }

View file

@ -9,9 +9,6 @@ typedef uint8_t byte_t;
#define _MIN(x,y) ((x) <= (y)? (x) : (y)) #define _MIN(x,y) ((x) <= (y)? (x) : (y))
#define _MAX(x,y) ((x) >= (y)? (x) : (y)) #define _MAX(x,y) ((x) >= (y)? (x) : (y))
#define MIN(x,y) (_MIN(x,y))
#define MAX(x,y) (_MAX(x,y))
static inline uint64_t align(uint64_t size, uint64_t align) static inline uint64_t align(uint64_t size, uint64_t align)
{ {
return (size % align) == 0? size : (size - (size % align) + align); return (size % align) == 0? size : (size - (size % align) + align);

View file

@ -12,6 +12,10 @@ namespace nx
HandleTableSizeEntry(const KernelCapability& kernel_cap); HandleTableSizeEntry(const KernelCapability& kernel_cap);
HandleTableSizeEntry(uint16_t size); HandleTableSizeEntry(uint16_t size);
void operator=(const HandleTableSizeEntry& other);
bool operator==(const HandleTableSizeEntry& other) const;
bool operator!=(const HandleTableSizeEntry& other) const;
// kernel capability // kernel capability
const KernelCapability& getKernelCapability() const; const KernelCapability& getKernelCapability() const;
void setKernelCapability(const KernelCapability& kernel_cap); void setKernelCapability(const KernelCapability& kernel_cap);

View file

@ -10,9 +10,9 @@ namespace nx
public: public:
HandleTableSizeHandler(); HandleTableSizeHandler();
void operator=(const HandleTableSizeHandler& other);
bool operator==(const HandleTableSizeHandler& other) const; bool operator==(const HandleTableSizeHandler& other) const;
bool operator!=(const HandleTableSizeHandler& other) const; bool operator!=(const HandleTableSizeHandler& other) const;
void operator=(const HandleTableSizeHandler& other);
// kernel capabilty list in/out // kernel capabilty list in/out
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps); void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
@ -30,9 +30,6 @@ namespace nx
bool mIsSet; bool mIsSet;
HandleTableSizeEntry mEntry; HandleTableSizeEntry mEntry;
void copyFrom(const HandleTableSizeHandler& other);
bool isEqual(const HandleTableSizeHandler& other) const;
}; };
} }

View file

@ -2,6 +2,7 @@
#include <nx/hierarchicalintegrity.h> #include <nx/hierarchicalintegrity.h>
#include <fnd/ISerialisable.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <crypto/sha.h>
namespace nx namespace nx
{ {

View file

@ -16,6 +16,10 @@ namespace nx
InteruptEntry(const KernelCapability& kernel_cap); InteruptEntry(const KernelCapability& kernel_cap);
InteruptEntry(uint32_t interupt0, uint32_t interupt1); InteruptEntry(uint32_t interupt0, uint32_t interupt1);
void operator=(const InteruptEntry& other);
bool operator==(const InteruptEntry& other) const;
bool operator!=(const InteruptEntry& other) const;
// kernel capability // kernel capability
const KernelCapability& getKernelCapability() const; const KernelCapability& getKernelCapability() const;
void setKernelCapability(const KernelCapability& kernel_cap); void setKernelCapability(const KernelCapability& kernel_cap);

View file

@ -10,9 +10,9 @@ namespace nx
public: public:
InteruptHandler(); InteruptHandler();
void operator=(const InteruptHandler& other);
bool operator==(const InteruptHandler& other) const; bool operator==(const InteruptHandler& other) const;
bool operator!=(const InteruptHandler& other) const; bool operator!=(const InteruptHandler& other) const;
void operator=(const InteruptHandler& other);
// kernel capabilty list in/out // kernel capabilty list in/out
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps); void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
@ -29,9 +29,6 @@ namespace nx
bool mIsSet; bool mIsSet;
fnd::List<uint16_t> mInterupts; fnd::List<uint16_t> mInterupts;
void copyFrom(const InteruptHandler& other);
bool isEqual(const InteruptHandler& other) const;
}; };
} }

View file

@ -24,7 +24,7 @@ namespace nx
KernelCapability(KernelCapId type); KernelCapability(KernelCapId type);
KernelCapability(KernelCapId type, uint32_t field); KernelCapability(KernelCapId type, uint32_t field);
const KernelCapability& operator=(const KernelCapability& other); void operator=(const KernelCapability& other);
bool operator==(const KernelCapability& other) const; bool operator==(const KernelCapability& other) const;
bool operator!=(const KernelCapability& other) const; bool operator!=(const KernelCapability& other) const;

View file

@ -12,6 +12,10 @@ namespace nx
KernelVersionEntry(const KernelCapability& kernel_cap); KernelVersionEntry(const KernelCapability& kernel_cap);
KernelVersionEntry(uint16_t major, uint8_t minor); KernelVersionEntry(uint16_t major, uint8_t minor);
void operator=(const KernelVersionEntry& other);
bool operator==(const KernelVersionEntry& other) const;
bool operator!=(const KernelVersionEntry& other) const;
// kernel capability // kernel capability
const KernelCapability& getKernelCapability() const; const KernelCapability& getKernelCapability() const;
void setKernelCapability(const KernelCapability& kernel_cap); void setKernelCapability(const KernelCapability& kernel_cap);

View file

@ -10,9 +10,9 @@ namespace nx
public: public:
KernelVersionHandler(); KernelVersionHandler();
void operator=(const KernelVersionHandler& other);
bool operator==(const KernelVersionHandler& other) const; bool operator==(const KernelVersionHandler& other) const;
bool operator!=(const KernelVersionHandler& other) const; bool operator!=(const KernelVersionHandler& other) const;
void operator=(const KernelVersionHandler& other);
// kernel capabilty list in/out // kernel capabilty list in/out
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps); void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
@ -32,9 +32,6 @@ namespace nx
bool mIsSet; bool mIsSet;
KernelVersionEntry mEntry; KernelVersionEntry mEntry;
void copyFrom(const KernelVersionHandler& other);
bool isEqual(const KernelVersionHandler& other) const;
}; };
} }

View file

@ -52,9 +52,9 @@ namespace nx
MemoryMappingHandler(); MemoryMappingHandler();
void operator=(const MemoryMappingHandler& other);
bool operator==(const MemoryMappingHandler& other) const; bool operator==(const MemoryMappingHandler& other) const;
bool operator!=(const MemoryMappingHandler& other) const; bool operator!=(const MemoryMappingHandler& other) const;
void operator=(const MemoryMappingHandler& other);
// kernel capabilty list in/out // kernel capabilty list in/out
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps); void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
@ -73,9 +73,6 @@ namespace nx
bool mIsSet; bool mIsSet;
fnd::List<sMemoryMapping> mMemRange; fnd::List<sMemoryMapping> mMemRange;
fnd::List<sMemoryMapping> mMemPage; fnd::List<sMemoryMapping> mMemPage;
void copyFrom(const MemoryMappingHandler& other);
bool isEqual(const MemoryMappingHandler& other) const;
}; };
} }

View file

@ -13,6 +13,10 @@ namespace nx
MemoryPageEntry(uint32_t page); MemoryPageEntry(uint32_t page);
MemoryPageEntry(uint32_t page, bool flag); MemoryPageEntry(uint32_t page, bool flag);
void operator=(const MemoryPageEntry& other);
bool operator==(const MemoryPageEntry& other) const;
bool operator!=(const MemoryPageEntry& other) const;
// kernel capability // kernel capability
const KernelCapability& getKernelCapability() const; const KernelCapability& getKernelCapability() const;
void setKernelCapability(const KernelCapability& kernel_cap); void setKernelCapability(const KernelCapability& kernel_cap);

View file

@ -12,6 +12,10 @@ namespace nx
MiscFlagsEntry(const KernelCapability& kernel_cap); MiscFlagsEntry(const KernelCapability& kernel_cap);
MiscFlagsEntry(uint32_t flags); MiscFlagsEntry(uint32_t flags);
void operator=(const MiscFlagsEntry& other);
bool operator==(const MiscFlagsEntry& other) const;
bool operator!=(const MiscFlagsEntry& other) const;
// kernel capability // kernel capability
const KernelCapability& getKernelCapability() const; const KernelCapability& getKernelCapability() const;
void setKernelCapability(const KernelCapability& kernel_cap); void setKernelCapability(const KernelCapability& kernel_cap);

View file

@ -30,9 +30,9 @@ namespace nx
MiscFlagsHandler(); MiscFlagsHandler();
void operator=(const MiscFlagsHandler& other);
bool operator==(const MiscFlagsHandler& other) const; bool operator==(const MiscFlagsHandler& other) const;
bool operator!=(const MiscFlagsHandler& other) const; bool operator!=(const MiscFlagsHandler& other) const;
void operator=(const MiscFlagsHandler& other);
// kernel capabilty list in/out // kernel capabilty list in/out
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps); void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
@ -50,9 +50,6 @@ namespace nx
bool mIsSet; bool mIsSet;
fnd::List<Flags> mFlags; fnd::List<Flags> mFlags;
void copyFrom(const MiscFlagsHandler& other);
bool isEqual(const MiscFlagsHandler& other) const;
}; };
} }

View file

@ -12,6 +12,10 @@ namespace nx
MiscParamsEntry(const KernelCapability& kernel_cap); MiscParamsEntry(const KernelCapability& kernel_cap);
MiscParamsEntry(byte_t program_type); MiscParamsEntry(byte_t program_type);
void operator=(const MiscParamsEntry& other);
bool operator==(const MiscParamsEntry& other) const;
bool operator!=(const MiscParamsEntry& other) const;
// kernel capability // kernel capability
const KernelCapability& getKernelCapability() const; const KernelCapability& getKernelCapability() const;
void setKernelCapability(const KernelCapability& kernel_cap); void setKernelCapability(const KernelCapability& kernel_cap);

View file

@ -10,9 +10,9 @@ namespace nx
public: public:
MiscParamsHandler(); MiscParamsHandler();
void operator=(const MiscParamsHandler& other);
bool operator==(const MiscParamsHandler& other) const; bool operator==(const MiscParamsHandler& other) const;
bool operator!=(const MiscParamsHandler& other) const; bool operator!=(const MiscParamsHandler& other) const;
void operator=(const MiscParamsHandler& other);
// kernel capabilty list in/out // kernel capabilty list in/out
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps); void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
@ -30,9 +30,6 @@ namespace nx
bool mIsSet; bool mIsSet;
MiscParamsEntry mEntry; MiscParamsEntry mEntry;
void copyFrom(const MiscParamsHandler& other);
bool isEqual(const MiscParamsHandler& other) const;
}; };
} }

View file

@ -1,13 +1,12 @@
#pragma once #pragma once
#include <nx/nca.h> #include <nx/nca.h>
#include <fnd/MemoryBlob.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {
class NcaHeader : class NcaHeader :
public fnd::ISerialiseableBinary public fnd::ISerialisable
{ {
public: public:
enum FormatVersion enum FormatVersion

View file

@ -12,6 +12,10 @@ namespace nx
SystemCallEntry(const KernelCapability& kernel_cap); SystemCallEntry(const KernelCapability& kernel_cap);
SystemCallEntry(uint32_t upper_bits, uint32_t lower_bits); SystemCallEntry(uint32_t upper_bits, uint32_t lower_bits);
void operator=(const SystemCallEntry& other);
bool operator==(const SystemCallEntry& other) const;
bool operator!=(const SystemCallEntry& other) const;
// kernel capability // kernel capability
const KernelCapability& getKernelCapability() const; const KernelCapability& getKernelCapability() const;
void setKernelCapability(const KernelCapability& kernel_cap); void setKernelCapability(const KernelCapability& kernel_cap);

View file

@ -11,9 +11,9 @@ namespace nx
SystemCallHandler(); SystemCallHandler();
void operator=(const SystemCallHandler& other);
bool operator==(const SystemCallHandler& other) const; bool operator==(const SystemCallHandler& other) const;
bool operator!=(const SystemCallHandler& other) const; bool operator!=(const SystemCallHandler& other) const;
void operator=(const SystemCallHandler& other);
// kernel capabilty list in/out // kernel capabilty list in/out
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps); void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
@ -31,9 +31,6 @@ namespace nx
bool mIsSet; bool mIsSet;
fnd::List<uint8_t> mSystemCalls; fnd::List<uint8_t> mSystemCalls;
void copyFrom(const SystemCallHandler& other);
bool isEqual(const SystemCallHandler& other) const;
}; };
} }

View file

@ -12,6 +12,10 @@ namespace nx
ThreadInfoEntry(const KernelCapability& kernel_cap); ThreadInfoEntry(const KernelCapability& kernel_cap);
ThreadInfoEntry(uint8_t min_priority, uint8_t max_priority, uint8_t min_cpu_id, uint8_t max_cpu_id); ThreadInfoEntry(uint8_t min_priority, uint8_t max_priority, uint8_t min_cpu_id, uint8_t max_cpu_id);
void operator=(const ThreadInfoEntry& other);
bool operator==(const ThreadInfoEntry& other) const;
bool operator!=(const ThreadInfoEntry& other) const;
// kernel capability // kernel capability
const KernelCapability& getKernelCapability() const; const KernelCapability& getKernelCapability() const;
void setKernelCapability(const KernelCapability& kernel_cap); void setKernelCapability(const KernelCapability& kernel_cap);

View file

@ -10,9 +10,9 @@ namespace nx
public: public:
ThreadInfoHandler(); ThreadInfoHandler();
void operator=(const ThreadInfoHandler& other);
bool operator==(const ThreadInfoHandler& other) const; bool operator==(const ThreadInfoHandler& other) const;
bool operator!=(const ThreadInfoHandler& other) const; bool operator!=(const ThreadInfoHandler& other) const;
void operator=(const ThreadInfoHandler& other);
// kernel capabilty list in/out // kernel capabilty list in/out
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps); void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
@ -36,9 +36,6 @@ namespace nx
bool mIsSet; bool mIsSet;
ThreadInfoEntry mEntry; ThreadInfoEntry mEntry;
void copyFrom(const ThreadInfoHandler& other);
bool isEqual(const ThreadInfoHandler& other) const;
}; };
} }

View file

@ -1,5 +1,4 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <nx/macro.h> #include <nx/macro.h>

View file

@ -1,9 +1,6 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/aes.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {

View file

@ -1,8 +1,5 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h> #include <nx/macro.h>
namespace nx namespace nx

View file

@ -1,8 +1,6 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {

View file

@ -1,7 +1,5 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {

View file

@ -1,10 +1,8 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/aes.h> #include <crypto/aes.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <crypto/rsa.h> #include <crypto/rsa.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h> #include <nx/macro.h>
namespace nx namespace nx

View file

@ -1,9 +1,5 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/aes.h>
#include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h> #include <nx/macro.h>
namespace nx namespace nx

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/sha.h>
#include <nx/macro.h> #include <nx/macro.h>
namespace nx namespace nx
@ -9,7 +8,6 @@ namespace nx
{ {
static const uint32_t kNroSig = _MAKE_STRUCT_SIGNATURE("NRO0"); static const uint32_t kNroSig = _MAKE_STRUCT_SIGNATURE("NRO0");
static const uint32_t kDefaultFormatVersion = 0; static const uint32_t kDefaultFormatVersion = 0;
static const size_t kRoCrtSize = 8; static const size_t kRoCrtSize = 8;
static const size_t kModuleIdSize = 32; static const size_t kModuleIdSize = 32;

View file

@ -1,7 +1,5 @@
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h> #include <nx/macro.h>
namespace nx namespace nx

View file

@ -1,9 +1,5 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/aes.h>
#include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx namespace nx
{ {

View file

@ -1,11 +1,9 @@
#pragma once #pragma once
#include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <crypto/aes.h> #include <crypto/aes.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <crypto/rsa.h> #include <crypto/rsa.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h> #include <nx/macro.h>
namespace nx namespace nx

View file

@ -67,6 +67,8 @@ void nx::AciBinary::toBytes()
void nx::AciBinary::fromBytes(const byte_t * bytes, size_t len) void nx::AciBinary::fromBytes(const byte_t * bytes, size_t len)
{ {
clear();
AciHeader::fromBytes(bytes, len); AciHeader::fromBytes(bytes, len);
if (getAciSize() > len) if (getAciSize() > len)

View file

@ -1,18 +1,16 @@
#include <nx/AciHeader.h> #include <nx/AciHeader.h>
using namespace nx; nx::AciHeader::AciHeader()
AciHeader::AciHeader()
{ {
clear(); clear();
} }
AciHeader::AciHeader(const AciHeader & other) nx::AciHeader::AciHeader(const AciHeader & other)
{ {
*this = other; *this = other;
} }
void AciHeader::operator=(const AciHeader & other) void nx::AciHeader::operator=(const AciHeader & other)
{ {
if (other.getBytes().size()) if (other.getBytes().size())
{ {
@ -34,7 +32,7 @@ void AciHeader::operator=(const AciHeader & other)
} }
} }
bool AciHeader::operator==(const AciHeader & other) const bool nx::AciHeader::operator==(const AciHeader & other) const
{ {
return (mHeaderOffset == other.mHeaderOffset) \ return (mHeaderOffset == other.mHeaderOffset) \
&& (mType == other.mType) \ && (mType == other.mType) \
@ -49,12 +47,12 @@ bool AciHeader::operator==(const AciHeader & other) const
&& (mKc == other.mKc); && (mKc == other.mKc);
} }
bool AciHeader::operator!=(const AciHeader & other) const bool nx::AciHeader::operator!=(const AciHeader & other) const
{ {
return !(*this == other); return !(*this == other);
} }
void AciHeader::toBytes() void nx::AciHeader::toBytes()
{ {
mRawBinary.alloc(sizeof(sAciHeader)); mRawBinary.alloc(sizeof(sAciHeader));
sAciHeader* hdr = (sAciHeader*)mRawBinary.data(); sAciHeader* hdr = (sAciHeader*)mRawBinary.data();
@ -103,7 +101,7 @@ void AciHeader::toBytes()
} }
} }
void AciHeader::fromBytes(const byte_t * bytes, size_t len) void nx::AciHeader::fromBytes(const byte_t * bytes, size_t len)
{ {
if (len < sizeof(sAciHeader)) if (len < sizeof(sAciHeader))
{ {
@ -149,8 +147,8 @@ void AciHeader::fromBytes(const byte_t * bytes, size_t len)
mProgramIdMax = hdr->program_id_info.program_id_restrict.max.get(); mProgramIdMax = hdr->program_id_info.program_id_restrict.max.get();
} }
// the header offset is the MIN(sac.offset, fac.offset, kc.offset) - sizeof(sHeader) // the header offset is the _MIN(sac.offset, fac.offset, kc.offset) - sizeof(sHeader)
mHeaderOffset = MAX(MIN(hdr->sac.offset.get(), MIN(hdr->fac.offset.get(), hdr->kc.offset.get())), align(sizeof(sAciHeader), aci::kAciAlignSize)) - align(sizeof(sAciHeader), aci::kAciAlignSize); mHeaderOffset = _MAX(_MIN(hdr->sac.offset.get(), _MIN(hdr->fac.offset.get(), hdr->kc.offset.get())), align(sizeof(sAciHeader), aci::kAciAlignSize)) - align(sizeof(sAciHeader), aci::kAciAlignSize);
mFac.offset = hdr->fac.offset.get() - mHeaderOffset; mFac.offset = hdr->fac.offset.get() - mHeaderOffset;
mFac.size = hdr->fac.size.get(); mFac.size = hdr->fac.size.get();
@ -160,7 +158,7 @@ void AciHeader::fromBytes(const byte_t * bytes, size_t len)
mKc.size = hdr->kc.size.get(); mKc.size = hdr->kc.size.get();
} }
const fnd::Vec<byte_t>& AciHeader::getBytes() const const fnd::Vec<byte_t>& nx::AciHeader::getBytes() const
{ {
return mRawBinary; return mRawBinary;
} }
@ -186,7 +184,7 @@ void nx::AciHeader::clear()
size_t nx::AciHeader::getAciSize() const size_t nx::AciHeader::getAciSize() const
{ {
return MAX(MAX(MAX(mSac.offset + mSac.size, mKc.offset + mKc.size), mFac.offset + mFac.size), sizeof(sAciHeader)); return _MAX(_MAX(_MAX(mSac.offset + mSac.size, mKc.offset + mKc.size), mFac.offset + mFac.size), sizeof(sAciHeader));
} }
size_t nx::AciHeader::getAcidSize() const size_t nx::AciHeader::getAcidSize() const
@ -226,12 +224,12 @@ void nx::AciHeader::setHeaderOffset(size_t offset)
mHeaderOffset = offset; mHeaderOffset = offset;
} }
AciHeader::AciType AciHeader::getAciType() const nx::AciHeader::AciType nx::AciHeader::getAciType() const
{ {
return mType; return mType;
} }
void AciHeader::setAciType(AciType type) void nx::AciHeader::setAciType(AciType type)
{ {
mType = type; mType = type;
} }
@ -256,47 +254,47 @@ void nx::AciHeader::setIsUnqualifiedApproval(bool isUnqualifiedApproval)
mIsUnqualifiedApproval = isUnqualifiedApproval; mIsUnqualifiedApproval = isUnqualifiedApproval;
} }
uint64_t AciHeader::getProgramId() const uint64_t nx::AciHeader::getProgramId() const
{ {
return mProgramId; return mProgramId;
} }
void AciHeader::setProgramId(uint64_t program_id) void nx::AciHeader::setProgramId(uint64_t program_id)
{ {
mProgramId = program_id; mProgramId = program_id;
} }
const AciHeader::sSection & AciHeader::getFacPos() const const nx::AciHeader::sSection & nx::AciHeader::getFacPos() const
{ {
return mFac; return mFac;
} }
void AciHeader::setFacSize(size_t size) void nx::AciHeader::setFacSize(size_t size)
{ {
mFac.size = size; mFac.size = size;
} }
const AciHeader::sSection & AciHeader::getSacPos() const const nx::AciHeader::sSection & nx::AciHeader::getSacPos() const
{ {
return mSac; return mSac;
} }
void AciHeader::setSacSize(size_t size) void nx::AciHeader::setSacSize(size_t size)
{ {
mSac.size = size; mSac.size = size;
} }
const AciHeader::sSection & AciHeader::getKcPos() const const nx::AciHeader::sSection & nx::AciHeader::getKcPos() const
{ {
return mKc; return mKc;
} }
void AciHeader::setKcSize(size_t size) void nx::AciHeader::setKcSize(size_t size)
{ {
mKc.size = size; mKc.size = size;
} }
void AciHeader::calculateSectionOffsets() void nx::AciHeader::calculateSectionOffsets()
{ {
mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize); mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize);
mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize); mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize);

View file

@ -25,7 +25,7 @@ void nx::AcidBinary::operator=(const AcidBinary & other)
{ {
if (other.getBytes().size()) if (other.getBytes().size())
{ {
importBinary(other.getBytes().data(), other.getBytes().size()); fromBytes(other.getBytes().data(), other.getBytes().size());
} }
else else
{ {
@ -37,7 +37,7 @@ void nx::AcidBinary::operator=(const AcidBinary & other)
void nx::AcidBinary::toBytes() void nx::AcidBinary::toBytes()
{ {
AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature
AciBinary::exportBinary(); AciBinary::toBytes();
mRawBinary.alloc(AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2); mRawBinary.alloc(AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2);
memcpy(mRawBinary.data() + crypto::rsa::kRsa2048Size, mEmbeddedPublicKey.modulus, crypto::rsa::kRsa2048Size); memcpy(mRawBinary.data() + crypto::rsa::kRsa2048Size, mEmbeddedPublicKey.modulus, crypto::rsa::kRsa2048Size);
@ -48,7 +48,7 @@ void nx::AcidBinary::signBinary(const crypto::rsa::sRsa2048Key & key)
{ {
if (mRawBinary.size() == 0) if (mRawBinary.size() == 0)
{ {
exportBinary(); toBytes();
} }
byte_t hash[crypto::sha::kSha256HashLen]; byte_t hash[crypto::sha::kSha256HashLen];
@ -67,8 +67,10 @@ void nx::AcidBinary::fromBytes(const byte_t * bytes, size_t len)
throw fnd::Exception(kModuleName, "ACID binary too small"); throw fnd::Exception(kModuleName, "ACID binary too small");
} }
clear();
// import aci binary past sig + pubkey // import aci binary past sig + pubkey
AciBinary::importBinary(bytes + crypto::rsa::kRsa2048Size * 2, len - crypto::rsa::kRsa2048Size * 2); AciBinary::fromBytes(bytes + crypto::rsa::kRsa2048Size * 2, len - crypto::rsa::kRsa2048Size * 2);
// save internal copy // save internal copy
size_t acid_size = AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2; size_t acid_size = AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2;

View file

@ -7,39 +7,73 @@ nx::ContentMetaBinary::ContentMetaBinary()
nx::ContentMetaBinary::ContentMetaBinary(const ContentMetaBinary & other) nx::ContentMetaBinary::ContentMetaBinary(const ContentMetaBinary & other)
{ {
copyFrom(other); *this = other;
} }
nx::ContentMetaBinary::ContentMetaBinary(const byte_t * bytes, size_t len) void nx::ContentMetaBinary::operator=(const ContentMetaBinary& other)
{ {
importBinary(bytes, len); if (other.getBytes().size() > 0)
{
fromBytes(other.getBytes().data(), other.getBytes().size());
}
else
{
clear();
mTitleId = other.mTitleId;
mTitleVersion = other.mTitleVersion;
mType = other.mType;
mAttributes = other.mAttributes;
mRequiredDownloadSystemVersion = other.mRequiredDownloadSystemVersion;
mExtendedHeader = other.mExtendedHeader;
mApplicationMetaExtendedHeader = other.mApplicationMetaExtendedHeader;
mPatchMetaExtendedHeader = other.mPatchMetaExtendedHeader;
mAddOnContentMetaExtendedHeader = other.mAddOnContentMetaExtendedHeader;
mDeltaMetaExtendedHeader = other.mDeltaMetaExtendedHeader;
mContentInfo = other.mContentInfo;
mContentMetaInfo = other.mContentMetaInfo;
mExtendedData = other.mExtendedData;
memcpy(mDigest.data, other.mDigest.data, cnmt::kDigestLen);
}
} }
const byte_t * nx::ContentMetaBinary::getBytes() const bool nx::ContentMetaBinary::operator==(const ContentMetaBinary& other) const
{ {
return mRawBinary.getBytes(); return (mTitleId == other.mTitleId) \
&& (mTitleVersion == other.mTitleVersion) \
&& (mType == other.mType) \
&& (mAttributes == other.mAttributes) \
&& (mRequiredDownloadSystemVersion == other.mRequiredDownloadSystemVersion) \
&& (mExtendedHeader == other.mExtendedHeader) \
&& (mApplicationMetaExtendedHeader == other.mApplicationMetaExtendedHeader) \
&& (mPatchMetaExtendedHeader == other.mPatchMetaExtendedHeader) \
&& (mAddOnContentMetaExtendedHeader == other.mAddOnContentMetaExtendedHeader) \
&& (mDeltaMetaExtendedHeader == other.mDeltaMetaExtendedHeader) \
&& (mContentInfo == other.mContentInfo) \
&& (mContentMetaInfo == other.mContentMetaInfo) \
&& (mExtendedData == other.mExtendedData) \
&& (memcmp(mDigest.data, other.mDigest.data, cnmt::kDigestLen) == 0);
} }
size_t nx::ContentMetaBinary::getSize() const bool nx::ContentMetaBinary::operator!=(const ContentMetaBinary& other) const
{ {
return mRawBinary.getSize(); return !(*this == other);
} }
void nx::ContentMetaBinary::exportBinary() void nx::ContentMetaBinary::toBytes()
{ {
throw fnd::Exception(kModuleName, "exportBinary() not implemented"); throw fnd::Exception(kModuleName, "exportBinary() not implemented");
} }
void nx::ContentMetaBinary::importBinary(const byte_t * bytes, size_t len) void nx::ContentMetaBinary::fromBytes(const byte_t* data, size_t len)
{ {
// clear member variables // clear member variables
clear(); clear();
// validate layout // validate layout
validateBinary(bytes, len); validateBinary(data, len);
// get pointer to header structure // get pointer to header structure
const sContentMetaHeader* hdr = (const sContentMetaHeader*)bytes; const sContentMetaHeader* hdr = (const sContentMetaHeader*)data;
mTitleId = hdr->id.get(); mTitleId = hdr->id.get();
mTitleVersion = hdr->version.get(); mTitleVersion = hdr->version.get();
@ -52,36 +86,36 @@ void nx::ContentMetaBinary::importBinary(const byte_t * bytes, size_t len)
if (hdr->exhdr_size.get() > 0) if (hdr->exhdr_size.get() > 0)
{ {
mExtendedHeader.alloc(hdr->exhdr_size.get()); mExtendedHeader.alloc(hdr->exhdr_size.get());
memcpy(mExtendedHeader.getBytes(), bytes + getExtendedHeaderOffset(), hdr->exhdr_size.get()); memcpy(mExtendedHeader.data(), data + getExtendedHeaderOffset(), hdr->exhdr_size.get());
switch (mType) switch (mType)
{ {
case (cnmt::METATYPE_APPLICATION): case (cnmt::METATYPE_APPLICATION):
mApplicationMetaExtendedHeader.patch_id = ((sApplicationMetaExtendedHeader*)mExtendedHeader.getBytes())->patch_id.get(); mApplicationMetaExtendedHeader.patch_id = ((sApplicationMetaExtendedHeader*)mExtendedHeader.data())->patch_id.get();
mApplicationMetaExtendedHeader.required_system_version = ((sApplicationMetaExtendedHeader*)mExtendedHeader.getBytes())->required_system_version.get(); mApplicationMetaExtendedHeader.required_system_version = ((sApplicationMetaExtendedHeader*)mExtendedHeader.data())->required_system_version.get();
break; break;
case (cnmt::METATYPE_PATCH): case (cnmt::METATYPE_PATCH):
mPatchMetaExtendedHeader.application_id = ((sPatchMetaExtendedHeader*)mExtendedHeader.getBytes())->application_id.get(); mPatchMetaExtendedHeader.application_id = ((sPatchMetaExtendedHeader*)mExtendedHeader.data())->application_id.get();
mPatchMetaExtendedHeader.required_system_version = ((sPatchMetaExtendedHeader*)mExtendedHeader.getBytes())->required_system_version.get(); mPatchMetaExtendedHeader.required_system_version = ((sPatchMetaExtendedHeader*)mExtendedHeader.data())->required_system_version.get();
break; break;
case (cnmt::METATYPE_ADD_ON_CONTENT): case (cnmt::METATYPE_ADD_ON_CONTENT):
mAddOnContentMetaExtendedHeader.application_id = ((sAddOnContentMetaExtendedHeader*)mExtendedHeader.getBytes())->application_id.get(); mAddOnContentMetaExtendedHeader.application_id = ((sAddOnContentMetaExtendedHeader*)mExtendedHeader.data())->application_id.get();
mAddOnContentMetaExtendedHeader.required_system_version = ((sAddOnContentMetaExtendedHeader*)mExtendedHeader.getBytes())->required_system_version.get(); mAddOnContentMetaExtendedHeader.required_system_version = ((sAddOnContentMetaExtendedHeader*)mExtendedHeader.data())->required_system_version.get();
break; break;
case (cnmt::METATYPE_DELTA): case (cnmt::METATYPE_DELTA):
mDeltaMetaExtendedHeader.application_id = ((sDeltaMetaExtendedHeader*)mExtendedHeader.getBytes())->application_id.get(); mDeltaMetaExtendedHeader.application_id = ((sDeltaMetaExtendedHeader*)mExtendedHeader.data())->application_id.get();
break; break;
default: default:
break; break;
} }
exdata_size = getExtendedDataSize(mType, mExtendedHeader.getBytes()); exdata_size = getExtendedDataSize(mType, mExtendedHeader.data());
} }
// save content info // save content info
if (hdr->content_count.get() > 0) if (hdr->content_count.get() > 0)
{ {
const sContentInfo* info = (const sContentInfo*)(bytes + getContentInfoOffset(hdr->exhdr_size.get())); const sContentInfo* info = (const sContentInfo*)(data + getContentInfoOffset(hdr->exhdr_size.get()));
for (size_t i = 0; i < hdr->content_count.get(); i++) for (size_t i = 0; i < hdr->content_count.get(); i++)
{ {
mContentInfo[i].hash = info[i].content_hash; mContentInfo[i].hash = info[i].content_hash;
@ -94,7 +128,7 @@ void nx::ContentMetaBinary::importBinary(const byte_t * bytes, size_t len)
// save content meta info // save content meta info
if (hdr->content_meta_count.get() > 0) if (hdr->content_meta_count.get() > 0)
{ {
const sContentMetaInfo* info = (const sContentMetaInfo*)(bytes + getContentMetaInfoOffset(hdr->exhdr_size.get(), hdr->content_count.get())); const sContentMetaInfo* info = (const sContentMetaInfo*)(data + getContentMetaInfoOffset(hdr->exhdr_size.get(), hdr->content_count.get()));
for (size_t i = 0; i < hdr->content_meta_count.get(); i++) for (size_t i = 0; i < hdr->content_meta_count.get(); i++)
{ {
mContentMetaInfo[i].id = info[i].id.get(); mContentMetaInfo[i].id = info[i].id.get();
@ -108,14 +142,19 @@ void nx::ContentMetaBinary::importBinary(const byte_t * bytes, size_t len)
if (exdata_size > 0) if (exdata_size > 0)
{ {
mExtendedData.alloc(exdata_size); mExtendedData.alloc(exdata_size);
memcpy(mExtendedData.getBytes(), bytes + getExtendedDataOffset(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get()), exdata_size); memcpy(mExtendedData.data(), data + getExtendedDataOffset(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get()), exdata_size);
} }
// save digest // save digest
memcpy(mDigest.data, bytes + getDigestOffset(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get(), exdata_size), cnmt::kDigestLen); memcpy(mDigest.data, data + getDigestOffset(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get(), exdata_size), cnmt::kDigestLen);
} }
const fnd::Vec<byte_t>& nx::ContentMetaBinary::getBytes() const
{
return mRawBinary;
}
void nx::ContentMetaBinary::clear() void nx::ContentMetaBinary::clear()
{ {
mRawBinary.clear(); mRawBinary.clear();
@ -245,12 +284,12 @@ void nx::ContentMetaBinary::setContentMetaInfo(const fnd::List<nx::ContentMetaBi
mContentMetaInfo = info; mContentMetaInfo = info;
} }
const fnd::MemoryBlob & nx::ContentMetaBinary::getExtendedData() const const fnd::Vec<byte_t> & nx::ContentMetaBinary::getExtendedData() const
{ {
return mExtendedData; return mExtendedData;
} }
void nx::ContentMetaBinary::setExtendedData(const fnd::MemoryBlob & data) void nx::ContentMetaBinary::setExtendedData(const fnd::Vec<byte_t> & data)
{ {
mExtendedData = data; mExtendedData = data;
} }
@ -307,7 +346,7 @@ size_t nx::ContentMetaBinary::getExtendedDataSize(cnmt::ContentMetaType type, co
return exdata_len; return exdata_len;
} }
void nx::ContentMetaBinary::validateBinary(const byte_t * bytes, size_t len) const void nx::ContentMetaBinary::validateBinary(const byte_t * data, size_t len) const
{ {
// check if it is large enough to read the header // check if it is large enough to read the header
if (len < sizeof(sContentMetaHeader)) if (len < sizeof(sContentMetaHeader))
@ -316,7 +355,7 @@ void nx::ContentMetaBinary::validateBinary(const byte_t * bytes, size_t len) con
} }
// get pointer to header structure // get pointer to header structure
const sContentMetaHeader* hdr = (const sContentMetaHeader*)bytes; const sContentMetaHeader* hdr = (const sContentMetaHeader*)data;
// validate extended header size // validate extended header size
if (validateExtendedHeaderSize((cnmt::ContentMetaType)hdr->type, hdr->exhdr_size.get()) == false) if (validateExtendedHeaderSize((cnmt::ContentMetaType)hdr->type, hdr->exhdr_size.get()) == false)
@ -331,52 +370,8 @@ void nx::ContentMetaBinary::validateBinary(const byte_t * bytes, size_t len) con
} }
// check binary size again with extended data size // check binary size again with extended data size
if (len < getTotalSize(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get(), getExtendedDataSize((cnmt::ContentMetaType)hdr->type, bytes + getExtendedHeaderOffset()))) if (len < getTotalSize(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get(), getExtendedDataSize((cnmt::ContentMetaType)hdr->type, data + getExtendedHeaderOffset())))
{ {
throw fnd::Exception(kModuleName, "Binary too small"); throw fnd::Exception(kModuleName, "Binary too small");
} }
} }
bool nx::ContentMetaBinary::isEqual(const ContentMetaBinary & other) const
{
return (mTitleId == other.mTitleId) \
&& (mTitleVersion == other.mTitleVersion) \
&& (mType == other.mType) \
&& (mAttributes == other.mAttributes) \
&& (mRequiredDownloadSystemVersion == other.mRequiredDownloadSystemVersion) \
&& (mExtendedHeader == other.mExtendedHeader) \
&& (mApplicationMetaExtendedHeader == other.mApplicationMetaExtendedHeader) \
&& (mPatchMetaExtendedHeader == other.mPatchMetaExtendedHeader) \
&& (mAddOnContentMetaExtendedHeader == other.mAddOnContentMetaExtendedHeader) \
&& (mDeltaMetaExtendedHeader == other.mDeltaMetaExtendedHeader) \
&& (mContentInfo == other.mContentInfo) \
&& (mContentMetaInfo == other.mContentMetaInfo) \
&& (mExtendedData == other.mExtendedData) \
&& (memcmp(mDigest.data, other.mDigest.data, cnmt::kDigestLen) == 0);
}
void nx::ContentMetaBinary::copyFrom(const ContentMetaBinary & other)
{
if (other.getSize() > 0)
{
importBinary(other.getBytes(), other.getSize());
}
else
{
clear();
mTitleId = other.mTitleId;
mTitleVersion = other.mTitleVersion;
mType = other.mType;
mAttributes = other.mAttributes;
mRequiredDownloadSystemVersion = other.mRequiredDownloadSystemVersion;
mExtendedHeader = other.mExtendedHeader;
mApplicationMetaExtendedHeader = other.mApplicationMetaExtendedHeader;
mPatchMetaExtendedHeader = other.mPatchMetaExtendedHeader;
mAddOnContentMetaExtendedHeader = other.mAddOnContentMetaExtendedHeader;
mDeltaMetaExtendedHeader = other.mDeltaMetaExtendedHeader;
mContentInfo = other.mContentInfo;
mContentMetaInfo = other.mContentMetaInfo;
mExtendedData = other.mExtendedData;
memcpy(mDigest.data, other.mDigest.data, cnmt::kDigestLen);
}
}

View file

@ -75,6 +75,9 @@ void nx::FacHeader::fromBytes(const byte_t* data, size_t len)
throw fnd::Exception(kModuleName, "FAC header too small"); throw fnd::Exception(kModuleName, "FAC header too small");
} }
// clear internal members
clear();
mRawBinary.alloc(sizeof(sFacHeader)); mRawBinary.alloc(sizeof(sFacHeader));
memcpy(mRawBinary.data(), data, mRawBinary.size()); memcpy(mRawBinary.data(), data, mRawBinary.size());
sFacHeader* hdr = (sFacHeader*)mRawBinary.data(); sFacHeader* hdr = (sFacHeader*)mRawBinary.data();
@ -85,7 +88,6 @@ void nx::FacHeader::fromBytes(const byte_t* data, size_t len)
} }
mVersion = hdr->version.get(); mVersion = hdr->version.get();
clear();
for (uint64_t i = 0; i < 64; i++) for (uint64_t i = 0; i < 64; i++)
{ {
if (_HAS_BIT(hdr->fac_flags.get(), i)) if (_HAS_BIT(hdr->fac_flags.get(), i))

View file

@ -1,7 +1,5 @@
#include <nx/HandleTableSizeEntry.h> #include <nx/HandleTableSizeEntry.h>
nx::HandleTableSizeEntry::HandleTableSizeEntry() : nx::HandleTableSizeEntry::HandleTableSizeEntry() :
mCap(kCapId), mCap(kCapId),
mHandleTableSize(0) mHandleTableSize(0)
@ -21,6 +19,23 @@ nx::HandleTableSizeEntry::HandleTableSizeEntry(uint16_t size) :
setHandleTableSize(size); setHandleTableSize(size);
} }
void nx::HandleTableSizeEntry::operator=(const HandleTableSizeEntry& other)
{
mHandleTableSize = other.mHandleTableSize;
updateCapField();
}
bool nx::HandleTableSizeEntry::operator==(const HandleTableSizeEntry& other) const
{
return (mHandleTableSize == other.mHandleTableSize);
}
bool nx::HandleTableSizeEntry::operator!=(const HandleTableSizeEntry& other) const
{
return !(*this == other);
}
const nx::KernelCapability & nx::HandleTableSizeEntry::getKernelCapability() const const nx::KernelCapability & nx::HandleTableSizeEntry::getKernelCapability() const
{ {
return mCap; return mCap;

View file

@ -1,35 +1,35 @@
#include <nx/HandleTableSizeHandler.h> #include <nx/HandleTableSizeHandler.h>
nx::HandleTableSizeHandler::HandleTableSizeHandler() : nx::HandleTableSizeHandler::HandleTableSizeHandler() :
mIsSet(false), mIsSet(false),
mEntry(0) mEntry(0)
{} {}
void nx::HandleTableSizeHandler::operator=(const HandleTableSizeHandler & other)
{
mIsSet = other.mIsSet;
mEntry.setKernelCapability(other.mEntry.getKernelCapability());
}
bool nx::HandleTableSizeHandler::operator==(const HandleTableSizeHandler & other) const bool nx::HandleTableSizeHandler::operator==(const HandleTableSizeHandler & other) const
{ {
return isEqual(other); return (mIsSet == other.mIsSet) \
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
} }
bool nx::HandleTableSizeHandler::operator!=(const HandleTableSizeHandler & other) const bool nx::HandleTableSizeHandler::operator!=(const HandleTableSizeHandler & other) const
{ {
return !isEqual(other); return !(*this == other);
}
void nx::HandleTableSizeHandler::operator=(const HandleTableSizeHandler & other)
{
copyFrom(other);
} }
void nx::HandleTableSizeHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps) void nx::HandleTableSizeHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
{ {
if (caps.getSize() > kMaxKernelCapNum) if (caps.size() > kMaxKernelCapNum)
{ {
throw fnd::Exception(kModuleName, "Too many kernel capabilities"); throw fnd::Exception(kModuleName, "Too many kernel capabilities");
} }
if (caps.getSize() == 0) if (caps.size() == 0)
return; return;
mEntry.setKernelCapability(caps[0]); mEntry.setKernelCapability(caps[0]);
@ -64,16 +64,4 @@ void nx::HandleTableSizeHandler::setHandleTableSize(uint16_t size)
{ {
mEntry.setHandleTableSize(size); mEntry.setHandleTableSize(size);
mIsSet = true; mIsSet = true;
} }
void nx::HandleTableSizeHandler::copyFrom(const HandleTableSizeHandler & other)
{
mIsSet = other.mIsSet;
mEntry.setKernelCapability(other.mEntry.getKernelCapability());
}
bool nx::HandleTableSizeHandler::isEqual(const HandleTableSizeHandler & other) const
{
return (mIsSet == other.mIsSet) \
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
}

View file

@ -1,7 +1,5 @@
#include <nx/InteruptEntry.h> #include <nx/InteruptEntry.h>
nx::InteruptEntry::InteruptEntry() : nx::InteruptEntry::InteruptEntry() :
mCap(kCapId), mCap(kCapId),
mInterupt{0,0} mInterupt{0,0}
@ -24,6 +22,24 @@ nx::InteruptEntry::InteruptEntry(uint32_t interupt0, uint32_t interupt1) :
setInterupt(1, interupt1); setInterupt(1, interupt1);
} }
void nx::InteruptEntry::operator=(const InteruptEntry& other)
{
mInterupt[0] = other.mInterupt[0];
mInterupt[1] = other.mInterupt[1];
updateCapField();
}
bool nx::InteruptEntry::operator==(const InteruptEntry& other) const
{
return (mInterupt[0] == other.mInterupt[0]) \
&& (mInterupt[1] == other.mInterupt[1]);
}
bool nx::InteruptEntry::operator!=(const InteruptEntry& other) const
{
return !(*this == other);
}
const nx::KernelCapability & nx::InteruptEntry::getKernelCapability() const const nx::KernelCapability & nx::InteruptEntry::getKernelCapability() const
{ {
return mCap; return mCap;

View file

@ -1,41 +1,41 @@
#include <nx/InteruptHandler.h> #include <nx/InteruptHandler.h>
nx::InteruptHandler::InteruptHandler() : nx::InteruptHandler::InteruptHandler() :
mIsSet(false), mIsSet(false),
mInterupts() mInterupts()
{} {}
void nx::InteruptHandler::operator=(const InteruptHandler & other)
{
mIsSet = other.mIsSet;
mInterupts = other.mInterupts;
}
bool nx::InteruptHandler::operator==(const InteruptHandler & other) const bool nx::InteruptHandler::operator==(const InteruptHandler & other) const
{ {
return isEqual(other); return (mIsSet == other.mIsSet) \
&& (mInterupts == other.mInterupts);
} }
bool nx::InteruptHandler::operator!=(const InteruptHandler & other) const bool nx::InteruptHandler::operator!=(const InteruptHandler & other) const
{ {
return !isEqual(other); return !(*this == other);
}
void nx::InteruptHandler::operator=(const InteruptHandler & other)
{
copyFrom(other);
} }
void nx::InteruptHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps) void nx::InteruptHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
{ {
if (caps.getSize() == 0) if (caps.size() == 0)
return; return;
// convert to interupts // convert to interupts
fnd::List<InteruptEntry> interupts; fnd::List<InteruptEntry> interupts;
for (size_t i = 0; i < caps.getSize(); i++) for (size_t i = 0; i < caps.size(); i++)
{ {
interupts[i].setKernelCapability(caps[i]); interupts[i].setKernelCapability(caps[i]);
} }
mInterupts.clear(); mInterupts.clear();
for (size_t i = 0; i < interupts.getSize(); i++) for (size_t i = 0; i < interupts.size(); i++)
{ {
// weird condition for first interupt // weird condition for first interupt
if (interupts[i][1] == 0 && i == 0) if (interupts[i][1] == 0 && i == 0)
@ -64,12 +64,12 @@ void nx::InteruptHandler::exportKernelCapabilityList(fnd::List<KernelCapability>
return; return;
size_t i = 0; size_t i = 0;
if (mInterupts.getSize() % 2) if (mInterupts.size() % 2)
{ {
caps.addElement(InteruptEntry(mInterupts[i], 0).getKernelCapability()); caps.addElement(InteruptEntry(mInterupts[i], 0).getKernelCapability());
i++; i++;
} }
for (; i < mInterupts.getSize(); i += 2) for (; i < mInterupts.size(); i += 2)
{ {
if (mInterupts[i] == InteruptEntry::kInteruptMax) if (mInterupts[i] == InteruptEntry::kInteruptMax)
{ {
@ -103,22 +103,10 @@ const fnd::List<uint16_t>& nx::InteruptHandler::getInteruptList() const
void nx::InteruptHandler::setInteruptList(const fnd::List<uint16_t>& interupts) void nx::InteruptHandler::setInteruptList(const fnd::List<uint16_t>& interupts)
{ {
mInterupts.clear(); mInterupts.clear();
for (size_t i = 0; i < interupts.getSize(); i++) for (size_t i = 0; i < interupts.size(); i++)
{ {
mInterupts.hasElement(interupts[i]) == false ? mInterupts.addElement(interupts[i]) : throw fnd::Exception(kModuleName, "Interupt already added"); mInterupts.hasElement(interupts[i]) == false ? mInterupts.addElement(interupts[i]) : throw fnd::Exception(kModuleName, "Interupt already added");
} }
mIsSet = true; mIsSet = true;
} }
void nx::InteruptHandler::copyFrom(const InteruptHandler & other)
{
mIsSet = other.mIsSet;
mInterupts = other.mInterupts;
}
bool nx::InteruptHandler::isEqual(const InteruptHandler & other) const
{
return (mIsSet == other.mIsSet) \
&& (mInterupts == other.mInterupts);
}

View file

@ -1,26 +1,23 @@
#include <nx/KernelCapability.h> #include <nx/KernelCapability.h>
using namespace nx; nx::KernelCapability::KernelCapability() :
KernelCapability::KernelCapability() :
mType(KC_INVALID) mType(KC_INVALID)
{} {}
KernelCapability::KernelCapability(KernelCapId type) : nx::KernelCapability::KernelCapability(KernelCapId type) :
mType(type), mType(type),
mField(0) mField(0)
{} {}
KernelCapability::KernelCapability(KernelCapId type, uint32_t field) : nx::KernelCapability::KernelCapability(KernelCapId type, uint32_t field) :
mType(type), mType(type),
mField(field) mField(field)
{} {}
const KernelCapability & nx::KernelCapability::operator=(const KernelCapability & other) void nx::KernelCapability::operator=(const KernelCapability & other)
{ {
mType = other.mType; mType = other.mType;
mField = other.mField; mField = other.mField;
return *this;
} }
bool nx::KernelCapability::operator==(const KernelCapability & other) const bool nx::KernelCapability::operator==(const KernelCapability & other) const
@ -34,33 +31,33 @@ bool nx::KernelCapability::operator!=(const KernelCapability & other) const
return !operator==(other); return !operator==(other);
} }
uint32_t KernelCapability::getCap() const uint32_t nx::KernelCapability::getCap() const
{ {
return (mField & getFieldMask()) << getFieldShift() | getCapMask(); return (mField & getFieldMask()) << getFieldShift() | getCapMask();
} }
void KernelCapability::setCap(uint32_t cap) void nx::KernelCapability::setCap(uint32_t cap)
{ {
mType = getCapId(cap); mType = getCapId(cap);
mField = (cap >> getFieldShift()) & getFieldMask(); mField = (cap >> getFieldShift()) & getFieldMask();
} }
KernelCapability::KernelCapId KernelCapability::getType() const nx::KernelCapability::KernelCapId nx::KernelCapability::getType() const
{ {
return mType; return mType;
} }
void KernelCapability::setType(KernelCapId type) void nx::KernelCapability::setType(KernelCapId type)
{ {
mType = type; mType = type;
} }
uint32_t KernelCapability::getField() const uint32_t nx::KernelCapability::getField() const
{ {
return mField & getFieldMask(); return mField & getFieldMask();
} }
void KernelCapability::setField(uint32_t field) void nx::KernelCapability::setField(uint32_t field)
{ {
mField = field; mField = field;
} }

View file

@ -1,7 +1,5 @@
#include <nx/KernelVersionEntry.h> #include <nx/KernelVersionEntry.h>
nx::KernelVersionEntry::KernelVersionEntry() : nx::KernelVersionEntry::KernelVersionEntry() :
mCap(kCapId), mCap(kCapId),
mVerMajor(0), mVerMajor(0),
@ -25,6 +23,24 @@ nx::KernelVersionEntry::KernelVersionEntry(uint16_t major, uint8_t minor) :
setVerMinor(minor); setVerMinor(minor);
} }
void nx::KernelVersionEntry::operator=(const KernelVersionEntry& other)
{
mVerMajor = other.mVerMajor;
mVerMinor = other.mVerMinor;
updateCapField();
}
bool nx::KernelVersionEntry::operator==(const KernelVersionEntry& other) const
{
return (mVerMajor == other.mVerMajor) \
&& (mVerMinor == other.mVerMinor);
}
bool nx::KernelVersionEntry::operator!=(const KernelVersionEntry& other) const
{
return !(*this == other);
}
const nx::KernelCapability & nx::KernelVersionEntry::getKernelCapability() const const nx::KernelCapability & nx::KernelVersionEntry::getKernelCapability() const
{ {
return mCap; return mCap;

View file

@ -1,35 +1,35 @@
#include <nx/KernelVersionHandler.h> #include <nx/KernelVersionHandler.h>
nx::KernelVersionHandler::KernelVersionHandler() : nx::KernelVersionHandler::KernelVersionHandler() :
mIsSet(false), mIsSet(false),
mEntry(0,0) mEntry(0,0)
{} {}
void nx::KernelVersionHandler::operator=(const KernelVersionHandler & other)
{
mIsSet = other.mIsSet;
mEntry.setKernelCapability(other.mEntry.getKernelCapability());
}
bool nx::KernelVersionHandler::operator==(const KernelVersionHandler & other) const bool nx::KernelVersionHandler::operator==(const KernelVersionHandler & other) const
{ {
return isEqual(other); return (mIsSet == other.mIsSet) \
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
} }
bool nx::KernelVersionHandler::operator!=(const KernelVersionHandler & other) const bool nx::KernelVersionHandler::operator!=(const KernelVersionHandler & other) const
{ {
return !isEqual(other); return !(*this == other);
}
void nx::KernelVersionHandler::operator=(const KernelVersionHandler & other)
{
copyFrom(other);
} }
void nx::KernelVersionHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps) void nx::KernelVersionHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
{ {
if (caps.getSize() > kMaxKernelCapNum) if (caps.size() > kMaxKernelCapNum)
{ {
throw fnd::Exception(kModuleName, "Too many kernel capabilities"); throw fnd::Exception(kModuleName, "Too many kernel capabilities");
} }
if (caps.getSize() == 0) if (caps.size() == 0)
return; return;
mEntry.setKernelCapability(caps[0]); mEntry.setKernelCapability(caps[0]);
@ -77,16 +77,4 @@ void nx::KernelVersionHandler::setVerMinor(uint8_t minor)
{ {
mEntry.setVerMinor(minor); mEntry.setVerMinor(minor);
mIsSet = true; mIsSet = true;
} }
void nx::KernelVersionHandler::copyFrom(const KernelVersionHandler & other)
{
mIsSet = other.mIsSet;
mEntry.setKernelCapability(other.mEntry.getKernelCapability());
}
bool nx::KernelVersionHandler::isEqual(const KernelVersionHandler & other) const
{
return (mIsSet == other.mIsSet) \
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
}

View file

@ -1,48 +1,51 @@
#include <nx/MemoryMappingHandler.h> #include <nx/MemoryMappingHandler.h>
#include <nx/MemoryPageEntry.h> #include <nx/MemoryPageEntry.h>
nx::MemoryMappingHandler::MemoryMappingHandler() : nx::MemoryMappingHandler::MemoryMappingHandler() :
mIsSet(false) mIsSet(false)
{} {}
void nx::MemoryMappingHandler::operator=(const MemoryMappingHandler & other)
{
mIsSet = other.mIsSet;
mMemRange = other.mMemRange;
mMemPage = other.mMemPage;
}
bool nx::MemoryMappingHandler::operator==(const MemoryMappingHandler & other) const bool nx::MemoryMappingHandler::operator==(const MemoryMappingHandler & other) const
{ {
return isEqual(other); return (mIsSet == other.mIsSet) \
&& (mMemRange == other.mMemRange) \
&& (mMemPage == other.mMemPage);
} }
bool nx::MemoryMappingHandler::operator!=(const MemoryMappingHandler & other) const bool nx::MemoryMappingHandler::operator!=(const MemoryMappingHandler & other) const
{ {
return !isEqual(other); return !(*this == other);
}
void nx::MemoryMappingHandler::operator=(const MemoryMappingHandler & other)
{
copyFrom(other);
} }
void nx::MemoryMappingHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps) void nx::MemoryMappingHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
{ {
if (caps.getSize() == 0) if (caps.size() == 0)
return; return;
// get entry list // get entry list
fnd::List<MemoryPageEntry> entries; fnd::List<MemoryPageEntry> entries;
for (size_t i = 0; i < caps.getSize(); i++) for (size_t i = 0; i < caps.size(); i++)
{ {
entries[i].setKernelCapability(caps[i]); entries[i].setKernelCapability(caps[i]);
} }
mMemRange.clear(); mMemRange.clear();
mMemPage.clear(); mMemPage.clear();
for (size_t i = 0; i < entries.getSize();) for (size_t i = 0; i < entries.size();)
{ {
// has flag means "MemMap" // has flag means "MemMap"
if (entries[i].isMultiplePages()) if (entries[i].isMultiplePages())
{ {
// this entry is the last one or the next one isn't a memory map // this entry is the last one or the next one isn't a memory map
if ((i + 1) == entries.getSize() || entries[i+1].isMultiplePages() == false) if ((i + 1) == entries.size() || entries[i+1].isMultiplePages() == false)
{ {
throw fnd::Exception(kModuleName, "No paired entry"); throw fnd::Exception(kModuleName, "No paired entry");
} }
@ -94,7 +97,7 @@ void nx::MemoryMappingHandler::exportKernelCapabilityList(fnd::List<KernelCapabi
// "mem maps" // "mem maps"
cap.setMapMultiplePages(true); cap.setMapMultiplePages(true);
for (size_t i = 0; i < mMemRange.getSize(); i++) for (size_t i = 0; i < mMemRange.size(); i++)
{ {
cap.setPage(mMemRange[i].addr & kMaxPageAddr); cap.setPage(mMemRange[i].addr & kMaxPageAddr);
cap.setFlag(mMemRange[i].perm == MEM_RO); cap.setFlag(mMemRange[i].perm == MEM_RO);
@ -107,7 +110,7 @@ void nx::MemoryMappingHandler::exportKernelCapabilityList(fnd::List<KernelCapabi
// "io maps" // "io maps"
cap.setMapMultiplePages(false); cap.setMapMultiplePages(false);
for (size_t i = 0; i < mMemPage.getSize(); i++) for (size_t i = 0; i < mMemPage.size(); i++)
{ {
cap.setPage(mMemPage[i].addr & kMaxPageAddr); cap.setPage(mMemPage[i].addr & kMaxPageAddr);
caps.addElement(cap.getKernelCapability()); caps.addElement(cap.getKernelCapability());
@ -134,18 +137,4 @@ const fnd::List<nx::MemoryMappingHandler::sMemoryMapping>& nx::MemoryMappingHand
const fnd::List<nx::MemoryMappingHandler::sMemoryMapping>& nx::MemoryMappingHandler::getIoMemoryMaps() const const fnd::List<nx::MemoryMappingHandler::sMemoryMapping>& nx::MemoryMappingHandler::getIoMemoryMaps() const
{ {
return mMemPage; return mMemPage;
} }
void nx::MemoryMappingHandler::copyFrom(const MemoryMappingHandler & other)
{
mIsSet = other.mIsSet;
mMemRange = other.mMemRange;
mMemPage = other.mMemPage;
}
bool nx::MemoryMappingHandler::isEqual(const MemoryMappingHandler & other) const
{
return (mIsSet == other.mIsSet) \
&& (mMemRange == other.mMemRange) \
&& (mMemPage == other.mMemPage);
}

View file

@ -1,7 +1,5 @@
#include <nx/MemoryPageEntry.h> #include <nx/MemoryPageEntry.h>
nx::MemoryPageEntry::MemoryPageEntry() : nx::MemoryPageEntry::MemoryPageEntry() :
mCap(KernelCapability::KC_INVALID), mCap(KernelCapability::KC_INVALID),
mPage(0), mPage(0),
@ -37,6 +35,26 @@ nx::MemoryPageEntry::MemoryPageEntry(uint32_t page, bool flag) :
setFlag(flag); setFlag(flag);
} }
void nx::MemoryPageEntry::operator=(const MemoryPageEntry& other)
{
mPage = other.mPage;
mFlag = other.mFlag;
mUseFlag = other.mUseFlag;
updateCapField();
}
bool nx::MemoryPageEntry::operator==(const MemoryPageEntry& other) const
{
return (mPage == other.mPage) \
&& (mFlag == other.mFlag) \
&& (mUseFlag == other.mUseFlag);
}
bool nx::MemoryPageEntry::operator!=(const MemoryPageEntry& other) const
{
return !(*this == other);
}
const nx::KernelCapability & nx::MemoryPageEntry::getKernelCapability() const const nx::KernelCapability & nx::MemoryPageEntry::getKernelCapability() const
{ {
return mCap; return mCap;

View file

@ -1,7 +1,5 @@
#include <nx/MiscFlagsEntry.h> #include <nx/MiscFlagsEntry.h>
nx::MiscFlagsEntry::MiscFlagsEntry() : nx::MiscFlagsEntry::MiscFlagsEntry() :
mCap(kCapId), mCap(kCapId),
mFlags(0) mFlags(0)
@ -21,6 +19,22 @@ nx::MiscFlagsEntry::MiscFlagsEntry(uint32_t flags) :
setFlags(flags); setFlags(flags);
} }
void nx::MiscFlagsEntry::operator=(const MiscFlagsEntry& other)
{
mFlags = other.mFlags;
updateCapField();
}
bool nx::MiscFlagsEntry::operator==(const MiscFlagsEntry& other) const
{
return (mFlags == other.mFlags);
}
bool nx::MiscFlagsEntry::operator!=(const MiscFlagsEntry& other) const
{
return !(*this == other);
}
const nx::KernelCapability & nx::MiscFlagsEntry::getKernelCapability() const const nx::KernelCapability & nx::MiscFlagsEntry::getKernelCapability() const
{ {
return mCap; return mCap;

View file

@ -1,34 +1,34 @@
#include <nx/MiscFlagsHandler.h> #include <nx/MiscFlagsHandler.h>
nx::MiscFlagsHandler::MiscFlagsHandler() : nx::MiscFlagsHandler::MiscFlagsHandler() :
mIsSet(false) mIsSet(false)
{} {}
void nx::MiscFlagsHandler::operator=(const MiscFlagsHandler & other)
{
mIsSet = other.mIsSet;
mFlags = other.mFlags;
}
bool nx::MiscFlagsHandler::operator==(const MiscFlagsHandler & other) const bool nx::MiscFlagsHandler::operator==(const MiscFlagsHandler & other) const
{ {
return isEqual(other); return (mIsSet == other.mIsSet) \
&& (mFlags == other.mFlags);
} }
bool nx::MiscFlagsHandler::operator!=(const MiscFlagsHandler & other) const bool nx::MiscFlagsHandler::operator!=(const MiscFlagsHandler & other) const
{ {
return !isEqual(other); return !(*this == other);
}
void nx::MiscFlagsHandler::operator=(const MiscFlagsHandler & other)
{
copyFrom(other);
} }
void nx::MiscFlagsHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps) void nx::MiscFlagsHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
{ {
if (caps.getSize() > kMaxKernelCapNum) if (caps.size() > kMaxKernelCapNum)
{ {
throw fnd::Exception(kModuleName, "Too many kernel capabilities"); throw fnd::Exception(kModuleName, "Too many kernel capabilities");
} }
if (caps.getSize() == 0) if (caps.size() == 0)
return; return;
MiscFlagsEntry entry; MiscFlagsEntry entry;
@ -53,7 +53,7 @@ void nx::MiscFlagsHandler::exportKernelCapabilityList(fnd::List<KernelCapability
// convert list to word flags // convert list to word flags
uint32_t flag = 0; uint32_t flag = 0;
for (size_t i = 0; i < mFlags.getSize(); i++) for (size_t i = 0; i < mFlags.size(); i++)
{ {
flag |= BIT(mFlags[i]); flag |= BIT(mFlags[i]);
} }
@ -86,16 +86,4 @@ void nx::MiscFlagsHandler::setFlagList(fnd::List<Flags> flags)
{ {
mFlags = flags; mFlags = flags;
mIsSet = true; mIsSet = true;
} }
void nx::MiscFlagsHandler::copyFrom(const MiscFlagsHandler & other)
{
mIsSet = other.mIsSet;
mFlags = other.mFlags;
}
bool nx::MiscFlagsHandler::isEqual(const MiscFlagsHandler & other) const
{
return (mIsSet == other.mIsSet) \
&& (mFlags == other.mFlags);
}

View file

@ -1,7 +1,5 @@
#include <nx/MiscParamsEntry.h> #include <nx/MiscParamsEntry.h>
nx::MiscParamsEntry::MiscParamsEntry() : nx::MiscParamsEntry::MiscParamsEntry() :
mCap(kCapId), mCap(kCapId),
mProgramType(0) mProgramType(0)
@ -21,6 +19,22 @@ nx::MiscParamsEntry::MiscParamsEntry(uint8_t program_type) :
setProgramType(program_type); setProgramType(program_type);
} }
void nx::MiscParamsEntry::operator=(const MiscParamsEntry& other)
{
mProgramType = other.mProgramType;
updateCapField();
}
bool nx::MiscParamsEntry::operator==(const MiscParamsEntry& other) const
{
return (mProgramType == other.mProgramType);
}
bool nx::MiscParamsEntry::operator!=(const MiscParamsEntry& other) const
{
return !(*this == other);
}
const nx::KernelCapability & nx::MiscParamsEntry::getKernelCapability() const const nx::KernelCapability & nx::MiscParamsEntry::getKernelCapability() const
{ {
return mCap; return mCap;

View file

@ -1,35 +1,35 @@
#include <nx/MiscParamsHandler.h> #include <nx/MiscParamsHandler.h>
nx::MiscParamsHandler::MiscParamsHandler() : nx::MiscParamsHandler::MiscParamsHandler() :
mIsSet(false), mIsSet(false),
mEntry(0) mEntry(0)
{} {}
void nx::MiscParamsHandler::operator=(const MiscParamsHandler & other)
{
mIsSet = other.mIsSet;
mEntry.setKernelCapability(other.mEntry.getKernelCapability());
}
bool nx::MiscParamsHandler::operator==(const MiscParamsHandler & other) const bool nx::MiscParamsHandler::operator==(const MiscParamsHandler & other) const
{ {
return isEqual(other); return (mIsSet == other.mIsSet) \
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
} }
bool nx::MiscParamsHandler::operator!=(const MiscParamsHandler & other) const bool nx::MiscParamsHandler::operator!=(const MiscParamsHandler & other) const
{ {
return !isEqual(other); return !(*this == other);
}
void nx::MiscParamsHandler::operator=(const MiscParamsHandler & other)
{
copyFrom(other);
} }
void nx::MiscParamsHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps) void nx::MiscParamsHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
{ {
if (caps.getSize() > kMaxKernelCapNum) if (caps.size() > kMaxKernelCapNum)
{ {
throw fnd::Exception(kModuleName, "Too many kernel capabilities"); throw fnd::Exception(kModuleName, "Too many kernel capabilities");
} }
if (caps.getSize() == 0) if (caps.size() == 0)
return; return;
mEntry.setKernelCapability(caps[0]); mEntry.setKernelCapability(caps[0]);
@ -65,16 +65,4 @@ void nx::MiscParamsHandler::setProgramType(uint8_t type)
{ {
mEntry.setProgramType(type); mEntry.setProgramType(type);
mIsSet = true; mIsSet = true;
} }
void nx::MiscParamsHandler::copyFrom(const MiscParamsHandler & other)
{
mIsSet = other.mIsSet;
mEntry.setKernelCapability(other.mEntry.getKernelCapability());
}
bool nx::MiscParamsHandler::isEqual(const MiscParamsHandler & other) const
{
return (mIsSet == other.mIsSet) \
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
}

View file

@ -1,18 +1,16 @@
#include <nx/NcaHeader.h> #include <nx/NcaHeader.h>
using namespace nx; nx::NcaHeader::NcaHeader()
NcaHeader::NcaHeader()
{ {
clear(); clear();
} }
NcaHeader::NcaHeader(const NcaHeader & other) nx::NcaHeader::NcaHeader(const NcaHeader & other)
{ {
*this = other; *this = other;
} }
bool NcaHeader::operator==(const NcaHeader & other) const bool nx::NcaHeader::operator==(const NcaHeader & other) const
{ {
return (mDistributionType == other.mDistributionType) \ return (mDistributionType == other.mDistributionType) \
&& (mContentType == other.mContentType) \ && (mContentType == other.mContentType) \
@ -26,12 +24,12 @@ bool NcaHeader::operator==(const NcaHeader & other) const
&& (mEncAesKeys == other.mEncAesKeys); && (mEncAesKeys == other.mEncAesKeys);
} }
bool NcaHeader::operator!=(const NcaHeader & other) const bool nx::NcaHeader::operator!=(const NcaHeader & other) const
{ {
return !(*this == other); return !(*this == other);
} }
void NcaHeader::operator=(const NcaHeader & other) void nx::NcaHeader::operator=(const NcaHeader & other)
{ {
if (other.getBytes().size()) if (other.getBytes().size())
{ {
@ -53,7 +51,7 @@ void NcaHeader::operator=(const NcaHeader & other)
} }
} }
void NcaHeader::toBytes() void nx::NcaHeader::toBytes()
{ {
mRawBinary.alloc(sizeof(sNcaHeader)); mRawBinary.alloc(sizeof(sNcaHeader));
sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data(); sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data();
@ -110,7 +108,7 @@ void NcaHeader::toBytes()
} }
} }
void NcaHeader::fromBytes(const byte_t * data, size_t len) void nx::NcaHeader::fromBytes(const byte_t * data, size_t len)
{ {
if (len < sizeof(sNcaHeader)) if (len < sizeof(sNcaHeader))
{ {
@ -137,7 +135,7 @@ void NcaHeader::fromBytes(const byte_t * data, size_t len)
mDistributionType = (nca::DistributionType)hdr->distribution_type; mDistributionType = (nca::DistributionType)hdr->distribution_type;
mContentType = (nca::ContentType)hdr->content_type; mContentType = (nca::ContentType)hdr->content_type;
mKeyGeneration = MAX(hdr->key_generation, hdr->key_generation_2); mKeyGeneration = _MAX(hdr->key_generation, hdr->key_generation_2);
mKaekIndex = hdr->key_area_encryption_key_index; mKaekIndex = hdr->key_area_encryption_key_index;
mContentSize = *hdr->content_size; mContentSize = *hdr->content_size;
mProgramId = *hdr->program_id; mProgramId = *hdr->program_id;
@ -160,7 +158,7 @@ void NcaHeader::fromBytes(const byte_t * data, size_t len)
} }
} }
const fnd::Vec<byte_t>& NcaHeader::getBytes() const const fnd::Vec<byte_t>& nx::NcaHeader::getBytes() const
{ {
return mRawBinary; return mRawBinary;
} }
@ -231,22 +229,22 @@ void nx::NcaHeader::setKaekIndex(byte_t index)
mKaekIndex = index; mKaekIndex = index;
} }
uint64_t NcaHeader::getContentSize() const uint64_t nx::NcaHeader::getContentSize() const
{ {
return mContentSize; return mContentSize;
} }
void NcaHeader::setContentSize(uint64_t size) void nx::NcaHeader::setContentSize(uint64_t size)
{ {
mContentSize = size; mContentSize = size;
} }
uint64_t NcaHeader::getProgramId() const uint64_t nx::NcaHeader::getProgramId() const
{ {
return mProgramId; return mProgramId;
} }
void NcaHeader::setProgramId(uint64_t program_id) void nx::NcaHeader::setProgramId(uint64_t program_id)
{ {
mProgramId = program_id; mProgramId = program_id;
} }
@ -294,12 +292,12 @@ void nx::NcaHeader::setRightsId(const byte_t* rights_id)
memcpy(mRightsId, rights_id, nca::kRightsIdLen); memcpy(mRightsId, rights_id, nca::kRightsIdLen);
} }
const fnd::List<NcaHeader::sPartition>& NcaHeader::getPartitions() const const fnd::List<nx::NcaHeader::sPartition>& nx::NcaHeader::getPartitions() const
{ {
return mPartitions; return mPartitions;
} }
void NcaHeader::setPartitions(const fnd::List<NcaHeader::sPartition>& partitions) void nx::NcaHeader::setPartitions(const fnd::List<nx::NcaHeader::sPartition>& partitions)
{ {
mPartitions = partitions; mPartitions = partitions;
if (mPartitions.size() >= nca::kPartitionNum) if (mPartitions.size() >= nca::kPartitionNum)
@ -308,22 +306,22 @@ void NcaHeader::setPartitions(const fnd::List<NcaHeader::sPartition>& partitions
} }
} }
const fnd::List<crypto::aes::sAes128Key>& NcaHeader::getEncAesKeys() const const fnd::List<crypto::aes::sAes128Key>& nx::NcaHeader::getEncAesKeys() const
{ {
return mEncAesKeys; return mEncAesKeys;
} }
void NcaHeader::setEncAesKeys(const fnd::List<crypto::aes::sAes128Key>& keys) void nx::NcaHeader::setEncAesKeys(const fnd::List<crypto::aes::sAes128Key>& keys)
{ {
mEncAesKeys = keys; mEncAesKeys = keys;
} }
uint64_t NcaHeader::blockNumToSize(uint32_t block_num) const uint64_t nx::NcaHeader::blockNumToSize(uint32_t block_num) const
{ {
return block_num*nca::kSectorSize; return block_num*nca::kSectorSize;
} }
uint32_t NcaHeader::sizeToBlockNum(uint64_t real_size) const uint32_t nx::NcaHeader::sizeToBlockNum(uint64_t real_size) const
{ {
return (uint32_t)(align(real_size, nca::kSectorSize) / nca::kSectorSize); return (uint32_t)(align(real_size, nca::kSectorSize) / nca::kSectorSize);
} }

View file

@ -42,8 +42,8 @@ bool nx::NpdmBinary::operator!=(const NpdmBinary & other) const
void nx::NpdmBinary::toBytes() void nx::NpdmBinary::toBytes()
{ {
mAci.exportBinary(); mAci.toBytes();
mAcid.exportBinary(); mAcid.toBytes();
setAciSize(mAci.getBytes().size()); setAciSize(mAci.getBytes().size());
setAcidSize(mAcid.getBytes().size()); setAcidSize(mAcid.getBytes().size());
@ -70,11 +70,11 @@ void nx::NpdmBinary::fromBytes(const byte_t* data, size_t len)
// import Aci/Acid // import Aci/Acid
if (getAciPos().size) if (getAciPos().size)
{ {
mAci.importBinary(mRawBinary.data() + getAciPos().offset, getAciPos().size); mAci.fromBytes(mRawBinary.data() + getAciPos().offset, getAciPos().size);
} }
if (getAcidPos().size) if (getAcidPos().size)
{ {
mAcid.importBinary(mRawBinary.data() + getAcidPos().offset, getAcidPos().size); mAcid.fromBytes(mRawBinary.data() + getAcidPos().offset, getAcidPos().size);
} }
} }

View file

@ -14,7 +14,7 @@ void nx::NpdmHeader::operator=(const NpdmHeader & other)
{ {
if (other.getBytes().size()) if (other.getBytes().size())
{ {
fromBytes(other.getBytes().data, other.getBytes().size()); fromBytes(other.getBytes().data(), other.getBytes().size());
} }
else else
{ {
@ -80,6 +80,7 @@ void nx::NpdmHeader::fromBytes(const byte_t* data, size_t len)
throw fnd::Exception(kModuleName, "NPDM header too small"); throw fnd::Exception(kModuleName, "NPDM header too small");
} }
// clear internal members
clear(); clear();
mRawBinary.alloc(sizeof(sNpdmHeader)); mRawBinary.alloc(sizeof(sNpdmHeader));
@ -138,7 +139,7 @@ void nx::NpdmHeader::clear()
size_t nx::NpdmHeader::getNpdmSize() const size_t nx::NpdmHeader::getNpdmSize() const
{ {
return MAX(mAcidPos.offset + mAcidPos.size, mAciPos.offset + mAciPos.size); return _MAX(mAcidPos.offset + mAcidPos.size, mAciPos.offset + mAciPos.size);
} }
nx::npdm::InstructionType nx::NpdmHeader::getInstructionType() const nx::npdm::InstructionType nx::NpdmHeader::getInstructionType() const

View file

@ -120,6 +120,9 @@ void nx::PfsHeader::fromBytes(const byte_t* data, size_t len)
{ {
throw fnd::Exception(kModuleName, "PFS header too small"); throw fnd::Exception(kModuleName, "PFS header too small");
} }
// clear variables
clear();
// import minimum header // import minimum header
mRawBinary.alloc(sizeof(sPfsHeader)); mRawBinary.alloc(sizeof(sPfsHeader));
@ -154,9 +157,6 @@ void nx::PfsHeader::fromBytes(const byte_t* data, size_t len)
memcpy(mRawBinary.data(), data, mRawBinary.size()); memcpy(mRawBinary.data(), data, mRawBinary.size());
hdr = (const sPfsHeader*)mRawBinary.data(); hdr = (const sPfsHeader*)mRawBinary.data();
// clear variables
clear();
mFsType = fs_type; mFsType = fs_type;
if (mFsType == TYPE_PFS0) if (mFsType == TYPE_PFS0)
{ {

View file

@ -1,18 +1,16 @@
#include <nx/SacBinary.h> #include <nx/SacBinary.h>
using namespace nx; nx::SacBinary::SacBinary()
SacBinary::SacBinary()
{ {
clear(); clear();
} }
SacBinary::SacBinary(const SacBinary & other) nx::SacBinary::SacBinary(const SacBinary & other)
{ {
*this = other; *this = other;
} }
void SacBinary::operator=(const SacBinary & other) void nx::SacBinary::operator=(const SacBinary & other)
{ {
if (other.getBytes().data()) if (other.getBytes().data())
{ {
@ -25,17 +23,17 @@ void SacBinary::operator=(const SacBinary & other)
} }
} }
bool SacBinary::operator==(const SacBinary & other) const bool nx::SacBinary::operator==(const SacBinary & other) const
{ {
return mServices == other.mServices; return (mServices == other.mServices);
} }
bool SacBinary::operator!=(const SacBinary & other) const bool nx::SacBinary::operator!=(const SacBinary & other) const
{ {
return !(*this == other); return !(*this == other);
} }
void SacBinary::toBytes() void nx::SacBinary::toBytes()
{ {
size_t totalSize = 0; size_t totalSize = 0;
for (size_t i = 0; i < mServices.size(); i++) for (size_t i = 0; i < mServices.size(); i++)
@ -51,7 +49,7 @@ void SacBinary::toBytes()
} }
} }
void SacBinary::fromBytes(const byte_t* data, size_t len) void nx::SacBinary::fromBytes(const byte_t* data, size_t len)
{ {
clear(); clear();
mRawBinary.alloc(len); mRawBinary.alloc(len);
@ -65,7 +63,7 @@ void SacBinary::fromBytes(const byte_t* data, size_t len)
} }
} }
const fnd::Vec<byte_t>& SacBinary::getBytes() const const fnd::Vec<byte_t>& nx::SacBinary::getBytes() const
{ {
return mRawBinary; return mRawBinary;
} }
@ -76,12 +74,12 @@ void nx::SacBinary::clear()
mServices.clear(); mServices.clear();
} }
const fnd::List<SacEntry>& SacBinary::getServiceList() const const fnd::List<nx::SacEntry>& nx::SacBinary::getServiceList() const
{ {
return mServices; return mServices;
} }
void SacBinary::addService(const SacEntry& service) void nx::SacBinary::addService(const SacEntry& service)
{ {
mServices.addElement(service); mServices.addElement(service);
} }

View file

@ -1,25 +1,23 @@
#include <nx/SacEntry.h> #include <nx/SacEntry.h>
using namespace nx; nx::SacEntry::SacEntry()
SacEntry::SacEntry() :
{ {
clear(); clear();
} }
SacEntry::SacEntry(const std::string & name, bool isServer) : nx::SacEntry::SacEntry(const std::string & name, bool isServer) :
mIsServer(isServer), mIsServer(isServer),
mName(name) mName(name)
{ {
toBytes(); toBytes();
} }
SacEntry::SacEntry(const SacEntry & other) nx::SacEntry::SacEntry(const SacEntry & other)
{ {
*this = other; *this = other;
} }
void SacEntry::operator=(const SacEntry & other) void nx::SacEntry::operator=(const SacEntry & other)
{ {
if (other.getBytes().size()) if (other.getBytes().size())
{ {
@ -33,19 +31,19 @@ void SacEntry::operator=(const SacEntry & other)
} }
} }
bool SacEntry::operator==(const SacEntry & other) const bool nx::SacEntry::operator==(const SacEntry & other) const
{ {
return (mIsServer == other.mIsServer) \ return (mIsServer == other.mIsServer) \
&& (mName == other.mName); && (mName == other.mName);
} }
bool SacEntry::operator!=(const SacEntry & other) const bool nx::SacEntry::operator!=(const SacEntry & other) const
{ {
return !(*this == other); return !(*this == other);
} }
void SacEntry::toBytes() void nx::SacEntry::toBytes()
{ {
try { try {
mRawBinary.alloc(mName.size() + 1); mRawBinary.alloc(mName.size() + 1);
@ -70,7 +68,7 @@ void SacEntry::toBytes()
memcpy(mRawBinary.data() + 1, mName.c_str(), mName.length()); memcpy(mRawBinary.data() + 1, mName.c_str(), mName.length());
} }
void SacEntry::fromBytes(const byte_t* data, size_t len) void nx::SacEntry::fromBytes(const byte_t* data, size_t len)
{ {
bool isServer = (data[0] & SAC_IS_SERVER) == SAC_IS_SERVER; bool isServer = (data[0] & SAC_IS_SERVER) == SAC_IS_SERVER;
size_t nameLen = (data[0] & SAC_NAME_LEN_MASK) + 1; // bug? size_t nameLen = (data[0] & SAC_NAME_LEN_MASK) + 1; // bug?
@ -96,7 +94,7 @@ void SacEntry::fromBytes(const byte_t* data, size_t len)
mName = std::string((const char*)(mRawBinary.data() + 1), nameLen); mName = std::string((const char*)(mRawBinary.data() + 1), nameLen);
} }
const fnd::Vec<byte_t>& SacEntry::getBytes() const const fnd::Vec<byte_t>& nx::SacEntry::getBytes() const
{ {
return mRawBinary; return mRawBinary;
} }
@ -107,22 +105,22 @@ void nx::SacEntry::clear()
mName.clear(); mName.clear();
} }
bool SacEntry::isServer() const bool nx::SacEntry::isServer() const
{ {
return mIsServer; return mIsServer;
} }
void SacEntry::setIsServer(bool isServer) void nx::SacEntry::setIsServer(bool isServer)
{ {
mIsServer = isServer; mIsServer = isServer;
} }
const std::string & SacEntry::getName() const const std::string & nx::SacEntry::getName() const
{ {
return mName; return mName;
} }
void SacEntry::setName(const std::string & name) void nx::SacEntry::setName(const std::string & name)
{ {
if (name.length() > kMaxServiceNameLen) if (name.length() > kMaxServiceNameLen)
{ {

View file

@ -1,7 +1,5 @@
#include <nx/SystemCallEntry.h> #include <nx/SystemCallEntry.h>
nx::SystemCallEntry::SystemCallEntry() : nx::SystemCallEntry::SystemCallEntry() :
mCap(kCapId), mCap(kCapId),
mSystemCallUpper(0), mSystemCallUpper(0),
@ -27,6 +25,24 @@ nx::SystemCallEntry::SystemCallEntry(uint32_t upper_bits, uint32_t lower_bits) :
setSystemCallLowerBits(lower_bits); setSystemCallLowerBits(lower_bits);
} }
void nx::SystemCallEntry::operator=(const SystemCallEntry& other)
{
mSystemCallUpper = other.mSystemCallUpper;
mSystemCallLower = other.mSystemCallLower;
updateCapField();
}
bool nx::SystemCallEntry::operator==(const SystemCallEntry& other) const
{
return (mSystemCallUpper == other.mSystemCallUpper) \
&& (mSystemCallLower == other.mSystemCallLower);
}
bool nx::SystemCallEntry::operator!=(const SystemCallEntry& other) const
{
return !(*this == other);
}
const nx::KernelCapability & nx::SystemCallEntry::getKernelCapability() const const nx::KernelCapability & nx::SystemCallEntry::getKernelCapability() const
{ {
return mCap; return mCap;

View file

@ -1,36 +1,37 @@
#include <nx/SystemCallHandler.h> #include <nx/SystemCallHandler.h>
#include <nx/SystemCallEntry.h> #include <nx/SystemCallEntry.h>
nx::SystemCallHandler::SystemCallHandler() : nx::SystemCallHandler::SystemCallHandler() :
mIsSet(false), mIsSet(false),
mSystemCalls() mSystemCalls()
{} {}
void nx::SystemCallHandler::operator=(const SystemCallHandler & other)
{
mIsSet = other.mIsSet;
mSystemCalls = other.mSystemCalls;
}
bool nx::SystemCallHandler::operator==(const SystemCallHandler & other) const bool nx::SystemCallHandler::operator==(const SystemCallHandler & other) const
{ {
return isEqual(other); return (mIsSet == other.mIsSet) \
&& (mSystemCalls == other.mSystemCalls);
} }
bool nx::SystemCallHandler::operator!=(const SystemCallHandler & other) const bool nx::SystemCallHandler::operator!=(const SystemCallHandler & other) const
{ {
return !isEqual(other); return !(*this == other);
}
void nx::SystemCallHandler::operator=(const SystemCallHandler & other)
{
copyFrom(other);
} }
void nx::SystemCallHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps) void nx::SystemCallHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
{ {
if (caps.getSize() == 0) if (caps.size() == 0)
return; return;
SystemCallEntry entry; SystemCallEntry entry;
uint8_t syscallUpper, syscall; uint8_t syscallUpper, syscall;
for (size_t i = 0; i < caps.getSize(); i++) for (size_t i = 0; i < caps.size(); i++)
{ {
entry.setKernelCapability(caps[i]); entry.setKernelCapability(caps[i]);
syscallUpper = 24 * entry.getSystemCallUpperBits(); syscallUpper = 24 * entry.getSystemCallUpperBits();
@ -60,7 +61,7 @@ void nx::SystemCallHandler::exportKernelCapabilityList(fnd::List<KernelCapabilit
entries[i].setSystemCallLowerBits(0); entries[i].setSystemCallLowerBits(0);
} }
for (size_t i = 0; i < mSystemCalls.getSize(); i++) for (size_t i = 0; i < mSystemCalls.size(); i++)
{ {
if (mSystemCalls[i] > kMaxSystemCall) if (mSystemCalls[i] > kMaxSystemCall)
{ {
@ -70,7 +71,7 @@ void nx::SystemCallHandler::exportKernelCapabilityList(fnd::List<KernelCapabilit
entries[mSystemCalls[i] / 24].setSystemCallLowerBits(entries[mSystemCalls[i] / 24].getSystemCallLowerBits() | BIT(mSystemCalls[i] % 24)); entries[mSystemCalls[i] / 24].setSystemCallLowerBits(entries[mSystemCalls[i] / 24].getSystemCallLowerBits() | BIT(mSystemCalls[i] % 24));
} }
for (size_t i = 0; i < entries.getSize(); i++) for (size_t i = 0; i < entries.size(); i++)
{ {
if (entries[i].getSystemCallLowerBits() != 0) if (entries[i].getSystemCallLowerBits() != 0)
{ {
@ -98,7 +99,7 @@ const fnd::List<uint8_t>& nx::SystemCallHandler::getSystemCalls() const
void nx::SystemCallHandler::setSystemCallList(const fnd::List<uint8_t>& calls) void nx::SystemCallHandler::setSystemCallList(const fnd::List<uint8_t>& calls)
{ {
mSystemCalls.clear(); mSystemCalls.clear();
for (size_t i = 0; i < calls.getSize(); i++) for (size_t i = 0; i < calls.size(); i++)
{ {
if (mSystemCalls[i] > kMaxSystemCall) if (mSystemCalls[i] > kMaxSystemCall)
{ {
@ -109,16 +110,4 @@ void nx::SystemCallHandler::setSystemCallList(const fnd::List<uint8_t>& calls)
} }
mIsSet = true; mIsSet = true;
} }
void nx::SystemCallHandler::copyFrom(const SystemCallHandler & other)
{
mIsSet = other.mIsSet;
mSystemCalls = other.mSystemCalls;
}
bool nx::SystemCallHandler::isEqual(const SystemCallHandler & other) const
{
return (mIsSet == other.mIsSet) \
&& (mSystemCalls == other.mSystemCalls);
}

View file

@ -1,7 +1,5 @@
#include <nx/ThreadInfoEntry.h> #include <nx/ThreadInfoEntry.h>
nx::ThreadInfoEntry::ThreadInfoEntry() : nx::ThreadInfoEntry::ThreadInfoEntry() :
mCap(kCapId), mCap(kCapId),
mMinPriority(kDefaultPriority), mMinPriority(kDefaultPriority),
@ -33,6 +31,28 @@ nx::ThreadInfoEntry::ThreadInfoEntry(uint8_t min_priority, uint8_t max_priority,
setMaxCpuId(max_core_number); setMaxCpuId(max_core_number);
} }
void nx::ThreadInfoEntry::operator=(const ThreadInfoEntry& other)
{
mMinPriority = other.mMinPriority;
mMaxPriority = other.mMaxPriority;
mMinCpuId = other.mMinCpuId;
mMaxCpuId = other.mMaxCpuId;
updateCapField();
}
bool nx::ThreadInfoEntry::operator==(const ThreadInfoEntry& other) const
{
return (mMinPriority == other.mMinPriority) \
&& (mMaxPriority == other.mMaxPriority) \
&& (mMinCpuId == other.mMinCpuId) \
&& (mMaxCpuId == other.mMaxCpuId);
}
bool nx::ThreadInfoEntry::operator!=(const ThreadInfoEntry& other) const
{
return !(*this == other);
}
const nx::KernelCapability & nx::ThreadInfoEntry::getKernelCapability() const const nx::KernelCapability & nx::ThreadInfoEntry::getKernelCapability() const
{ {
return mCap; return mCap;

View file

@ -1,35 +1,35 @@
#include <nx/ThreadInfoHandler.h> #include <nx/ThreadInfoHandler.h>
nx::ThreadInfoHandler::ThreadInfoHandler() : nx::ThreadInfoHandler::ThreadInfoHandler() :
mIsSet(false), mIsSet(false),
mEntry(0,0,0,0) mEntry(0,0,0,0)
{} {}
void nx::ThreadInfoHandler::operator=(const ThreadInfoHandler & other)
{
mIsSet = other.mIsSet;
mEntry.setKernelCapability(other.mEntry.getKernelCapability());
}
bool nx::ThreadInfoHandler::operator==(const ThreadInfoHandler & other) const bool nx::ThreadInfoHandler::operator==(const ThreadInfoHandler & other) const
{ {
return isEqual(other); return (mIsSet == other.mIsSet) \
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
} }
bool nx::ThreadInfoHandler::operator!=(const ThreadInfoHandler & other) const bool nx::ThreadInfoHandler::operator!=(const ThreadInfoHandler & other) const
{ {
return !isEqual(other); return !(*this == other);
}
void nx::ThreadInfoHandler::operator=(const ThreadInfoHandler & other)
{
copyFrom(other);
} }
void nx::ThreadInfoHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps) void nx::ThreadInfoHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
{ {
if (caps.getSize() > kMaxKernelCapNum) if (caps.size() > kMaxKernelCapNum)
{ {
throw fnd::Exception(kModuleName, "Too many kernel capabilities"); throw fnd::Exception(kModuleName, "Too many kernel capabilities");
} }
if (caps.getSize() == 0) if (caps.size() == 0)
return; return;
mEntry.setKernelCapability(caps[0]); mEntry.setKernelCapability(caps[0]);
@ -100,16 +100,4 @@ void nx::ThreadInfoHandler::setMaxCpuId(uint8_t core_num)
{ {
mEntry.setMaxCpuId(core_num); mEntry.setMaxCpuId(core_num);
mIsSet = true; mIsSet = true;
} }
void nx::ThreadInfoHandler::copyFrom(const ThreadInfoHandler & other)
{
mIsSet = other.mIsSet;
mEntry.setKernelCapability(other.mEntry.getKernelCapability());
}
bool nx::ThreadInfoHandler::isEqual(const ThreadInfoHandler & other) const
{
return (mIsSet == other.mIsSet) \
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
}

View file

@ -45,35 +45,35 @@ void nx::XciHeader::operator=(const XciHeader& other)
bool nx::XciHeader::operator==(const XciHeader& other) const bool nx::XciHeader::operator==(const XciHeader& other) const
{ {
return (mRomAreaStartPage == other.mRomAreaStartPage \ return (mRomAreaStartPage == other.mRomAreaStartPage)
&& mBackupAreaStartPage == other.mBackupAreaStartPage \ && (mBackupAreaStartPage == other.mBackupAreaStartPage)
&& mKekIndex == other.mKekIndex \ && (mKekIndex == other.mKekIndex)
&& mTitleKeyDecIndex == other.mTitleKeyDecIndex \ && (mTitleKeyDecIndex == other.mTitleKeyDecIndex)
&& mRomSize == other.mRomSize \ && (mRomSize == other.mRomSize)
&& mCardHeaderVersion == other.mCardHeaderVersion \ && (mCardHeaderVersion == other.mCardHeaderVersion)
&& mFlags == other.mFlags \ && (mFlags == other.mFlags)
&& mPackageId == other.mPackageId \ && (mPackageId == other.mPackageId)
&& mValidDataEndPage == other.mValidDataEndPage \ && (mValidDataEndPage == other.mValidDataEndPage)
&& mAesCbcIv == other.mAesCbcIv \ && (mAesCbcIv == other.mAesCbcIv)
&& mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress \ && (mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress)
&& mPartitionFsHeaderSize == other.mPartitionFsHeaderSize \ && (mPartitionFsHeaderSize == other.mPartitionFsHeaderSize)
&& mPartitionFsHeaderHash == other.mPartitionFsHeaderHash \ && (mPartitionFsHeaderHash == other.mPartitionFsHeaderHash)
&& mInitialDataHash == other.mInitialDataHash \ && (mInitialDataHash == other.mInitialDataHash)
&& mSelSec == other.mSelSec \ && (mSelSec == other.mSelSec)
&& mSelT1Key == other.mSelT1Key \ && (mSelT1Key == other.mSelT1Key)
&& mSelKey == other.mSelKey \ && (mSelKey == other.mSelKey)
&& mLimAreaPage == other.mLimAreaPage \ && (mLimAreaPage == other.mLimAreaPage)
&& mFwVersion[0] == other.mFwVersion[0] \ && (mFwVersion[0] == other.mFwVersion[0])
&& mFwVersion[1] == other.mFwVersion[1] \ && (mFwVersion[1] == other.mFwVersion[1])
&& mAccCtrl1 == other.mAccCtrl1 \ && (mAccCtrl1 == other.mAccCtrl1)
&& mWait1TimeRead == other.mWait1TimeRead \ && (mWait1TimeRead == other.mWait1TimeRead)
&& mWait2TimeRead == other.mWait2TimeRead \ && (mWait2TimeRead == other.mWait2TimeRead)
&& mWait1TimeWrite == other.mWait1TimeWrite \ && (mWait1TimeWrite == other.mWait1TimeWrite)
&& mWait2TimeWrite == other.mWait2TimeWrite \ && (mWait2TimeWrite == other.mWait2TimeWrite)
&& mFwMode == other.mFwMode \ && (mFwMode == other.mFwMode)
&& mUppVersion == other.mUppVersion \ && (mUppVersion == other.mUppVersion)
&& memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) \ && (memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) == 0)
&& mUppId == other.mUppId); && (mUppId == other.mUppId);
} }
bool nx::XciHeader::operator!=(const XciHeader& other) const bool nx::XciHeader::operator!=(const XciHeader& other) const

View file

@ -39,18 +39,18 @@ void AesCtrWrappedIFile::read(byte_t* out, size_t len)
for (size_t i = 0; i < cache_reads; i++) for (size_t i = 0; i < cache_reads; i++)
{ {
read_len = MIN(len - (i * kCacheSize), kCacheSize); read_len = _MIN(len - (i * kCacheSize), kCacheSize);
read_pos = ((mFileOffset >> 4) << 4) + (i * kCacheSize); read_pos = ((mFileOffset >> 4) << 4) + (i * kCacheSize);
//printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len); //printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len);
mFile->seek(read_pos); mFile->seek(read_pos);
mFile->read(mCache.getBytes(), kCacheSizeAllocSize); mFile->read(mCache.data(), kCacheSizeAllocSize);
crypto::aes::AesIncrementCounter(mBaseCtr.iv, read_pos>>4, mCurrentCtr.iv); crypto::aes::AesIncrementCounter(mBaseCtr.iv, read_pos>>4, mCurrentCtr.iv);
crypto::aes::AesCtr(mCache.getBytes(), kCacheSizeAllocSize, mKey.key, mCurrentCtr.iv, mCache.getBytes()); crypto::aes::AesCtr(mCache.data(), kCacheSizeAllocSize, mKey.key, mCurrentCtr.iv, mCache.data());
memcpy(out + (i * kCacheSize), mCache.getBytes() + (mFileOffset & 0xf), read_len); memcpy(out + (i * kCacheSize), mCache.data() + (mFileOffset & 0xf), read_len);
} }
seek(mFileOffset + len); seek(mFileOffset + len);
@ -71,18 +71,18 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len)
for (size_t i = 0; i < cache_writes; i++) for (size_t i = 0; i < cache_writes; i++)
{ {
write_len = MIN(len - (i * kCacheSize), kCacheSize); write_len = _MIN(len - (i * kCacheSize), kCacheSize);
write_pos = ((mFileOffset >> 4) << 4) + (i * kCacheSize); write_pos = ((mFileOffset >> 4) << 4) + (i * kCacheSize);
//printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len); //printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len);
memcpy(mCache.getBytes() + (mFileOffset & 0xf), in + (i * kCacheSize), write_len); memcpy(mCache.data() + (mFileOffset & 0xf), in + (i * kCacheSize), write_len);
crypto::aes::AesIncrementCounter(mBaseCtr.iv, write_pos>>4, mCurrentCtr.iv); crypto::aes::AesIncrementCounter(mBaseCtr.iv, write_pos>>4, mCurrentCtr.iv);
crypto::aes::AesCtr(mCache.getBytes(), kCacheSizeAllocSize, mKey.key, mCurrentCtr.iv, mCache.getBytes()); crypto::aes::AesCtr(mCache.data(), kCacheSizeAllocSize, mKey.key, mCurrentCtr.iv, mCache.data());
mFile->seek(write_pos); mFile->seek(write_pos);
mFile->write(mCache.getBytes(), kCacheSizeAllocSize); mFile->write(mCache.data(), kCacheSizeAllocSize);
} }
seek(mFileOffset + len); seek(mFileOffset + len);
@ -90,18 +90,18 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len)
/* /*
for (size_t i = 0; i < (len / kAesCtrScratchSize); i++) for (size_t i = 0; i < (len / kAesCtrScratchSize); i++)
{ {
memcpy(mScratch.getBytes() + mBlockOffset, out + (i * kAesCtrScratchSize), kAesCtrScratchSize); memcpy(mScratch.data() + mBlockOffset, out + (i * kAesCtrScratchSize), kAesCtrScratchSize);
crypto::aes::AesCtr(mScratch.getBytes(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.getBytes()); crypto::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data());
mFile->write(mScratch.getBytes() + mBlockOffset, kAesCtrScratchSize); mFile->write(mScratch.data() + mBlockOffset, kAesCtrScratchSize);
} }
if (len % kAesCtrScratchSize) if (len % kAesCtrScratchSize)
{ {
size_t write_len = len % kAesCtrScratchSize; size_t write_len = len % kAesCtrScratchSize;
size_t write_pos = ((len / kAesCtrScratchSize) * kAesCtrScratchSize); size_t write_pos = ((len / kAesCtrScratchSize) * kAesCtrScratchSize);
memcpy(mScratch.getBytes() + mBlockOffset, out + write_pos, write_len); memcpy(mScratch.data() + mBlockOffset, out + write_pos, write_len);
crypto::aes::AesCtr(mScratch.getBytes(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.getBytes()); crypto::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data());
mFile->write(mScratch.getBytes() + mBlockOffset, write_len); mFile->write(mScratch.data() + mBlockOffset, write_len);
} }
*/ */
seek(mFileOffset + len); seek(mFileOffset + len);

View file

@ -1,5 +1,5 @@
#include <fnd/IFile.h> #include <fnd/IFile.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include <crypto/aes.h> #include <crypto/aes.h>
class AesCtrWrappedIFile : public fnd::IFile class AesCtrWrappedIFile : public fnd::IFile
@ -25,5 +25,5 @@ private:
crypto::aes::sAesIvCtr mBaseCtr, mCurrentCtr; crypto::aes::sAesIvCtr mBaseCtr, mCurrentCtr;
size_t mFileOffset; size_t mFileOffset;
fnd::MemoryBlob mCache; fnd::Vec<byte_t> mCache;
}; };

View file

@ -1,5 +1,5 @@
#include <fnd/SimpleFile.h> #include <fnd/SimpleFile.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include "AssetProcess.h" #include "AssetProcess.h"
#include "OffsetAdjustedIFile.h" #include "OffsetAdjustedIFile.h"
@ -73,16 +73,16 @@ void AssetProcess::setRomfsExtractPath(const std::string& path)
void AssetProcess::importHeader() void AssetProcess::importHeader()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
if (mFile->size() < sizeof(nx::sAssetHeader)) if (mFile->size() < sizeof(nx::sAssetHeader))
{ {
throw fnd::Exception(kModuleName, "Corrupt ASET: file too small"); throw fnd::Exception(kModuleName, "Corrupt ASET: file too small");
} }
scratch.alloc(sizeof(nx::sAssetHeader)); scratch.alloc(sizeof(nx::sAssetHeader));
mFile->read(scratch.getBytes(), 0, scratch.getSize()); mFile->read(scratch.data(), 0, scratch.size());
mHdr.importBinary(scratch.getBytes(), scratch.getSize()); mHdr.fromBytes(scratch.data(), scratch.size());
} }
void AssetProcess::processSections() void AssetProcess::processSections()
@ -93,11 +93,11 @@ void AssetProcess::processSections()
throw fnd::Exception(kModuleName, "ASET geometry for icon beyond file size"); throw fnd::Exception(kModuleName, "ASET geometry for icon beyond file size");
fnd::SimpleFile outfile(mIconExtractPath.var, fnd::SimpleFile::Create); fnd::SimpleFile outfile(mIconExtractPath.var, fnd::SimpleFile::Create);
fnd::MemoryBlob cache; fnd::Vec<byte_t> cache;
cache.alloc(mHdr.getIconInfo().size); cache.alloc(mHdr.getIconInfo().size);
mFile->read(cache.getBytes(), mHdr.getIconInfo().offset, cache.getSize()); mFile->read(cache.data(), mHdr.getIconInfo().offset, cache.size());
outfile.write(cache.getBytes(), cache.getSize()); outfile.write(cache.data(), cache.size());
outfile.close(); outfile.close();
} }
@ -109,11 +109,11 @@ void AssetProcess::processSections()
if (mNacpExtractPath.isSet) if (mNacpExtractPath.isSet)
{ {
fnd::SimpleFile outfile(mNacpExtractPath.var, fnd::SimpleFile::Create); fnd::SimpleFile outfile(mNacpExtractPath.var, fnd::SimpleFile::Create);
fnd::MemoryBlob cache; fnd::Vec<byte_t> cache;
cache.alloc(mHdr.getNacpInfo().size); cache.alloc(mHdr.getNacpInfo().size);
mFile->read(cache.getBytes(), mHdr.getNacpInfo().offset, cache.getSize()); mFile->read(cache.data(), mHdr.getNacpInfo().offset, cache.size());
outfile.write(cache.getBytes(), cache.getSize()); outfile.write(cache.data(), cache.size());
outfile.close(); outfile.close();
} }

View file

@ -100,10 +100,10 @@ void CnmtProcess::displayCmnt()
default: default:
break; break;
} }
if (mCnmt.getContentInfo().getSize() > 0) if (mCnmt.getContentInfo().size() > 0)
{ {
printf(" ContentInfo:\n"); printf(" ContentInfo:\n");
for (size_t i = 0; i < mCnmt.getContentInfo().getSize(); i++) for (size_t i = 0; i < mCnmt.getContentInfo().size(); i++)
{ {
const nx::ContentMetaBinary::ContentInfo& info = mCnmt.getContentInfo()[i]; const nx::ContentMetaBinary::ContentInfo& info = mCnmt.getContentInfo()[i];
printf(" %d\n", (int)i); printf(" %d\n", (int)i);
@ -117,10 +117,10 @@ void CnmtProcess::displayCmnt()
printf("\n"); printf("\n");
} }
} }
if (mCnmt.getContentMetaInfo().getSize() > 0) if (mCnmt.getContentMetaInfo().size() > 0)
{ {
printf(" ContentMetaInfo:\n"); printf(" ContentMetaInfo:\n");
for (size_t i = 0; i < mCnmt.getContentMetaInfo().getSize(); i++) for (size_t i = 0; i < mCnmt.getContentMetaInfo().size(); i++)
{ {
const nx::ContentMetaBinary::ContentMetaInfo& info = mCnmt.getContentMetaInfo()[i]; const nx::ContentMetaBinary::ContentMetaInfo& info = mCnmt.getContentMetaInfo()[i];
printf(" %d\n", (int)i); printf(" %d\n", (int)i);
@ -159,7 +159,7 @@ CnmtProcess::~CnmtProcess()
void CnmtProcess::process() void CnmtProcess::process()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
if (mFile == nullptr) if (mFile == nullptr)
{ {
@ -167,9 +167,9 @@ void CnmtProcess::process()
} }
scratch.alloc(mFile->size()); scratch.alloc(mFile->size());
mFile->read(scratch.getBytes(), 0, scratch.getSize()); mFile->read(scratch.data(), 0, scratch.size());
mCnmt.importBinary(scratch.getBytes(), scratch.getSize()); mCnmt.fromBytes(scratch.data(), scratch.size());
if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC)) if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC))
displayCmnt(); displayCmnt();

View file

@ -5,19 +5,19 @@ ElfSymbolParser::ElfSymbolParser()
mSymbolList.clear(); mSymbolList.clear();
} }
void ElfSymbolParser::operator=(const ElfSymbolParser& other)
{
mSymbolList = other.mSymbolList;
}
bool ElfSymbolParser::operator==(const ElfSymbolParser& other) const bool ElfSymbolParser::operator==(const ElfSymbolParser& other) const
{ {
return isEqual(other); return mSymbolList == other.mSymbolList;
} }
bool ElfSymbolParser::operator!=(const ElfSymbolParser& other) const bool ElfSymbolParser::operator!=(const ElfSymbolParser& other) const
{ {
return !isEqual(other); return !(*this == other);
}
void ElfSymbolParser::operator=(const ElfSymbolParser& other)
{
copyFrom(other);
} }
void ElfSymbolParser::parseData(const byte_t *dyn_sym, size_t dyn_sym_size, const byte_t *dyn_str, size_t dyn_str_size, bool is64Bit) void ElfSymbolParser::parseData(const byte_t *dyn_sym, size_t dyn_sym_size, const byte_t *dyn_str, size_t dyn_str_size, bool is64Bit)
@ -59,14 +59,4 @@ void ElfSymbolParser::parseData(const byte_t *dyn_sym, size_t dyn_sym_size, cons
const fnd::List<ElfSymbolParser::sElfSymbol>& ElfSymbolParser::getSymbolList() const const fnd::List<ElfSymbolParser::sElfSymbol>& ElfSymbolParser::getSymbolList() const
{ {
return mSymbolList; return mSymbolList;
} }
bool ElfSymbolParser::isEqual(const ElfSymbolParser& other) const
{
return mSymbolList == other.mSymbolList;
}
void ElfSymbolParser::copyFrom(const ElfSymbolParser& other)
{
mSymbolList = other.mSymbolList;
}

View file

@ -34,9 +34,9 @@ public:
ElfSymbolParser(); ElfSymbolParser();
void operator=(const ElfSymbolParser& other);
bool operator==(const ElfSymbolParser& other) const; bool operator==(const ElfSymbolParser& other) const;
bool operator!=(const ElfSymbolParser& other) const; bool operator!=(const ElfSymbolParser& other) const;
void operator=(const ElfSymbolParser& other);
void parseData(const byte_t *dyn_sym, size_t dyn_sym_size, const byte_t *dyn_str, size_t dyn_str_size, bool is64Bit); void parseData(const byte_t *dyn_sym, size_t dyn_sym_size, const byte_t *dyn_str, size_t dyn_str_size, bool is64Bit);
@ -45,7 +45,4 @@ private:
// data // data
fnd::List<sElfSymbol> mSymbolList; fnd::List<sElfSymbol> mSymbolList;
bool isEqual(const ElfSymbolParser& other) const;
void copyFrom(const ElfSymbolParser& other);
}; };

View file

@ -9,79 +9,47 @@ HashTreeMeta::HashTreeMeta() :
} }
HashTreeMeta::HashTreeMeta(const nx::HierarchicalIntegrityHeader& hdr) : HashTreeMeta::HashTreeMeta(const byte_t* data, size_t len, HashTreeType type) :
mLayerInfo(), HashTreeMeta()
mDataLayer(),
mMasterHashList(),
mDoAlignHashToBlock(false)
{ {
importHierarchicalIntergityHeader(hdr); importData(data, len, type);
}
HashTreeMeta::HashTreeMeta(const nx::HierarchicalSha256Header& hdr) :
mLayerInfo(),
mDataLayer(),
mMasterHashList(),
mDoAlignHashToBlock(false)
{
importHierarchicalSha256Header(hdr);
}
bool HashTreeMeta::operator==(const HashTreeMeta& other) const
{
return isEqual(other);
}
bool HashTreeMeta::operator!=(const HashTreeMeta& other) const
{
return !isEqual(other);
} }
void HashTreeMeta::operator=(const HashTreeMeta& other) void HashTreeMeta::operator=(const HashTreeMeta& other)
{ {
copyFrom(other); mLayerInfo = other.mLayerInfo;
mDataLayer = other.mDataLayer;
mMasterHashList = other.mMasterHashList;
mDoAlignHashToBlock = other.mDoAlignHashToBlock;
} }
void HashTreeMeta::importHierarchicalIntergityHeader(const nx::HierarchicalIntegrityHeader& hdr) bool HashTreeMeta::operator==(const HashTreeMeta& other) const
{ {
mDoAlignHashToBlock = true; return (mLayerInfo == other.mLayerInfo) \
for (size_t i = 0; i < hdr.getLayerInfo().getSize(); i++) && (mDataLayer == other.mDataLayer) \
{ && (mMasterHashList == other.mMasterHashList) \
sLayer layer; && (mDoAlignHashToBlock == other.mDoAlignHashToBlock);
layer.offset = hdr.getLayerInfo()[i].offset;
layer.size = hdr.getLayerInfo()[i].size;
layer.block_size = _BIT(hdr.getLayerInfo()[i].block_size);
if (i+1 == hdr.getLayerInfo().getSize())
{
mDataLayer = layer;
}
else
{
mLayerInfo.addElement(layer);
}
}
mMasterHashList = hdr.getMasterHashList();
} }
void HashTreeMeta::importHierarchicalSha256Header(const nx::HierarchicalSha256Header& hdr) bool HashTreeMeta::operator!=(const HashTreeMeta& other) const
{ {
mDoAlignHashToBlock = false; return !(*this == other);
for (size_t i = 0; i < hdr.getLayerInfo().getSize(); i++) }
void HashTreeMeta::importData(const byte_t* data, size_t len, HashTreeType type)
{
if (type == HASH_TYPE_INTEGRITY)
{ {
sLayer layer; nx::HierarchicalIntegrityHeader hdr;
layer.offset = hdr.getLayerInfo()[i].offset; hdr.fromBytes(data, len);
layer.size = hdr.getLayerInfo()[i].size; importHierarchicalIntergityHeader(hdr);
layer.block_size = hdr.getHashBlockSize(); }
if (i+1 == hdr.getLayerInfo().getSize()) else if (type == HASH_TYPE_SHA256)
{ {
mDataLayer = layer; nx::HierarchicalSha256Header hdr;
} hdr.fromBytes(data, len);
else importHierarchicalSha256Header(hdr);
{
mLayerInfo.addElement(layer);
}
} }
mMasterHashList.addElement(hdr.getMasterHash());
} }
const fnd::List<HashTreeMeta::sLayer>& HashTreeMeta::getHashLayerInfo() const const fnd::List<HashTreeMeta::sLayer>& HashTreeMeta::getHashLayerInfo() const
@ -124,18 +92,44 @@ void HashTreeMeta::setAlignHashToBlock(bool doAlign)
mDoAlignHashToBlock = doAlign; mDoAlignHashToBlock = doAlign;
} }
bool HashTreeMeta::isEqual(const HashTreeMeta& other) const void HashTreeMeta::importHierarchicalIntergityHeader(const nx::HierarchicalIntegrityHeader& hdr)
{ {
return (mLayerInfo == other.mLayerInfo) \ mDoAlignHashToBlock = true;
&& (mDataLayer == other.mDataLayer) \ for (size_t i = 0; i < hdr.getLayerInfo().size(); i++)
&& (mMasterHashList == other.mMasterHashList) \ {
&& (mDoAlignHashToBlock == other.mDoAlignHashToBlock); sLayer layer;
layer.offset = hdr.getLayerInfo()[i].offset;
layer.size = hdr.getLayerInfo()[i].size;
layer.block_size = _BIT(hdr.getLayerInfo()[i].block_size);
if (i+1 == hdr.getLayerInfo().size())
{
mDataLayer = layer;
}
else
{
mLayerInfo.addElement(layer);
}
}
mMasterHashList = hdr.getMasterHashList();
} }
void HashTreeMeta::copyFrom(const HashTreeMeta& other) void HashTreeMeta::importHierarchicalSha256Header(const nx::HierarchicalSha256Header& hdr)
{ {
mLayerInfo = other.mLayerInfo; mDoAlignHashToBlock = false;
mDataLayer = other.mDataLayer; for (size_t i = 0; i < hdr.getLayerInfo().size(); i++)
mMasterHashList = other.mMasterHashList; {
mDoAlignHashToBlock = other.mDoAlignHashToBlock; sLayer layer;
} layer.offset = hdr.getLayerInfo()[i].offset;
layer.size = hdr.getLayerInfo()[i].size;
layer.block_size = hdr.getHashBlockSize();
if (i+1 == hdr.getLayerInfo().size())
{
mDataLayer = layer;
}
else
{
mLayerInfo.addElement(layer);
}
}
mMasterHashList.addElement(hdr.getMasterHash());
}

View file

@ -5,6 +5,12 @@
class HashTreeMeta class HashTreeMeta
{ {
public: public:
enum HashTreeType
{
HASH_TYPE_INTEGRITY,
HASH_TYPE_SHA256
};
struct sLayer struct sLayer
{ {
size_t offset; size_t offset;
@ -30,15 +36,13 @@ public:
}; };
HashTreeMeta(); HashTreeMeta();
HashTreeMeta(const nx::HierarchicalIntegrityHeader& hdr); HashTreeMeta(const byte_t* data, size_t len, HashTreeType type);
HashTreeMeta(const nx::HierarchicalSha256Header& hdr);
void operator=(const HashTreeMeta& other);
bool operator==(const HashTreeMeta& other) const; bool operator==(const HashTreeMeta& other) const;
bool operator!=(const HashTreeMeta& other) const; bool operator!=(const HashTreeMeta& other) const;
void operator=(const HashTreeMeta& other);
void importHierarchicalIntergityHeader(const nx::HierarchicalIntegrityHeader& hdr); void importData(const byte_t* data, size_t len, HashTreeType type);
void importHierarchicalSha256Header(const nx::HierarchicalSha256Header& hdr);
const fnd::List<sLayer>& getHashLayerInfo() const; const fnd::List<sLayer>& getHashLayerInfo() const;
void setHashLayerInfo(const fnd::List<sLayer>& layer_info); void setHashLayerInfo(const fnd::List<sLayer>& layer_info);
@ -57,8 +61,8 @@ private:
fnd::List<sLayer> mLayerInfo; fnd::List<sLayer> mLayerInfo;
sLayer mDataLayer; sLayer mDataLayer;
fnd::List<crypto::sha::sSha256Hash> mMasterHashList; fnd::List<crypto::sha::sSha256Hash> mMasterHashList;
bool mDoAlignHashToBlock; bool mDoAlignHashToBlock;
bool isEqual(const HashTreeMeta& other) const; void importHierarchicalIntergityHeader(const nx::HierarchicalIntegrityHeader& hdr);
void copyFrom(const HashTreeMeta& other); void importHierarchicalSha256Header(const nx::HierarchicalSha256Header& hdr);
}; };

View file

@ -68,7 +68,7 @@ void HashTreeWrappedIFile::read(byte_t* out, size_t len)
readData(start_block + (i * mCacheBlockNum), block_read_len); readData(start_block + (i * mCacheBlockNum), block_read_len);
// export the section of data that is relevant // export the section of data that is relevant
memcpy(out + block_export_pos, mCache.getBytes() + block_export_offset, block_export_size); memcpy(out + block_export_pos, mCache.data() + block_export_offset, block_export_size);
// update export position // update export position
block_export_pos += block_export_size; block_export_pos += block_export_size;
@ -97,19 +97,19 @@ void HashTreeWrappedIFile::write(const byte_t* out, size_t offset, size_t len)
void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr) void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
{ {
crypto::sha::sSha256Hash hash; crypto::sha::sSha256Hash hash;
fnd::MemoryBlob cur, prev; fnd::Vec<byte_t> cur, prev;
mAlignHashCalcToBlock = hdr.getAlignHashToBlock(); mAlignHashCalcToBlock = hdr.getAlignHashToBlock();
// copy master hash into prev // copy master hash into prev
prev.alloc(sizeof(crypto::sha::sSha256Hash) * hdr.getMasterHashList().getSize()); prev.alloc(sizeof(crypto::sha::sSha256Hash) * hdr.getMasterHashList().size());
for (size_t i = 0; i < hdr.getMasterHashList().getSize(); i++) for (size_t i = 0; i < hdr.getMasterHashList().size(); i++)
{ {
((crypto::sha::sSha256Hash*)prev.getBytes())[i] = hdr.getMasterHashList()[i]; ((crypto::sha::sSha256Hash*)prev.data())[i] = hdr.getMasterHashList()[i];
} }
// check each hash layer // check each hash layer
for (size_t i = 0; i < hdr.getHashLayerInfo().getSize(); i++) for (size_t i = 0; i < hdr.getHashLayerInfo().size(); i++)
{ {
// get block size // get block size
const HashTreeMeta::sLayer& layer = hdr.getHashLayerInfo()[i]; const HashTreeMeta::sLayer& layer = hdr.getHashLayerInfo()[i];
@ -118,15 +118,15 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
cur.alloc(align(layer.size, layer.block_size)); cur.alloc(align(layer.size, layer.block_size));
// read layer // read layer
mFile->read(cur.getBytes(), layer.offset, layer.size); mFile->read(cur.data(), layer.offset, layer.size);
// validate blocks // validate blocks
size_t validate_size; size_t validate_size;
for (size_t j = 0; j < cur.getSize() / layer.block_size; j++) for (size_t j = 0; j < cur.size() / layer.block_size; j++)
{ {
validate_size = mAlignHashCalcToBlock? layer.block_size : MIN(layer.size - (j * layer.block_size), layer.block_size); validate_size = mAlignHashCalcToBlock? layer.block_size : _MIN(layer.size - (j * layer.block_size), layer.block_size);
crypto::sha::Sha256(cur.getBytes() + (j * layer.block_size), validate_size, hash.bytes); crypto::sha::Sha256(cur.data() + (j * layer.block_size), validate_size, hash.bytes);
if (hash.compare(prev.getBytes() + j * sizeof(crypto::sha::sSha256Hash)) == false) if (hash.compare(prev.data() + j * sizeof(crypto::sha::sSha256Hash)) == false)
{ {
mErrorSs << "Hash tree layer verification failed (layer: " << i << ", block: " << j << ")"; mErrorSs << "Hash tree layer verification failed (layer: " << i << ", block: " << j << ")";
throw fnd::Exception(kModuleName, mErrorSs.str()); throw fnd::Exception(kModuleName, mErrorSs.str());
@ -138,8 +138,8 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
} }
// save last layer as hash table for data layer // save last layer as hash table for data layer
crypto::sha::sSha256Hash* hash_list = (crypto::sha::sSha256Hash*)prev.getBytes(); crypto::sha::sSha256Hash* hash_list = (crypto::sha::sSha256Hash*)prev.data();
for (size_t i = 0; i < prev.getSize() / sizeof(crypto::sha::sSha256Hash); i++) for (size_t i = 0; i < prev.size() / sizeof(crypto::sha::sSha256Hash); i++)
{ {
mDataHashLayer.addElement(hash_list[i]); mDataHashLayer.addElement(hash_list[i]);
} }
@ -168,7 +168,7 @@ void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
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.getBytes(), 0, block_num * mDataBlockSize); 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()))
{ {
@ -180,7 +180,7 @@ void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
} }
// read // read
mData->read(mCache.getBytes(), block_offset * mDataBlockSize, read_len); mData->read(mCache.data(), block_offset * mDataBlockSize, read_len);
if (block_num > mCacheBlockNum) if (block_num > mCacheBlockNum)
{ {
@ -193,8 +193,8 @@ void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
size_t validate_size; size_t validate_size;
for (size_t i = 0; i < block_num; i++) for (size_t i = 0; i < block_num; i++)
{ {
validate_size = mAlignHashCalcToBlock? mDataBlockSize : MIN(read_len - (i * mDataBlockSize), mDataBlockSize); validate_size = mAlignHashCalcToBlock? mDataBlockSize : _MIN(read_len - (i * mDataBlockSize), mDataBlockSize);
crypto::sha::Sha256(mCache.getBytes() + (i * mDataBlockSize), validate_size, hash.bytes); crypto::sha::Sha256(mCache.data() + (i * mDataBlockSize), validate_size, hash.bytes);
if (hash != mDataHashLayer[block_offset + i]) if (hash != mDataHashLayer[block_offset + i])
{ {
mErrorSs << "Hash tree layer verification failed (layer: data, block: " << (block_offset + i) << " ( " << i << "/" << block_num-1 << " ), offset: 0x" << std::hex << ((block_offset + i) * mDataBlockSize) << ", size: 0x" << std::hex << validate_size <<")"; mErrorSs << "Hash tree layer verification failed (layer: data, block: " << (block_offset + i) << " ( " << i << "/" << block_num-1 << " ), offset: 0x" << std::hex << ((block_offset + i) * mDataBlockSize) << ", size: 0x" << std::hex << validate_size <<")";

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <sstream> #include <sstream>
#include <fnd/IFile.h> #include <fnd/IFile.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include "HashTreeMeta.h" #include "HashTreeMeta.h"
@ -33,7 +33,7 @@ private:
fnd::List<crypto::sha::sSha256Hash> mDataHashLayer; fnd::List<crypto::sha::sSha256Hash> mDataHashLayer;
bool mAlignHashCalcToBlock; bool mAlignHashCalcToBlock;
fnd::MemoryBlob mCache; fnd::Vec<byte_t> mCache;
size_t mCacheBlockNum; size_t mCacheBlockNum;
inline size_t getOffsetBlock(size_t offset) const { return offset / mDataBlockSize; } inline size_t getOffsetBlock(size_t offset) const { return offset / mDataBlockSize; }

View file

@ -441,7 +441,7 @@ NacpProcess::~NacpProcess()
void NacpProcess::process() void NacpProcess::process()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
if (mFile == nullptr) if (mFile == nullptr)
{ {
@ -449,9 +449,9 @@ void NacpProcess::process()
} }
scratch.alloc(mFile->size()); scratch.alloc(mFile->size());
mFile->read(scratch.getBytes(), 0, scratch.getSize()); mFile->read(scratch.data(), 0, scratch.size());
mNacp.importBinary(scratch.getBytes(), scratch.getSize()); mNacp.fromBytes(scratch.data(), scratch.size());
if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC)) if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC))
displayNacp(); displayNacp();
@ -485,7 +485,7 @@ void NacpProcess::displayNacp()
printf(" DisplayVersion: %s\n", mNacp.getDisplayVersion().c_str()); printf(" DisplayVersion: %s\n", mNacp.getDisplayVersion().c_str());
if (mNacp.getIsbn().empty() == false || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) if (mNacp.getIsbn().empty() == false || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
printf(" ISBN: %s\n", mNacp.getIsbn().c_str()); printf(" ISBN: %s\n", mNacp.getIsbn().c_str());
for (size_t i = 0; i < mNacp.getTitle().getSize(); i++) for (size_t i = 0; i < mNacp.getTitle().size(); i++)
{ {
printf(" %s Title:\n", getLanguageStr(mNacp.getTitle()[i].language)); printf(" %s Title:\n", getLanguageStr(mNacp.getTitle()[i].language));
printf(" Name: %s\n", mNacp.getTitle()[i].name.c_str()); printf(" Name: %s\n", mNacp.getTitle()[i].name.c_str());
@ -501,17 +501,17 @@ void NacpProcess::displayNacp()
printf(" Play Log:\n"); printf(" Play Log:\n");
printf(" PlayLogPolicy: %s\n", getPlayLogPolicyStr(mNacp.getPlayLogPolicy())); printf(" PlayLogPolicy: %s\n", getPlayLogPolicyStr(mNacp.getPlayLogPolicy()));
printf(" PlayLogQueryCapability: %s\n", getPlayLogQueryCapabilityStr(mNacp.getPlayLogQueryCapability())); printf(" PlayLogQueryCapability: %s\n", getPlayLogQueryCapabilityStr(mNacp.getPlayLogQueryCapability()));
if (mNacp.getPlayLogQueryableApplicationId().getSize() > 0) if (mNacp.getPlayLogQueryableApplicationId().size() > 0)
{ {
printf(" PlayLogQueryableApplicationId:\n"); printf(" PlayLogQueryableApplicationId:\n");
for (size_t i = 0; i < mNacp.getPlayLogQueryableApplicationId().getSize(); i++) for (size_t i = 0; i < mNacp.getPlayLogQueryableApplicationId().size(); i++)
{ {
printf(" 0x%016" PRIx64 "\n", mNacp.getPlayLogQueryableApplicationId()[i]); printf(" 0x%016" PRIx64 "\n", mNacp.getPlayLogQueryableApplicationId()[i]);
} }
} }
printf(" Parental Controls:\n"); printf(" Parental Controls:\n");
printf(" ParentalControlFlag: %s\n", getParentalControlFlagStr(mNacp.getParentalControlFlag())); printf(" ParentalControlFlag: %s\n", getParentalControlFlagStr(mNacp.getParentalControlFlag()));
for (size_t i = 0; i < mNacp.getRatingAge().getSize(); i++) for (size_t i = 0; i < mNacp.getRatingAge().size(); i++)
{ {
printf(" Age Restriction:\n"); printf(" Age Restriction:\n");
printf(" Agency: %s\n", getOrganisationStr(mNacp.getRatingAge()[i].organisation)); printf(" Agency: %s\n", getOrganisationStr(mNacp.getRatingAge()[i].organisation));
@ -524,11 +524,11 @@ void NacpProcess::displayNacp()
printf(" BcatPassphase: %s\n", mNacp.getBcatPassphase().c_str()); printf(" BcatPassphase: %s\n", mNacp.getBcatPassphase().c_str());
printf(" DeliveryCacheStorageSize: 0x%016" PRIx64 "\n", mNacp.getBcatDeliveryCacheStorageSize()); printf(" DeliveryCacheStorageSize: 0x%016" PRIx64 "\n", mNacp.getBcatDeliveryCacheStorageSize());
} }
if (mNacp.getLocalCommunicationId().getSize() > 0) if (mNacp.getLocalCommunicationId().size() > 0)
{ {
printf(" Local Area Communication:\n"); printf(" Local Area Communication:\n");
printf(" LocalCommunicationId:\n"); printf(" LocalCommunicationId:\n");
for (size_t i = 0; i < mNacp.getLocalCommunicationId().getSize(); i++) for (size_t i = 0; i < mNacp.getLocalCommunicationId().size(); i++)
{ {
printf(" 0x%016" PRIx64 "\n", mNacp.getLocalCommunicationId()[i]); printf(" 0x%016" PRIx64 "\n", mNacp.getLocalCommunicationId()[i]);
} }

View file

@ -253,8 +253,6 @@ NcaProcess::~NcaProcess()
void NcaProcess::process() void NcaProcess::process()
{ {
fnd::MemoryBlob scratch;
if (mFile == nullptr) if (mFile == nullptr)
{ {
throw fnd::Exception(kModuleName, "No file reader set."); throw fnd::Exception(kModuleName, "No file reader set.");
@ -270,7 +268,7 @@ void NcaProcess::process()
crypto::sha::Sha256((byte_t*)&mHdrBlock.header, sizeof(nx::sNcaHeader), mHdrHash.bytes); crypto::sha::Sha256((byte_t*)&mHdrBlock.header, sizeof(nx::sNcaHeader), mHdrHash.bytes);
// proccess main header // proccess main header
mHdr.importBinary((byte_t*)&mHdrBlock.header, sizeof(nx::sNcaHeader)); mHdr.fromBytes((byte_t*)&mHdrBlock.header, sizeof(nx::sNcaHeader));
// determine keys // determine keys
generateNcaBodyEncryptionKeys(); generateNcaBodyEncryptionKeys();
@ -423,7 +421,7 @@ void NcaProcess::generateNcaBodyEncryptionKeys()
{ {
crypto::aes::sAes128Key keak_aesctr_key = zero_aesctr_key; crypto::aes::sAes128Key keak_aesctr_key = zero_aesctr_key;
crypto::aes::sAesXts128Key keak_aesxts_key = zero_aesxts_key; crypto::aes::sAesXts128Key keak_aesxts_key = zero_aesxts_key;
for (size_t i = 0; i < mBodyKeys.keak_list.getSize(); i++) for (size_t i = 0; i < mBodyKeys.keak_list.size(); i++)
{ {
if (mBodyKeys.keak_list[i].index == nx::nca::KEY_AESCTR && mBodyKeys.keak_list[i].decrypted) if (mBodyKeys.keak_list[i].index == nx::nca::KEY_AESCTR && mBodyKeys.keak_list[i].decrypted)
{ {
@ -485,7 +483,7 @@ void NcaProcess::generatePartitionConfiguration()
{ {
std::stringstream error; std::stringstream error;
for (size_t i = 0; i < mHdr.getPartitions().getSize(); i++) for (size_t i = 0; i < mHdr.getPartitions().size(); i++)
{ {
// get reference to relevant structures // get reference to relevant structures
const nx::NcaHeader::sPartition& partition = mHdr.getPartitions()[i]; const nx::NcaHeader::sPartition& partition = mHdr.getPartitions()[i];
@ -523,10 +521,9 @@ void NcaProcess::generatePartitionConfiguration()
info.hash_type = (nx::nca::HashType)fs_header.hash_type; info.hash_type = (nx::nca::HashType)fs_header.hash_type;
info.enc_type = (nx::nca::EncryptionType)fs_header.encryption_type; info.enc_type = (nx::nca::EncryptionType)fs_header.encryption_type;
if (info.hash_type == nx::nca::HASH_HIERARCHICAL_SHA256) if (info.hash_type == nx::nca::HASH_HIERARCHICAL_SHA256)
info.hash_tree_meta.importHierarchicalSha256Header(nx::HierarchicalSha256Header(fs_header.hash_superblock, nx::nca::kFsHeaderHashSuperblockLen)); info.hash_tree_meta.importData(fs_header.hash_superblock, nx::nca::kFsHeaderHashSuperblockLen, HashTreeMeta::HASH_TYPE_SHA256);
else if (info.hash_type == nx::nca::HASH_HIERARCHICAL_INTERGRITY) else if (info.hash_type == nx::nca::HASH_HIERARCHICAL_INTERGRITY)
info.hash_tree_meta.importHierarchicalIntergityHeader(nx::HierarchicalIntegrityHeader(fs_header.hash_superblock, nx::nca::kFsHeaderHashSuperblockLen)); info.hash_tree_meta.importData(fs_header.hash_superblock, nx::nca::kFsHeaderHashSuperblockLen, HashTreeMeta::HASH_TYPE_INTEGRITY);
// create reader // create reader
try try
@ -614,7 +611,7 @@ void NcaProcess::validateNcaSignatures()
// open main.npdm // open main.npdm
if (exefs.getPfsHeader().getFileList().hasElement(kNpdmExefsPath) == true) if (exefs.getPfsHeader().getFileList().hasElement(kNpdmExefsPath) == true)
{ {
const nx::PfsHeader::sFile& file = exefs.getPfsHeader().getFileList()[exefs.getPfsHeader().getFileList().getIndexOf(kNpdmExefsPath)]; const nx::PfsHeader::sFile& file = exefs.getPfsHeader().getFileList().getElement(kNpdmExefsPath);
NpdmProcess npdm; NpdmProcess npdm;
npdm.setInputFile(new OffsetAdjustedIFile(mPartitions[nx::nca::PARTITION_CODE].reader, SHARED_IFILE, file.offset, file.size), OWN_IFILE); npdm.setInputFile(new OffsetAdjustedIFile(mPartitions[nx::nca::PARTITION_CODE].reader, SHARED_IFILE, file.offset, file.size), OWN_IFILE);
@ -631,8 +628,6 @@ void NcaProcess::validateNcaSignatures()
{ {
printf("[WARNING] NCA Header ACID Signature: FAIL (\"%s\" not present in ExeFs)\n", kNpdmExefsPath.c_str()); printf("[WARNING] NCA Header ACID Signature: FAIL (\"%s\" not present in ExeFs)\n", kNpdmExefsPath.c_str());
} }
} }
else else
{ {
@ -670,13 +665,13 @@ void NcaProcess::displayHeader()
} }
if (mBodyKeys.keak_list.getSize() > 0 && _HAS_BIT(mCliOutputMode, OUTPUT_KEY_DATA)) if (mBodyKeys.keak_list.size() > 0 && _HAS_BIT(mCliOutputMode, OUTPUT_KEY_DATA))
{ {
printf(" Key Area: \n"); printf(" Key Area: \n");
printf(" <--------------------------------------------------------------------------->\n"); printf(" <--------------------------------------------------------------------------->\n");
printf(" | IDX | ENCRYPTED KEY | DECRYPTED KEY |\n"); printf(" | IDX | ENCRYPTED KEY | DECRYPTED KEY |\n");
printf(" |-----|----------------------------------|----------------------------------|\n"); printf(" |-----|----------------------------------|----------------------------------|\n");
for (size_t i = 0; i < mBodyKeys.keak_list.getSize(); i++) for (size_t i = 0; i < mBodyKeys.keak_list.size(); i++)
{ {
printf(" | %3d | ", mBodyKeys.keak_list[i].index); printf(" | %3d | ", mBodyKeys.keak_list[i].index);
@ -698,7 +693,7 @@ void NcaProcess::displayHeader()
if (_HAS_BIT(mCliOutputMode, OUTPUT_LAYOUT)) if (_HAS_BIT(mCliOutputMode, OUTPUT_LAYOUT))
{ {
printf(" Partitions:\n"); printf(" Partitions:\n");
for (size_t i = 0; i < mHdr.getPartitions().getSize(); i++) for (size_t i = 0; i < mHdr.getPartitions().size(); i++)
{ {
sPartitionInfo& info = mPartitions[i]; sPartitionInfo& info = mPartitions[i];
@ -721,8 +716,8 @@ void NcaProcess::displayHeader()
printf(" HierarchicalIntegrity Header:\n"); printf(" HierarchicalIntegrity Header:\n");
//printf(" TypeId: 0x%x\n", hash_hdr.type_id.get()); //printf(" TypeId: 0x%x\n", hash_hdr.type_id.get());
//printf(" MasterHashSize: 0x%x\n", hash_hdr.master_hash_size.get()); //printf(" MasterHashSize: 0x%x\n", hash_hdr.master_hash_size.get());
//printf(" LayerNum: %d\n", hash_hdr.getLayerInfo().getSize()); //printf(" LayerNum: %d\n", hash_hdr.getLayerInfo().size());
for (size_t j = 0; j < hash_hdr.getHashLayerInfo().getSize(); j++) for (size_t j = 0; j < hash_hdr.getHashLayerInfo().size(); j++)
{ {
printf(" Hash Layer %d:\n", (int)j); printf(" Hash Layer %d:\n", (int)j);
printf(" Offset: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getHashLayerInfo()[j].offset); printf(" Offset: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getHashLayerInfo()[j].offset);
@ -734,7 +729,7 @@ void NcaProcess::displayHeader()
printf(" Offset: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getDataLayer().offset); printf(" Offset: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getDataLayer().offset);
printf(" Size: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getDataLayer().size); printf(" Size: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getDataLayer().size);
printf(" BlockSize: 0x%" PRIx32 "\n", (uint32_t)hash_hdr.getDataLayer().block_size); printf(" BlockSize: 0x%" PRIx32 "\n", (uint32_t)hash_hdr.getDataLayer().block_size);
for (size_t j = 0; j < hash_hdr.getMasterHashList().getSize(); j++) for (size_t j = 0; j < hash_hdr.getMasterHashList().size(); j++)
{ {
printf(" Master Hash %d: ", (int)j); printf(" Master Hash %d: ", (int)j);
fnd::SimpleTextOutput::hexDump(hash_hdr.getMasterHashList()[j].bytes, sizeof(crypto::sha::sSha256Hash)); fnd::SimpleTextOutput::hexDump(hash_hdr.getMasterHashList()[j].bytes, sizeof(crypto::sha::sSha256Hash));
@ -747,7 +742,7 @@ void NcaProcess::displayHeader()
printf(" Master Hash: "); printf(" Master Hash: ");
fnd::SimpleTextOutput::hexDump(hash_hdr.getMasterHashList()[0].bytes, sizeof(crypto::sha::sSha256Hash)); fnd::SimpleTextOutput::hexDump(hash_hdr.getMasterHashList()[0].bytes, sizeof(crypto::sha::sSha256Hash));
printf(" HashBlockSize: 0x%" PRIx32 "\n", (uint32_t)hash_hdr.getDataLayer().block_size); printf(" HashBlockSize: 0x%" PRIx32 "\n", (uint32_t)hash_hdr.getDataLayer().block_size);
//printf(" LayerNum: %d\n", hash_hdr.getLayerInfo().getSize()); //printf(" LayerNum: %d\n", hash_hdr.getLayerInfo().size());
printf(" Hash Layer:\n"); printf(" Hash Layer:\n");
printf(" Offset: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getHashLayerInfo()[0].offset); printf(" Offset: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getHashLayerInfo()[0].offset);
printf(" Size: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getHashLayerInfo()[0].size); printf(" Size: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getHashLayerInfo()[0].size);
@ -770,7 +765,7 @@ void NcaProcess::displayHeader()
void NcaProcess::processPartitions() void NcaProcess::processPartitions()
{ {
for (size_t i = 0; i < mHdr.getPartitions().getSize(); i++) for (size_t i = 0; i < mHdr.getPartitions().size(); i++)
{ {
size_t index = mHdr.getPartitions()[i].index; size_t index = mHdr.getPartitions()[i].index;
struct sPartitionInfo& partition = mPartitions[index]; struct sPartitionInfo& partition = mPartitions[index];

View file

@ -19,7 +19,7 @@ NpdmProcess::~NpdmProcess()
void NpdmProcess::process() void NpdmProcess::process()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
if (mFile == nullptr) if (mFile == nullptr)
{ {
@ -27,9 +27,9 @@ void NpdmProcess::process()
} }
scratch.alloc(mFile->size()); scratch.alloc(mFile->size());
mFile->read(scratch.getBytes(), 0, scratch.getSize()); mFile->read(scratch.data(), 0, scratch.size());
mNpdm.importBinary(scratch.getBytes(), scratch.getSize()); mNpdm.fromBytes(scratch.data(), scratch.size());
if (mVerify) if (mVerify)
{ {
@ -322,10 +322,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
printf("[WARNING] ACI/FAC FormatVersion: FAIL (%d != %d (expected))\n", aci.getFac().getFormatVersion(),acid.getFac().getFormatVersion()); printf("[WARNING] ACI/FAC FormatVersion: FAIL (%d != %d (expected))\n", aci.getFac().getFormatVersion(),acid.getFac().getFormatVersion());
} }
for (size_t i = 0; i < aci.getFac().getFsaRightsList().getSize(); i++) for (size_t i = 0; i < aci.getFac().getFsaRightsList().size(); i++)
{ {
bool fsaRightFound = false; bool fsaRightFound = false;
for (size_t j = 0; j < acid.getFac().getFsaRightsList().getSize() && fsaRightFound == false; j++) for (size_t j = 0; j < acid.getFac().getFsaRightsList().size() && fsaRightFound == false; j++)
{ {
if (aci.getFac().getFsaRightsList()[i] == acid.getFac().getFsaRightsList()[j]) if (aci.getFac().getFsaRightsList()[i] == acid.getFac().getFsaRightsList()[j])
fsaRightFound = true; fsaRightFound = true;
@ -338,10 +338,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
} }
} }
for (size_t i = 0; i < aci.getFac().getContentOwnerIdList().getSize(); i++) for (size_t i = 0; i < aci.getFac().getContentOwnerIdList().size(); i++)
{ {
bool rightFound = false; bool rightFound = false;
for (size_t j = 0; j < acid.getFac().getContentOwnerIdList().getSize() && rightFound == false; j++) for (size_t j = 0; j < acid.getFac().getContentOwnerIdList().size() && rightFound == false; j++)
{ {
if (aci.getFac().getContentOwnerIdList()[i] == acid.getFac().getContentOwnerIdList()[j]) if (aci.getFac().getContentOwnerIdList()[i] == acid.getFac().getContentOwnerIdList()[j])
rightFound = true; rightFound = true;
@ -354,10 +354,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
} }
} }
for (size_t i = 0; i < aci.getFac().getSaveDataOwnerIdList().getSize(); i++) for (size_t i = 0; i < aci.getFac().getSaveDataOwnerIdList().size(); i++)
{ {
bool rightFound = false; bool rightFound = false;
for (size_t j = 0; j < acid.getFac().getSaveDataOwnerIdList().getSize() && rightFound == false; j++) for (size_t j = 0; j < acid.getFac().getSaveDataOwnerIdList().size() && rightFound == false; j++)
{ {
if (aci.getFac().getSaveDataOwnerIdList()[i] == acid.getFac().getSaveDataOwnerIdList()[j]) if (aci.getFac().getSaveDataOwnerIdList()[i] == acid.getFac().getSaveDataOwnerIdList()[j])
rightFound = true; rightFound = true;
@ -371,10 +371,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
} }
// check SAC // check SAC
for (size_t i = 0; i < aci.getSac().getServiceList().getSize(); i++) for (size_t i = 0; i < aci.getSac().getServiceList().size(); i++)
{ {
bool rightFound = false; bool rightFound = false;
for (size_t j = 0; j < acid.getSac().getServiceList().getSize() && rightFound == false; j++) for (size_t j = 0; j < acid.getSac().getServiceList().size() && rightFound == false; j++)
{ {
if (aci.getSac().getServiceList()[i] == acid.getSac().getServiceList()[j]) if (aci.getSac().getServiceList()[i] == acid.getSac().getServiceList()[j])
rightFound = true; rightFound = true;
@ -406,10 +406,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
printf("[WARNING] ACI/KC ThreadInfo/MinPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinPriority()); printf("[WARNING] ACI/KC ThreadInfo/MinPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinPriority());
} }
// check system calls // check system calls
for (size_t i = 0; i < aci.getKc().getSystemCalls().getSystemCalls().getSize(); i++) for (size_t i = 0; i < aci.getKc().getSystemCalls().getSystemCalls().size(); i++)
{ {
bool rightFound = false; bool rightFound = false;
for (size_t j = 0; j < acid.getKc().getSystemCalls().getSystemCalls().getSize() && rightFound == false; j++) for (size_t j = 0; j < acid.getKc().getSystemCalls().getSystemCalls().size() && rightFound == false; j++)
{ {
if (aci.getKc().getSystemCalls().getSystemCalls()[i] == acid.getKc().getSystemCalls().getSystemCalls()[j]) if (aci.getKc().getSystemCalls().getSystemCalls()[i] == acid.getKc().getSystemCalls().getSystemCalls()[j])
rightFound = true; rightFound = true;
@ -422,10 +422,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
} }
} }
// check memory maps // check memory maps
for (size_t i = 0; i < aci.getKc().getMemoryMaps().getMemoryMaps().getSize(); i++) for (size_t i = 0; i < aci.getKc().getMemoryMaps().getMemoryMaps().size(); i++)
{ {
bool rightFound = false; bool rightFound = false;
for (size_t j = 0; j < acid.getKc().getMemoryMaps().getMemoryMaps().getSize() && rightFound == false; j++) for (size_t j = 0; j < acid.getKc().getMemoryMaps().getMemoryMaps().size() && rightFound == false; j++)
{ {
if (aci.getKc().getMemoryMaps().getMemoryMaps()[i] == acid.getKc().getMemoryMaps().getMemoryMaps()[j]) if (aci.getKc().getMemoryMaps().getMemoryMaps()[i] == acid.getKc().getMemoryMaps().getMemoryMaps()[j])
rightFound = true; rightFound = true;
@ -438,10 +438,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
printf("[WARNING] ACI/KC MemoryMap: FAIL (0x%016" PRIx64 " - 0x%016" PRIx64 " (perm=%s) (type=%s) not permitted)\n", (uint64_t)map.addr << 12, ((uint64_t)(map.addr + map.size) << 12) - 1, kMemMapPerm[map.perm].c_str(), kMemMapType[map.type].c_str()); printf("[WARNING] ACI/KC MemoryMap: FAIL (0x%016" PRIx64 " - 0x%016" PRIx64 " (perm=%s) (type=%s) not permitted)\n", (uint64_t)map.addr << 12, ((uint64_t)(map.addr + map.size) << 12) - 1, kMemMapPerm[map.perm].c_str(), kMemMapType[map.type].c_str());
} }
} }
for (size_t i = 0; i < aci.getKc().getMemoryMaps().getIoMemoryMaps().getSize(); i++) for (size_t i = 0; i < aci.getKc().getMemoryMaps().getIoMemoryMaps().size(); i++)
{ {
bool rightFound = false; bool rightFound = false;
for (size_t j = 0; j < acid.getKc().getMemoryMaps().getIoMemoryMaps().getSize() && rightFound == false; j++) for (size_t j = 0; j < acid.getKc().getMemoryMaps().getIoMemoryMaps().size() && rightFound == false; j++)
{ {
if (aci.getKc().getMemoryMaps().getIoMemoryMaps()[i] == acid.getKc().getMemoryMaps().getIoMemoryMaps()[j]) if (aci.getKc().getMemoryMaps().getIoMemoryMaps()[i] == acid.getKc().getMemoryMaps().getIoMemoryMaps()[j])
rightFound = true; rightFound = true;
@ -455,10 +455,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
} }
} }
// check interupts // check interupts
for (size_t i = 0; i < aci.getKc().getInterupts().getInteruptList().getSize(); i++) for (size_t i = 0; i < aci.getKc().getInterupts().getInteruptList().size(); i++)
{ {
bool rightFound = false; bool rightFound = false;
for (size_t j = 0; j < acid.getKc().getInterupts().getInteruptList().getSize() && rightFound == false; j++) for (size_t j = 0; j < acid.getKc().getInterupts().getInteruptList().size() && rightFound == false; j++)
{ {
if (aci.getKc().getInterupts().getInteruptList()[i] == acid.getKc().getInterupts().getInteruptList()[j]) if (aci.getKc().getInterupts().getInteruptList()[i] == acid.getKc().getInterupts().getInteruptList()[j])
rightFound = true; rightFound = true;
@ -487,10 +487,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
printf("[WARNING] ACI/KC HandleTableSize: FAIL (0x%x too large)\n", aci.getKc().getHandleTableSize().getHandleTableSize()); printf("[WARNING] ACI/KC HandleTableSize: FAIL (0x%x too large)\n", aci.getKc().getHandleTableSize().getHandleTableSize());
} }
// check misc flags // check misc flags
for (size_t i = 0; i < aci.getKc().getMiscFlags().getFlagList().getSize(); i++) for (size_t i = 0; i < aci.getKc().getMiscFlags().getFlagList().size(); i++)
{ {
bool rightFound = false; bool rightFound = false;
for (size_t j = 0; j < acid.getKc().getMiscFlags().getFlagList().getSize() && rightFound == false; j++) for (size_t j = 0; j < acid.getKc().getMiscFlags().getFlagList().size() && rightFound == false; j++)
{ {
if (aci.getKc().getMiscFlags().getFlagList()[i] == acid.getKc().getMiscFlags().getFlagList()[j]) if (aci.getKc().getMiscFlags().getFlagList()[i] == acid.getKc().getMiscFlags().getFlagList()[j])
rightFound = true; rightFound = true;
@ -549,10 +549,10 @@ void NpdmProcess::displayFac(const nx::FacBinary& fac)
printf("[FS Access Control]\n"); printf("[FS Access Control]\n");
printf(" Format Version: %d\n", fac.getFormatVersion()); printf(" Format Version: %d\n", fac.getFormatVersion());
if (fac.getFsaRightsList().getSize()) if (fac.getFsaRightsList().size())
{ {
printf(" FS Rights:\n"); printf(" FS Rights:\n");
for (size_t i = 0; i < fac.getFsaRightsList().getSize(); i++) for (size_t i = 0; i < fac.getFsaRightsList().size(); i++)
{ {
if (i % 10 == 0) if (i % 10 == 0)
{ {
@ -566,18 +566,18 @@ void NpdmProcess::displayFac(const nx::FacBinary& fac)
printf(" FS Rights: NONE\n"); printf(" FS Rights: NONE\n");
} }
if (fac.getContentOwnerIdList().getSize()) if (fac.getContentOwnerIdList().size())
{ {
printf(" Content Owner IDs:\n"); printf(" Content Owner IDs:\n");
for (size_t i = 0; i < fac.getContentOwnerIdList().getSize(); i++) for (size_t i = 0; i < fac.getContentOwnerIdList().size(); i++)
{ {
printf(" 0x%08x\n", fac.getContentOwnerIdList()[i]); printf(" 0x%08x\n", fac.getContentOwnerIdList()[i]);
} }
} }
if (fac.getSaveDataOwnerIdList().getSize()) if (fac.getSaveDataOwnerIdList().size())
{ {
printf(" Save Data Owner IDs:\n"); printf(" Save Data Owner IDs:\n");
for (size_t i = 0; i < fac.getSaveDataOwnerIdList().getSize(); i++) for (size_t i = 0; i < fac.getSaveDataOwnerIdList().size(); i++)
{ {
printf(" 0x%08x\n", fac.getSaveDataOwnerIdList()[i]); printf(" 0x%08x\n", fac.getSaveDataOwnerIdList()[i]);
} }
@ -589,7 +589,7 @@ void NpdmProcess::displaySac(const nx::SacBinary& sac)
{ {
printf("[Service Access Control]\n"); printf("[Service Access Control]\n");
printf(" Service List:\n"); printf(" Service List:\n");
for (size_t i = 0; i < sac.getServiceList().getSize(); i++) for (size_t i = 0; i < sac.getServiceList().size(); i++)
{ {
if (i % 10 == 0) if (i % 10 == 0)
{ {
@ -618,7 +618,7 @@ void NpdmProcess::displayKernelCap(const nx::KcBinary& kern)
printf(" SystemCalls:"); printf(" SystemCalls:");
printf("\n "); printf("\n ");
size_t lineLen = 0; size_t lineLen = 0;
for (size_t i = 0; i < syscalls.getSize(); i++) for (size_t i = 0; i < syscalls.size(); i++)
{ {
if (lineLen > 60) if (lineLen > 60)
{ {
@ -635,12 +635,12 @@ void NpdmProcess::displayKernelCap(const nx::KcBinary& kern)
fnd::List<nx::MemoryMappingHandler::sMemoryMapping> ioMaps = kern.getMemoryMaps().getIoMemoryMaps(); fnd::List<nx::MemoryMappingHandler::sMemoryMapping> ioMaps = kern.getMemoryMaps().getIoMemoryMaps();
printf(" MemoryMaps:\n"); printf(" MemoryMaps:\n");
for (size_t i = 0; i < maps.getSize(); i++) for (size_t i = 0; i < maps.size(); i++)
{ {
printf(" 0x%016" PRIx64 " - 0x%016" PRIx64 " (perm=%s) (type=%s)\n", (uint64_t)maps[i].addr << 12, ((uint64_t)(maps[i].addr + maps[i].size) << 12) - 1, kMemMapPerm[maps[i].perm].c_str(), kMemMapType[maps[i].type].c_str()); printf(" 0x%016" PRIx64 " - 0x%016" PRIx64 " (perm=%s) (type=%s)\n", (uint64_t)maps[i].addr << 12, ((uint64_t)(maps[i].addr + maps[i].size) << 12) - 1, kMemMapPerm[maps[i].perm].c_str(), kMemMapType[maps[i].type].c_str());
} }
//printf(" IoMaps:\n"); //printf(" IoMaps:\n");
for (size_t i = 0; i < ioMaps.getSize(); i++) for (size_t i = 0; i < ioMaps.size(); i++)
{ {
printf(" 0x%016" PRIx64 " - 0x%016" PRIx64 " (perm=%s) (type=%s)\n", (uint64_t)ioMaps[i].addr << 12, ((uint64_t)(ioMaps[i].addr + ioMaps[i].size) << 12) - 1, kMemMapPerm[ioMaps[i].perm].c_str(), kMemMapType[ioMaps[i].type].c_str()); printf(" 0x%016" PRIx64 " - 0x%016" PRIx64 " (perm=%s) (type=%s)\n", (uint64_t)ioMaps[i].addr << 12, ((uint64_t)(ioMaps[i].addr + ioMaps[i].size) << 12) - 1, kMemMapPerm[ioMaps[i].perm].c_str(), kMemMapType[ioMaps[i].type].c_str());
} }
@ -649,7 +649,7 @@ void NpdmProcess::displayKernelCap(const nx::KcBinary& kern)
{ {
fnd::List<uint16_t> interupts = kern.getInterupts().getInteruptList(); fnd::List<uint16_t> interupts = kern.getInterupts().getInteruptList();
printf(" Interupts Flags:\n"); printf(" Interupts Flags:\n");
for (uint32_t i = 0; i < interupts.getSize(); i++) for (uint32_t i = 0; i < interupts.size(); i++)
{ {
if (i % 10 == 0) if (i % 10 == 0)
{ {
@ -675,7 +675,7 @@ void NpdmProcess::displayKernelCap(const nx::KcBinary& kern)
fnd::List<nx::MiscFlagsHandler::Flags> flagList = kern.getMiscFlags().getFlagList(); fnd::List<nx::MiscFlagsHandler::Flags> flagList = kern.getMiscFlags().getFlagList();
printf(" Misc Flags:\n"); printf(" Misc Flags:\n");
for (uint32_t i = 0; i < flagList.getSize(); i++) for (uint32_t i = 0; i < flagList.size(); i++)
{ {
if (i % 10 == 0) if (i % 10 == 0)
{ {

View file

@ -1,5 +1,5 @@
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include <compress/lz4.h> #include <compress/lz4.h>
#include <nx/nro-hb.h> #include <nx/nro-hb.h>
#include "OffsetAdjustedIFile.h" #include "OffsetAdjustedIFile.h"
@ -93,19 +93,19 @@ void NroProcess::setAssetRomfsExtractPath(const std::string& path)
void NroProcess::importHeader() void NroProcess::importHeader()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
if (mFile->size() < sizeof(nx::sNroHeader)) if (mFile->size() < sizeof(nx::sNroHeader))
{ {
throw fnd::Exception(kModuleName, "Corrupt NRO: file too small"); throw fnd::Exception(kModuleName, "Corrupt NRO: file too small");
} }
scratch.alloc(sizeof(nx::sNroHeader)); scratch.alloc(sizeof(nx::sNroHeader));
mFile->read(scratch.getBytes(), 0, scratch.getSize()); mFile->read(scratch.data(), 0, scratch.size());
mHdr.importBinary(scratch.getBytes(), scratch.getSize()); mHdr.fromBytes(scratch.data(), scratch.size());
// setup homebrew extension // setup homebrew extension
nx::sNroHeader* raw_hdr = (nx::sNroHeader*)scratch.getBytes(); nx::sNroHeader* raw_hdr = (nx::sNroHeader*)scratch.data();
if (((le_uint64_t*)raw_hdr->reserved_0)->get() == nx::nro::kNroHomebrewSig && mFile->size() > mHdr.getNroSize()) if (((le_uint64_t*)raw_hdr->reserved_0)->get() == nx::nro::kNroHomebrewSig && mFile->size() > mHdr.getNroSize())
{ {
mIsHomebrewNro = true; mIsHomebrewNro = true;
@ -120,11 +120,11 @@ void NroProcess::importHeader()
void NroProcess::importCodeSegments() void NroProcess::importCodeSegments()
{ {
mTextBlob.alloc(mHdr.getTextInfo().size); mTextBlob.alloc(mHdr.getTextInfo().size);
mFile->read(mTextBlob.getBytes(), mHdr.getTextInfo().memory_offset, mTextBlob.getSize()); mFile->read(mTextBlob.data(), mHdr.getTextInfo().memory_offset, mTextBlob.size());
mRoBlob.alloc(mHdr.getRoInfo().size); mRoBlob.alloc(mHdr.getRoInfo().size);
mFile->read(mRoBlob.getBytes(), mHdr.getRoInfo().memory_offset, mRoBlob.getSize()); mFile->read(mRoBlob.data(), mHdr.getRoInfo().memory_offset, mRoBlob.size());
mDataBlob.alloc(mHdr.getDataInfo().size); mDataBlob.alloc(mHdr.getDataInfo().size);
mFile->read(mDataBlob.getBytes(), mHdr.getDataInfo().memory_offset, mDataBlob.getSize()); mFile->read(mDataBlob.data(), mHdr.getDataInfo().memory_offset, mDataBlob.size());
} }
void NroProcess::displayHeader() void NroProcess::displayHeader()
@ -168,7 +168,7 @@ void NroProcess::displayHeader()
void NroProcess::processRoMeta() void NroProcess::processRoMeta()
{ {
if (mRoBlob.getSize()) if (mRoBlob.size())
{ {
// setup ro metadata // setup ro metadata
mRoMeta.setApiInfo(mHdr.getRoEmbeddedInfo().memory_offset, mHdr.getRoEmbeddedInfo().size); mRoMeta.setApiInfo(mHdr.getRoEmbeddedInfo().memory_offset, mHdr.getRoEmbeddedInfo().size);

View file

@ -41,7 +41,7 @@ private:
bool mVerify; bool mVerify;
nx::NroHeader mHdr; nx::NroHeader mHdr;
fnd::MemoryBlob mTextBlob, mRoBlob, mDataBlob; fnd::Vec<byte_t> mTextBlob, mRoBlob, mDataBlob;
RoMetadataProcess mRoMeta; RoMetadataProcess mRoMeta;
bool mIsHomebrewNro; bool mIsHomebrewNro;
AssetProcess mAssetProc; AssetProcess mAssetProc;

View file

@ -1,5 +1,5 @@
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include <compress/lz4.h> #include <compress/lz4.h>
#include "OffsetAdjustedIFile.h" #include "OffsetAdjustedIFile.h"
#include "NsoProcess.h" #include "NsoProcess.h"
@ -68,21 +68,21 @@ void NsoProcess::setListSymbols(bool listSymbols)
void NsoProcess::importHeader() void NsoProcess::importHeader()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
if (mFile->size() < sizeof(nx::sNsoHeader)) if (mFile->size() < sizeof(nx::sNsoHeader))
{ {
throw fnd::Exception(kModuleName, "Corrupt NSO: file too small"); throw fnd::Exception(kModuleName, "Corrupt NSO: file too small");
} }
scratch.alloc(sizeof(nx::sNsoHeader)); scratch.alloc(sizeof(nx::sNsoHeader));
mFile->read(scratch.getBytes(), 0, scratch.getSize()); mFile->read(scratch.data(), 0, scratch.size());
mHdr.importBinary(scratch.getBytes(), scratch.getSize()); mHdr.fromBytes(scratch.data(), scratch.size());
} }
void NsoProcess::importCodeSegments() void NsoProcess::importCodeSegments()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
uint32_t decompressed_len; uint32_t decompressed_len;
crypto::sha::sSha256Hash calc_hash; crypto::sha::sSha256Hash calc_hash;
@ -90,10 +90,10 @@ void NsoProcess::importCodeSegments()
if (mHdr.getTextSegmentInfo().is_compressed) if (mHdr.getTextSegmentInfo().is_compressed)
{ {
scratch.alloc(mHdr.getTextSegmentInfo().file_layout.size); scratch.alloc(mHdr.getTextSegmentInfo().file_layout.size);
mFile->read(scratch.getBytes(), mHdr.getTextSegmentInfo().file_layout.offset, scratch.getSize()); mFile->read(scratch.data(), mHdr.getTextSegmentInfo().file_layout.offset, scratch.size());
mTextBlob.alloc(mHdr.getTextSegmentInfo().memory_layout.size); mTextBlob.alloc(mHdr.getTextSegmentInfo().memory_layout.size);
compress::lz4::decompressData(scratch.getBytes(), (uint32_t)scratch.getSize(), mTextBlob.getBytes(), (uint32_t)mTextBlob.getSize(), decompressed_len); compress::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mTextBlob.data(), (uint32_t)mTextBlob.size(), decompressed_len);
if (decompressed_len != mTextBlob.getSize()) if (decompressed_len != mTextBlob.size())
{ {
throw fnd::Exception(kModuleName, "NSO text segment failed to decompress"); throw fnd::Exception(kModuleName, "NSO text segment failed to decompress");
} }
@ -101,11 +101,11 @@ void NsoProcess::importCodeSegments()
else else
{ {
mTextBlob.alloc(mHdr.getTextSegmentInfo().file_layout.size); mTextBlob.alloc(mHdr.getTextSegmentInfo().file_layout.size);
mFile->read(mTextBlob.getBytes(), mHdr.getTextSegmentInfo().file_layout.offset, mTextBlob.getSize()); mFile->read(mTextBlob.data(), mHdr.getTextSegmentInfo().file_layout.offset, mTextBlob.size());
} }
if (mHdr.getTextSegmentInfo().is_hashed) if (mHdr.getTextSegmentInfo().is_hashed)
{ {
crypto::sha::Sha256(mTextBlob.getBytes(), mTextBlob.getSize(), calc_hash.bytes); crypto::sha::Sha256(mTextBlob.data(), mTextBlob.size(), calc_hash.bytes);
if (calc_hash != mHdr.getTextSegmentInfo().hash) if (calc_hash != mHdr.getTextSegmentInfo().hash)
{ {
throw fnd::Exception(kModuleName, "NSO text segment failed SHA256 verification"); throw fnd::Exception(kModuleName, "NSO text segment failed SHA256 verification");
@ -116,10 +116,10 @@ void NsoProcess::importCodeSegments()
if (mHdr.getRoSegmentInfo().is_compressed) if (mHdr.getRoSegmentInfo().is_compressed)
{ {
scratch.alloc(mHdr.getRoSegmentInfo().file_layout.size); scratch.alloc(mHdr.getRoSegmentInfo().file_layout.size);
mFile->read(scratch.getBytes(), mHdr.getRoSegmentInfo().file_layout.offset, scratch.getSize()); mFile->read(scratch.data(), mHdr.getRoSegmentInfo().file_layout.offset, scratch.size());
mRoBlob.alloc(mHdr.getRoSegmentInfo().memory_layout.size); mRoBlob.alloc(mHdr.getRoSegmentInfo().memory_layout.size);
compress::lz4::decompressData(scratch.getBytes(), (uint32_t)scratch.getSize(), mRoBlob.getBytes(), (uint32_t)mRoBlob.getSize(), decompressed_len); compress::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mRoBlob.data(), (uint32_t)mRoBlob.size(), decompressed_len);
if (decompressed_len != mRoBlob.getSize()) if (decompressed_len != mRoBlob.size())
{ {
throw fnd::Exception(kModuleName, "NSO ro segment failed to decompress"); throw fnd::Exception(kModuleName, "NSO ro segment failed to decompress");
} }
@ -127,11 +127,11 @@ void NsoProcess::importCodeSegments()
else else
{ {
mRoBlob.alloc(mHdr.getRoSegmentInfo().file_layout.size); mRoBlob.alloc(mHdr.getRoSegmentInfo().file_layout.size);
mFile->read(mRoBlob.getBytes(), mHdr.getRoSegmentInfo().file_layout.offset, mRoBlob.getSize()); mFile->read(mRoBlob.data(), mHdr.getRoSegmentInfo().file_layout.offset, mRoBlob.size());
} }
if (mHdr.getRoSegmentInfo().is_hashed) if (mHdr.getRoSegmentInfo().is_hashed)
{ {
crypto::sha::Sha256(mRoBlob.getBytes(), mRoBlob.getSize(), calc_hash.bytes); crypto::sha::Sha256(mRoBlob.data(), mRoBlob.size(), calc_hash.bytes);
if (calc_hash != mHdr.getRoSegmentInfo().hash) if (calc_hash != mHdr.getRoSegmentInfo().hash)
{ {
throw fnd::Exception(kModuleName, "NSO ro segment failed SHA256 verification"); throw fnd::Exception(kModuleName, "NSO ro segment failed SHA256 verification");
@ -142,10 +142,10 @@ void NsoProcess::importCodeSegments()
if (mHdr.getDataSegmentInfo().is_compressed) if (mHdr.getDataSegmentInfo().is_compressed)
{ {
scratch.alloc(mHdr.getDataSegmentInfo().file_layout.size); scratch.alloc(mHdr.getDataSegmentInfo().file_layout.size);
mFile->read(scratch.getBytes(), mHdr.getDataSegmentInfo().file_layout.offset, scratch.getSize()); mFile->read(scratch.data(), mHdr.getDataSegmentInfo().file_layout.offset, scratch.size());
mDataBlob.alloc(mHdr.getDataSegmentInfo().memory_layout.size); mDataBlob.alloc(mHdr.getDataSegmentInfo().memory_layout.size);
compress::lz4::decompressData(scratch.getBytes(), (uint32_t)scratch.getSize(), mDataBlob.getBytes(), (uint32_t)mDataBlob.getSize(), decompressed_len); compress::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mDataBlob.data(), (uint32_t)mDataBlob.size(), decompressed_len);
if (decompressed_len != mDataBlob.getSize()) if (decompressed_len != mDataBlob.size())
{ {
throw fnd::Exception(kModuleName, "NSO data segment failed to decompress"); throw fnd::Exception(kModuleName, "NSO data segment failed to decompress");
} }
@ -153,11 +153,11 @@ void NsoProcess::importCodeSegments()
else else
{ {
mDataBlob.alloc(mHdr.getDataSegmentInfo().file_layout.size); mDataBlob.alloc(mHdr.getDataSegmentInfo().file_layout.size);
mFile->read(mDataBlob.getBytes(), mHdr.getDataSegmentInfo().file_layout.offset, mDataBlob.getSize()); mFile->read(mDataBlob.data(), mHdr.getDataSegmentInfo().file_layout.offset, mDataBlob.size());
} }
if (mHdr.getDataSegmentInfo().is_hashed) if (mHdr.getDataSegmentInfo().is_hashed)
{ {
crypto::sha::Sha256(mDataBlob.getBytes(), mDataBlob.getSize(), calc_hash.bytes); crypto::sha::Sha256(mDataBlob.data(), mDataBlob.size(), calc_hash.bytes);
if (calc_hash != mHdr.getDataSegmentInfo().hash) if (calc_hash != mHdr.getDataSegmentInfo().hash)
{ {
throw fnd::Exception(kModuleName, "NSO data segment failed SHA256 verification"); throw fnd::Exception(kModuleName, "NSO data segment failed SHA256 verification");
@ -237,7 +237,7 @@ void NsoProcess::displayNsoHeader()
void NsoProcess::processRoMeta() void NsoProcess::processRoMeta()
{ {
if (mRoBlob.getSize()) if (mRoBlob.size())
{ {
// setup ro metadata // setup ro metadata
mRoMeta.setApiInfo(mHdr.getRoEmbeddedInfo().offset, mHdr.getRoEmbeddedInfo().size); mRoMeta.setApiInfo(mHdr.getRoEmbeddedInfo().offset, mHdr.getRoEmbeddedInfo().size);

View file

@ -37,7 +37,7 @@ private:
bool mListSymbols; bool mListSymbols;
nx::NsoHeader mHdr; nx::NsoHeader mHdr;
fnd::MemoryBlob mTextBlob, mRoBlob, mDataBlob; fnd::Vec<byte_t> mTextBlob, mRoBlob, mDataBlob;
RoMetadataProcess mRoMeta; RoMetadataProcess mRoMeta;
void importHeader(); void importHeader();

View file

@ -25,7 +25,7 @@ size_t OffsetAdjustedIFile::size()
void OffsetAdjustedIFile::seek(size_t offset) void OffsetAdjustedIFile::seek(size_t offset)
{ {
mCurrentOffset = MIN(offset, mSize); mCurrentOffset = _MIN(offset, mSize);
} }
void OffsetAdjustedIFile::read(byte_t* out, size_t len) void OffsetAdjustedIFile::read(byte_t* out, size_t len)

View file

@ -25,7 +25,7 @@ PfsProcess::~PfsProcess()
void PfsProcess::process() void PfsProcess::process()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
if (mFile == nullptr) if (mFile == nullptr)
{ {
@ -34,17 +34,17 @@ void PfsProcess::process()
// open minimum header to get full header size // open minimum header to get full header size
scratch.alloc(sizeof(nx::sPfsHeader)); scratch.alloc(sizeof(nx::sPfsHeader));
mFile->read(scratch.getBytes(), 0, scratch.getSize()); mFile->read(scratch.data(), 0, scratch.size());
if (validateHeaderMagic(((nx::sPfsHeader*)scratch.getBytes())) == false) if (validateHeaderMagic(((nx::sPfsHeader*)scratch.data())) == false)
{ {
throw fnd::Exception(kModuleName, "Corrupt Header"); throw fnd::Exception(kModuleName, "Corrupt Header");
} }
size_t pfsHeaderSize = determineHeaderSize(((nx::sPfsHeader*)scratch.getBytes())); size_t pfsHeaderSize = determineHeaderSize(((nx::sPfsHeader*)scratch.data()));
// open minimum header to get full header size // open minimum header to get full header size
scratch.alloc(pfsHeaderSize); scratch.alloc(pfsHeaderSize);
mFile->read(scratch.getBytes(), 0, scratch.getSize()); mFile->read(scratch.data(), 0, scratch.size());
mPfs.importBinary(scratch.getBytes(), scratch.getSize()); mPfs.fromBytes(scratch.data(), scratch.size());
if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC)) if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC))
{ {
@ -99,14 +99,14 @@ void PfsProcess::displayHeader()
{ {
printf("[PartitionFS]\n"); printf("[PartitionFS]\n");
printf(" Type: %s\n", mPfs.getFsType() == mPfs.TYPE_PFS0? "PFS0" : "HFS0"); printf(" Type: %s\n", mPfs.getFsType() == mPfs.TYPE_PFS0? "PFS0" : "HFS0");
printf(" FileNum: %" PRId64 "\n", (uint64_t)mPfs.getFileList().getSize()); printf(" FileNum: %" PRId64 "\n", (uint64_t)mPfs.getFileList().size());
if (mMountName.empty() == false) if (mMountName.empty() == false)
printf(" MountPoint: %s%s\n", mMountName.c_str(), mMountName.at(mMountName.length()-1) != '/' ? "/" : ""); printf(" MountPoint: %s%s\n", mMountName.c_str(), mMountName.at(mMountName.length()-1) != '/' ? "/" : "");
} }
void PfsProcess::displayFs() void PfsProcess::displayFs()
{ {
for (size_t i = 0; i < mPfs.getFileList().getSize(); i++) for (size_t i = 0; i < mPfs.getFileList().size(); i++)
{ {
printf(" %s", mPfs.getFileList()[i].name.c_str()); printf(" %s", mPfs.getFileList()[i].name.c_str());
if (_HAS_BIT(mCliOutputMode, OUTPUT_LAYOUT)) if (_HAS_BIT(mCliOutputMode, OUTPUT_LAYOUT))
@ -144,11 +144,11 @@ void PfsProcess::validateHfs()
{ {
crypto::sha::sSha256Hash hash; crypto::sha::sSha256Hash hash;
const fnd::List<nx::PfsHeader::sFile>& file = mPfs.getFileList(); const fnd::List<nx::PfsHeader::sFile>& file = mPfs.getFileList();
for (size_t i = 0; i < file.getSize(); i++) for (size_t i = 0; i < file.size(); i++)
{ {
mCache.alloc(file[i].hash_protected_size); mCache.alloc(file[i].hash_protected_size);
mFile->read(mCache.getBytes(), file[i].offset, file[i].hash_protected_size); mFile->read(mCache.data(), file[i].offset, file[i].hash_protected_size);
crypto::sha::Sha256(mCache.getBytes(), file[i].hash_protected_size, hash.bytes); crypto::sha::Sha256(mCache.data(), file[i].hash_protected_size, hash.bytes);
if (hash != file[i].hash) if (hash != file[i].hash)
{ {
printf("[WARNING] HFS0 %s%s%s: FAIL (bad hash)\n", !mMountName.empty()? mMountName.c_str() : "", (!mMountName.empty() && mMountName.at(mMountName.length()-1) != '/' )? "/" : "", file[i].name.c_str()); printf("[WARNING] HFS0 %s%s%s: FAIL (bad hash)\n", !mMountName.empty()? mMountName.c_str() : "", (!mMountName.empty() && mMountName.at(mMountName.length()-1) != '/' )? "/" : "", file[i].name.c_str());
@ -168,7 +168,7 @@ void PfsProcess::extractFs()
const fnd::List<nx::PfsHeader::sFile>& file = mPfs.getFileList(); const fnd::List<nx::PfsHeader::sFile>& file = mPfs.getFileList();
std::string file_path; std::string file_path;
for (size_t i = 0; i < file.getSize(); i++) for (size_t i = 0; i < file.size(); i++)
{ {
file_path.clear(); file_path.clear();
fnd::io::appendToPath(file_path, mExtractPath); fnd::io::appendToPath(file_path, mExtractPath);
@ -181,8 +181,8 @@ void PfsProcess::extractFs()
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++) for (size_t j = 0; j < ((file[i].size / kCacheSize) + ((file[i].size % kCacheSize) != 0)); j++)
{ {
mFile->read(mCache.getBytes(), MIN(file[i].size - (kCacheSize * j),kCacheSize)); mFile->read(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
outFile.write(mCache.getBytes(), MIN(file[i].size - (kCacheSize * j),kCacheSize)); outFile.write(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
} }
outFile.close(); outFile.close();
} }

View file

@ -40,7 +40,7 @@ private:
std::string mMountName; std::string mMountName;
bool mListFs; bool mListFs;
fnd::MemoryBlob mCache; fnd::Vec<byte_t> mCache;
nx::PfsHeader mPfs; nx::PfsHeader mPfs;

View file

@ -23,7 +23,7 @@ RoMetadataProcess::RoMetadataProcess() :
void RoMetadataProcess::process() void RoMetadataProcess::process()
{ {
if (mRoBlob.getSize() == 0) if (mRoBlob.size() == 0)
{ {
throw fnd::Exception(kModuleName, "No ro binary set."); throw fnd::Exception(kModuleName, "No ro binary set.");
} }
@ -33,7 +33,7 @@ void RoMetadataProcess::process()
displayRoMetaData(); displayRoMetaData();
} }
void RoMetadataProcess::setRoBinary(const fnd::MemoryBlob& bin) void RoMetadataProcess::setRoBinary(const fnd::Vec<byte_t>& bin)
{ {
mRoBlob = bin; mRoBlob = bin;
} }
@ -78,7 +78,7 @@ void RoMetadataProcess::importApiList()
{ {
if (mApiInfo.size > 0) if (mApiInfo.size > 0)
{ {
std::stringstream list_stream(std::string((char*)mRoBlob.getBytes() + mApiInfo.offset, mApiInfo.size)); std::stringstream list_stream(std::string((char*)mRoBlob.data() + mApiInfo.offset, mApiInfo.size));
std::string api_str; std::string api_str;
while(std::getline(list_stream, api_str, (char)0x00)) while(std::getline(list_stream, api_str, (char)0x00))
@ -98,7 +98,7 @@ void RoMetadataProcess::importApiList()
if (mDynSym.size > 0) if (mDynSym.size > 0)
{ {
mSymbolList.parseData(mRoBlob.getBytes() + mDynSym.offset, mDynSym.size, mRoBlob.getBytes() + mDynStr.offset, mDynStr.size, mInstructionType == nx::npdm::INSTR_64BIT); mSymbolList.parseData(mRoBlob.data() + mDynSym.offset, mDynSym.size, mRoBlob.data() + mDynStr.offset, mDynStr.size, mInstructionType == nx::npdm::INSTR_64BIT);
} }
} }
@ -138,10 +138,10 @@ void RoMetadataProcess::displayRoMetaData()
} }
} }
} }
if (mSymbolList.getSymbolList().getSize() > 0 && (mListSymbols || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))) if (mSymbolList.getSymbolList().size() > 0 && (mListSymbols || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)))
{ {
printf("[Symbol List]\n"); printf("[Symbol List]\n");
for (size_t i = 0; i < mSymbolList.getSymbolList().getSize(); i++) for (size_t i = 0; i < mSymbolList.getSymbolList().size(); i++)
{ {
const ElfSymbolParser::sElfSymbol& symbol = mSymbolList.getSymbolList()[i]; const ElfSymbolParser::sElfSymbol& symbol = mSymbolList.getSymbolList()[i];
printf(" %s [SHN=%s (%04x)][STT=%s][STB=%s]\n", symbol.name.c_str(), getSectionIndexStr(symbol.shn_index), symbol.shn_index, getSymbolTypeStr(symbol.symbol_type), getSymbolBindingStr(symbol.symbol_binding)); printf(" %s [SHN=%s (%04x)][STT=%s][STB=%s]\n", symbol.name.c_str(), getSectionIndexStr(symbol.shn_index), symbol.shn_index, getSymbolTypeStr(symbol.symbol_type), getSymbolBindingStr(symbol.symbol_binding));

View file

@ -2,7 +2,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include <nx/npdm.h> #include <nx/npdm.h>
@ -17,7 +17,7 @@ public:
void process(); void process();
void setRoBinary(const fnd::MemoryBlob& bin); void setRoBinary(const fnd::Vec<byte_t>& bin);
void setApiInfo(size_t offset, size_t size); void setApiInfo(size_t offset, size_t size);
void setDynSym(size_t offset, size_t size); void setDynSym(size_t offset, size_t size);
void setDynStr(size_t offset, size_t size); void setDynStr(size_t offset, size_t size);
@ -45,7 +45,7 @@ private:
sLayout mApiInfo; sLayout mApiInfo;
sLayout mDynSym; sLayout mDynSym;
sLayout mDynStr; sLayout mDynStr;
fnd::MemoryBlob mRoBlob; fnd::Vec<byte_t> mRoBlob;
std::vector<SdkApiString> mSdkVerApiList; std::vector<SdkApiString> mSdkVerApiList;
std::vector<SdkApiString> mPublicApiList; std::vector<SdkApiString> mPublicApiList;
std::vector<SdkApiString> mDebugApiList; std::vector<SdkApiString> mDebugApiList;

View file

@ -36,7 +36,6 @@ void RomfsProcess::process()
} }
resolveRomfs(); resolveRomfs();
if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC)) if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC))
{ {
displayHeader(); displayHeader();
@ -44,7 +43,7 @@ void RomfsProcess::process()
displayFs(); displayFs();
} }
if (mExtract) if (mExtract)
extractFs(); extractFs();
} }
void RomfsProcess::setInputFile(fnd::IFile* file, bool ownIFile) void RomfsProcess::setInputFile(fnd::IFile* file, bool ownIFile)
@ -111,11 +110,11 @@ void RomfsProcess::displayDir(const sDirectory& dir, size_t tab) const
printf("%s\n", dir.name.c_str()); printf("%s\n", dir.name.c_str());
} }
for (size_t i = 0; i < dir.dir_list.getSize(); i++) for (size_t i = 0; i < dir.dir_list.size(); i++)
{ {
displayDir(dir.dir_list[i], tab+1); displayDir(dir.dir_list[i], tab+1);
} }
for (size_t i = 0; i < dir.file_list.getSize(); i++) for (size_t i = 0; i < dir.file_list.size(); i++)
{ {
displayFile(dir.file_list[i], tab+1); displayFile(dir.file_list[i], tab+1);
} }
@ -150,7 +149,7 @@ void RomfsProcess::extractDir(const std::string& path, const sDirectory& dir)
// extract files // extract files
fnd::SimpleFile outFile; fnd::SimpleFile outFile;
for (size_t i = 0; i < dir.file_list.getSize(); i++) for (size_t i = 0; i < dir.file_list.size(); i++)
{ {
file_path.clear(); file_path.clear();
fnd::io::appendToPath(file_path, dir_path); fnd::io::appendToPath(file_path, dir_path);
@ -163,13 +162,13 @@ void RomfsProcess::extractDir(const std::string& path, const sDirectory& dir)
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++) for (size_t j = 0; j < ((dir.file_list[i].size / kCacheSize) + ((dir.file_list[i].size % kCacheSize) != 0)); j++)
{ {
mFile->read(mCache.getBytes(), 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.getBytes(), MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize)); outFile.write(mCache.data(), _MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize));
} }
outFile.close(); outFile.close();
} }
for (size_t i = 0; i < dir.dir_list.getSize(); i++) for (size_t i = 0; i < dir.dir_list.size(); i++)
{ {
extractDir(dir_path, dir.dir_list[i]); extractDir(dir_path, dir.dir_list[i]);
} }
@ -266,15 +265,15 @@ void RomfsProcess::resolveRomfs()
// read directory nodes // read directory nodes
mDirNodes.alloc(mHdr.sections[nx::romfs::DIR_NODE_TABLE].size.get()); mDirNodes.alloc(mHdr.sections[nx::romfs::DIR_NODE_TABLE].size.get());
mFile->read(mDirNodes.getBytes(), mHdr.sections[nx::romfs::DIR_NODE_TABLE].offset.get(), mDirNodes.getSize()); mFile->read(mDirNodes.data(), mHdr.sections[nx::romfs::DIR_NODE_TABLE].offset.get(), mDirNodes.size());
//printf("[RAW DIR NODES]\n"); //printf("[RAW DIR NODES]\n");
//fnd::SimpleTextOutput::hxdStyleDump(mDirNodes.getBytes(), mDirNodes.getSize()); //fnd::SimpleTextOutput::hxdStyleDump(mDirNodes.data(), mDirNodes.size());
// read file nodes // read file nodes
mFileNodes.alloc(mHdr.sections[nx::romfs::FILE_NODE_TABLE].size.get()); mFileNodes.alloc(mHdr.sections[nx::romfs::FILE_NODE_TABLE].size.get());
mFile->read(mFileNodes.getBytes(), mHdr.sections[nx::romfs::FILE_NODE_TABLE].offset.get(), mFileNodes.getSize()); mFile->read(mFileNodes.data(), mHdr.sections[nx::romfs::FILE_NODE_TABLE].offset.get(), mFileNodes.size());
//printf("[RAW FILE NODES]\n"); //printf("[RAW FILE NODES]\n");
//fnd::SimpleTextOutput::hxdStyleDump(mFileNodes.getBytes(), mFileNodes.getSize()); //fnd::SimpleTextOutput::hxdStyleDump(mFileNodes.data(), mFileNodes.size());
// A logic check on the root directory node // A logic check on the root directory node
if ( get_dir_node(0)->parent.get() != 0 \ if ( get_dir_node(0)->parent.get() != 0 \

View file

@ -2,7 +2,7 @@
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/IFile.h> #include <fnd/IFile.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <nx/romfs.h> #include <nx/romfs.h>
@ -20,12 +20,11 @@ public:
fnd::List<sDirectory> dir_list; fnd::List<sDirectory> dir_list;
fnd::List<sFile> file_list; fnd::List<sFile> file_list;
sDirectory& operator=(const sDirectory& other) void operator=(const sDirectory& other)
{ {
name = other.name; name = other.name;
dir_list = other.dir_list; dir_list = other.dir_list;
file_list = other.file_list; file_list = other.file_list;
return *this;
} }
bool operator==(const sDirectory& other) const bool operator==(const sDirectory& other) const
@ -44,11 +43,6 @@ public:
{ {
return (name == other); return (name == other);
} }
bool operator!=(const std::string& other) const
{
return !operator==(other);
}
}; };
struct sFile struct sFile
@ -57,12 +51,11 @@ public:
uint64_t offset; uint64_t offset;
uint64_t size; uint64_t size;
sFile& operator=(const sFile& other) void operator=(const sFile& other)
{ {
name = other.name; name = other.name;
offset = other.offset; offset = other.offset;
size = other.size; size = other.size;
return *this;
} }
bool operator==(const sFile& other) const bool operator==(const sFile& other) const
@ -81,11 +74,6 @@ public:
{ {
return (name == other); return (name == other);
} }
bool operator!=(const std::string& other) const
{
return !operator==(other);
}
}; };
RomfsProcess(); RomfsProcess();
@ -118,17 +106,17 @@ private:
std::string mMountName; std::string mMountName;
bool mListFs; bool mListFs;
fnd::MemoryBlob mCache; fnd::Vec<byte_t> mCache;
size_t mDirNum; size_t mDirNum;
size_t mFileNum; size_t mFileNum;
nx::sRomfsHeader mHdr; nx::sRomfsHeader mHdr;
fnd::MemoryBlob mDirNodes; fnd::Vec<byte_t> mDirNodes;
fnd::MemoryBlob mFileNodes; fnd::Vec<byte_t> mFileNodes;
sDirectory mRootDir; sDirectory mRootDir;
inline nx::sRomfsDirEntry* get_dir_node(uint32_t offset) { return (nx::sRomfsDirEntry*)(mDirNodes.getBytes() + offset); } inline nx::sRomfsDirEntry* get_dir_node(uint32_t offset) { return (nx::sRomfsDirEntry*)(mDirNodes.data() + offset); }
inline nx::sRomfsFileEntry* get_file_node(uint32_t offset) { return (nx::sRomfsFileEntry*)(mFileNodes.getBytes() + offset); } inline nx::sRomfsFileEntry* get_file_node(uint32_t offset) { return (nx::sRomfsFileEntry*)(mFileNodes.data() + offset); }
void printTab(size_t tab) const; void printTab(size_t tab) const;

View file

@ -8,7 +8,7 @@
#include <fnd/io.h> #include <fnd/io.h>
#include <fnd/SimpleFile.h> #include <fnd/SimpleFile.h>
#include <fnd/SimpleTextOutput.h> #include <fnd/SimpleTextOutput.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include <fnd/ResourceFileReader.h> #include <fnd/ResourceFileReader.h>
#include <nx/NcaUtils.h> #include <nx/NcaUtils.h>
#include <nx/AesKeygen.h> #include <nx/AesKeygen.h>
@ -708,37 +708,35 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
static const size_t kMaxReadSize = 0x4000; static const size_t kMaxReadSize = 0x4000;
FileType file_type = FILE_INVALID; FileType file_type = FILE_INVALID;
fnd::SimpleFile file; fnd::SimpleFile file;
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
// open file // open file
file.open(path, file.Read); file.open(path, file.Read);
// read file // read file
scratch.alloc(MIN(kMaxReadSize, file.size())); scratch.alloc(_MIN(kMaxReadSize, file.size()));
file.read(scratch.getBytes(), 0, scratch.getSize()); file.read(scratch.data(), 0, scratch.size());
// close file // close file
file.close(); file.close();
// _TYPE_PTR resolves to a pointer of type 'st' located at scratch.data()
#define _TYPE_PTR(st) ((st*)(scratch.data()))
// _QUICK_CAST resolves to a pointer of type 'st' located at scratch.getBytes() + 'oft' #define _ASSERT_SIZE(sz) (scratch.size() >= (sz))
#define _QUICK_CAST(st, oft) ((st*)(scratch.getBytes() + (oft)))
#define _ASSERT_SIZE(size) (scratch.getSize() >= (size))
// test npdm // test npdm
if (_ASSERT_SIZE(sizeof(nx::sXciHeaderPage)) && _QUICK_CAST(nx::sXciHeaderPage, 0)->header.signature.get() == nx::xci::kXciSig) if (_ASSERT_SIZE(sizeof(nx::sXciHeaderPage)) && _TYPE_PTR(nx::sXciHeaderPage)->header.signature.get() == nx::xci::kXciSig)
file_type = FILE_XCI; file_type = FILE_XCI;
// test pfs0 // test pfs0
else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && _QUICK_CAST(nx::sPfsHeader, 0)->signature.get() == nx::pfs::kPfsSig) else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && _TYPE_PTR(nx::sPfsHeader)->signature.get() == nx::pfs::kPfsSig)
file_type = FILE_PARTITIONFS; file_type = FILE_PARTITIONFS;
// test hfs0 // test hfs0
else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && _QUICK_CAST(nx::sPfsHeader, 0)->signature.get() == nx::pfs::kHashedPfsSig) else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && _TYPE_PTR(nx::sPfsHeader)->signature.get() == nx::pfs::kHashedPfsSig)
file_type = FILE_PARTITIONFS; file_type = FILE_PARTITIONFS;
// test romfs // test romfs
else if (_ASSERT_SIZE(sizeof(nx::sRomfsHeader)) && _QUICK_CAST(nx::sRomfsHeader, 0)->header_size.get() == sizeof(nx::sRomfsHeader) && _QUICK_CAST(nx::sRomfsHeader, 0)->sections[1].offset.get() == (_QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].offset.get() + _QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].size.get())) else if (_ASSERT_SIZE(sizeof(nx::sRomfsHeader)) && _TYPE_PTR(nx::sRomfsHeader)->header_size.get() == sizeof(nx::sRomfsHeader) && _TYPE_PTR(nx::sRomfsHeader)->sections[1].offset.get() == (_TYPE_PTR(nx::sRomfsHeader)->sections[0].offset.get() + _TYPE_PTR(nx::sRomfsHeader)->sections[0].size.get()))
file_type = FILE_ROMFS; file_type = FILE_ROMFS;
// test npdm // test npdm
else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && _QUICK_CAST(nx::sNpdmHeader, 0)->signature.get() == nx::npdm::kNpdmStructSig) else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && _TYPE_PTR(nx::sNpdmHeader)->signature.get() == nx::npdm::kNpdmStructSig)
file_type = FILE_NPDM; file_type = FILE_NPDM;
// test nca // test nca
else if (determineValidNcaFromSample(scratch)) else if (determineValidNcaFromSample(scratch))
@ -750,34 +748,34 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
else if (determineValidNacpFromSample(scratch)) else if (determineValidNacpFromSample(scratch))
file_type = FILE_NACP; file_type = FILE_NACP;
// test nso // test nso
else if (_ASSERT_SIZE(sizeof(nx::sNsoHeader)) && _QUICK_CAST(nx::sNsoHeader, 0)->signature.get() == nx::nso::kNsoSig) else if (_ASSERT_SIZE(sizeof(nx::sNsoHeader)) && _TYPE_PTR(nx::sNsoHeader)->signature.get() == nx::nso::kNsoSig)
file_type = FILE_NSO; file_type = FILE_NSO;
// test nso // test nso
else if (_ASSERT_SIZE(sizeof(nx::sNroHeader)) && _QUICK_CAST(nx::sNroHeader, 0)->signature.get() == nx::nro::kNroSig) else if (_ASSERT_SIZE(sizeof(nx::sNroHeader)) && _TYPE_PTR(nx::sNroHeader)->signature.get() == nx::nro::kNroSig)
file_type = FILE_NRO; file_type = FILE_NRO;
// test hb asset // test hb asset
else if (_ASSERT_SIZE(sizeof(nx::sAssetHeader)) && _QUICK_CAST(nx::sAssetHeader, 0)->signature.get() == nx::aset::kAssetSig) else if (_ASSERT_SIZE(sizeof(nx::sAssetHeader)) && _TYPE_PTR(nx::sAssetHeader)->signature.get() == nx::aset::kAssetSig)
file_type = FILE_HB_ASSET; file_type = FILE_HB_ASSET;
// else unrecognised // else unrecognised
else else
file_type = FILE_INVALID; file_type = FILE_INVALID;
#undef _ASSERT_SIZE #undef _ASSERT_SIZE
#undef _QUICK_CAST #undef _TYPE_PTR
return file_type; return file_type;
} }
bool UserSettings::determineValidNcaFromSample(const fnd::MemoryBlob& sample) const bool UserSettings::determineValidNcaFromSample(const fnd::Vec<byte_t>& sample) const
{ {
// prepare decrypted NCA data // prepare decrypted NCA data
byte_t nca_raw[nx::nca::kHeaderSize]; byte_t nca_raw[nx::nca::kHeaderSize];
nx::sNcaHeader* nca_header = (nx::sNcaHeader*)(nca_raw + nx::NcaUtils::sectorToOffset(1)); nx::sNcaHeader* nca_header = (nx::sNcaHeader*)(nca_raw + nx::NcaUtils::sectorToOffset(1));
if (sample.getSize() < nx::nca::kHeaderSize) if (sample.size() < nx::nca::kHeaderSize)
return false; return false;
nx::NcaUtils::decryptNcaHeader(sample.getBytes(), nca_raw, mKeyset.nca.header_key); nx::NcaUtils::decryptNcaHeader(sample.data(), nca_raw, mKeyset.nca.header_key);
if (nca_header->signature.get() != nx::nca::kNca2Sig && nca_header->signature.get() != nx::nca::kNca3Sig) if (nca_header->signature.get() != nx::nca::kNca2Sig && nca_header->signature.get() != nx::nca::kNca3Sig)
return false; return false;
@ -785,27 +783,27 @@ bool UserSettings::determineValidNcaFromSample(const fnd::MemoryBlob& sample) co
return true; return true;
} }
bool UserSettings::determineValidCnmtFromSample(const fnd::MemoryBlob& sample) const bool UserSettings::determineValidCnmtFromSample(const fnd::Vec<byte_t>& sample) const
{ {
if (sample.getSize() < sizeof(nx::sContentMetaHeader)) if (sample.size() < sizeof(nx::sContentMetaHeader))
return false; return false;
const nx::sContentMetaHeader* data = (const nx::sContentMetaHeader*)sample.getBytes(); const nx::sContentMetaHeader* data = (const nx::sContentMetaHeader*)sample.data();
size_t minimum_size = sizeof(nx::sContentMetaHeader) + data->exhdr_size.get() + data->content_count.get() * sizeof(nx::sContentInfo) + data->content_meta_count.get() * sizeof(nx::sContentMetaInfo) + nx::cnmt::kDigestLen; size_t minimum_size = sizeof(nx::sContentMetaHeader) + data->exhdr_size.get() + data->content_count.get() * sizeof(nx::sContentInfo) + data->content_meta_count.get() * sizeof(nx::sContentMetaInfo) + nx::cnmt::kDigestLen;
if (sample.getSize() < minimum_size) if (sample.size() < minimum_size)
return false; return false;
if (data->type == nx::cnmt::METATYPE_APPLICATION) if (data->type == nx::cnmt::METATYPE_APPLICATION)
{ {
const nx::sApplicationMetaExtendedHeader* meta = (const nx::sApplicationMetaExtendedHeader*)(sample.getBytes() + sizeof(nx::sContentMetaHeader)); const nx::sApplicationMetaExtendedHeader* meta = (const nx::sApplicationMetaExtendedHeader*)(sample.data() + sizeof(nx::sContentMetaHeader));
if ((meta->patch_id.get() & data->id.get()) != data->id.get()) if ((meta->patch_id.get() & data->id.get()) != data->id.get())
return false; return false;
} }
else if (data->type == nx::cnmt::METATYPE_PATCH) else if (data->type == nx::cnmt::METATYPE_PATCH)
{ {
const nx::sPatchMetaExtendedHeader* meta = (const nx::sPatchMetaExtendedHeader*)(sample.getBytes() + sizeof(nx::sContentMetaHeader)); const nx::sPatchMetaExtendedHeader* meta = (const nx::sPatchMetaExtendedHeader*)(sample.data() + sizeof(nx::sContentMetaHeader));
if ((meta->application_id.get() & data->id.get()) != meta->application_id.get()) if ((meta->application_id.get() & data->id.get()) != meta->application_id.get())
return false; return false;
@ -813,31 +811,31 @@ bool UserSettings::determineValidCnmtFromSample(const fnd::MemoryBlob& sample) c
} }
else if (data->type == nx::cnmt::METATYPE_ADD_ON_CONTENT) else if (data->type == nx::cnmt::METATYPE_ADD_ON_CONTENT)
{ {
const nx::sAddOnContentMetaExtendedHeader* meta = (const nx::sAddOnContentMetaExtendedHeader*)(sample.getBytes() + sizeof(nx::sContentMetaHeader)); const nx::sAddOnContentMetaExtendedHeader* meta = (const nx::sAddOnContentMetaExtendedHeader*)(sample.data() + sizeof(nx::sContentMetaHeader));
if ((meta->application_id.get() & data->id.get()) != meta->application_id.get()) if ((meta->application_id.get() & data->id.get()) != meta->application_id.get())
return false; return false;
} }
else if (data->type == nx::cnmt::METATYPE_DELTA) else if (data->type == nx::cnmt::METATYPE_DELTA)
{ {
const nx::sDeltaMetaExtendedHeader* meta = (const nx::sDeltaMetaExtendedHeader*)(sample.getBytes() + sizeof(nx::sContentMetaHeader)); const nx::sDeltaMetaExtendedHeader* meta = (const nx::sDeltaMetaExtendedHeader*)(sample.data() + sizeof(nx::sContentMetaHeader));
if ((meta->application_id.get() & data->id.get()) != meta->application_id.get()) if ((meta->application_id.get() & data->id.get()) != meta->application_id.get())
return false; return false;
minimum_size += meta->extended_data_size.get(); minimum_size += meta->extended_data_size.get();
} }
if (sample.getSize() != minimum_size) if (sample.size() != minimum_size)
return false; return false;
return true; return true;
} }
bool UserSettings::determineValidNacpFromSample(const fnd::MemoryBlob& sample) const bool UserSettings::determineValidNacpFromSample(const fnd::Vec<byte_t>& sample) const
{ {
if (sample.getSize() != sizeof(nx::sApplicationControlProperty)) if (sample.size() != sizeof(nx::sApplicationControlProperty))
return false; return false;
const nx::sApplicationControlProperty* data = (const nx::sApplicationControlProperty*)sample.getBytes(); const nx::sApplicationControlProperty* data = (const nx::sApplicationControlProperty*)sample.data();
if (data->logo_type > nx::nacp::LOGO_Nintendo) if (data->logo_type > nx::nacp::LOGO_Nintendo)
return false; return false;

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/MemoryBlob.h> #include <fnd/Vec.h>
#include <nx/npdm.h> #include <nx/npdm.h>
#include "nstool.h" #include "nstool.h"
@ -103,8 +103,8 @@ private:
void decodeHexStringToBytes(const std::string& name, const std::string& str, byte_t* out, size_t out_len); void decodeHexStringToBytes(const std::string& name, const std::string& str, byte_t* out, size_t out_len);
FileType getFileTypeFromString(const std::string& type_str); FileType getFileTypeFromString(const std::string& type_str);
FileType determineFileTypeFromFile(const std::string& path); FileType determineFileTypeFromFile(const std::string& path);
bool determineValidNcaFromSample(const fnd::MemoryBlob& sample) const; bool determineValidNcaFromSample(const fnd::Vec<byte_t>& sample) const;
bool determineValidCnmtFromSample(const fnd::MemoryBlob& sample) const; bool determineValidCnmtFromSample(const fnd::Vec<byte_t>& sample) const;
bool determineValidNacpFromSample(const fnd::MemoryBlob& sample) const; bool determineValidNacpFromSample(const fnd::Vec<byte_t>& sample) const;
nx::npdm::InstructionType getInstructionTypeFromString(const std::string& type_str); nx::npdm::InstructionType getInstructionTypeFromString(const std::string& type_str);
}; };

View file

@ -25,7 +25,7 @@ XciProcess::~XciProcess()
void XciProcess::process() void XciProcess::process()
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
if (mFile == nullptr) if (mFile == nullptr)
{ {
@ -37,7 +37,7 @@ void XciProcess::process()
// allocate memory for and decrypt sXciHeader // allocate memory for and decrypt sXciHeader
scratch.alloc(sizeof(nx::sXciHeader)); scratch.alloc(sizeof(nx::sXciHeader));
nx::XciUtils::decryptXciHeader((const byte_t*)&mHdrPage.header, scratch.getBytes(), mKeyset->xci.header_key.key); nx::XciUtils::decryptXciHeader((const byte_t*)&mHdrPage.header, scratch.data(), mKeyset->xci.header_key.key);
// validate header signature // validate header signature
if (mVerify) if (mVerify)
@ -46,7 +46,7 @@ void XciProcess::process()
} }
// deserialise header // deserialise header
mHdr.importBinary(scratch.getBytes(), scratch.getSize()); mHdr.fromBytes(scratch.data(), scratch.size());
// display header // display header
if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC)) if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC))
@ -82,7 +82,7 @@ void XciProcess::setVerifyMode(bool verify)
void XciProcess::setPartitionForExtract(const std::string& partition_name, const std::string& extract_path) void XciProcess::setPartitionForExtract(const std::string& partition_name, const std::string& extract_path)
{ {
mExtractInfo.push_back({partition_name, extract_path}); mExtractInfo.addElement({partition_name, extract_path});
} }
void XciProcess::setListFs(bool list_fs) void XciProcess::setListFs(bool list_fs)
@ -219,11 +219,11 @@ void XciProcess::displayHeader()
bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash) bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash)
{ {
fnd::MemoryBlob scratch; fnd::Vec<byte_t> scratch;
crypto::sha::sSha256Hash calc_hash; crypto::sha::sSha256Hash calc_hash;
scratch.alloc(len); scratch.alloc(len);
mFile->read(scratch.getBytes(), offset, len); mFile->read(scratch.data(), offset, scratch.size());
crypto::sha::Sha256(scratch.getBytes(), scratch.getSize(), calc_hash.bytes); crypto::sha::Sha256(scratch.data(), scratch.size(), calc_hash.bytes);
return calc_hash.compare(test_hash); return calc_hash.compare(test_hash);
} }
@ -254,7 +254,7 @@ void XciProcess::processRootPfs()
void XciProcess::processPartitionPfs() void XciProcess::processPartitionPfs()
{ {
const fnd::List<nx::PfsHeader::sFile>& rootPartitions = mRootPfs.getPfsHeader().getFileList(); const fnd::List<nx::PfsHeader::sFile>& rootPartitions = mRootPfs.getPfsHeader().getFileList();
for (size_t i = 0; i < rootPartitions.getSize(); i++) for (size_t i = 0; i < rootPartitions.size(); i++)
{ {
// this must be validated here because only the size of the root partiton header is known at verification time // this must be validated here because only the size of the root partiton header is known at verification time
if (mVerify && validateRegionOfFile(mHdr.getPartitionFsAddress() + rootPartitions[i].offset, rootPartitions[i].hash_protected_size, rootPartitions[i].hash.bytes) == false) if (mVerify && validateRegionOfFile(mHdr.getPartitionFsAddress() + rootPartitions[i].offset, rootPartitions[i].hash_protected_size, rootPartitions[i].hash.bytes) == false)
@ -268,13 +268,9 @@ void XciProcess::processPartitionPfs()
tmp.setVerifyMode(mVerify); tmp.setVerifyMode(mVerify);
tmp.setCliOutputMode(mCliOutputMode); tmp.setCliOutputMode(mCliOutputMode);
tmp.setMountPointName(kXciMountPointName + rootPartitions[i].name); tmp.setMountPointName(kXciMountPointName + rootPartitions[i].name);
for (size_t j = 0; j < mExtractInfo.size(); j++) if (mExtractInfo.hasElement<std::string>(rootPartitions[i].name))
{ tmp.setExtractPath(mExtractInfo.getElement<std::string>(rootPartitions[i].name).extract_path);
if (mExtractInfo[j].partition_name == rootPartitions[i].name)
{
tmp.setExtractPath(mExtractInfo[j].extract_path);
}
}
tmp.process(); tmp.process();
} }
} }

View file

@ -2,6 +2,7 @@
#include <string> #include <string>
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/IFile.h> #include <fnd/IFile.h>
#include <fnd/List.h>
#include <nx/XciHeader.h> #include <nx/XciHeader.h>
#include "nstool.h" #include "nstool.h"
@ -41,6 +42,17 @@ private:
{ {
std::string partition_name; std::string partition_name;
std::string extract_path; std::string extract_path;
void operator=(const sExtractInfo& other)
{
partition_name = other.partition_name;
extract_path = other.extract_path;
}
bool operator==(const std::string& name) const
{
return name == partition_name;
}
}; };
bool mListFs; bool mListFs;
@ -48,7 +60,7 @@ private:
nx::sXciHeaderPage mHdrPage; nx::sXciHeaderPage mHdrPage;
nx::XciHeader mHdr; nx::XciHeader mHdr;
PfsProcess mRootPfs; PfsProcess mRootPfs;
std::vector<sExtractInfo> mExtractInfo; fnd::List<sExtractInfo> mExtractInfo;
void displayHeader(); void displayHeader();
bool validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash); bool validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash);