mirror of
https://github.com/jakcron/nstool
synced 2024-11-22 21:49:30 +00:00
[nx|es|fnd|nstool] Commit working refactor.
This commit is contained in:
parent
4be0b51ddb
commit
48ac29f3ce
93 changed files with 886 additions and 938 deletions
|
@ -19,7 +19,7 @@ namespace es
|
|||
// export/import binary
|
||||
void toBytes();
|
||||
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
|
||||
void clear();
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace es
|
|||
{
|
||||
template <class T>
|
||||
class SignedData
|
||||
: public fnd::ISerialiseable
|
||||
: public fnd::ISerialisable
|
||||
{
|
||||
public:
|
||||
SignedData();
|
||||
|
@ -18,7 +18,7 @@ namespace es
|
|||
bool operator!=(const SignedData& other) const;
|
||||
|
||||
// export/import
|
||||
const void toBytes();
|
||||
void toBytes();
|
||||
void fromBytes(const byte_t* src, size_t size);
|
||||
const fnd::Vec<byte_t>& getBytes() const;
|
||||
|
||||
|
@ -42,19 +42,19 @@ namespace es
|
|||
};
|
||||
|
||||
template <class T>
|
||||
inline SignedData::SignedData()
|
||||
inline SignedData<T>::SignedData()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline SignedData::SignedData(const SignedData& other)
|
||||
inline SignedData<T>::SignedData(const SignedData& other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void SignedData::operator=(const SignedData& other)
|
||||
inline void SignedData<T>::operator=(const SignedData& other)
|
||||
{
|
||||
mRawBinary = other.mRawBinary;
|
||||
mSignature = other.mSignature;
|
||||
|
@ -62,48 +62,48 @@ namespace es
|
|||
}
|
||||
|
||||
template <class T>
|
||||
inline bool SignedData::operator==(const SignedData& other) const
|
||||
inline bool SignedData<T>::operator==(const SignedData& other) const
|
||||
{
|
||||
return (mSignature == other.mSignature) \
|
||||
&& (mBody == other.mBody);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool SignedData::operator!=(const SignedData& other) const
|
||||
inline bool SignedData<T>::operator!=(const SignedData& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline const void SignedData::toBytes()
|
||||
inline void SignedData<T>::toBytes()
|
||||
{
|
||||
mSignature.toBytes();
|
||||
mBody.toBytes();
|
||||
|
||||
mRawBinary.alloc(mSignature.getBytes().size() + mBody.getBytes().size());
|
||||
|
||||
memcpy(mRawBinary.getBytes().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().data(), mSignature.getBytes().size());
|
||||
memcpy(mRawBinary.data() + mSignature.getBytes().size(), mBody.getBytes().data(), mBody.getBytes().size());
|
||||
}
|
||||
|
||||
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);
|
||||
mBody.fromBytes(src + mSignature.getBytes().size(), size - mSignature.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>
|
||||
inline const fnd::Vec<byte_t>& SignedData::getBytes() const
|
||||
inline const fnd::Vec<byte_t>& SignedData<T>::getBytes() const
|
||||
{
|
||||
return mRawBinary;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void SignedData::clear()
|
||||
inline void SignedData<T>::clear()
|
||||
{
|
||||
mRawBinary.clear();
|
||||
mSignature.clear();
|
||||
|
@ -111,25 +111,25 @@ namespace es
|
|||
}
|
||||
|
||||
template <class T>
|
||||
inline const es::SignatureBlock& SignedData::getSignature() const
|
||||
inline const es::SignatureBlock& SignedData<T>::getSignature() const
|
||||
{
|
||||
return mSignature;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void SignedData::setSignature(const SignatureBlock& signature)
|
||||
inline void SignedData<T>::setSignature(const SignatureBlock& signature)
|
||||
{
|
||||
mSignature = signature;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline const T& SignedData::getBody() const
|
||||
inline const T& SignedData<T>::getBody() const
|
||||
{
|
||||
return mBody;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void SignedData::setBody(const T& body)
|
||||
inline void SignedData<T>::setBody(const T& body)
|
||||
{
|
||||
mBody = body;
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ const byte_t * es::TicketBody_V2::getEncTitleKey() const
|
|||
void es::TicketBody_V2::setEncTitleKey(const byte_t * data, size_t len)
|
||||
{
|
||||
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
|
||||
|
@ -262,7 +262,7 @@ const byte_t * es::TicketBody_V2::getReservedRegion() const
|
|||
void es::TicketBody_V2::setReservedRegion(const byte_t * data, size_t len)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <vector>
|
||||
//#include <fnd/Vec.h>
|
||||
|
||||
namespace fnd
|
||||
{
|
||||
|
@ -13,7 +14,7 @@ namespace fnd
|
|||
List(const List<T>& other);
|
||||
|
||||
// copy operator
|
||||
const List<T>& operator=(const List<T>& other);
|
||||
void operator=(const List<T>& other);
|
||||
|
||||
// equivalence operators
|
||||
bool operator==(const List<T>& other) const;
|
||||
|
@ -43,52 +44,32 @@ namespace fnd
|
|||
T& getElement(const K& key);
|
||||
|
||||
private:
|
||||
static const size_t kDefaultSize = 20;
|
||||
|
||||
fnd::Vec<T> m_Vec;
|
||||
size_t m_Num;
|
||||
std::vector<T> m_Vec;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline List<T>::List() :
|
||||
m_Vec(),
|
||||
m_Num(0)
|
||||
m_Vec()
|
||||
{
|
||||
m_Vec.alloc(kDefaultSize);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline List<T>::List(const List<T>& other) :
|
||||
m_Vec(other.m_Vec),
|
||||
m_Size(other.m_Size)
|
||||
{}
|
||||
List()
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
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_Size = other.m_Size;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool List<T>::operator==(const List<T>& other) const
|
||||
{
|
||||
bool isEqual = true;
|
||||
|
||||
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;
|
||||
return m_Vec == other.m_Vec;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
@ -100,62 +81,42 @@ namespace fnd
|
|||
template<class T>
|
||||
inline void List<T>::addElement(const T & element)
|
||||
{
|
||||
(*this)[m_Num] = element;
|
||||
m_Vec.push_back(element);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
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];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
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];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline const T & List<T>::atBack() const
|
||||
{
|
||||
return m_Vec[m_Num - 1];
|
||||
return m_Vec.back();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T & List<T>::atBack()
|
||||
{
|
||||
return m_Vec[m_Num - 1];
|
||||
return m_Vec.back();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline size_t List<T>::size() const
|
||||
{
|
||||
return m_Num;
|
||||
return m_Vec.size();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void List<T>::clear()
|
||||
{
|
||||
m_Num = 0;
|
||||
m_Vec.clear();
|
||||
}
|
||||
|
||||
|
@ -163,9 +124,9 @@ namespace fnd
|
|||
template<class K>
|
||||
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;
|
||||
}
|
||||
|
@ -178,11 +139,11 @@ namespace fnd
|
|||
template<class K>
|
||||
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>
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace fnd
|
|||
~Vec();
|
||||
|
||||
// copy operator
|
||||
const Vec<T>& operator=(const Vec<T>& other);
|
||||
void operator=(const Vec<T>& other);
|
||||
|
||||
// equivalence operators
|
||||
bool operator==(const Vec<T>& other) const;
|
||||
|
@ -34,10 +34,13 @@ namespace fnd
|
|||
// allocate vector
|
||||
void alloc(size_t new_size);
|
||||
|
||||
// resize vector
|
||||
void resize(size_t new_size);
|
||||
|
||||
// clear vector
|
||||
void clear();
|
||||
private:
|
||||
T * m_Vec;
|
||||
T* m_Vec;
|
||||
size_t m_Size;
|
||||
|
||||
void copyFrom(const T * array, size_t num);
|
||||
|
@ -70,7 +73,7 @@ namespace fnd
|
|||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
@ -136,6 +139,18 @@ namespace fnd
|
|||
|
||||
template<class T>
|
||||
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)
|
||||
{
|
||||
|
@ -145,7 +160,7 @@ namespace fnd
|
|||
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];
|
||||
}
|
||||
|
@ -155,12 +170,7 @@ namespace fnd
|
|||
}
|
||||
else
|
||||
{
|
||||
m_Vec = new T[new_size];
|
||||
if (m_Vec == nullptr)
|
||||
{
|
||||
fnd::Exception("Vec", "Failed to allocate memory for vector");
|
||||
}
|
||||
m_Size = new_size;
|
||||
alloc(new_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,6 @@ typedef uint8_t byte_t;
|
|||
#define _MIN(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)
|
||||
{
|
||||
return (size % align) == 0? size : (size - (size % align) + align);
|
||||
|
|
|
@ -12,6 +12,10 @@ namespace nx
|
|||
HandleTableSizeEntry(const KernelCapability& kernel_cap);
|
||||
HandleTableSizeEntry(uint16_t size);
|
||||
|
||||
void operator=(const HandleTableSizeEntry& other);
|
||||
bool operator==(const HandleTableSizeEntry& other) const;
|
||||
bool operator!=(const HandleTableSizeEntry& other) const;
|
||||
|
||||
// kernel capability
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
void setKernelCapability(const KernelCapability& kernel_cap);
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace nx
|
|||
public:
|
||||
HandleTableSizeHandler();
|
||||
|
||||
void operator=(const HandleTableSizeHandler& other);
|
||||
bool operator==(const HandleTableSizeHandler& other) const;
|
||||
bool operator!=(const HandleTableSizeHandler& other) const;
|
||||
void operator=(const HandleTableSizeHandler& other);
|
||||
|
||||
// kernel capabilty list in/out
|
||||
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
|
||||
|
@ -30,9 +30,6 @@ namespace nx
|
|||
|
||||
bool mIsSet;
|
||||
HandleTableSizeEntry mEntry;
|
||||
|
||||
void copyFrom(const HandleTableSizeHandler& other);
|
||||
bool isEqual(const HandleTableSizeHandler& other) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <nx/hierarchicalintegrity.h>
|
||||
#include <fnd/ISerialisable.h>
|
||||
#include <fnd/List.h>
|
||||
#include <crypto/sha.h>
|
||||
|
||||
namespace nx
|
||||
{
|
||||
|
|
|
@ -16,6 +16,10 @@ namespace nx
|
|||
InteruptEntry(const KernelCapability& kernel_cap);
|
||||
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
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
void setKernelCapability(const KernelCapability& kernel_cap);
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace nx
|
|||
public:
|
||||
InteruptHandler();
|
||||
|
||||
void operator=(const InteruptHandler& other);
|
||||
bool operator==(const InteruptHandler& other) const;
|
||||
bool operator!=(const InteruptHandler& other) const;
|
||||
void operator=(const InteruptHandler& other);
|
||||
|
||||
// kernel capabilty list in/out
|
||||
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
|
||||
|
@ -29,9 +29,6 @@ namespace nx
|
|||
|
||||
bool mIsSet;
|
||||
fnd::List<uint16_t> mInterupts;
|
||||
|
||||
void copyFrom(const InteruptHandler& other);
|
||||
bool isEqual(const InteruptHandler& other) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace nx
|
|||
KernelCapability(KernelCapId type);
|
||||
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;
|
||||
|
||||
|
|
|
@ -12,6 +12,10 @@ namespace nx
|
|||
KernelVersionEntry(const KernelCapability& kernel_cap);
|
||||
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
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
void setKernelCapability(const KernelCapability& kernel_cap);
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace nx
|
|||
public:
|
||||
KernelVersionHandler();
|
||||
|
||||
void operator=(const KernelVersionHandler& other);
|
||||
bool operator==(const KernelVersionHandler& other) const;
|
||||
bool operator!=(const KernelVersionHandler& other) const;
|
||||
void operator=(const KernelVersionHandler& other);
|
||||
|
||||
// kernel capabilty list in/out
|
||||
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
|
||||
|
@ -32,9 +32,6 @@ namespace nx
|
|||
|
||||
bool mIsSet;
|
||||
KernelVersionEntry mEntry;
|
||||
|
||||
void copyFrom(const KernelVersionHandler& other);
|
||||
bool isEqual(const KernelVersionHandler& other) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,9 @@ namespace nx
|
|||
|
||||
MemoryMappingHandler();
|
||||
|
||||
void operator=(const MemoryMappingHandler& other);
|
||||
bool operator==(const MemoryMappingHandler& other) const;
|
||||
bool operator!=(const MemoryMappingHandler& other) const;
|
||||
void operator=(const MemoryMappingHandler& other);
|
||||
|
||||
// kernel capabilty list in/out
|
||||
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
|
||||
|
@ -73,9 +73,6 @@ namespace nx
|
|||
bool mIsSet;
|
||||
fnd::List<sMemoryMapping> mMemRange;
|
||||
fnd::List<sMemoryMapping> mMemPage;
|
||||
|
||||
void copyFrom(const MemoryMappingHandler& other);
|
||||
bool isEqual(const MemoryMappingHandler& other) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@ namespace nx
|
|||
MemoryPageEntry(uint32_t page);
|
||||
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
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
void setKernelCapability(const KernelCapability& kernel_cap);
|
||||
|
|
|
@ -12,6 +12,10 @@ namespace nx
|
|||
MiscFlagsEntry(const KernelCapability& kernel_cap);
|
||||
MiscFlagsEntry(uint32_t flags);
|
||||
|
||||
void operator=(const MiscFlagsEntry& other);
|
||||
bool operator==(const MiscFlagsEntry& other) const;
|
||||
bool operator!=(const MiscFlagsEntry& other) const;
|
||||
|
||||
// kernel capability
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
void setKernelCapability(const KernelCapability& kernel_cap);
|
||||
|
|
|
@ -30,9 +30,9 @@ namespace nx
|
|||
|
||||
MiscFlagsHandler();
|
||||
|
||||
void operator=(const MiscFlagsHandler& other);
|
||||
bool operator==(const MiscFlagsHandler& other) const;
|
||||
bool operator!=(const MiscFlagsHandler& other) const;
|
||||
void operator=(const MiscFlagsHandler& other);
|
||||
|
||||
// kernel capabilty list in/out
|
||||
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
|
||||
|
@ -50,9 +50,6 @@ namespace nx
|
|||
|
||||
bool mIsSet;
|
||||
fnd::List<Flags> mFlags;
|
||||
|
||||
void copyFrom(const MiscFlagsHandler& other);
|
||||
bool isEqual(const MiscFlagsHandler& other) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@ namespace nx
|
|||
MiscParamsEntry(const KernelCapability& kernel_cap);
|
||||
MiscParamsEntry(byte_t program_type);
|
||||
|
||||
void operator=(const MiscParamsEntry& other);
|
||||
bool operator==(const MiscParamsEntry& other) const;
|
||||
bool operator!=(const MiscParamsEntry& other) const;
|
||||
|
||||
// kernel capability
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
void setKernelCapability(const KernelCapability& kernel_cap);
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace nx
|
|||
public:
|
||||
MiscParamsHandler();
|
||||
|
||||
void operator=(const MiscParamsHandler& other);
|
||||
bool operator==(const MiscParamsHandler& other) const;
|
||||
bool operator!=(const MiscParamsHandler& other) const;
|
||||
void operator=(const MiscParamsHandler& other);
|
||||
|
||||
// kernel capabilty list in/out
|
||||
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
|
||||
|
@ -30,9 +30,6 @@ namespace nx
|
|||
|
||||
bool mIsSet;
|
||||
MiscParamsEntry mEntry;
|
||||
|
||||
void copyFrom(const MiscParamsHandler& other);
|
||||
bool isEqual(const MiscParamsHandler& other) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#pragma once
|
||||
#include <nx/nca.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/ISerialisable.h>
|
||||
#include <fnd/List.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
|
||||
namespace nx
|
||||
{
|
||||
class NcaHeader :
|
||||
public fnd::ISerialiseableBinary
|
||||
public fnd::ISerialisable
|
||||
{
|
||||
public:
|
||||
enum FormatVersion
|
||||
|
|
|
@ -12,6 +12,10 @@ namespace nx
|
|||
SystemCallEntry(const KernelCapability& kernel_cap);
|
||||
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
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
void setKernelCapability(const KernelCapability& kernel_cap);
|
||||
|
|
|
@ -11,9 +11,9 @@ namespace nx
|
|||
|
||||
SystemCallHandler();
|
||||
|
||||
void operator=(const SystemCallHandler& other);
|
||||
bool operator==(const SystemCallHandler& other) const;
|
||||
bool operator!=(const SystemCallHandler& other) const;
|
||||
void operator=(const SystemCallHandler& other);
|
||||
|
||||
// kernel capabilty list in/out
|
||||
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
|
||||
|
@ -31,9 +31,6 @@ namespace nx
|
|||
|
||||
bool mIsSet;
|
||||
fnd::List<uint8_t> mSystemCalls;
|
||||
|
||||
void copyFrom(const SystemCallHandler& other);
|
||||
bool isEqual(const SystemCallHandler& other) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@ namespace nx
|
|||
ThreadInfoEntry(const KernelCapability& kernel_cap);
|
||||
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
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
void setKernelCapability(const KernelCapability& kernel_cap);
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace nx
|
|||
public:
|
||||
ThreadInfoHandler();
|
||||
|
||||
void operator=(const ThreadInfoHandler& other);
|
||||
bool operator==(const ThreadInfoHandler& other) const;
|
||||
bool operator!=(const ThreadInfoHandler& other) const;
|
||||
void operator=(const ThreadInfoHandler& other);
|
||||
|
||||
// kernel capabilty list in/out
|
||||
void importKernelCapabilityList(const fnd::List<KernelCapability>& caps);
|
||||
|
@ -36,9 +36,6 @@ namespace nx
|
|||
|
||||
bool mIsSet;
|
||||
ThreadInfoEntry mEntry;
|
||||
|
||||
void copyFrom(const ThreadInfoHandler& other);
|
||||
bool isEqual(const ThreadInfoHandler& other) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <nx/macro.h>
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
|
||||
namespace nx
|
||||
{
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
#include <nx/macro.h>
|
||||
|
||||
namespace nx
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
|
||||
namespace nx
|
||||
{
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
|
||||
namespace nx
|
||||
{
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <crypto/rsa.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
#include <nx/macro.h>
|
||||
|
||||
namespace nx
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
#include <nx/macro.h>
|
||||
|
||||
namespace nx
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <nx/macro.h>
|
||||
|
||||
namespace nx
|
||||
|
@ -9,7 +8,6 @@ namespace nx
|
|||
{
|
||||
static const uint32_t kNroSig = _MAKE_STRUCT_SIGNATURE("NRO0");
|
||||
|
||||
|
||||
static const uint32_t kDefaultFormatVersion = 0;
|
||||
static const size_t kRoCrtSize = 8;
|
||||
static const size_t kModuleIdSize = 32;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
#include <nx/macro.h>
|
||||
|
||||
namespace nx
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
|
||||
namespace nx
|
||||
{
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/List.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <crypto/rsa.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
#include <nx/macro.h>
|
||||
|
||||
namespace nx
|
||||
|
|
|
@ -67,6 +67,8 @@ void nx::AciBinary::toBytes()
|
|||
|
||||
void nx::AciBinary::fromBytes(const byte_t * bytes, size_t len)
|
||||
{
|
||||
clear();
|
||||
|
||||
AciHeader::fromBytes(bytes, len);
|
||||
|
||||
if (getAciSize() > len)
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
#include <nx/AciHeader.h>
|
||||
|
||||
using namespace nx;
|
||||
|
||||
AciHeader::AciHeader()
|
||||
nx::AciHeader::AciHeader()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
AciHeader::AciHeader(const AciHeader & other)
|
||||
nx::AciHeader::AciHeader(const AciHeader & other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
void AciHeader::operator=(const AciHeader & other)
|
||||
void nx::AciHeader::operator=(const AciHeader & other)
|
||||
{
|
||||
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) \
|
||||
&& (mType == other.mType) \
|
||||
|
@ -49,12 +47,12 @@ bool AciHeader::operator==(const AciHeader & other) const
|
|||
&& (mKc == other.mKc);
|
||||
}
|
||||
|
||||
bool AciHeader::operator!=(const AciHeader & other) const
|
||||
bool nx::AciHeader::operator!=(const AciHeader & other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void AciHeader::toBytes()
|
||||
void nx::AciHeader::toBytes()
|
||||
{
|
||||
mRawBinary.alloc(sizeof(sAciHeader));
|
||||
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))
|
||||
{
|
||||
|
@ -149,8 +147,8 @@ void AciHeader::fromBytes(const byte_t * bytes, size_t len)
|
|||
mProgramIdMax = hdr->program_id_info.program_id_restrict.max.get();
|
||||
}
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
mFac.offset = hdr->fac.offset.get() - mHeaderOffset;
|
||||
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();
|
||||
}
|
||||
|
||||
const fnd::Vec<byte_t>& AciHeader::getBytes() const
|
||||
const fnd::Vec<byte_t>& nx::AciHeader::getBytes() const
|
||||
{
|
||||
return mRawBinary;
|
||||
}
|
||||
|
@ -186,7 +184,7 @@ void nx::AciHeader::clear()
|
|||
|
||||
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
|
||||
|
@ -226,12 +224,12 @@ void nx::AciHeader::setHeaderOffset(size_t offset)
|
|||
mHeaderOffset = offset;
|
||||
}
|
||||
|
||||
AciHeader::AciType AciHeader::getAciType() const
|
||||
nx::AciHeader::AciType nx::AciHeader::getAciType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
void AciHeader::setAciType(AciType type)
|
||||
void nx::AciHeader::setAciType(AciType type)
|
||||
{
|
||||
mType = type;
|
||||
}
|
||||
|
@ -256,47 +254,47 @@ void nx::AciHeader::setIsUnqualifiedApproval(bool isUnqualifiedApproval)
|
|||
mIsUnqualifiedApproval = isUnqualifiedApproval;
|
||||
}
|
||||
|
||||
uint64_t AciHeader::getProgramId() const
|
||||
uint64_t nx::AciHeader::getProgramId() const
|
||||
{
|
||||
return mProgramId;
|
||||
}
|
||||
|
||||
void AciHeader::setProgramId(uint64_t program_id)
|
||||
void nx::AciHeader::setProgramId(uint64_t program_id)
|
||||
{
|
||||
mProgramId = program_id;
|
||||
}
|
||||
|
||||
const AciHeader::sSection & AciHeader::getFacPos() const
|
||||
const nx::AciHeader::sSection & nx::AciHeader::getFacPos() const
|
||||
{
|
||||
return mFac;
|
||||
}
|
||||
|
||||
void AciHeader::setFacSize(size_t size)
|
||||
void nx::AciHeader::setFacSize(size_t size)
|
||||
{
|
||||
mFac.size = size;
|
||||
}
|
||||
|
||||
const AciHeader::sSection & AciHeader::getSacPos() const
|
||||
const nx::AciHeader::sSection & nx::AciHeader::getSacPos() const
|
||||
{
|
||||
return mSac;
|
||||
}
|
||||
|
||||
void AciHeader::setSacSize(size_t size)
|
||||
void nx::AciHeader::setSacSize(size_t size)
|
||||
{
|
||||
mSac.size = size;
|
||||
}
|
||||
|
||||
const AciHeader::sSection & AciHeader::getKcPos() const
|
||||
const nx::AciHeader::sSection & nx::AciHeader::getKcPos() const
|
||||
{
|
||||
return mKc;
|
||||
}
|
||||
|
||||
void AciHeader::setKcSize(size_t size)
|
||||
void nx::AciHeader::setKcSize(size_t size)
|
||||
{
|
||||
mKc.size = size;
|
||||
}
|
||||
|
||||
void AciHeader::calculateSectionOffsets()
|
||||
void nx::AciHeader::calculateSectionOffsets()
|
||||
{
|
||||
mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize);
|
||||
mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize);
|
||||
|
|
|
@ -25,7 +25,7 @@ void nx::AcidBinary::operator=(const AcidBinary & other)
|
|||
{
|
||||
if (other.getBytes().size())
|
||||
{
|
||||
importBinary(other.getBytes().data(), other.getBytes().size());
|
||||
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ void nx::AcidBinary::operator=(const AcidBinary & other)
|
|||
void nx::AcidBinary::toBytes()
|
||||
{
|
||||
AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature
|
||||
AciBinary::exportBinary();
|
||||
AciBinary::toBytes();
|
||||
mRawBinary.alloc(AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2);
|
||||
|
||||
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)
|
||||
{
|
||||
exportBinary();
|
||||
toBytes();
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
clear();
|
||||
|
||||
// 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
|
||||
size_t acid_size = AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2;
|
||||
|
|
|
@ -7,39 +7,73 @@ nx::ContentMetaBinary::ContentMetaBinary()
|
|||
|
||||
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");
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
// validate layout
|
||||
validateBinary(bytes, len);
|
||||
validateBinary(data, len);
|
||||
|
||||
// get pointer to header structure
|
||||
const sContentMetaHeader* hdr = (const sContentMetaHeader*)bytes;
|
||||
const sContentMetaHeader* hdr = (const sContentMetaHeader*)data;
|
||||
|
||||
mTitleId = hdr->id.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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
case (cnmt::METATYPE_APPLICATION):
|
||||
mApplicationMetaExtendedHeader.patch_id = ((sApplicationMetaExtendedHeader*)mExtendedHeader.getBytes())->patch_id.get();
|
||||
mApplicationMetaExtendedHeader.required_system_version = ((sApplicationMetaExtendedHeader*)mExtendedHeader.getBytes())->required_system_version.get();
|
||||
mApplicationMetaExtendedHeader.patch_id = ((sApplicationMetaExtendedHeader*)mExtendedHeader.data())->patch_id.get();
|
||||
mApplicationMetaExtendedHeader.required_system_version = ((sApplicationMetaExtendedHeader*)mExtendedHeader.data())->required_system_version.get();
|
||||
break;
|
||||
case (cnmt::METATYPE_PATCH):
|
||||
mPatchMetaExtendedHeader.application_id = ((sPatchMetaExtendedHeader*)mExtendedHeader.getBytes())->application_id.get();
|
||||
mPatchMetaExtendedHeader.required_system_version = ((sPatchMetaExtendedHeader*)mExtendedHeader.getBytes())->required_system_version.get();
|
||||
mPatchMetaExtendedHeader.application_id = ((sPatchMetaExtendedHeader*)mExtendedHeader.data())->application_id.get();
|
||||
mPatchMetaExtendedHeader.required_system_version = ((sPatchMetaExtendedHeader*)mExtendedHeader.data())->required_system_version.get();
|
||||
break;
|
||||
case (cnmt::METATYPE_ADD_ON_CONTENT):
|
||||
mAddOnContentMetaExtendedHeader.application_id = ((sAddOnContentMetaExtendedHeader*)mExtendedHeader.getBytes())->application_id.get();
|
||||
mAddOnContentMetaExtendedHeader.required_system_version = ((sAddOnContentMetaExtendedHeader*)mExtendedHeader.getBytes())->required_system_version.get();
|
||||
mAddOnContentMetaExtendedHeader.application_id = ((sAddOnContentMetaExtendedHeader*)mExtendedHeader.data())->application_id.get();
|
||||
mAddOnContentMetaExtendedHeader.required_system_version = ((sAddOnContentMetaExtendedHeader*)mExtendedHeader.data())->required_system_version.get();
|
||||
break;
|
||||
case (cnmt::METATYPE_DELTA):
|
||||
mDeltaMetaExtendedHeader.application_id = ((sDeltaMetaExtendedHeader*)mExtendedHeader.getBytes())->application_id.get();
|
||||
mDeltaMetaExtendedHeader.application_id = ((sDeltaMetaExtendedHeader*)mExtendedHeader.data())->application_id.get();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
exdata_size = getExtendedDataSize(mType, mExtendedHeader.getBytes());
|
||||
exdata_size = getExtendedDataSize(mType, mExtendedHeader.data());
|
||||
}
|
||||
|
||||
// save content info
|
||||
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++)
|
||||
{
|
||||
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
|
||||
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++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
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()
|
||||
{
|
||||
mRawBinary.clear();
|
||||
|
@ -245,12 +284,12 @@ void nx::ContentMetaBinary::setContentMetaInfo(const fnd::List<nx::ContentMetaBi
|
|||
mContentMetaInfo = info;
|
||||
}
|
||||
|
||||
const fnd::MemoryBlob & nx::ContentMetaBinary::getExtendedData() const
|
||||
const fnd::Vec<byte_t> & nx::ContentMetaBinary::getExtendedData() const
|
||||
{
|
||||
return mExtendedData;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setExtendedData(const fnd::MemoryBlob & data)
|
||||
void nx::ContentMetaBinary::setExtendedData(const fnd::Vec<byte_t> & data)
|
||||
{
|
||||
mExtendedData = data;
|
||||
}
|
||||
|
@ -307,7 +346,7 @@ size_t nx::ContentMetaBinary::getExtendedDataSize(cnmt::ContentMetaType type, co
|
|||
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
|
||||
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
|
||||
const sContentMetaHeader* hdr = (const sContentMetaHeader*)bytes;
|
||||
const sContentMetaHeader* hdr = (const sContentMetaHeader*)data;
|
||||
|
||||
// validate extended header size
|
||||
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
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,9 @@ void nx::FacHeader::fromBytes(const byte_t* data, size_t len)
|
|||
throw fnd::Exception(kModuleName, "FAC header too small");
|
||||
}
|
||||
|
||||
// clear internal members
|
||||
clear();
|
||||
|
||||
mRawBinary.alloc(sizeof(sFacHeader));
|
||||
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||
sFacHeader* hdr = (sFacHeader*)mRawBinary.data();
|
||||
|
@ -85,7 +88,6 @@ void nx::FacHeader::fromBytes(const byte_t* data, size_t len)
|
|||
}
|
||||
mVersion = hdr->version.get();
|
||||
|
||||
clear();
|
||||
for (uint64_t i = 0; i < 64; i++)
|
||||
{
|
||||
if (_HAS_BIT(hdr->fac_flags.get(), i))
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <nx/HandleTableSizeEntry.h>
|
||||
|
||||
|
||||
|
||||
nx::HandleTableSizeEntry::HandleTableSizeEntry() :
|
||||
mCap(kCapId),
|
||||
mHandleTableSize(0)
|
||||
|
@ -21,6 +19,23 @@ nx::HandleTableSizeEntry::HandleTableSizeEntry(uint16_t 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
|
||||
{
|
||||
return mCap;
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
#include <nx/HandleTableSizeHandler.h>
|
||||
|
||||
|
||||
|
||||
nx::HandleTableSizeHandler::HandleTableSizeHandler() :
|
||||
mIsSet(false),
|
||||
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
|
||||
{
|
||||
return isEqual(other);
|
||||
return (mIsSet == other.mIsSet) \
|
||||
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
|
||||
}
|
||||
|
||||
bool nx::HandleTableSizeHandler::operator!=(const HandleTableSizeHandler & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::HandleTableSizeHandler::operator=(const HandleTableSizeHandler & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
if (caps.getSize() == 0)
|
||||
if (caps.size() == 0)
|
||||
return;
|
||||
|
||||
mEntry.setKernelCapability(caps[0]);
|
||||
|
@ -65,15 +65,3 @@ void nx::HandleTableSizeHandler::setHandleTableSize(uint16_t size)
|
|||
mEntry.setHandleTableSize(size);
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <nx/InteruptEntry.h>
|
||||
|
||||
|
||||
|
||||
nx::InteruptEntry::InteruptEntry() :
|
||||
mCap(kCapId),
|
||||
mInterupt{0,0}
|
||||
|
@ -24,6 +22,24 @@ nx::InteruptEntry::InteruptEntry(uint32_t interupt0, uint32_t 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
|
||||
{
|
||||
return mCap;
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
#include <nx/InteruptHandler.h>
|
||||
|
||||
|
||||
|
||||
nx::InteruptHandler::InteruptHandler() :
|
||||
mIsSet(false),
|
||||
mInterupts()
|
||||
{}
|
||||
|
||||
void nx::InteruptHandler::operator=(const InteruptHandler & other)
|
||||
{
|
||||
mIsSet = other.mIsSet;
|
||||
mInterupts = other.mInterupts;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::InteruptHandler::operator=(const InteruptHandler & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void nx::InteruptHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
|
||||
{
|
||||
if (caps.getSize() == 0)
|
||||
if (caps.size() == 0)
|
||||
return;
|
||||
|
||||
// convert to 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]);
|
||||
}
|
||||
|
||||
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
|
||||
if (interupts[i][1] == 0 && i == 0)
|
||||
|
@ -64,12 +64,12 @@ void nx::InteruptHandler::exportKernelCapabilityList(fnd::List<KernelCapability>
|
|||
return;
|
||||
|
||||
size_t i = 0;
|
||||
if (mInterupts.getSize() % 2)
|
||||
if (mInterupts.size() % 2)
|
||||
{
|
||||
caps.addElement(InteruptEntry(mInterupts[i], 0).getKernelCapability());
|
||||
i++;
|
||||
}
|
||||
for (; i < mInterupts.getSize(); i += 2)
|
||||
for (; i < mInterupts.size(); i += 2)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,26 +1,23 @@
|
|||
#include <nx/KernelCapability.h>
|
||||
|
||||
using namespace nx;
|
||||
|
||||
KernelCapability::KernelCapability() :
|
||||
nx::KernelCapability::KernelCapability() :
|
||||
mType(KC_INVALID)
|
||||
{}
|
||||
|
||||
KernelCapability::KernelCapability(KernelCapId type) :
|
||||
nx::KernelCapability::KernelCapability(KernelCapId type) :
|
||||
mType(type),
|
||||
mField(0)
|
||||
{}
|
||||
|
||||
KernelCapability::KernelCapability(KernelCapId type, uint32_t field) :
|
||||
nx::KernelCapability::KernelCapability(KernelCapId type, uint32_t field) :
|
||||
mType(type),
|
||||
mField(field)
|
||||
{}
|
||||
|
||||
const KernelCapability & nx::KernelCapability::operator=(const KernelCapability & other)
|
||||
void nx::KernelCapability::operator=(const KernelCapability & other)
|
||||
{
|
||||
mType = other.mType;
|
||||
mField = other.mField;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool nx::KernelCapability::operator==(const KernelCapability & other) const
|
||||
|
@ -34,33 +31,33 @@ bool nx::KernelCapability::operator!=(const KernelCapability & other) const
|
|||
return !operator==(other);
|
||||
}
|
||||
|
||||
uint32_t KernelCapability::getCap() const
|
||||
uint32_t nx::KernelCapability::getCap() const
|
||||
{
|
||||
return (mField & getFieldMask()) << getFieldShift() | getCapMask();
|
||||
}
|
||||
|
||||
void KernelCapability::setCap(uint32_t cap)
|
||||
void nx::KernelCapability::setCap(uint32_t cap)
|
||||
{
|
||||
mType = getCapId(cap);
|
||||
mField = (cap >> getFieldShift()) & getFieldMask();
|
||||
}
|
||||
|
||||
KernelCapability::KernelCapId KernelCapability::getType() const
|
||||
nx::KernelCapability::KernelCapId nx::KernelCapability::getType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
void KernelCapability::setType(KernelCapId type)
|
||||
void nx::KernelCapability::setType(KernelCapId type)
|
||||
{
|
||||
mType = type;
|
||||
}
|
||||
|
||||
uint32_t KernelCapability::getField() const
|
||||
uint32_t nx::KernelCapability::getField() const
|
||||
{
|
||||
return mField & getFieldMask();
|
||||
}
|
||||
|
||||
void KernelCapability::setField(uint32_t field)
|
||||
void nx::KernelCapability::setField(uint32_t field)
|
||||
{
|
||||
mField = field;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <nx/KernelVersionEntry.h>
|
||||
|
||||
|
||||
|
||||
nx::KernelVersionEntry::KernelVersionEntry() :
|
||||
mCap(kCapId),
|
||||
mVerMajor(0),
|
||||
|
@ -25,6 +23,24 @@ nx::KernelVersionEntry::KernelVersionEntry(uint16_t major, uint8_t 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
|
||||
{
|
||||
return mCap;
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
#include <nx/KernelVersionHandler.h>
|
||||
|
||||
|
||||
|
||||
nx::KernelVersionHandler::KernelVersionHandler() :
|
||||
mIsSet(false),
|
||||
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
|
||||
{
|
||||
return isEqual(other);
|
||||
return (mIsSet == other.mIsSet) \
|
||||
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
|
||||
}
|
||||
|
||||
bool nx::KernelVersionHandler::operator!=(const KernelVersionHandler & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::KernelVersionHandler::operator=(const KernelVersionHandler & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
if (caps.getSize() == 0)
|
||||
if (caps.size() == 0)
|
||||
return;
|
||||
|
||||
mEntry.setKernelCapability(caps[0]);
|
||||
|
@ -78,15 +78,3 @@ void nx::KernelVersionHandler::setVerMinor(uint8_t minor)
|
|||
mEntry.setVerMinor(minor);
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -1,48 +1,51 @@
|
|||
#include <nx/MemoryMappingHandler.h>
|
||||
#include <nx/MemoryPageEntry.h>
|
||||
|
||||
|
||||
nx::MemoryMappingHandler::MemoryMappingHandler() :
|
||||
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
|
||||
{
|
||||
return isEqual(other);
|
||||
return (mIsSet == other.mIsSet) \
|
||||
&& (mMemRange == other.mMemRange) \
|
||||
&& (mMemPage == other.mMemPage);
|
||||
}
|
||||
|
||||
bool nx::MemoryMappingHandler::operator!=(const MemoryMappingHandler & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::MemoryMappingHandler::operator=(const MemoryMappingHandler & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void nx::MemoryMappingHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
|
||||
{
|
||||
if (caps.getSize() == 0)
|
||||
if (caps.size() == 0)
|
||||
return;
|
||||
|
||||
// get entry list
|
||||
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]);
|
||||
}
|
||||
|
||||
mMemRange.clear();
|
||||
mMemPage.clear();
|
||||
for (size_t i = 0; i < entries.getSize();)
|
||||
for (size_t i = 0; i < entries.size();)
|
||||
{
|
||||
// has flag means "MemMap"
|
||||
if (entries[i].isMultiplePages())
|
||||
{
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
@ -94,7 +97,7 @@ void nx::MemoryMappingHandler::exportKernelCapabilityList(fnd::List<KernelCapabi
|
|||
|
||||
// "mem maps"
|
||||
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.setFlag(mMemRange[i].perm == MEM_RO);
|
||||
|
@ -107,7 +110,7 @@ void nx::MemoryMappingHandler::exportKernelCapabilityList(fnd::List<KernelCapabi
|
|||
|
||||
// "io maps"
|
||||
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);
|
||||
caps.addElement(cap.getKernelCapability());
|
||||
|
@ -135,17 +138,3 @@ const fnd::List<nx::MemoryMappingHandler::sMemoryMapping>& nx::MemoryMappingHand
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <nx/MemoryPageEntry.h>
|
||||
|
||||
|
||||
|
||||
nx::MemoryPageEntry::MemoryPageEntry() :
|
||||
mCap(KernelCapability::KC_INVALID),
|
||||
mPage(0),
|
||||
|
@ -37,6 +35,26 @@ nx::MemoryPageEntry::MemoryPageEntry(uint32_t page, bool 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
|
||||
{
|
||||
return mCap;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <nx/MiscFlagsEntry.h>
|
||||
|
||||
|
||||
|
||||
nx::MiscFlagsEntry::MiscFlagsEntry() :
|
||||
mCap(kCapId),
|
||||
mFlags(0)
|
||||
|
@ -21,6 +19,22 @@ nx::MiscFlagsEntry::MiscFlagsEntry(uint32_t 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
|
||||
{
|
||||
return mCap;
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
#include <nx/MiscFlagsHandler.h>
|
||||
|
||||
|
||||
|
||||
nx::MiscFlagsHandler::MiscFlagsHandler() :
|
||||
mIsSet(false)
|
||||
{}
|
||||
|
||||
void nx::MiscFlagsHandler::operator=(const MiscFlagsHandler & other)
|
||||
{
|
||||
mIsSet = other.mIsSet;
|
||||
mFlags = other.mFlags;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::MiscFlagsHandler::operator=(const MiscFlagsHandler & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
if (caps.getSize() == 0)
|
||||
if (caps.size() == 0)
|
||||
return;
|
||||
|
||||
MiscFlagsEntry entry;
|
||||
|
@ -53,7 +53,7 @@ void nx::MiscFlagsHandler::exportKernelCapabilityList(fnd::List<KernelCapability
|
|||
|
||||
// convert list to word flags
|
||||
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]);
|
||||
}
|
||||
|
@ -87,15 +87,3 @@ void nx::MiscFlagsHandler::setFlagList(fnd::List<Flags> flags)
|
|||
mFlags = flags;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <nx/MiscParamsEntry.h>
|
||||
|
||||
|
||||
|
||||
nx::MiscParamsEntry::MiscParamsEntry() :
|
||||
mCap(kCapId),
|
||||
mProgramType(0)
|
||||
|
@ -21,6 +19,22 @@ nx::MiscParamsEntry::MiscParamsEntry(uint8_t 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
|
||||
{
|
||||
return mCap;
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
#include <nx/MiscParamsHandler.h>
|
||||
|
||||
|
||||
|
||||
nx::MiscParamsHandler::MiscParamsHandler() :
|
||||
mIsSet(false),
|
||||
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
|
||||
{
|
||||
return isEqual(other);
|
||||
return (mIsSet == other.mIsSet) \
|
||||
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
|
||||
}
|
||||
|
||||
bool nx::MiscParamsHandler::operator!=(const MiscParamsHandler & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::MiscParamsHandler::operator=(const MiscParamsHandler & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
if (caps.getSize() == 0)
|
||||
if (caps.size() == 0)
|
||||
return;
|
||||
|
||||
mEntry.setKernelCapability(caps[0]);
|
||||
|
@ -66,15 +66,3 @@ void nx::MiscParamsHandler::setProgramType(uint8_t type)
|
|||
mEntry.setProgramType(type);
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
#include <nx/NcaHeader.h>
|
||||
|
||||
using namespace nx;
|
||||
|
||||
NcaHeader::NcaHeader()
|
||||
nx::NcaHeader::NcaHeader()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
NcaHeader::NcaHeader(const NcaHeader & other)
|
||||
nx::NcaHeader::NcaHeader(const NcaHeader & other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
bool NcaHeader::operator==(const NcaHeader & other) const
|
||||
bool nx::NcaHeader::operator==(const NcaHeader & other) const
|
||||
{
|
||||
return (mDistributionType == other.mDistributionType) \
|
||||
&& (mContentType == other.mContentType) \
|
||||
|
@ -26,12 +24,12 @@ bool NcaHeader::operator==(const NcaHeader & other) const
|
|||
&& (mEncAesKeys == other.mEncAesKeys);
|
||||
}
|
||||
|
||||
bool NcaHeader::operator!=(const NcaHeader & other) const
|
||||
bool nx::NcaHeader::operator!=(const NcaHeader & other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void NcaHeader::operator=(const NcaHeader & other)
|
||||
void nx::NcaHeader::operator=(const NcaHeader & other)
|
||||
{
|
||||
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));
|
||||
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))
|
||||
{
|
||||
|
@ -137,7 +135,7 @@ void NcaHeader::fromBytes(const byte_t * data, size_t len)
|
|||
|
||||
mDistributionType = (nca::DistributionType)hdr->distribution_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;
|
||||
mContentSize = *hdr->content_size;
|
||||
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;
|
||||
}
|
||||
|
@ -231,22 +229,22 @@ void nx::NcaHeader::setKaekIndex(byte_t index)
|
|||
mKaekIndex = index;
|
||||
}
|
||||
|
||||
uint64_t NcaHeader::getContentSize() const
|
||||
uint64_t nx::NcaHeader::getContentSize() const
|
||||
{
|
||||
return mContentSize;
|
||||
}
|
||||
|
||||
void NcaHeader::setContentSize(uint64_t size)
|
||||
void nx::NcaHeader::setContentSize(uint64_t size)
|
||||
{
|
||||
mContentSize = size;
|
||||
}
|
||||
|
||||
uint64_t NcaHeader::getProgramId() const
|
||||
uint64_t nx::NcaHeader::getProgramId() const
|
||||
{
|
||||
return mProgramId;
|
||||
}
|
||||
|
||||
void NcaHeader::setProgramId(uint64_t program_id)
|
||||
void nx::NcaHeader::setProgramId(uint64_t program_id)
|
||||
{
|
||||
mProgramId = program_id;
|
||||
}
|
||||
|
@ -294,12 +292,12 @@ void nx::NcaHeader::setRightsId(const byte_t* rights_id)
|
|||
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;
|
||||
}
|
||||
|
||||
void NcaHeader::setPartitions(const fnd::List<NcaHeader::sPartition>& partitions)
|
||||
void nx::NcaHeader::setPartitions(const fnd::List<nx::NcaHeader::sPartition>& partitions)
|
||||
{
|
||||
mPartitions = partitions;
|
||||
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;
|
||||
}
|
||||
|
||||
void NcaHeader::setEncAesKeys(const fnd::List<crypto::aes::sAes128Key>& keys)
|
||||
void nx::NcaHeader::setEncAesKeys(const fnd::List<crypto::aes::sAes128Key>& 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
|
@ -42,8 +42,8 @@ bool nx::NpdmBinary::operator!=(const NpdmBinary & other) const
|
|||
|
||||
void nx::NpdmBinary::toBytes()
|
||||
{
|
||||
mAci.exportBinary();
|
||||
mAcid.exportBinary();
|
||||
mAci.toBytes();
|
||||
mAcid.toBytes();
|
||||
|
||||
setAciSize(mAci.getBytes().size());
|
||||
setAcidSize(mAcid.getBytes().size());
|
||||
|
@ -70,11 +70,11 @@ void nx::NpdmBinary::fromBytes(const byte_t* data, size_t len)
|
|||
// import Aci/Acid
|
||||
if (getAciPos().size)
|
||||
{
|
||||
mAci.importBinary(mRawBinary.data() + getAciPos().offset, getAciPos().size);
|
||||
mAci.fromBytes(mRawBinary.data() + getAciPos().offset, getAciPos().size);
|
||||
}
|
||||
if (getAcidPos().size)
|
||||
{
|
||||
mAcid.importBinary(mRawBinary.data() + getAcidPos().offset, getAcidPos().size);
|
||||
mAcid.fromBytes(mRawBinary.data() + getAcidPos().offset, getAcidPos().size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ void nx::NpdmHeader::operator=(const NpdmHeader & other)
|
|||
{
|
||||
if (other.getBytes().size())
|
||||
{
|
||||
fromBytes(other.getBytes().data, other.getBytes().size());
|
||||
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -80,6 +80,7 @@ void nx::NpdmHeader::fromBytes(const byte_t* data, size_t len)
|
|||
throw fnd::Exception(kModuleName, "NPDM header too small");
|
||||
}
|
||||
|
||||
// clear internal members
|
||||
clear();
|
||||
|
||||
mRawBinary.alloc(sizeof(sNpdmHeader));
|
||||
|
@ -138,7 +139,7 @@ void nx::NpdmHeader::clear()
|
|||
|
||||
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
|
||||
|
|
|
@ -121,6 +121,9 @@ void nx::PfsHeader::fromBytes(const byte_t* data, size_t len)
|
|||
throw fnd::Exception(kModuleName, "PFS header too small");
|
||||
}
|
||||
|
||||
// clear variables
|
||||
clear();
|
||||
|
||||
// import minimum header
|
||||
mRawBinary.alloc(sizeof(sPfsHeader));
|
||||
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||
|
@ -154,9 +157,6 @@ void nx::PfsHeader::fromBytes(const byte_t* data, size_t len)
|
|||
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||
hdr = (const sPfsHeader*)mRawBinary.data();
|
||||
|
||||
// clear variables
|
||||
clear();
|
||||
|
||||
mFsType = fs_type;
|
||||
if (mFsType == TYPE_PFS0)
|
||||
{
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
#include <nx/SacBinary.h>
|
||||
|
||||
using namespace nx;
|
||||
|
||||
SacBinary::SacBinary()
|
||||
nx::SacBinary::SacBinary()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
SacBinary::SacBinary(const SacBinary & other)
|
||||
nx::SacBinary::SacBinary(const SacBinary & other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
void SacBinary::operator=(const SacBinary & other)
|
||||
void nx::SacBinary::operator=(const SacBinary & other)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void SacBinary::toBytes()
|
||||
void nx::SacBinary::toBytes()
|
||||
{
|
||||
size_t totalSize = 0;
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
@ -76,12 +74,12 @@ void nx::SacBinary::clear()
|
|||
mServices.clear();
|
||||
}
|
||||
|
||||
const fnd::List<SacEntry>& SacBinary::getServiceList() const
|
||||
const fnd::List<nx::SacEntry>& nx::SacBinary::getServiceList() const
|
||||
{
|
||||
return mServices;
|
||||
}
|
||||
|
||||
void SacBinary::addService(const SacEntry& service)
|
||||
void nx::SacBinary::addService(const SacEntry& service)
|
||||
{
|
||||
mServices.addElement(service);
|
||||
}
|
|
@ -1,25 +1,23 @@
|
|||
#include <nx/SacEntry.h>
|
||||
|
||||
using namespace nx;
|
||||
|
||||
SacEntry::SacEntry() :
|
||||
nx::SacEntry::SacEntry()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
SacEntry::SacEntry(const std::string & name, bool isServer) :
|
||||
nx::SacEntry::SacEntry(const std::string & name, bool isServer) :
|
||||
mIsServer(isServer),
|
||||
mName(name)
|
||||
{
|
||||
toBytes();
|
||||
}
|
||||
|
||||
SacEntry::SacEntry(const SacEntry & other)
|
||||
nx::SacEntry::SacEntry(const SacEntry & other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
void SacEntry::operator=(const SacEntry & other)
|
||||
void nx::SacEntry::operator=(const SacEntry & other)
|
||||
{
|
||||
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) \
|
||||
&& (mName == other.mName);
|
||||
}
|
||||
|
||||
bool SacEntry::operator!=(const SacEntry & other) const
|
||||
bool nx::SacEntry::operator!=(const SacEntry & other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
void SacEntry::toBytes()
|
||||
void nx::SacEntry::toBytes()
|
||||
{
|
||||
try {
|
||||
mRawBinary.alloc(mName.size() + 1);
|
||||
|
@ -70,7 +68,7 @@ void SacEntry::toBytes()
|
|||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
const fnd::Vec<byte_t>& SacEntry::getBytes() const
|
||||
const fnd::Vec<byte_t>& nx::SacEntry::getBytes() const
|
||||
{
|
||||
return mRawBinary;
|
||||
}
|
||||
|
@ -107,22 +105,22 @@ void nx::SacEntry::clear()
|
|||
mName.clear();
|
||||
}
|
||||
|
||||
bool SacEntry::isServer() const
|
||||
bool nx::SacEntry::isServer() const
|
||||
{
|
||||
return mIsServer;
|
||||
}
|
||||
|
||||
void SacEntry::setIsServer(bool isServer)
|
||||
void nx::SacEntry::setIsServer(bool isServer)
|
||||
{
|
||||
mIsServer = isServer;
|
||||
}
|
||||
|
||||
const std::string & SacEntry::getName() const
|
||||
const std::string & nx::SacEntry::getName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
void SacEntry::setName(const std::string & name)
|
||||
void nx::SacEntry::setName(const std::string & name)
|
||||
{
|
||||
if (name.length() > kMaxServiceNameLen)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <nx/SystemCallEntry.h>
|
||||
|
||||
|
||||
|
||||
nx::SystemCallEntry::SystemCallEntry() :
|
||||
mCap(kCapId),
|
||||
mSystemCallUpper(0),
|
||||
|
@ -27,6 +25,24 @@ nx::SystemCallEntry::SystemCallEntry(uint32_t upper_bits, uint32_t 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
|
||||
{
|
||||
return mCap;
|
||||
|
|
|
@ -1,36 +1,37 @@
|
|||
#include <nx/SystemCallHandler.h>
|
||||
#include <nx/SystemCallEntry.h>
|
||||
|
||||
|
||||
nx::SystemCallHandler::SystemCallHandler() :
|
||||
mIsSet(false),
|
||||
mSystemCalls()
|
||||
{}
|
||||
|
||||
void nx::SystemCallHandler::operator=(const SystemCallHandler & other)
|
||||
{
|
||||
mIsSet = other.mIsSet;
|
||||
mSystemCalls = other.mSystemCalls;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::SystemCallHandler::operator=(const SystemCallHandler & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void nx::SystemCallHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
|
||||
{
|
||||
if (caps.getSize() == 0)
|
||||
if (caps.size() == 0)
|
||||
return;
|
||||
|
||||
SystemCallEntry entry;
|
||||
|
||||
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]);
|
||||
syscallUpper = 24 * entry.getSystemCallUpperBits();
|
||||
|
@ -60,7 +61,7 @@ void nx::SystemCallHandler::exportKernelCapabilityList(fnd::List<KernelCapabilit
|
|||
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)
|
||||
{
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < entries.getSize(); i++)
|
||||
for (size_t i = 0; i < entries.size(); i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
mSystemCalls.clear();
|
||||
for (size_t i = 0; i < calls.getSize(); i++)
|
||||
for (size_t i = 0; i < calls.size(); i++)
|
||||
{
|
||||
if (mSystemCalls[i] > kMaxSystemCall)
|
||||
{
|
||||
|
@ -110,15 +111,3 @@ void nx::SystemCallHandler::setSystemCallList(const fnd::List<uint8_t>& calls)
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <nx/ThreadInfoEntry.h>
|
||||
|
||||
|
||||
|
||||
nx::ThreadInfoEntry::ThreadInfoEntry() :
|
||||
mCap(kCapId),
|
||||
mMinPriority(kDefaultPriority),
|
||||
|
@ -33,6 +31,28 @@ nx::ThreadInfoEntry::ThreadInfoEntry(uint8_t min_priority, uint8_t max_priority,
|
|||
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
|
||||
{
|
||||
return mCap;
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
#include <nx/ThreadInfoHandler.h>
|
||||
|
||||
|
||||
|
||||
nx::ThreadInfoHandler::ThreadInfoHandler() :
|
||||
mIsSet(false),
|
||||
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
|
||||
{
|
||||
return isEqual(other);
|
||||
return (mIsSet == other.mIsSet) \
|
||||
&& (mEntry.getKernelCapability() == other.mEntry.getKernelCapability());
|
||||
}
|
||||
|
||||
bool nx::ThreadInfoHandler::operator!=(const ThreadInfoHandler & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::ThreadInfoHandler::operator=(const ThreadInfoHandler & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
if (caps.getSize() == 0)
|
||||
if (caps.size() == 0)
|
||||
return;
|
||||
|
||||
mEntry.setKernelCapability(caps[0]);
|
||||
|
@ -101,15 +101,3 @@ void nx::ThreadInfoHandler::setMaxCpuId(uint8_t core_num)
|
|||
mEntry.setMaxCpuId(core_num);
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -45,35 +45,35 @@ void nx::XciHeader::operator=(const XciHeader& other)
|
|||
|
||||
bool nx::XciHeader::operator==(const XciHeader& other) const
|
||||
{
|
||||
return (mRomAreaStartPage == other.mRomAreaStartPage \
|
||||
&& mBackupAreaStartPage == other.mBackupAreaStartPage \
|
||||
&& mKekIndex == other.mKekIndex \
|
||||
&& mTitleKeyDecIndex == other.mTitleKeyDecIndex \
|
||||
&& mRomSize == other.mRomSize \
|
||||
&& mCardHeaderVersion == other.mCardHeaderVersion \
|
||||
&& mFlags == other.mFlags \
|
||||
&& mPackageId == other.mPackageId \
|
||||
&& mValidDataEndPage == other.mValidDataEndPage \
|
||||
&& mAesCbcIv == other.mAesCbcIv \
|
||||
&& mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress \
|
||||
&& mPartitionFsHeaderSize == other.mPartitionFsHeaderSize \
|
||||
&& mPartitionFsHeaderHash == other.mPartitionFsHeaderHash \
|
||||
&& mInitialDataHash == other.mInitialDataHash \
|
||||
&& mSelSec == other.mSelSec \
|
||||
&& mSelT1Key == other.mSelT1Key \
|
||||
&& mSelKey == other.mSelKey \
|
||||
&& mLimAreaPage == other.mLimAreaPage \
|
||||
&& mFwVersion[0] == other.mFwVersion[0] \
|
||||
&& mFwVersion[1] == other.mFwVersion[1] \
|
||||
&& mAccCtrl1 == other.mAccCtrl1 \
|
||||
&& mWait1TimeRead == other.mWait1TimeRead \
|
||||
&& mWait2TimeRead == other.mWait2TimeRead \
|
||||
&& mWait1TimeWrite == other.mWait1TimeWrite \
|
||||
&& mWait2TimeWrite == other.mWait2TimeWrite \
|
||||
&& mFwMode == other.mFwMode \
|
||||
&& mUppVersion == other.mUppVersion \
|
||||
&& memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) \
|
||||
&& mUppId == other.mUppId);
|
||||
return (mRomAreaStartPage == other.mRomAreaStartPage)
|
||||
&& (mBackupAreaStartPage == other.mBackupAreaStartPage)
|
||||
&& (mKekIndex == other.mKekIndex)
|
||||
&& (mTitleKeyDecIndex == other.mTitleKeyDecIndex)
|
||||
&& (mRomSize == other.mRomSize)
|
||||
&& (mCardHeaderVersion == other.mCardHeaderVersion)
|
||||
&& (mFlags == other.mFlags)
|
||||
&& (mPackageId == other.mPackageId)
|
||||
&& (mValidDataEndPage == other.mValidDataEndPage)
|
||||
&& (mAesCbcIv == other.mAesCbcIv)
|
||||
&& (mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress)
|
||||
&& (mPartitionFsHeaderSize == other.mPartitionFsHeaderSize)
|
||||
&& (mPartitionFsHeaderHash == other.mPartitionFsHeaderHash)
|
||||
&& (mInitialDataHash == other.mInitialDataHash)
|
||||
&& (mSelSec == other.mSelSec)
|
||||
&& (mSelT1Key == other.mSelT1Key)
|
||||
&& (mSelKey == other.mSelKey)
|
||||
&& (mLimAreaPage == other.mLimAreaPage)
|
||||
&& (mFwVersion[0] == other.mFwVersion[0])
|
||||
&& (mFwVersion[1] == other.mFwVersion[1])
|
||||
&& (mAccCtrl1 == other.mAccCtrl1)
|
||||
&& (mWait1TimeRead == other.mWait1TimeRead)
|
||||
&& (mWait2TimeRead == other.mWait2TimeRead)
|
||||
&& (mWait1TimeWrite == other.mWait1TimeWrite)
|
||||
&& (mWait2TimeWrite == other.mWait2TimeWrite)
|
||||
&& (mFwMode == other.mFwMode)
|
||||
&& (mUppVersion == other.mUppVersion)
|
||||
&& (memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) == 0)
|
||||
&& (mUppId == other.mUppId);
|
||||
}
|
||||
|
||||
bool nx::XciHeader::operator!=(const XciHeader& other) const
|
||||
|
|
|
@ -39,18 +39,18 @@ void AesCtrWrappedIFile::read(byte_t* out, size_t len)
|
|||
|
||||
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);
|
||||
|
||||
//printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len);
|
||||
|
||||
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::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);
|
||||
|
@ -71,18 +71,18 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len)
|
|||
|
||||
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);
|
||||
|
||||
//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::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->write(mCache.getBytes(), kCacheSizeAllocSize);
|
||||
mFile->write(mCache.data(), kCacheSizeAllocSize);
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
memcpy(mScratch.getBytes() + mBlockOffset, out + (i * kAesCtrScratchSize), kAesCtrScratchSize);
|
||||
crypto::aes::AesCtr(mScratch.getBytes(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.getBytes());
|
||||
mFile->write(mScratch.getBytes() + mBlockOffset, kAesCtrScratchSize);
|
||||
memcpy(mScratch.data() + mBlockOffset, out + (i * kAesCtrScratchSize), kAesCtrScratchSize);
|
||||
crypto::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data());
|
||||
mFile->write(mScratch.data() + mBlockOffset, kAesCtrScratchSize);
|
||||
}
|
||||
|
||||
if (len % kAesCtrScratchSize)
|
||||
{
|
||||
size_t write_len = len % kAesCtrScratchSize;
|
||||
size_t write_pos = ((len / kAesCtrScratchSize) * kAesCtrScratchSize);
|
||||
memcpy(mScratch.getBytes() + mBlockOffset, out + write_pos, write_len);
|
||||
crypto::aes::AesCtr(mScratch.getBytes(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.getBytes());
|
||||
mFile->write(mScratch.getBytes() + mBlockOffset, write_len);
|
||||
memcpy(mScratch.data() + mBlockOffset, out + write_pos, write_len);
|
||||
crypto::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data());
|
||||
mFile->write(mScratch.data() + mBlockOffset, write_len);
|
||||
}
|
||||
*/
|
||||
seek(mFileOffset + len);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <fnd/IFile.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <crypto/aes.h>
|
||||
|
||||
class AesCtrWrappedIFile : public fnd::IFile
|
||||
|
@ -25,5 +25,5 @@ private:
|
|||
crypto::aes::sAesIvCtr mBaseCtr, mCurrentCtr;
|
||||
size_t mFileOffset;
|
||||
|
||||
fnd::MemoryBlob mCache;
|
||||
fnd::Vec<byte_t> mCache;
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
#include <fnd/SimpleFile.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include "AssetProcess.h"
|
||||
#include "OffsetAdjustedIFile.h"
|
||||
|
||||
|
@ -73,16 +73,16 @@ void AssetProcess::setRomfsExtractPath(const std::string& path)
|
|||
|
||||
void AssetProcess::importHeader()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
if (mFile->size() < sizeof(nx::sAssetHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Corrupt ASET: file too small");
|
||||
}
|
||||
|
||||
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()
|
||||
|
@ -93,11 +93,11 @@ void AssetProcess::processSections()
|
|||
throw fnd::Exception(kModuleName, "ASET geometry for icon beyond file size");
|
||||
|
||||
fnd::SimpleFile outfile(mIconExtractPath.var, fnd::SimpleFile::Create);
|
||||
fnd::MemoryBlob cache;
|
||||
fnd::Vec<byte_t> cache;
|
||||
|
||||
cache.alloc(mHdr.getIconInfo().size);
|
||||
mFile->read(cache.getBytes(), mHdr.getIconInfo().offset, cache.getSize());
|
||||
outfile.write(cache.getBytes(), cache.getSize());
|
||||
mFile->read(cache.data(), mHdr.getIconInfo().offset, cache.size());
|
||||
outfile.write(cache.data(), cache.size());
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
|
@ -109,11 +109,11 @@ void AssetProcess::processSections()
|
|||
if (mNacpExtractPath.isSet)
|
||||
{
|
||||
fnd::SimpleFile outfile(mNacpExtractPath.var, fnd::SimpleFile::Create);
|
||||
fnd::MemoryBlob cache;
|
||||
fnd::Vec<byte_t> cache;
|
||||
|
||||
cache.alloc(mHdr.getNacpInfo().size);
|
||||
mFile->read(cache.getBytes(), mHdr.getNacpInfo().offset, cache.getSize());
|
||||
outfile.write(cache.getBytes(), cache.getSize());
|
||||
mFile->read(cache.data(), mHdr.getNacpInfo().offset, cache.size());
|
||||
outfile.write(cache.data(), cache.size());
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
|
|
|
@ -100,10 +100,10 @@ void CnmtProcess::displayCmnt()
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (mCnmt.getContentInfo().getSize() > 0)
|
||||
if (mCnmt.getContentInfo().size() > 0)
|
||||
{
|
||||
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];
|
||||
printf(" %d\n", (int)i);
|
||||
|
@ -117,10 +117,10 @@ void CnmtProcess::displayCmnt()
|
|||
printf("\n");
|
||||
}
|
||||
}
|
||||
if (mCnmt.getContentMetaInfo().getSize() > 0)
|
||||
if (mCnmt.getContentMetaInfo().size() > 0)
|
||||
{
|
||||
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];
|
||||
printf(" %d\n", (int)i);
|
||||
|
@ -159,7 +159,7 @@ CnmtProcess::~CnmtProcess()
|
|||
|
||||
void CnmtProcess::process()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
{
|
||||
|
@ -167,9 +167,9 @@ void CnmtProcess::process()
|
|||
}
|
||||
|
||||
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))
|
||||
displayCmnt();
|
||||
|
|
|
@ -5,19 +5,19 @@ ElfSymbolParser::ElfSymbolParser()
|
|||
mSymbolList.clear();
|
||||
}
|
||||
|
||||
void ElfSymbolParser::operator=(const ElfSymbolParser& other)
|
||||
{
|
||||
mSymbolList = other.mSymbolList;
|
||||
}
|
||||
|
||||
bool ElfSymbolParser::operator==(const ElfSymbolParser& other) const
|
||||
{
|
||||
return isEqual(other);
|
||||
return mSymbolList == other.mSymbolList;
|
||||
}
|
||||
|
||||
bool ElfSymbolParser::operator!=(const ElfSymbolParser& other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void ElfSymbolParser::operator=(const ElfSymbolParser& other)
|
||||
{
|
||||
copyFrom(other);
|
||||
return !(*this == 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)
|
||||
|
@ -60,13 +60,3 @@ const fnd::List<ElfSymbolParser::sElfSymbol>& ElfSymbolParser::getSymbolList() c
|
|||
{
|
||||
return mSymbolList;
|
||||
}
|
||||
|
||||
bool ElfSymbolParser::isEqual(const ElfSymbolParser& other) const
|
||||
{
|
||||
return mSymbolList == other.mSymbolList;
|
||||
}
|
||||
|
||||
void ElfSymbolParser::copyFrom(const ElfSymbolParser& other)
|
||||
{
|
||||
mSymbolList = other.mSymbolList;
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ public:
|
|||
|
||||
ElfSymbolParser();
|
||||
|
||||
void operator=(const ElfSymbolParser& other);
|
||||
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);
|
||||
|
||||
|
@ -45,7 +45,4 @@ private:
|
|||
|
||||
// data
|
||||
fnd::List<sElfSymbol> mSymbolList;
|
||||
|
||||
bool isEqual(const ElfSymbolParser& other) const;
|
||||
void copyFrom(const ElfSymbolParser& other);
|
||||
};
|
|
@ -9,79 +9,47 @@ HashTreeMeta::HashTreeMeta() :
|
|||
|
||||
}
|
||||
|
||||
HashTreeMeta::HashTreeMeta(const nx::HierarchicalIntegrityHeader& hdr) :
|
||||
mLayerInfo(),
|
||||
mDataLayer(),
|
||||
mMasterHashList(),
|
||||
mDoAlignHashToBlock(false)
|
||||
HashTreeMeta::HashTreeMeta(const byte_t* data, size_t len, HashTreeType type) :
|
||||
HashTreeMeta()
|
||||
{
|
||||
importHierarchicalIntergityHeader(hdr);
|
||||
}
|
||||
|
||||
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);
|
||||
importData(data, len, type);
|
||||
}
|
||||
|
||||
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;
|
||||
for (size_t i = 0; i < hdr.getLayerInfo().getSize(); i++)
|
||||
{
|
||||
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().getSize())
|
||||
{
|
||||
mDataLayer = layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLayerInfo.addElement(layer);
|
||||
}
|
||||
}
|
||||
mMasterHashList = hdr.getMasterHashList();
|
||||
return (mLayerInfo == other.mLayerInfo) \
|
||||
&& (mDataLayer == other.mDataLayer) \
|
||||
&& (mMasterHashList == other.mMasterHashList) \
|
||||
&& (mDoAlignHashToBlock == other.mDoAlignHashToBlock);
|
||||
}
|
||||
|
||||
void HashTreeMeta::importHierarchicalSha256Header(const nx::HierarchicalSha256Header& hdr)
|
||||
bool HashTreeMeta::operator!=(const HashTreeMeta& other) const
|
||||
{
|
||||
mDoAlignHashToBlock = false;
|
||||
for (size_t i = 0; i < hdr.getLayerInfo().getSize(); i++)
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void HashTreeMeta::importData(const byte_t* data, size_t len, HashTreeType type)
|
||||
{
|
||||
if (type == HASH_TYPE_INTEGRITY)
|
||||
{
|
||||
sLayer layer;
|
||||
layer.offset = hdr.getLayerInfo()[i].offset;
|
||||
layer.size = hdr.getLayerInfo()[i].size;
|
||||
layer.block_size = hdr.getHashBlockSize();
|
||||
if (i+1 == hdr.getLayerInfo().getSize())
|
||||
nx::HierarchicalIntegrityHeader hdr;
|
||||
hdr.fromBytes(data, len);
|
||||
importHierarchicalIntergityHeader(hdr);
|
||||
}
|
||||
else if (type == HASH_TYPE_SHA256)
|
||||
{
|
||||
mDataLayer = layer;
|
||||
nx::HierarchicalSha256Header hdr;
|
||||
hdr.fromBytes(data, len);
|
||||
importHierarchicalSha256Header(hdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLayerInfo.addElement(layer);
|
||||
}
|
||||
}
|
||||
mMasterHashList.addElement(hdr.getMasterHash());
|
||||
}
|
||||
|
||||
const fnd::List<HashTreeMeta::sLayer>& HashTreeMeta::getHashLayerInfo() const
|
||||
|
@ -124,18 +92,44 @@ void HashTreeMeta::setAlignHashToBlock(bool doAlign)
|
|||
mDoAlignHashToBlock = doAlign;
|
||||
}
|
||||
|
||||
bool HashTreeMeta::isEqual(const HashTreeMeta& other) const
|
||||
void HashTreeMeta::importHierarchicalIntergityHeader(const nx::HierarchicalIntegrityHeader& hdr)
|
||||
{
|
||||
return (mLayerInfo == other.mLayerInfo) \
|
||||
&& (mDataLayer == other.mDataLayer) \
|
||||
&& (mMasterHashList == other.mMasterHashList) \
|
||||
&& (mDoAlignHashToBlock == other.mDoAlignHashToBlock);
|
||||
mDoAlignHashToBlock = true;
|
||||
for (size_t i = 0; i < hdr.getLayerInfo().size(); i++)
|
||||
{
|
||||
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;
|
||||
mDataLayer = other.mDataLayer;
|
||||
mMasterHashList = other.mMasterHashList;
|
||||
mDoAlignHashToBlock = other.mDoAlignHashToBlock;
|
||||
mDoAlignHashToBlock = false;
|
||||
for (size_t i = 0; i < hdr.getLayerInfo().size(); i++)
|
||||
{
|
||||
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());
|
||||
}
|
|
@ -5,6 +5,12 @@
|
|||
class HashTreeMeta
|
||||
{
|
||||
public:
|
||||
enum HashTreeType
|
||||
{
|
||||
HASH_TYPE_INTEGRITY,
|
||||
HASH_TYPE_SHA256
|
||||
};
|
||||
|
||||
struct sLayer
|
||||
{
|
||||
size_t offset;
|
||||
|
@ -30,15 +36,13 @@ public:
|
|||
};
|
||||
|
||||
HashTreeMeta();
|
||||
HashTreeMeta(const nx::HierarchicalIntegrityHeader& hdr);
|
||||
HashTreeMeta(const nx::HierarchicalSha256Header& hdr);
|
||||
HashTreeMeta(const byte_t* data, size_t len, HashTreeType type);
|
||||
|
||||
void operator=(const HashTreeMeta& other);
|
||||
bool operator==(const HashTreeMeta& other) const;
|
||||
bool operator!=(const HashTreeMeta& other) const;
|
||||
void operator=(const HashTreeMeta& other);
|
||||
|
||||
void importHierarchicalIntergityHeader(const nx::HierarchicalIntegrityHeader& hdr);
|
||||
void importHierarchicalSha256Header(const nx::HierarchicalSha256Header& hdr);
|
||||
void importData(const byte_t* data, size_t len, HashTreeType type);
|
||||
|
||||
const fnd::List<sLayer>& getHashLayerInfo() const;
|
||||
void setHashLayerInfo(const fnd::List<sLayer>& layer_info);
|
||||
|
@ -59,6 +63,6 @@ private:
|
|||
fnd::List<crypto::sha::sSha256Hash> mMasterHashList;
|
||||
bool mDoAlignHashToBlock;
|
||||
|
||||
bool isEqual(const HashTreeMeta& other) const;
|
||||
void copyFrom(const HashTreeMeta& other);
|
||||
void importHierarchicalIntergityHeader(const nx::HierarchicalIntegrityHeader& hdr);
|
||||
void importHierarchicalSha256Header(const nx::HierarchicalSha256Header& hdr);
|
||||
};
|
|
@ -68,7 +68,7 @@ void HashTreeWrappedIFile::read(byte_t* out, size_t len)
|
|||
readData(start_block + (i * mCacheBlockNum), block_read_len);
|
||||
|
||||
// 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
|
||||
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)
|
||||
{
|
||||
crypto::sha::sSha256Hash hash;
|
||||
fnd::MemoryBlob cur, prev;
|
||||
fnd::Vec<byte_t> cur, prev;
|
||||
|
||||
mAlignHashCalcToBlock = hdr.getAlignHashToBlock();
|
||||
|
||||
// copy master hash into prev
|
||||
prev.alloc(sizeof(crypto::sha::sSha256Hash) * hdr.getMasterHashList().getSize());
|
||||
for (size_t i = 0; i < hdr.getMasterHashList().getSize(); i++)
|
||||
prev.alloc(sizeof(crypto::sha::sSha256Hash) * hdr.getMasterHashList().size());
|
||||
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
|
||||
for (size_t i = 0; i < hdr.getHashLayerInfo().getSize(); i++)
|
||||
for (size_t i = 0; i < hdr.getHashLayerInfo().size(); i++)
|
||||
{
|
||||
// get block size
|
||||
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));
|
||||
|
||||
// read layer
|
||||
mFile->read(cur.getBytes(), layer.offset, layer.size);
|
||||
mFile->read(cur.data(), layer.offset, layer.size);
|
||||
|
||||
// validate blocks
|
||||
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);
|
||||
crypto::sha::Sha256(cur.getBytes() + (j * layer.block_size), validate_size, hash.bytes);
|
||||
if (hash.compare(prev.getBytes() + j * sizeof(crypto::sha::sSha256Hash)) == false)
|
||||
validate_size = mAlignHashCalcToBlock? layer.block_size : _MIN(layer.size - (j * layer.block_size), layer.block_size);
|
||||
crypto::sha::Sha256(cur.data() + (j * layer.block_size), validate_size, hash.bytes);
|
||||
if (hash.compare(prev.data() + j * sizeof(crypto::sha::sSha256Hash)) == false)
|
||||
{
|
||||
mErrorSs << "Hash tree layer verification failed (layer: " << i << ", block: " << j << ")";
|
||||
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
|
||||
crypto::sha::sSha256Hash* hash_list = (crypto::sha::sSha256Hash*)prev.getBytes();
|
||||
for (size_t i = 0; i < prev.getSize() / sizeof(crypto::sha::sSha256Hash); i++)
|
||||
crypto::sha::sSha256Hash* hash_list = (crypto::sha::sSha256Hash*)prev.data();
|
||||
for (size_t i = 0; i < prev.size() / sizeof(crypto::sha::sSha256Hash); 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()))
|
||||
{
|
||||
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()))
|
||||
{
|
||||
|
@ -180,7 +180,7 @@ void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
|
|||
}
|
||||
|
||||
// read
|
||||
mData->read(mCache.getBytes(), block_offset * mDataBlockSize, read_len);
|
||||
mData->read(mCache.data(), block_offset * mDataBlockSize, read_len);
|
||||
|
||||
if (block_num > mCacheBlockNum)
|
||||
{
|
||||
|
@ -193,8 +193,8 @@ void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
|
|||
size_t validate_size;
|
||||
for (size_t i = 0; i < block_num; i++)
|
||||
{
|
||||
validate_size = mAlignHashCalcToBlock? mDataBlockSize : MIN(read_len - (i * mDataBlockSize), mDataBlockSize);
|
||||
crypto::sha::Sha256(mCache.getBytes() + (i * mDataBlockSize), validate_size, hash.bytes);
|
||||
validate_size = mAlignHashCalcToBlock? mDataBlockSize : _MIN(read_len - (i * mDataBlockSize), mDataBlockSize);
|
||||
crypto::sha::Sha256(mCache.data() + (i * mDataBlockSize), validate_size, hash.bytes);
|
||||
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 <<")";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include <sstream>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <crypto/sha.h>
|
||||
#include "HashTreeMeta.h"
|
||||
|
||||
|
@ -33,7 +33,7 @@ private:
|
|||
fnd::List<crypto::sha::sSha256Hash> mDataHashLayer;
|
||||
bool mAlignHashCalcToBlock;
|
||||
|
||||
fnd::MemoryBlob mCache;
|
||||
fnd::Vec<byte_t> mCache;
|
||||
size_t mCacheBlockNum;
|
||||
|
||||
inline size_t getOffsetBlock(size_t offset) const { return offset / mDataBlockSize; }
|
||||
|
|
|
@ -441,7 +441,7 @@ NacpProcess::~NacpProcess()
|
|||
|
||||
void NacpProcess::process()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
{
|
||||
|
@ -449,9 +449,9 @@ void NacpProcess::process()
|
|||
}
|
||||
|
||||
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))
|
||||
displayNacp();
|
||||
|
@ -485,7 +485,7 @@ void NacpProcess::displayNacp()
|
|||
printf(" DisplayVersion: %s\n", mNacp.getDisplayVersion().c_str());
|
||||
if (mNacp.getIsbn().empty() == false || _HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
|
||||
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(" Name: %s\n", mNacp.getTitle()[i].name.c_str());
|
||||
|
@ -501,17 +501,17 @@ void NacpProcess::displayNacp()
|
|||
printf(" Play Log:\n");
|
||||
printf(" PlayLogPolicy: %s\n", getPlayLogPolicyStr(mNacp.getPlayLogPolicy()));
|
||||
printf(" PlayLogQueryCapability: %s\n", getPlayLogQueryCapabilityStr(mNacp.getPlayLogQueryCapability()));
|
||||
if (mNacp.getPlayLogQueryableApplicationId().getSize() > 0)
|
||||
if (mNacp.getPlayLogQueryableApplicationId().size() > 0)
|
||||
{
|
||||
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(" Parental Controls:\n");
|
||||
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(" Agency: %s\n", getOrganisationStr(mNacp.getRatingAge()[i].organisation));
|
||||
|
@ -524,11 +524,11 @@ void NacpProcess::displayNacp()
|
|||
printf(" BcatPassphase: %s\n", mNacp.getBcatPassphase().c_str());
|
||||
printf(" DeliveryCacheStorageSize: 0x%016" PRIx64 "\n", mNacp.getBcatDeliveryCacheStorageSize());
|
||||
}
|
||||
if (mNacp.getLocalCommunicationId().getSize() > 0)
|
||||
if (mNacp.getLocalCommunicationId().size() > 0)
|
||||
{
|
||||
printf(" Local Area Communication:\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]);
|
||||
}
|
||||
|
|
|
@ -253,8 +253,6 @@ NcaProcess::~NcaProcess()
|
|||
|
||||
void NcaProcess::process()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
{
|
||||
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);
|
||||
|
||||
// proccess main header
|
||||
mHdr.importBinary((byte_t*)&mHdrBlock.header, sizeof(nx::sNcaHeader));
|
||||
mHdr.fromBytes((byte_t*)&mHdrBlock.header, sizeof(nx::sNcaHeader));
|
||||
|
||||
// determine keys
|
||||
generateNcaBodyEncryptionKeys();
|
||||
|
@ -423,7 +421,7 @@ void NcaProcess::generateNcaBodyEncryptionKeys()
|
|||
{
|
||||
crypto::aes::sAes128Key keak_aesctr_key = zero_aesctr_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)
|
||||
{
|
||||
|
@ -485,7 +483,7 @@ void NcaProcess::generatePartitionConfiguration()
|
|||
{
|
||||
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
|
||||
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.enc_type = (nx::nca::EncryptionType)fs_header.encryption_type;
|
||||
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)
|
||||
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
|
||||
try
|
||||
|
@ -614,7 +611,7 @@ void NcaProcess::validateNcaSignatures()
|
|||
// open main.npdm
|
||||
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;
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
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(" <--------------------------------------------------------------------------->\n");
|
||||
printf(" | IDX | ENCRYPTED KEY | DECRYPTED KEY |\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);
|
||||
|
||||
|
@ -698,7 +693,7 @@ void NcaProcess::displayHeader()
|
|||
if (_HAS_BIT(mCliOutputMode, OUTPUT_LAYOUT))
|
||||
{
|
||||
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];
|
||||
|
||||
|
@ -721,8 +716,8 @@ void NcaProcess::displayHeader()
|
|||
printf(" HierarchicalIntegrity Header:\n");
|
||||
//printf(" TypeId: 0x%x\n", hash_hdr.type_id.get());
|
||||
//printf(" MasterHashSize: 0x%x\n", hash_hdr.master_hash_size.get());
|
||||
//printf(" LayerNum: %d\n", hash_hdr.getLayerInfo().getSize());
|
||||
for (size_t j = 0; j < hash_hdr.getHashLayerInfo().getSize(); j++)
|
||||
//printf(" LayerNum: %d\n", hash_hdr.getLayerInfo().size());
|
||||
for (size_t j = 0; j < hash_hdr.getHashLayerInfo().size(); j++)
|
||||
{
|
||||
printf(" Hash Layer %d:\n", (int)j);
|
||||
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(" Size: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getDataLayer().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);
|
||||
fnd::SimpleTextOutput::hexDump(hash_hdr.getMasterHashList()[j].bytes, sizeof(crypto::sha::sSha256Hash));
|
||||
|
@ -747,7 +742,7 @@ void NcaProcess::displayHeader()
|
|||
printf(" Master Hash: ");
|
||||
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(" LayerNum: %d\n", hash_hdr.getLayerInfo().getSize());
|
||||
//printf(" LayerNum: %d\n", hash_hdr.getLayerInfo().size());
|
||||
printf(" Hash Layer:\n");
|
||||
printf(" Offset: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getHashLayerInfo()[0].offset);
|
||||
printf(" Size: 0x%" PRIx64 "\n", (uint64_t)hash_hdr.getHashLayerInfo()[0].size);
|
||||
|
@ -770,7 +765,7 @@ void NcaProcess::displayHeader()
|
|||
|
||||
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;
|
||||
struct sPartitionInfo& partition = mPartitions[index];
|
||||
|
|
|
@ -19,7 +19,7 @@ NpdmProcess::~NpdmProcess()
|
|||
|
||||
void NpdmProcess::process()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
{
|
||||
|
@ -27,9 +27,9 @@ void NpdmProcess::process()
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
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;
|
||||
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])
|
||||
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;
|
||||
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])
|
||||
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;
|
||||
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])
|
||||
rightFound = true;
|
||||
|
@ -371,10 +371,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
|
|||
}
|
||||
|
||||
// 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;
|
||||
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])
|
||||
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());
|
||||
}
|
||||
// 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;
|
||||
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])
|
||||
rightFound = true;
|
||||
|
@ -422,10 +422,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
|
|||
}
|
||||
}
|
||||
// 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;
|
||||
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])
|
||||
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());
|
||||
}
|
||||
}
|
||||
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;
|
||||
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])
|
||||
rightFound = true;
|
||||
|
@ -455,10 +455,10 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi
|
|||
}
|
||||
}
|
||||
// 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;
|
||||
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])
|
||||
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());
|
||||
}
|
||||
// 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;
|
||||
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])
|
||||
rightFound = true;
|
||||
|
@ -549,10 +549,10 @@ void NpdmProcess::displayFac(const nx::FacBinary& fac)
|
|||
printf("[FS Access Control]\n");
|
||||
printf(" Format Version: %d\n", fac.getFormatVersion());
|
||||
|
||||
if (fac.getFsaRightsList().getSize())
|
||||
if (fac.getFsaRightsList().size())
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -566,18 +566,18 @@ void NpdmProcess::displayFac(const nx::FacBinary& fac)
|
|||
printf(" FS Rights: NONE\n");
|
||||
}
|
||||
|
||||
if (fac.getContentOwnerIdList().getSize())
|
||||
if (fac.getContentOwnerIdList().size())
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
if (fac.getSaveDataOwnerIdList().getSize())
|
||||
if (fac.getSaveDataOwnerIdList().size())
|
||||
{
|
||||
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]);
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ void NpdmProcess::displaySac(const nx::SacBinary& sac)
|
|||
{
|
||||
printf("[Service Access Control]\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)
|
||||
{
|
||||
|
@ -618,7 +618,7 @@ void NpdmProcess::displayKernelCap(const nx::KcBinary& kern)
|
|||
printf(" SystemCalls:");
|
||||
printf("\n ");
|
||||
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)
|
||||
{
|
||||
|
@ -635,12 +635,12 @@ void NpdmProcess::displayKernelCap(const nx::KcBinary& kern)
|
|||
fnd::List<nx::MemoryMappingHandler::sMemoryMapping> ioMaps = kern.getMemoryMaps().getIoMemoryMaps();
|
||||
|
||||
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(" 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());
|
||||
}
|
||||
|
@ -649,7 +649,7 @@ void NpdmProcess::displayKernelCap(const nx::KcBinary& kern)
|
|||
{
|
||||
fnd::List<uint16_t> interupts = kern.getInterupts().getInteruptList();
|
||||
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)
|
||||
{
|
||||
|
@ -675,7 +675,7 @@ void NpdmProcess::displayKernelCap(const nx::KcBinary& kern)
|
|||
fnd::List<nx::MiscFlagsHandler::Flags> flagList = kern.getMiscFlags().getFlagList();
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <fnd/SimpleTextOutput.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <compress/lz4.h>
|
||||
#include <nx/nro-hb.h>
|
||||
#include "OffsetAdjustedIFile.h"
|
||||
|
@ -93,19 +93,19 @@ void NroProcess::setAssetRomfsExtractPath(const std::string& path)
|
|||
|
||||
void NroProcess::importHeader()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
if (mFile->size() < sizeof(nx::sNroHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Corrupt NRO: file too small");
|
||||
}
|
||||
|
||||
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
|
||||
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())
|
||||
{
|
||||
mIsHomebrewNro = true;
|
||||
|
@ -120,11 +120,11 @@ void NroProcess::importHeader()
|
|||
void NroProcess::importCodeSegments()
|
||||
{
|
||||
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);
|
||||
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);
|
||||
mFile->read(mDataBlob.getBytes(), mHdr.getDataInfo().memory_offset, mDataBlob.getSize());
|
||||
mFile->read(mDataBlob.data(), mHdr.getDataInfo().memory_offset, mDataBlob.size());
|
||||
}
|
||||
|
||||
void NroProcess::displayHeader()
|
||||
|
@ -168,7 +168,7 @@ void NroProcess::displayHeader()
|
|||
|
||||
void NroProcess::processRoMeta()
|
||||
{
|
||||
if (mRoBlob.getSize())
|
||||
if (mRoBlob.size())
|
||||
{
|
||||
// setup ro metadata
|
||||
mRoMeta.setApiInfo(mHdr.getRoEmbeddedInfo().memory_offset, mHdr.getRoEmbeddedInfo().size);
|
||||
|
|
|
@ -41,7 +41,7 @@ private:
|
|||
bool mVerify;
|
||||
|
||||
nx::NroHeader mHdr;
|
||||
fnd::MemoryBlob mTextBlob, mRoBlob, mDataBlob;
|
||||
fnd::Vec<byte_t> mTextBlob, mRoBlob, mDataBlob;
|
||||
RoMetadataProcess mRoMeta;
|
||||
bool mIsHomebrewNro;
|
||||
AssetProcess mAssetProc;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <fnd/SimpleTextOutput.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <compress/lz4.h>
|
||||
#include "OffsetAdjustedIFile.h"
|
||||
#include "NsoProcess.h"
|
||||
|
@ -68,21 +68,21 @@ void NsoProcess::setListSymbols(bool listSymbols)
|
|||
|
||||
void NsoProcess::importHeader()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
if (mFile->size() < sizeof(nx::sNsoHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Corrupt NSO: file too small");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
uint32_t decompressed_len;
|
||||
crypto::sha::sSha256Hash calc_hash;
|
||||
|
||||
|
@ -90,10 +90,10 @@ void NsoProcess::importCodeSegments()
|
|||
if (mHdr.getTextSegmentInfo().is_compressed)
|
||||
{
|
||||
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);
|
||||
compress::lz4::decompressData(scratch.getBytes(), (uint32_t)scratch.getSize(), mTextBlob.getBytes(), (uint32_t)mTextBlob.getSize(), decompressed_len);
|
||||
if (decompressed_len != mTextBlob.getSize())
|
||||
compress::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mTextBlob.data(), (uint32_t)mTextBlob.size(), decompressed_len);
|
||||
if (decompressed_len != mTextBlob.size())
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO text segment failed to decompress");
|
||||
}
|
||||
|
@ -101,11 +101,11 @@ void NsoProcess::importCodeSegments()
|
|||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO text segment failed SHA256 verification");
|
||||
|
@ -116,10 +116,10 @@ void NsoProcess::importCodeSegments()
|
|||
if (mHdr.getRoSegmentInfo().is_compressed)
|
||||
{
|
||||
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);
|
||||
compress::lz4::decompressData(scratch.getBytes(), (uint32_t)scratch.getSize(), mRoBlob.getBytes(), (uint32_t)mRoBlob.getSize(), decompressed_len);
|
||||
if (decompressed_len != mRoBlob.getSize())
|
||||
compress::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mRoBlob.data(), (uint32_t)mRoBlob.size(), decompressed_len);
|
||||
if (decompressed_len != mRoBlob.size())
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO ro segment failed to decompress");
|
||||
}
|
||||
|
@ -127,11 +127,11 @@ void NsoProcess::importCodeSegments()
|
|||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO ro segment failed SHA256 verification");
|
||||
|
@ -142,10 +142,10 @@ void NsoProcess::importCodeSegments()
|
|||
if (mHdr.getDataSegmentInfo().is_compressed)
|
||||
{
|
||||
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);
|
||||
compress::lz4::decompressData(scratch.getBytes(), (uint32_t)scratch.getSize(), mDataBlob.getBytes(), (uint32_t)mDataBlob.getSize(), decompressed_len);
|
||||
if (decompressed_len != mDataBlob.getSize())
|
||||
compress::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mDataBlob.data(), (uint32_t)mDataBlob.size(), decompressed_len);
|
||||
if (decompressed_len != mDataBlob.size())
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO data segment failed to decompress");
|
||||
}
|
||||
|
@ -153,11 +153,11 @@ void NsoProcess::importCodeSegments()
|
|||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NSO data segment failed SHA256 verification");
|
||||
|
@ -237,7 +237,7 @@ void NsoProcess::displayNsoHeader()
|
|||
|
||||
void NsoProcess::processRoMeta()
|
||||
{
|
||||
if (mRoBlob.getSize())
|
||||
if (mRoBlob.size())
|
||||
{
|
||||
// setup ro metadata
|
||||
mRoMeta.setApiInfo(mHdr.getRoEmbeddedInfo().offset, mHdr.getRoEmbeddedInfo().size);
|
||||
|
|
|
@ -37,7 +37,7 @@ private:
|
|||
bool mListSymbols;
|
||||
|
||||
nx::NsoHeader mHdr;
|
||||
fnd::MemoryBlob mTextBlob, mRoBlob, mDataBlob;
|
||||
fnd::Vec<byte_t> mTextBlob, mRoBlob, mDataBlob;
|
||||
RoMetadataProcess mRoMeta;
|
||||
|
||||
void importHeader();
|
||||
|
|
|
@ -25,7 +25,7 @@ size_t OffsetAdjustedIFile::size()
|
|||
|
||||
void OffsetAdjustedIFile::seek(size_t offset)
|
||||
{
|
||||
mCurrentOffset = MIN(offset, mSize);
|
||||
mCurrentOffset = _MIN(offset, mSize);
|
||||
}
|
||||
|
||||
void OffsetAdjustedIFile::read(byte_t* out, size_t len)
|
||||
|
|
|
@ -25,7 +25,7 @@ PfsProcess::~PfsProcess()
|
|||
|
||||
void PfsProcess::process()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
{
|
||||
|
@ -34,17 +34,17 @@ void PfsProcess::process()
|
|||
|
||||
// open minimum header to get full header size
|
||||
scratch.alloc(sizeof(nx::sPfsHeader));
|
||||
mFile->read(scratch.getBytes(), 0, scratch.getSize());
|
||||
if (validateHeaderMagic(((nx::sPfsHeader*)scratch.getBytes())) == false)
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
if (validateHeaderMagic(((nx::sPfsHeader*)scratch.data())) == false)
|
||||
{
|
||||
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
|
||||
scratch.alloc(pfsHeaderSize);
|
||||
mFile->read(scratch.getBytes(), 0, scratch.getSize());
|
||||
mPfs.importBinary(scratch.getBytes(), scratch.getSize());
|
||||
mFile->read(scratch.data(), 0, scratch.size());
|
||||
mPfs.fromBytes(scratch.data(), scratch.size());
|
||||
|
||||
if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC))
|
||||
{
|
||||
|
@ -99,14 +99,14 @@ void PfsProcess::displayHeader()
|
|||
{
|
||||
printf("[PartitionFS]\n");
|
||||
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)
|
||||
printf(" MountPoint: %s%s\n", mMountName.c_str(), mMountName.at(mMountName.length()-1) != '/' ? "/" : "");
|
||||
}
|
||||
|
||||
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());
|
||||
if (_HAS_BIT(mCliOutputMode, OUTPUT_LAYOUT))
|
||||
|
@ -144,11 +144,11 @@ void PfsProcess::validateHfs()
|
|||
{
|
||||
crypto::sha::sSha256Hash hash;
|
||||
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);
|
||||
mFile->read(mCache.getBytes(), file[i].offset, file[i].hash_protected_size);
|
||||
crypto::sha::Sha256(mCache.getBytes(), file[i].hash_protected_size, hash.bytes);
|
||||
mFile->read(mCache.data(), file[i].offset, file[i].hash_protected_size);
|
||||
crypto::sha::Sha256(mCache.data(), file[i].hash_protected_size, hash.bytes);
|
||||
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());
|
||||
|
@ -168,7 +168,7 @@ void PfsProcess::extractFs()
|
|||
const fnd::List<nx::PfsHeader::sFile>& file = mPfs.getFileList();
|
||||
|
||||
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();
|
||||
fnd::io::appendToPath(file_path, mExtractPath);
|
||||
|
@ -181,8 +181,8 @@ void PfsProcess::extractFs()
|
|||
mFile->seek(file[i].offset);
|
||||
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));
|
||||
outFile.write(mCache.getBytes(), MIN(file[i].size - (kCacheSize * j),kCacheSize));
|
||||
mFile->read(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
|
||||
outFile.write(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
|
||||
}
|
||||
outFile.close();
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ private:
|
|||
std::string mMountName;
|
||||
bool mListFs;
|
||||
|
||||
fnd::MemoryBlob mCache;
|
||||
fnd::Vec<byte_t> mCache;
|
||||
|
||||
nx::PfsHeader mPfs;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ RoMetadataProcess::RoMetadataProcess() :
|
|||
|
||||
void RoMetadataProcess::process()
|
||||
{
|
||||
if (mRoBlob.getSize() == 0)
|
||||
if (mRoBlob.size() == 0)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No ro binary set.");
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ void RoMetadataProcess::process()
|
|||
displayRoMetaData();
|
||||
}
|
||||
|
||||
void RoMetadataProcess::setRoBinary(const fnd::MemoryBlob& bin)
|
||||
void RoMetadataProcess::setRoBinary(const fnd::Vec<byte_t>& bin)
|
||||
{
|
||||
mRoBlob = bin;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ void RoMetadataProcess::importApiList()
|
|||
{
|
||||
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;
|
||||
|
||||
while(std::getline(list_stream, api_str, (char)0x00))
|
||||
|
@ -98,7 +98,7 @@ void RoMetadataProcess::importApiList()
|
|||
|
||||
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");
|
||||
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];
|
||||
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));
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
|
||||
#include <nx/npdm.h>
|
||||
|
||||
|
@ -17,7 +17,7 @@ public:
|
|||
|
||||
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 setDynSym(size_t offset, size_t size);
|
||||
void setDynStr(size_t offset, size_t size);
|
||||
|
@ -45,7 +45,7 @@ private:
|
|||
sLayout mApiInfo;
|
||||
sLayout mDynSym;
|
||||
sLayout mDynStr;
|
||||
fnd::MemoryBlob mRoBlob;
|
||||
fnd::Vec<byte_t> mRoBlob;
|
||||
std::vector<SdkApiString> mSdkVerApiList;
|
||||
std::vector<SdkApiString> mPublicApiList;
|
||||
std::vector<SdkApiString> mDebugApiList;
|
||||
|
|
|
@ -36,7 +36,6 @@ void RomfsProcess::process()
|
|||
}
|
||||
|
||||
resolveRomfs();
|
||||
|
||||
if (_HAS_BIT(mCliOutputMode, OUTPUT_BASIC))
|
||||
{
|
||||
displayHeader();
|
||||
|
@ -111,11 +110,11 @@ void RomfsProcess::displayDir(const sDirectory& dir, size_t tab) const
|
|||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -150,7 +149,7 @@ void RomfsProcess::extractDir(const std::string& path, const sDirectory& dir)
|
|||
|
||||
// extract files
|
||||
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();
|
||||
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);
|
||||
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));
|
||||
outFile.write(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.data(), _MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize));
|
||||
}
|
||||
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]);
|
||||
}
|
||||
|
@ -266,15 +265,15 @@ void RomfsProcess::resolveRomfs()
|
|||
|
||||
// read directory nodes
|
||||
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");
|
||||
//fnd::SimpleTextOutput::hxdStyleDump(mDirNodes.getBytes(), mDirNodes.getSize());
|
||||
//fnd::SimpleTextOutput::hxdStyleDump(mDirNodes.data(), mDirNodes.size());
|
||||
|
||||
// read file nodes
|
||||
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");
|
||||
//fnd::SimpleTextOutput::hxdStyleDump(mFileNodes.getBytes(), mFileNodes.getSize());
|
||||
//fnd::SimpleTextOutput::hxdStyleDump(mFileNodes.data(), mFileNodes.size());
|
||||
|
||||
// A logic check on the root directory node
|
||||
if ( get_dir_node(0)->parent.get() != 0 \
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <fnd/List.h>
|
||||
#include <nx/romfs.h>
|
||||
|
||||
|
@ -20,12 +20,11 @@ public:
|
|||
fnd::List<sDirectory> dir_list;
|
||||
fnd::List<sFile> file_list;
|
||||
|
||||
sDirectory& operator=(const sDirectory& other)
|
||||
void operator=(const sDirectory& other)
|
||||
{
|
||||
name = other.name;
|
||||
dir_list = other.dir_list;
|
||||
file_list = other.file_list;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const sDirectory& other) const
|
||||
|
@ -44,11 +43,6 @@ public:
|
|||
{
|
||||
return (name == other);
|
||||
}
|
||||
|
||||
bool operator!=(const std::string& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
struct sFile
|
||||
|
@ -57,12 +51,11 @@ public:
|
|||
uint64_t offset;
|
||||
uint64_t size;
|
||||
|
||||
sFile& operator=(const sFile& other)
|
||||
void operator=(const sFile& other)
|
||||
{
|
||||
name = other.name;
|
||||
offset = other.offset;
|
||||
size = other.size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const sFile& other) const
|
||||
|
@ -81,11 +74,6 @@ public:
|
|||
{
|
||||
return (name == other);
|
||||
}
|
||||
|
||||
bool operator!=(const std::string& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
RomfsProcess();
|
||||
|
@ -118,17 +106,17 @@ private:
|
|||
std::string mMountName;
|
||||
bool mListFs;
|
||||
|
||||
fnd::MemoryBlob mCache;
|
||||
fnd::Vec<byte_t> mCache;
|
||||
|
||||
size_t mDirNum;
|
||||
size_t mFileNum;
|
||||
nx::sRomfsHeader mHdr;
|
||||
fnd::MemoryBlob mDirNodes;
|
||||
fnd::MemoryBlob mFileNodes;
|
||||
fnd::Vec<byte_t> mDirNodes;
|
||||
fnd::Vec<byte_t> mFileNodes;
|
||||
sDirectory mRootDir;
|
||||
|
||||
inline nx::sRomfsDirEntry* get_dir_node(uint32_t offset) { return (nx::sRomfsDirEntry*)(mDirNodes.getBytes() + offset); }
|
||||
inline nx::sRomfsFileEntry* get_file_node(uint32_t offset) { return (nx::sRomfsFileEntry*)(mFileNodes.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.data() + offset); }
|
||||
|
||||
|
||||
void printTab(size_t tab) const;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <fnd/io.h>
|
||||
#include <fnd/SimpleFile.h>
|
||||
#include <fnd/SimpleTextOutput.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <fnd/ResourceFileReader.h>
|
||||
#include <nx/NcaUtils.h>
|
||||
#include <nx/AesKeygen.h>
|
||||
|
@ -708,37 +708,35 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
|
|||
static const size_t kMaxReadSize = 0x4000;
|
||||
FileType file_type = FILE_INVALID;
|
||||
fnd::SimpleFile file;
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
// open file
|
||||
file.open(path, file.Read);
|
||||
|
||||
// read file
|
||||
scratch.alloc(MIN(kMaxReadSize, file.size()));
|
||||
file.read(scratch.getBytes(), 0, scratch.getSize());
|
||||
scratch.alloc(_MIN(kMaxReadSize, file.size()));
|
||||
file.read(scratch.data(), 0, scratch.size());
|
||||
// close file
|
||||
file.close();
|
||||
|
||||
|
||||
|
||||
// _QUICK_CAST resolves to a pointer of type 'st' located at scratch.getBytes() + 'oft'
|
||||
#define _QUICK_CAST(st, oft) ((st*)(scratch.getBytes() + (oft)))
|
||||
#define _ASSERT_SIZE(size) (scratch.getSize() >= (size))
|
||||
// _TYPE_PTR resolves to a pointer of type 'st' located at scratch.data()
|
||||
#define _TYPE_PTR(st) ((st*)(scratch.data()))
|
||||
#define _ASSERT_SIZE(sz) (scratch.size() >= (sz))
|
||||
|
||||
// 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;
|
||||
// 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;
|
||||
// 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;
|
||||
// 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;
|
||||
// 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;
|
||||
// test nca
|
||||
else if (determineValidNcaFromSample(scratch))
|
||||
|
@ -750,34 +748,34 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
|
|||
else if (determineValidNacpFromSample(scratch))
|
||||
file_type = FILE_NACP;
|
||||
// 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;
|
||||
// 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;
|
||||
// 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;
|
||||
// else unrecognised
|
||||
else
|
||||
file_type = FILE_INVALID;
|
||||
|
||||
#undef _ASSERT_SIZE
|
||||
#undef _QUICK_CAST
|
||||
#undef _TYPE_PTR
|
||||
|
||||
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
|
||||
byte_t nca_raw[nx::nca::kHeaderSize];
|
||||
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;
|
||||
|
||||
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)
|
||||
return false;
|
||||
|
@ -785,27 +783,27 @@ bool UserSettings::determineValidNcaFromSample(const fnd::MemoryBlob& sample) co
|
|||
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;
|
||||
|
||||
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;
|
||||
|
||||
if (sample.getSize() < minimum_size)
|
||||
if (sample.size() < minimum_size)
|
||||
return false;
|
||||
|
||||
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())
|
||||
return false;
|
||||
}
|
||||
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())
|
||||
return false;
|
||||
|
||||
|
@ -813,31 +811,31 @@ bool UserSettings::determineValidCnmtFromSample(const fnd::MemoryBlob& sample) c
|
|||
}
|
||||
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())
|
||||
return false;
|
||||
}
|
||||
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())
|
||||
return false;
|
||||
|
||||
minimum_size += meta->extended_data_size.get();
|
||||
}
|
||||
|
||||
if (sample.getSize() != minimum_size)
|
||||
if (sample.size() != minimum_size)
|
||||
return false;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
return false;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/Vec.h>
|
||||
#include <nx/npdm.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);
|
||||
FileType getFileTypeFromString(const std::string& type_str);
|
||||
FileType determineFileTypeFromFile(const std::string& path);
|
||||
bool determineValidNcaFromSample(const fnd::MemoryBlob& sample) const;
|
||||
bool determineValidCnmtFromSample(const fnd::MemoryBlob& sample) const;
|
||||
bool determineValidNacpFromSample(const fnd::MemoryBlob& sample) const;
|
||||
bool determineValidNcaFromSample(const fnd::Vec<byte_t>& sample) const;
|
||||
bool determineValidCnmtFromSample(const fnd::Vec<byte_t>& sample) const;
|
||||
bool determineValidNacpFromSample(const fnd::Vec<byte_t>& sample) const;
|
||||
nx::npdm::InstructionType getInstructionTypeFromString(const std::string& type_str);
|
||||
};
|
|
@ -25,7 +25,7 @@ XciProcess::~XciProcess()
|
|||
|
||||
void XciProcess::process()
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
|
||||
if (mFile == nullptr)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ void XciProcess::process()
|
|||
|
||||
// allocate memory for and decrypt 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
|
||||
if (mVerify)
|
||||
|
@ -46,7 +46,7 @@ void XciProcess::process()
|
|||
}
|
||||
|
||||
// deserialise header
|
||||
mHdr.importBinary(scratch.getBytes(), scratch.getSize());
|
||||
mHdr.fromBytes(scratch.data(), scratch.size());
|
||||
|
||||
// display header
|
||||
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)
|
||||
{
|
||||
mExtractInfo.push_back({partition_name, extract_path});
|
||||
mExtractInfo.addElement({partition_name, extract_path});
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
fnd::MemoryBlob scratch;
|
||||
fnd::Vec<byte_t> scratch;
|
||||
crypto::sha::sSha256Hash calc_hash;
|
||||
scratch.alloc(len);
|
||||
mFile->read(scratch.getBytes(), offset, len);
|
||||
crypto::sha::Sha256(scratch.getBytes(), scratch.getSize(), calc_hash.bytes);
|
||||
mFile->read(scratch.data(), offset, scratch.size());
|
||||
crypto::sha::Sha256(scratch.data(), scratch.size(), calc_hash.bytes);
|
||||
return calc_hash.compare(test_hash);
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ void XciProcess::processRootPfs()
|
|||
void XciProcess::processPartitionPfs()
|
||||
{
|
||||
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
|
||||
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.setCliOutputMode(mCliOutputMode);
|
||||
tmp.setMountPointName(kXciMountPointName + rootPartitions[i].name);
|
||||
for (size_t j = 0; j < mExtractInfo.size(); j++)
|
||||
{
|
||||
if (mExtractInfo[j].partition_name == rootPartitions[i].name)
|
||||
{
|
||||
tmp.setExtractPath(mExtractInfo[j].extract_path);
|
||||
}
|
||||
}
|
||||
if (mExtractInfo.hasElement<std::string>(rootPartitions[i].name))
|
||||
tmp.setExtractPath(mExtractInfo.getElement<std::string>(rootPartitions[i].name).extract_path);
|
||||
|
||||
tmp.process();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <fnd/List.h>
|
||||
#include <nx/XciHeader.h>
|
||||
|
||||
#include "nstool.h"
|
||||
|
@ -41,6 +42,17 @@ private:
|
|||
{
|
||||
std::string partition_name;
|
||||
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;
|
||||
|
@ -48,7 +60,7 @@ private:
|
|||
nx::sXciHeaderPage mHdrPage;
|
||||
nx::XciHeader mHdr;
|
||||
PfsProcess mRootPfs;
|
||||
std::vector<sExtractInfo> mExtractInfo;
|
||||
fnd::List<sExtractInfo> mExtractInfo;
|
||||
|
||||
void displayHeader();
|
||||
bool validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash);
|
||||
|
|
Loading…
Reference in a new issue