[hac|nstool] Rename "Xci" to "Gc/GameCard"

This commit is contained in:
jakcron 2018-10-27 14:13:53 +08:00
parent 364a3880f1
commit e3e045ad0a
15 changed files with 218 additions and 218 deletions

View file

@ -1,5 +1,5 @@
#pragma once
#include <nn/hac/define/xci.h>
#include <nn/hac/define/gc.h>
#include <fnd/IByteModel.h>
#include <fnd/List.h>
@ -7,16 +7,16 @@ namespace nn
{
namespace hac
{
class XciHeader :
class GameCardHeader :
public fnd::IByteModel
{
public:
XciHeader();
XciHeader(const XciHeader& other);
GameCardHeader();
GameCardHeader(const GameCardHeader& other);
void operator=(const XciHeader& other);
bool operator==(const XciHeader& other) const;
bool operator!=(const XciHeader& other) const;
void operator=(const GameCardHeader& other);
bool operator==(const GameCardHeader& other) const;
bool operator!=(const GameCardHeader& other) const;
// IByteModel
void toBytes();
@ -86,7 +86,7 @@ namespace hac
void setUppId(uint64_t id);
private:
const std::string kModuleName = "XCI_HEADER";
const std::string kModuleName = "GAMECARD_HEADER";
// binary
fnd::Vec<byte_t> mRawBinary;
@ -111,7 +111,7 @@ namespace hac
uint32_t mSelKey;
uint32_t mLimAreaPage;
// Encrypted Data
// Encrypted/Extended Data
uint32_t mFwVersion[2];
uint32_t mAccCtrl1;
uint32_t mWait1TimeRead;

View file

@ -1,15 +1,15 @@
#pragma once
#include <nn/hac/define/xci.h>
#include <nn/hac/define/gc.h>
namespace nn
{
namespace hac
{
class XciUtils
class GameCardUtils
{
public:
static inline uint64_t blockToAddr(uint32_t block) { return ((uint64_t)block) << 9; }
static void getXciHeaderAesIv(const nn::hac::sXciHeader* hdr, byte_t* iv);
static void getXciHeaderAesIv(const nn::hac::sGcHeader* hdr, byte_t* iv);
static void decryptXciHeader(const byte_t* src, byte_t* dst, const byte_t* key);
};
}

View file

@ -10,9 +10,9 @@ namespace nn
{
namespace hac
{
namespace xci
namespace gc
{
static const uint32_t kXciStructMagic = _MAKE_STRUCT_MAGIC_U32("HEAD");
static const uint32_t kGcHeaderStructMagic = _MAKE_STRUCT_MAGIC_U32("HEAD");
static const uint32_t kHeaderEncOffset = 0x90;
static const uint32_t kHeaderEncSize = 0x70;
static const uint32_t kPageSize = 0x200;
@ -68,7 +68,7 @@ namespace hac
}
#pragma pack(push,1)
struct sXciHeader
struct sGcHeader
{
le_uint32_t st_magic;
le_uint32_t rom_area_start_page;
@ -99,16 +99,16 @@ namespace hac
le_uint32_t fw_mode;
le_uint32_t upp_version;
byte_t reserved_01[0x4];
byte_t upp_hash[xci::kUppHashLen];
byte_t upp_hash[gc::kUppHashLen];
le_uint64_t upp_id;
byte_t reserved_02[0x38];
// END ENCRYPTION
};
struct sXciHeaderPage
struct sGcHeaderPage
{
byte_t signature[fnd::rsa::kRsa2048Size];
sXciHeader header;
sGcHeader header;
}; // sizeof() = 512 (1 page)
struct sInitialData
@ -123,9 +123,9 @@ namespace hac
struct sKeyDataArea
{
sInitialData initial_data; // AES128-CCM encrypted {titlekey[16]}
byte_t encrypted_00[xci::kPageSize * 6]; // AES128-CTR encrypted {titlekey[16]}
byte_t encrypted_00[gc::kPageSize * 6]; // AES128-CTR encrypted {titlekey[16]}
byte_t encrypted_00_aesctr_data[fnd::rsa::kRsa2048Size]; // RSA2048-OAEP-SHA256 encrypted AES-CTR data used for encrypted_00 {key[16],iv[16]}
byte_t reserved[xci::kPageSize - fnd::rsa::kRsa2048Size];
byte_t reserved[gc::kPageSize - fnd::rsa::kRsa2048Size];
}; // sizeof() = 512*8 (8 pages)
#pragma pack(pop)

View file

@ -38,6 +38,7 @@
<ClInclude Include="include\nn\hac\define\cnmt.h" />
<ClInclude Include="include\nn\hac\define\delta.h" />
<ClInclude Include="include\nn\hac\define\fac.h" />
<ClInclude Include="include\nn\hac\define\gc.h" />
<ClInclude Include="include\nn\hac\define\hierarchicalintegrity.h" />
<ClInclude Include="include\nn\hac\define\hierarchicalsha256.h" />
<ClInclude Include="include\nn\hac\define\kc.h" />
@ -50,9 +51,10 @@
<ClInclude Include="include\nn\hac\define\nso.h" />
<ClInclude Include="include\nn\hac\define\pfs.h" />
<ClInclude Include="include\nn\hac\define\romfs.h" />
<ClInclude Include="include\nn\hac\define\xci.h" />
<ClInclude Include="include\nn\hac\DeltaMetaExtendedHeader.h" />
<ClInclude Include="include\nn\hac\FileSystemAccessControl.h" />
<ClInclude Include="include\nn\hac\GameCardHeader.h" />
<ClInclude Include="include\nn\hac\GameCardUtils.h" />
<ClInclude Include="include\nn\hac\HandleTableSizeEntry.h" />
<ClInclude Include="include\nn\hac\HandleTableSizeHandler.h" />
<ClInclude Include="include\nn\hac\HierarchicalIntegrityHeader.h" />
@ -83,8 +85,6 @@
<ClInclude Include="include\nn\hac\SystemCallHandler.h" />
<ClInclude Include="include\nn\hac\ThreadInfoEntry.h" />
<ClInclude Include="include\nn\hac\ThreadInfoHandler.h" />
<ClInclude Include="include\nn\hac\XciHeader.h" />
<ClInclude Include="include\nn\hac\XciUtils.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\AccessControlInfo.cpp" />
@ -101,6 +101,8 @@
<ClCompile Include="source\ContentMetaInfo.cpp" />
<ClCompile Include="source\DeltaMetaExtendedHeader.cpp" />
<ClCompile Include="source\FileSystemAccessControl.cpp" />
<ClCompile Include="source\GameCardHeader.cpp" />
<ClCompile Include="source\GameCardUtils.cpp" />
<ClCompile Include="source\HandleTableSizeEntry.cpp" />
<ClCompile Include="source\HandleTableSizeHandler.cpp" />
<ClCompile Include="source\HierarchicalIntegrityHeader.cpp" />
@ -130,8 +132,6 @@
<ClCompile Include="source\SystemCallHandler.cpp" />
<ClCompile Include="source\ThreadInfoEntry.cpp" />
<ClCompile Include="source\ThreadInfoHandler.cpp" />
<ClCompile Include="source\XciHeader.cpp" />
<ClCompile Include="source\XciUtils.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>

View file

@ -27,6 +27,9 @@
<ClInclude Include="include\nn\hac\define\fac.h">
<Filter>Header Files\define</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\define\gc.h">
<Filter>Header Files\define</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\define\hierarchicalintegrity.h">
<Filter>Header Files\define</Filter>
</ClInclude>
@ -63,9 +66,6 @@
<ClInclude Include="include\nn\hac\define\romfs.h">
<Filter>Header Files\define</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\define\xci.h">
<Filter>Header Files\define</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\AccessControlInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -108,6 +108,12 @@
<ClInclude Include="include\nn\hac\FileSystemAccessControl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\GameCardHeader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\GameCardUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\HandleTableSizeEntry.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -198,12 +204,6 @@
<ClInclude Include="include\nn\hac\ThreadInfoHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\XciHeader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nn\hac\XciUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\AccessControlInfo.cpp">
@ -248,6 +248,12 @@
<ClCompile Include="source\FileSystemAccessControl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\GameCardHeader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\GameCardUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\HandleTableSizeEntry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -335,11 +341,5 @@
<ClCompile Include="source\ThreadInfoHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\XciHeader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\XciUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -1,16 +1,16 @@
#include <nn/hac/XciHeader.h>
#include <nn/hac/GameCardHeader.h>
nn::hac::XciHeader::XciHeader()
nn::hac::GameCardHeader::GameCardHeader()
{
clear();
}
nn::hac::XciHeader::XciHeader(const XciHeader& other)
nn::hac::GameCardHeader::GameCardHeader(const GameCardHeader& other)
{
*this = other;
}
void nn::hac::XciHeader::operator=(const XciHeader& other)
void nn::hac::GameCardHeader::operator=(const GameCardHeader& other)
{
mRomAreaStartPage = other.mRomAreaStartPage;
mBackupAreaStartPage = other.mBackupAreaStartPage;
@ -39,11 +39,11 @@ void nn::hac::XciHeader::operator=(const XciHeader& other)
mWait2TimeWrite = other.mWait2TimeWrite;
mFwMode = other.mFwMode;
mUppVersion = other.mUppVersion;
memcpy(mUppHash, other.mUppHash, xci::kUppHashLen);
memcpy(mUppHash, other.mUppHash, gc::kUppHashLen);
mUppId = other.mUppId;
}
bool nn::hac::XciHeader::operator==(const XciHeader& other) const
bool nn::hac::GameCardHeader::operator==(const GameCardHeader& other) const
{
return (mRomAreaStartPage == other.mRomAreaStartPage)
&& (mBackupAreaStartPage == other.mBackupAreaStartPage)
@ -72,42 +72,42 @@ bool nn::hac::XciHeader::operator==(const XciHeader& other) const
&& (mWait2TimeWrite == other.mWait2TimeWrite)
&& (mFwMode == other.mFwMode)
&& (mUppVersion == other.mUppVersion)
&& (memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) == 0)
&& (memcmp(mUppHash, other.mUppHash, gc::kUppHashLen) == 0)
&& (mUppId == other.mUppId);
}
bool nn::hac::XciHeader::operator!=(const XciHeader& other) const
bool nn::hac::GameCardHeader::operator!=(const GameCardHeader& other) const
{
return !(*this == other);
}
void nn::hac::XciHeader::toBytes()
void nn::hac::GameCardHeader::toBytes()
{
fnd::Exception(kModuleName, "exportBinary() not implemented");
fnd::Exception(kModuleName, "toBytes() not implemented");
}
void nn::hac::XciHeader::fromBytes(const byte_t* data, size_t len)
void nn::hac::GameCardHeader::fromBytes(const byte_t* data, size_t len)
{
// check input data size
if (len < sizeof(sXciHeader))
if (len < sizeof(sGcHeader))
{
throw fnd::Exception(kModuleName, "XCI header size is too small");
throw fnd::Exception(kModuleName, "GameCardImage header size is too small");
}
// clear internal members
clear();
// allocate internal local binary copy
mRawBinary.alloc(sizeof(sXciHeader));
mRawBinary.alloc(sizeof(sGcHeader));
memcpy(mRawBinary.data(), data, mRawBinary.size());
// get sXciHeader ptr
const nn::hac::sXciHeader* hdr = (const nn::hac::sXciHeader*)mRawBinary.data();
// get sGcHeader ptr
const nn::hac::sGcHeader* hdr = (const nn::hac::sGcHeader*)mRawBinary.data();
// check XCI signature
if (hdr->st_magic.get() != xci::kXciStructMagic)
// check GameCardImage signature
if (hdr->st_magic.get() != gc::kGcHeaderStructMagic)
{
throw fnd::Exception(kModuleName, "XCI header corrupt");
throw fnd::Exception(kModuleName, "GameCardImage header corrupt");
}
mRomAreaStartPage = hdr->rom_area_start_page.get();
@ -133,8 +133,8 @@ void nn::hac::XciHeader::fromBytes(const byte_t* data, size_t len)
// if decrypted
if (hdr->reserved_02[sizeof(hdr->reserved_02)-1] == 0x00 && hdr->reserved_02[sizeof(hdr->reserved_02)-2] == 0x00)
{
mFwVersion[xci::FWVER_MAJOR] = hdr->fw_version[xci::FWVER_MAJOR].get();
mFwVersion[xci::FWVER_MINOR] = hdr->fw_version[xci::FWVER_MINOR].get();
mFwVersion[gc::FWVER_MAJOR] = hdr->fw_version[gc::FWVER_MAJOR].get();
mFwVersion[gc::FWVER_MINOR] = hdr->fw_version[gc::FWVER_MINOR].get();
mAccCtrl1 = hdr->acc_ctrl_1.get();
mWait1TimeRead = hdr->wait_1_time_read.get();
mWait2TimeRead = hdr->wait_2_time_read.get();
@ -142,19 +142,19 @@ void nn::hac::XciHeader::fromBytes(const byte_t* data, size_t len)
mWait2TimeWrite = hdr->wait_2_time_write.get();
mFwMode = hdr->fw_mode.get();
mUppVersion = hdr->upp_version.get();
memcpy(mUppHash, hdr->upp_hash, xci::kUppHashLen);
memcpy(mUppHash, hdr->upp_hash, gc::kUppHashLen);
mUppId = hdr->upp_id.get();
}
}
const fnd::Vec<byte_t>& nn::hac::XciHeader::getBytes() const
const fnd::Vec<byte_t>& nn::hac::GameCardHeader::getBytes() const
{
return mRawBinary;
}
// variables
void nn::hac::XciHeader::clear()
void nn::hac::GameCardHeader::clear()
{
mRomAreaStartPage = 0;
mBackupAreaStartPage = 0;
@ -183,297 +183,297 @@ void nn::hac::XciHeader::clear()
mWait2TimeWrite = 0;
mFwMode = 0;
mUppVersion = 0;
memset(mUppHash, 0, xci::kUppHashLen);
memset(mUppHash, 0, gc::kUppHashLen);
mUppId = 0;
}
uint32_t nn::hac::XciHeader::getRomAreaStartPage() const
uint32_t nn::hac::GameCardHeader::getRomAreaStartPage() const
{
return mRomAreaStartPage;
}
void nn::hac::XciHeader::setRomAreaStartPage(uint32_t startPage)
void nn::hac::GameCardHeader::setRomAreaStartPage(uint32_t startPage)
{
mRomAreaStartPage = startPage;
}
uint32_t nn::hac::XciHeader::getBackupAreaStartPage() const
uint32_t nn::hac::GameCardHeader::getBackupAreaStartPage() const
{
return mBackupAreaStartPage;
}
void nn::hac::XciHeader::setBackupAreaStartPage(uint32_t startPage)
void nn::hac::GameCardHeader::setBackupAreaStartPage(uint32_t startPage)
{
mBackupAreaStartPage = startPage;
}
byte_t nn::hac::XciHeader::getKekIndex() const
byte_t nn::hac::GameCardHeader::getKekIndex() const
{
return mKekIndex;
}
void nn::hac::XciHeader::setKekIndex(byte_t kekIndex)
void nn::hac::GameCardHeader::setKekIndex(byte_t kekIndex)
{
mKekIndex = kekIndex;
}
byte_t nn::hac::XciHeader::getTitleKeyDecIndex() const
byte_t nn::hac::GameCardHeader::getTitleKeyDecIndex() const
{
return mTitleKeyDecIndex;
}
void nn::hac::XciHeader::setTitleKeyDecIndex(byte_t index)
void nn::hac::GameCardHeader::setTitleKeyDecIndex(byte_t index)
{
mTitleKeyDecIndex = index;
}
byte_t nn::hac::XciHeader::getRomSizeType() const
byte_t nn::hac::GameCardHeader::getRomSizeType() const
{
return mRomSize;
}
void nn::hac::XciHeader::setRomSizeType(byte_t romSizeType)
void nn::hac::GameCardHeader::setRomSizeType(byte_t romSizeType)
{
mRomSize = romSizeType;
}
byte_t nn::hac::XciHeader::getCardHeaderVersion() const
byte_t nn::hac::GameCardHeader::getCardHeaderVersion() const
{
return mCardHeaderVersion;
}
void nn::hac::XciHeader::setCardHeaderVersion(byte_t version)
void nn::hac::GameCardHeader::setCardHeaderVersion(byte_t version)
{
mCardHeaderVersion = version;
}
byte_t nn::hac::XciHeader::getFlags() const
byte_t nn::hac::GameCardHeader::getFlags() const
{
return mFlags;
}
void nn::hac::XciHeader::setFlags(byte_t flags)
void nn::hac::GameCardHeader::setFlags(byte_t flags)
{
mFlags = flags;
}
uint64_t nn::hac::XciHeader::getPackageId() const
uint64_t nn::hac::GameCardHeader::getPackageId() const
{
return mPackageId;
}
void nn::hac::XciHeader::setPackageId(uint64_t id)
void nn::hac::GameCardHeader::setPackageId(uint64_t id)
{
mPackageId = id;
}
uint32_t nn::hac::XciHeader::getValidDataEndPage() const
uint32_t nn::hac::GameCardHeader::getValidDataEndPage() const
{
return mValidDataEndPage;
}
void nn::hac::XciHeader::setValidDataEndPage(uint32_t page)
void nn::hac::GameCardHeader::setValidDataEndPage(uint32_t page)
{
mValidDataEndPage = page;
}
const fnd::aes::sAesIvCtr& nn::hac::XciHeader::getAesCbcIv() const
const fnd::aes::sAesIvCtr& nn::hac::GameCardHeader::getAesCbcIv() const
{
return mAesCbcIv;
}
void nn::hac::XciHeader::setAesCbcIv(const fnd::aes::sAesIvCtr& iv)
void nn::hac::GameCardHeader::setAesCbcIv(const fnd::aes::sAesIvCtr& iv)
{
mAesCbcIv = iv;
}
uint64_t nn::hac::XciHeader::getPartitionFsAddress() const
uint64_t nn::hac::GameCardHeader::getPartitionFsAddress() const
{
return mPartitionFsHeaderAddress;
}
void nn::hac::XciHeader::setPartitionFsAddress(uint64_t address)
void nn::hac::GameCardHeader::setPartitionFsAddress(uint64_t address)
{
mPartitionFsHeaderAddress = address;
}
uint64_t nn::hac::XciHeader::getPartitionFsSize() const
uint64_t nn::hac::GameCardHeader::getPartitionFsSize() const
{
return mPartitionFsHeaderSize;
}
void nn::hac::XciHeader::setPartitionFsSize(uint64_t size)
void nn::hac::GameCardHeader::setPartitionFsSize(uint64_t size)
{
mPartitionFsHeaderSize = size;
}
const fnd::sha::sSha256Hash& nn::hac::XciHeader::getPartitionFsHash() const
const fnd::sha::sSha256Hash& nn::hac::GameCardHeader::getPartitionFsHash() const
{
return mPartitionFsHeaderHash;
}
void nn::hac::XciHeader::setPartitionFsHash(const fnd::sha::sSha256Hash& hash)
void nn::hac::GameCardHeader::setPartitionFsHash(const fnd::sha::sSha256Hash& hash)
{
mPartitionFsHeaderHash = hash;
}
const fnd::sha::sSha256Hash& nn::hac::XciHeader::getInitialDataHash() const
const fnd::sha::sSha256Hash& nn::hac::GameCardHeader::getInitialDataHash() const
{
return mInitialDataHash;
}
void nn::hac::XciHeader::setInitialDataHash(const fnd::sha::sSha256Hash& hash)
void nn::hac::GameCardHeader::setInitialDataHash(const fnd::sha::sSha256Hash& hash)
{
mInitialDataHash = hash;
}
uint32_t nn::hac::XciHeader::getSelSec() const
uint32_t nn::hac::GameCardHeader::getSelSec() const
{
return mSelSec;
}
void nn::hac::XciHeader::setSelSec(uint32_t sel_sec)
void nn::hac::GameCardHeader::setSelSec(uint32_t sel_sec)
{
mSelSec = sel_sec;
}
uint32_t nn::hac::XciHeader::getSelT1Key() const
uint32_t nn::hac::GameCardHeader::getSelT1Key() const
{
return mSelT1Key;
}
void nn::hac::XciHeader::setSelT1Key(uint32_t sel_t1_key)
void nn::hac::GameCardHeader::setSelT1Key(uint32_t sel_t1_key)
{
mSelT1Key = sel_t1_key;
}
uint32_t nn::hac::XciHeader::getSelKey() const
uint32_t nn::hac::GameCardHeader::getSelKey() const
{
return mSelKey;
}
void nn::hac::XciHeader::setSelKey(uint32_t sel_key)
void nn::hac::GameCardHeader::setSelKey(uint32_t sel_key)
{
mSelKey = sel_key;
}
uint32_t nn::hac::XciHeader::getLimAreaPage() const
uint32_t nn::hac::GameCardHeader::getLimAreaPage() const
{
return mLimAreaPage;
}
void nn::hac::XciHeader::setLimAreaPage(uint32_t page)
void nn::hac::GameCardHeader::setLimAreaPage(uint32_t page)
{
mLimAreaPage = page;
}
uint32_t nn::hac::XciHeader::getFwVerMajor() const
uint32_t nn::hac::GameCardHeader::getFwVerMajor() const
{
return mFwVersion[xci::FWVER_MAJOR];
return mFwVersion[gc::FWVER_MAJOR];
}
void nn::hac::XciHeader::setFwVerMajor(uint32_t ver)
void nn::hac::GameCardHeader::setFwVerMajor(uint32_t ver)
{
mFwVersion[xci::FWVER_MAJOR] = ver;
mFwVersion[gc::FWVER_MAJOR] = ver;
}
uint32_t nn::hac::XciHeader::getFwVerMinor() const
uint32_t nn::hac::GameCardHeader::getFwVerMinor() const
{
return mFwVersion[xci::FWVER_MINOR];
return mFwVersion[gc::FWVER_MINOR];
}
void nn::hac::XciHeader::setFwVerMinor(uint32_t ver)
void nn::hac::GameCardHeader::setFwVerMinor(uint32_t ver)
{
mFwVersion[xci::FWVER_MINOR] = ver;
mFwVersion[gc::FWVER_MINOR] = ver;
}
uint32_t nn::hac::XciHeader::getAccCtrl1() const
uint32_t nn::hac::GameCardHeader::getAccCtrl1() const
{
return mAccCtrl1;
}
void nn::hac::XciHeader::setAccCtrl1(uint32_t acc_ctrl_1)
void nn::hac::GameCardHeader::setAccCtrl1(uint32_t acc_ctrl_1)
{
mAccCtrl1 = acc_ctrl_1;
}
uint32_t nn::hac::XciHeader::getWait1TimeRead() const
uint32_t nn::hac::GameCardHeader::getWait1TimeRead() const
{
return mWait1TimeRead;
}
void nn::hac::XciHeader::setWait1TimeRead(uint32_t seconds)
void nn::hac::GameCardHeader::setWait1TimeRead(uint32_t seconds)
{
mWait1TimeRead = seconds;
}
uint32_t nn::hac::XciHeader::getWait2TimeRead() const
uint32_t nn::hac::GameCardHeader::getWait2TimeRead() const
{
return mWait2TimeRead;
}
void nn::hac::XciHeader::setWait2TimeRead(uint32_t seconds)
void nn::hac::GameCardHeader::setWait2TimeRead(uint32_t seconds)
{
mWait2TimeRead = seconds;
}
uint32_t nn::hac::XciHeader::getWait1TimeWrite() const
uint32_t nn::hac::GameCardHeader::getWait1TimeWrite() const
{
return mWait1TimeWrite;
}
void nn::hac::XciHeader::setWait1TimeWrite(uint32_t seconds)
void nn::hac::GameCardHeader::setWait1TimeWrite(uint32_t seconds)
{
mWait1TimeWrite = seconds;
}
uint32_t nn::hac::XciHeader::getWait2TimeWrite() const
uint32_t nn::hac::GameCardHeader::getWait2TimeWrite() const
{
return mWait2TimeWrite;
}
void nn::hac::XciHeader::setWait2TimeWrite(uint32_t seconds)
void nn::hac::GameCardHeader::setWait2TimeWrite(uint32_t seconds)
{
mWait2TimeWrite = seconds;
}
uint32_t nn::hac::XciHeader::getFwMode() const
uint32_t nn::hac::GameCardHeader::getFwMode() const
{
return mFwMode;
}
void nn::hac::XciHeader::setFwMode(uint32_t fw_mode)
void nn::hac::GameCardHeader::setFwMode(uint32_t fw_mode)
{
mFwMode = fw_mode;
}
uint32_t nn::hac::XciHeader::getUppVersion() const
uint32_t nn::hac::GameCardHeader::getUppVersion() const
{
return mUppVersion;
}
void nn::hac::XciHeader::setUppVersion(uint32_t version)
void nn::hac::GameCardHeader::setUppVersion(uint32_t version)
{
mUppVersion = version;
}
const byte_t* nn::hac::XciHeader::getUppHash() const
const byte_t* nn::hac::GameCardHeader::getUppHash() const
{
return mUppHash;
}
void nn::hac::XciHeader::setUppHash(const byte_t* hash)
void nn::hac::GameCardHeader::setUppHash(const byte_t* hash)
{
memcpy(mUppHash, hash, xci::kUppHashLen);
memcpy(mUppHash, hash, gc::kUppHashLen);
}
uint64_t nn::hac::XciHeader::getUppId() const
uint64_t nn::hac::GameCardHeader::getUppId() const
{
return mUppId;
}
void nn::hac::XciHeader::setUppId(uint64_t id)
void nn::hac::GameCardHeader::setUppId(uint64_t id)
{
mUppId = id;
}

View file

@ -0,0 +1,22 @@
#include <nn/hac/GameCardUtils.h>
void nn::hac::GameCardUtils::getXciHeaderAesIv(const nn::hac::sGcHeader* hdr, byte_t* iv)
{
for (size_t i = 0; i < 16; i++)
{
iv[15-i] = hdr->aescbc_iv.iv[i];
}
}
void nn::hac::GameCardUtils::decryptXciHeader(const byte_t* src, byte_t* dst, const byte_t* key)
{
byte_t iv[fnd::aes::kAesBlockSize];
getXciHeaderAesIv((const nn::hac::sGcHeader*)src, iv);
// copy plain
memcpy(dst, src, nn::hac::gc::kHeaderEncOffset);
// decrypt encrypted data
fnd::aes::AesCbcDecrypt(src + nn::hac::gc::kHeaderEncOffset, nn::hac::gc::kHeaderEncSize, key, iv, dst + nn::hac::gc::kHeaderEncOffset);
}

View file

@ -1,22 +0,0 @@
#include <nn/hac/XciUtils.h>
void nn::hac::XciUtils::getXciHeaderAesIv(const nn::hac::sXciHeader* hdr, byte_t* iv)
{
for (size_t i = 0; i < 16; i++)
{
iv[15-i] = hdr->aescbc_iv.iv[i];
}
}
void nn::hac::XciUtils::decryptXciHeader(const byte_t* src, byte_t* dst, const byte_t* key)
{
byte_t iv[fnd::aes::kAesBlockSize];
getXciHeaderAesIv((const nn::hac::sXciHeader*)src, iv);
// copy plain
memcpy(dst, src, nn::hac::xci::kHeaderEncOffset);
// decrypt encrypted data
fnd::aes::AesCbcDecrypt(src + nn::hac::xci::kHeaderEncOffset, nn::hac::xci::kHeaderEncSize, key, iv, dst + nn::hac::xci::kHeaderEncOffset);
}

View file

@ -197,7 +197,7 @@
<ClInclude Include="source\SdkApiString.h" />
<ClInclude Include="source\UserSettings.h" />
<ClInclude Include="source\version.h" />
<ClInclude Include="source\XciProcess.h" />
<ClInclude Include="source\GameCardProcess.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\AssetProcess.cpp" />
@ -218,7 +218,7 @@
<ClCompile Include="source\RomfsProcess.cpp" />
<ClCompile Include="source\SdkApiString.cpp" />
<ClCompile Include="source\UserSettings.cpp" />
<ClCompile Include="source\XciProcess.cpp" />
<ClCompile Include="source\GameCardProcess.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View file

@ -76,7 +76,7 @@
<ClInclude Include="source\version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\XciProcess.h">
<ClInclude Include="source\GameCardProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
@ -135,7 +135,7 @@
<ClCompile Include="source\UserSettings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\XciProcess.cpp">
<ClCompile Include="source\GameCardProcess.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>

View file

@ -2,10 +2,10 @@
#include <iomanip>
#include <fnd/SimpleTextOutput.h>
#include <fnd/OffsetAdjustedIFile.h>
#include <nn/hac/XciUtils.h>
#include "XciProcess.h"
#include <nn/hac/GameCardUtils.h>
#include "GameCardProcess.h"
XciProcess::XciProcess() :
GameCardProcess::GameCardProcess() :
mFile(),
mCliOutputMode(_BIT(OUTPUT_BASIC)),
mVerify(false),
@ -15,7 +15,7 @@ XciProcess::XciProcess() :
{
}
void XciProcess::process()
void GameCardProcess::process()
{
importHeader();
@ -34,37 +34,37 @@ void XciProcess::process()
processPartitionPfs();
}
void XciProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
void GameCardProcess::setInputFile(const fnd::SharedPtr<fnd::IFile>& file)
{
mFile = file;
}
void XciProcess::setKeyCfg(const KeyConfiguration& keycfg)
void GameCardProcess::setKeyCfg(const KeyConfiguration& keycfg)
{
mKeyCfg = keycfg;
}
void XciProcess::setCliOutputMode(CliOutputMode type)
void GameCardProcess::setCliOutputMode(CliOutputMode type)
{
mCliOutputMode = type;
}
void XciProcess::setVerifyMode(bool verify)
void GameCardProcess::setVerifyMode(bool verify)
{
mVerify = verify;
}
void XciProcess::setPartitionForExtract(const std::string& partition_name, const std::string& extract_path)
void GameCardProcess::setPartitionForExtract(const std::string& partition_name, const std::string& extract_path)
{
mExtractInfo.addElement({partition_name, extract_path});
}
void XciProcess::setListFs(bool list_fs)
void GameCardProcess::setListFs(bool list_fs)
{
mListFs = list_fs;
}
void XciProcess::importHeader()
void GameCardProcess::importHeader()
{
fnd::Vec<byte_t> scratch;
@ -74,22 +74,22 @@ void XciProcess::importHeader()
}
// read header page
(*mFile)->read((byte_t*)&mHdrPage, 0, sizeof(nn::hac::sXciHeaderPage));
(*mFile)->read((byte_t*)&mHdrPage, 0, sizeof(nn::hac::sGcHeaderPage));
// allocate memory for and decrypt sXciHeader
scratch.alloc(sizeof(nn::hac::sXciHeader));
scratch.alloc(sizeof(nn::hac::sGcHeader));
fnd::aes::sAes128Key header_key;
mKeyCfg.getXciHeaderKey(header_key);
nn::hac::XciUtils::decryptXciHeader((const byte_t*)&mHdrPage.header, scratch.data(), header_key.key);
nn::hac::GameCardUtils::decryptXciHeader((const byte_t*)&mHdrPage.header, scratch.data(), header_key.key);
// deserialise header
mHdr.fromBytes(scratch.data(), scratch.size());
}
void XciProcess::displayHeader()
void GameCardProcess::displayHeader()
{
std::cout << "[XCI Header]" << std::endl;
std::cout << "[GameCard Header]" << std::endl;
std::cout << " CardHeaderVersion: " << std::dec << (uint32_t)mHdr.getCardHeaderVersion() << std::endl;
std::cout << " RomSize: " << getRomSizeStr(mHdr.getRomSizeType());
if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED))
@ -128,22 +128,22 @@ void XciProcess::displayHeader()
{
std::cout << " RomAreaStartPage: 0x" << std::hex << mHdr.getRomAreaStartPage();
if (mHdr.getRomAreaStartPage() != (uint32_t)(-1))
std::cout << " (0x" << std::hex << nn::hac::XciUtils::blockToAddr(mHdr.getRomAreaStartPage()) << ")";
std::cout << " (0x" << std::hex << nn::hac::GameCardUtils::blockToAddr(mHdr.getRomAreaStartPage()) << ")";
std::cout << std::endl;
std::cout << " BackupAreaStartPage: 0x" << std::hex << mHdr.getBackupAreaStartPage();
if (mHdr.getBackupAreaStartPage() != (uint32_t)(-1))
std::cout << " (0x" << std::hex << nn::hac::XciUtils::blockToAddr(mHdr.getBackupAreaStartPage()) << ")";
std::cout << " (0x" << std::hex << nn::hac::GameCardUtils::blockToAddr(mHdr.getBackupAreaStartPage()) << ")";
std::cout << std::endl;
std::cout << " ValidDataEndPage: 0x" << std::hex << mHdr.getValidDataEndPage();
if (mHdr.getValidDataEndPage() != (uint32_t)(-1))
std::cout << " (0x" << std::hex << nn::hac::XciUtils::blockToAddr(mHdr.getValidDataEndPage()) << ")";
std::cout << " (0x" << std::hex << nn::hac::GameCardUtils::blockToAddr(mHdr.getValidDataEndPage()) << ")";
std::cout << std::endl;
std::cout << " LimArea: 0x" << std::hex << mHdr.getLimAreaPage();
if (mHdr.getLimAreaPage() != (uint32_t)(-1))
std::cout << " (0x" << std::hex << nn::hac::XciUtils::blockToAddr(mHdr.getLimAreaPage()) << ")";
std::cout << " (0x" << std::hex << nn::hac::GameCardUtils::blockToAddr(mHdr.getLimAreaPage()) << ")";
std::cout << std::endl;
std::cout << " PartitionFs Header:" << std::endl;
@ -160,7 +160,7 @@ void XciProcess::displayHeader()
if (mHdr.getFwVerMinor() != 0)
{
std::cout << "[XCI Extended Header]" << std::endl;
std::cout << "[GameCard Extended Header]" << std::endl;
std::cout << " FwVersion: v" << std::dec << mHdr.getFwVerMajor() << "." << mHdr.getFwVerMinor() << std::endl;
std::cout << " AccCtrl1: 0x" << std::hex << mHdr.getAccCtrl1() << std::endl;
std::cout << " CardClockRate: " << getCardClockRate(mHdr.getAccCtrl1()) << std::endl;
@ -178,7 +178,7 @@ void XciProcess::displayHeader()
}
}
bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash)
bool GameCardProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash)
{
fnd::Vec<byte_t> scratch;
fnd::sha::sSha256Hash calc_hash;
@ -188,23 +188,23 @@ bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* t
return calc_hash.compare(test_hash);
}
void XciProcess::validateXciSignature()
void GameCardProcess::validateXciSignature()
{
fnd::rsa::sRsa2048Key header_sign_key;
fnd::sha::sSha256Hash calc_hash;
fnd::sha::Sha256((byte_t*)&mHdrPage.header, sizeof(nn::hac::sXciHeader), calc_hash.bytes);
fnd::sha::Sha256((byte_t*)&mHdrPage.header, sizeof(nn::hac::sGcHeader), calc_hash.bytes);
mKeyCfg.getXciHeaderSignKey(header_sign_key);
if (fnd::rsa::pkcs::rsaVerify(header_sign_key, fnd::sha::HASH_SHA256, calc_hash.bytes, mHdrPage.signature) != 0)
{
std::cout << "[WARNING] XCI Header Signature: FAIL" << std::endl;
std::cout << "[WARNING] GameCard Header Signature: FAIL" << std::endl;
}
}
void XciProcess::processRootPfs()
void GameCardProcess::processRootPfs()
{
if (mVerify && validateRegionOfFile(mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize(), mHdr.getPartitionFsHash().bytes) == false)
{
std::cout << "[WARNING] XCI Root HFS0: FAIL (bad hash)" << std::endl;
std::cout << "[WARNING] GameCard Root HFS0: FAIL (bad hash)" << std::endl;
}
mRootPfs.setInputFile(new fnd::OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize()));
mRootPfs.setListFs(mListFs);
@ -214,7 +214,7 @@ void XciProcess::processRootPfs()
mRootPfs.process();
}
void XciProcess::processPartitionPfs()
void GameCardProcess::processPartitionPfs()
{
const fnd::List<nn::hac::PartitionFsHeader::sFile>& rootPartitions = mRootPfs.getPfsHeader().getFileList();
for (size_t i = 0; i < rootPartitions.size(); i++)
@ -222,7 +222,7 @@ void XciProcess::processPartitionPfs()
// 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)
{
std::cout << "[WARNING] XCI " << rootPartitions[i].name << " Partition HFS0: FAIL (bad hash)" << std::endl;
std::cout << "[WARNING] GameCard " << rootPartitions[i].name << " Partition HFS0: FAIL (bad hash)" << std::endl;
}
PfsProcess tmp;
@ -238,28 +238,28 @@ void XciProcess::processPartitionPfs()
}
}
const char* XciProcess::getRomSizeStr(byte_t rom_size) const
const char* GameCardProcess::getRomSizeStr(byte_t rom_size) const
{
const char* str = nullptr;
switch (rom_size)
{
case (nn::hac::xci::ROM_SIZE_1GB):
case (nn::hac::gc::ROM_SIZE_1GB):
str = "1GB";
break;
case (nn::hac::xci::ROM_SIZE_2GB):
case (nn::hac::gc::ROM_SIZE_2GB):
str = "2GB";
break;
case (nn::hac::xci::ROM_SIZE_4GB):
case (nn::hac::gc::ROM_SIZE_4GB):
str = "4GB";
break;
case (nn::hac::xci::ROM_SIZE_8GB):
case (nn::hac::gc::ROM_SIZE_8GB):
str = "8GB";
break;
case (nn::hac::xci::ROM_SIZE_16GB):
case (nn::hac::gc::ROM_SIZE_16GB):
str = "16GB";
break;
case (nn::hac::xci::ROM_SIZE_32GB):
case (nn::hac::gc::ROM_SIZE_32GB):
str = "32GB";
break;
default:
@ -270,19 +270,19 @@ const char* XciProcess::getRomSizeStr(byte_t rom_size) const
return str;
}
const char* XciProcess::getHeaderFlagStr(byte_t flag) const
const char* GameCardProcess::getHeaderFlagStr(byte_t flag) const
{
const char* str = nullptr;
switch (flag)
{
case (nn::hac::xci::FLAG_AUTOBOOT):
case (nn::hac::gc::FLAG_AUTOBOOT):
str = "AutoBoot";
break;
case (nn::hac::xci::FLAG_HISTORY_ERASE):
case (nn::hac::gc::FLAG_HISTORY_ERASE):
str = "HistoryErase";
break;
case (nn::hac::xci::FLAG_REPAIR_TOOL):
case (nn::hac::gc::FLAG_REPAIR_TOOL):
str = "RepairTool";
break;
default:
@ -294,16 +294,16 @@ const char* XciProcess::getHeaderFlagStr(byte_t flag) const
}
const char* XciProcess::getCardClockRate(uint32_t acc_ctrl_1) const
const char* GameCardProcess::getCardClockRate(uint32_t acc_ctrl_1) const
{
const char* str = nullptr;
switch (acc_ctrl_1)
{
case (nn::hac::xci::CLOCK_RATE_25):
case (nn::hac::gc::CLOCK_RATE_25):
str = "20 MHz";
break;
case (nn::hac::xci::CLOCK_RATE_50):
case (nn::hac::gc::CLOCK_RATE_50):
str = "50 MHz";
break;
default:

View file

@ -4,16 +4,16 @@
#include <fnd/IFile.h>
#include <fnd/SharedPtr.h>
#include <fnd/List.h>
#include <nn/hac/XciHeader.h>
#include <nn/hac/GameCardHeader.h>
#include "KeyConfiguration.h"
#include "PfsProcess.h"
#include "common.h"
class XciProcess
class GameCardProcess
{
public:
XciProcess();
GameCardProcess();
void process();
@ -28,7 +28,7 @@ public:
void setListFs(bool list_fs);
private:
const std::string kModuleName = "XciProcess";
const std::string kModuleName = "GameCardProcess";
const std::string kXciMountPointName = "gamecard:/";
fnd::SharedPtr<fnd::IFile> mFile;
@ -55,8 +55,8 @@ private:
bool mListFs;
nn::hac::sXciHeaderPage mHdrPage;
nn::hac::XciHeader mHdr;
nn::hac::sGcHeaderPage mHdrPage;
nn::hac::GameCardHeader mHdr;
PfsProcess mRootPfs;
fnd::List<sExtractInfo> mExtractInfo;

View file

@ -15,7 +15,7 @@
#include <fnd/ResourceFileReader.h>
#include <nn/hac/ContentArchiveUtils.h>
#include <nn/hac/AesKeygen.h>
#include <nn/hac/define/xci.h>
#include <nn/hac/define/gc.h>
#include <nn/hac/define/pfs.h>
#include <nn/hac/define/nca.h>
#include <nn/hac/define/meta.h>
@ -590,8 +590,8 @@ FileType UserSettings::getFileTypeFromString(const std::string& type_str)
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
FileType type;
if (str == "xci")
type = FILE_XCI;
if (str == "gc" || str == "gamecard" || str == "xci")
type = FILE_GC;
else if (str == "nsp")
type = FILE_NSP;
else if (str == "partitionfs" || str == "hashedpartitionfs" \
@ -600,9 +600,9 @@ FileType UserSettings::getFileTypeFromString(const std::string& type_str)
type = FILE_PARTITIONFS;
else if (str == "romfs")
type = FILE_ROMFS;
else if (str == "nca")
else if (str == "nca" || str == "contentarchive")
type = FILE_NCA;
else if (str == "meta")
else if (str == "meta" || str == "npdm")
type = FILE_META;
else if (str == "cnmt")
type = FILE_CNMT;
@ -645,8 +645,8 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
#define _ASSERT_SIZE(sz) (scratch.size() >= (sz))
// test npdm
if (_ASSERT_SIZE(sizeof(nn::hac::sXciHeaderPage)) && _TYPE_PTR(nn::hac::sXciHeaderPage)->header.st_magic.get() == nn::hac::xci::kXciStructMagic)
file_type = FILE_XCI;
if (_ASSERT_SIZE(sizeof(nn::hac::sGcHeaderPage)) && _TYPE_PTR(nn::hac::sGcHeaderPage)->header.st_magic.get() == nn::hac::gc::kGcHeaderStructMagic)
file_type = FILE_GC;
// test pfs0
else if (_ASSERT_SIZE(sizeof(nn::hac::sPfsHeader)) && _TYPE_PTR(nn::hac::sPfsHeader)->st_magic.get() == nn::hac::pfs::kPfsStructMagic)
file_type = FILE_PARTITIONFS;

View file

@ -10,7 +10,7 @@ static const size_t kNcaKeakNum = nn::hac::nca::kKeyAreaEncryptionKeyNum;
enum FileType
{
FILE_XCI,
FILE_GC,
FILE_NSP,
FILE_PARTITIONFS,
FILE_ROMFS,

View file

@ -3,7 +3,7 @@
#include <fnd/SharedPtr.h>
#include <fnd/StringConv.h>
#include "UserSettings.h"
#include "XciProcess.h"
#include "GameCardProcess.h"
#include "PfsProcess.h"
#include "RomfsProcess.h"
#include "NcaProcess.h"
@ -38,9 +38,9 @@ int main(int argc, char** argv)
fnd::SharedPtr<fnd::IFile> inputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read));
if (user_set.getFileType() == FILE_XCI)
if (user_set.getFileType() == FILE_GC)
{
XciProcess xci;
GameCardProcess xci;
xci.setInputFile(inputFile);
@ -49,13 +49,13 @@ int main(int argc, char** argv)
xci.setVerifyMode(user_set.isVerifyFile());
if (user_set.getXciUpdatePath().isSet)
xci.setPartitionForExtract(nn::hac::xci::kUpdatePartitionStr, user_set.getXciUpdatePath().var);
xci.setPartitionForExtract(nn::hac::gc::kUpdatePartitionStr, user_set.getXciUpdatePath().var);
if (user_set.getXciLogoPath().isSet)
xci.setPartitionForExtract(nn::hac::xci::kLogoPartitionStr, user_set.getXciLogoPath().var);
xci.setPartitionForExtract(nn::hac::gc::kLogoPartitionStr, user_set.getXciLogoPath().var);
if (user_set.getXciNormalPath().isSet)
xci.setPartitionForExtract(nn::hac::xci::kNormalPartitionStr, user_set.getXciNormalPath().var);
xci.setPartitionForExtract(nn::hac::gc::kNormalPartitionStr, user_set.getXciNormalPath().var);
if (user_set.getXciSecurePath().isSet)
xci.setPartitionForExtract(nn::hac::xci::kSecurePartitionStr, user_set.getXciSecurePath().var);
xci.setPartitionForExtract(nn::hac::gc::kSecurePartitionStr, user_set.getXciSecurePath().var);
xci.setListFs(user_set.isListFs());
xci.process();