Add Visual Studio (2017) support.

This commit is contained in:
jakcron 2018-04-25 12:59:42 +08:00
parent e1e6346628
commit 27347214f7
30 changed files with 407 additions and 990 deletions

View file

@ -8,6 +8,10 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcrypto", "lib\libcrypto\crypto.vcxproj", "{6ADBB60D-DBA0-411D-BD2D-A355EF8E0FE1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnx", "lib\libnx\nx.vcxproj", "{91BA9E79-8242-4F7D-B997-0DFEC95EA22B}"
ProjectSection(ProjectDependencies) = postProject
{6ADBB60D-DBA0-411D-BD2D-A355EF8E0FE1} = {6ADBB60D-DBA0-411D-BD2D-A355EF8E0FE1}
{4D27EDB9-5110-44FE-8CE2-D46C5AD3C55B} = {4D27EDB9-5110-44FE-8CE2-D46C5AD3C55B}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{170B4A09-1B67-4A62-93AB-116EBCFF4A8C}"
ProjectSection(SolutionItems) = preProject
@ -22,13 +26,14 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8F6C846D-35E2-47FD-AF42-7A3FD036346E}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
KEYS.md = KEYS.md
makefile = makefile
README.md = README.md
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libes", "lib\libes\es.vcxproj", "{7BE99936-0D40-410D-944B-4513C2EFF8DC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tiktool", "programs\tiktool\tiktool.vcxproj", "{2200B834-F15A-4C6E-9DDB-6012B9A5C246}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nstool", "programs\nstool\nstool.vcxproj", "{AF09FA96-4463-417D-8FE6-526063F41349}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -62,30 +67,6 @@ Global
{91BA9E79-8242-4F7D-B997-0DFEC95EA22B}.Release|x64.Build.0 = Release|x64
{91BA9E79-8242-4F7D-B997-0DFEC95EA22B}.Release|x86.ActiveCfg = Release|Win32
{91BA9E79-8242-4F7D-B997-0DFEC95EA22B}.Release|x86.Build.0 = Release|Win32
{7DA88C6F-4470-495D-995A-4F633F3370C1}.Debug|x64.ActiveCfg = Debug|x64
{7DA88C6F-4470-495D-995A-4F633F3370C1}.Debug|x64.Build.0 = Debug|x64
{7DA88C6F-4470-495D-995A-4F633F3370C1}.Debug|x86.ActiveCfg = Debug|Win32
{7DA88C6F-4470-495D-995A-4F633F3370C1}.Debug|x86.Build.0 = Debug|Win32
{7DA88C6F-4470-495D-995A-4F633F3370C1}.Release|x64.ActiveCfg = Release|x64
{7DA88C6F-4470-495D-995A-4F633F3370C1}.Release|x64.Build.0 = Release|x64
{7DA88C6F-4470-495D-995A-4F633F3370C1}.Release|x86.ActiveCfg = Release|Win32
{7DA88C6F-4470-495D-995A-4F633F3370C1}.Release|x86.Build.0 = Release|Win32
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}.Debug|x64.ActiveCfg = Debug|x64
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}.Debug|x64.Build.0 = Debug|x64
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}.Debug|x86.ActiveCfg = Debug|Win32
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}.Debug|x86.Build.0 = Debug|Win32
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}.Release|x64.ActiveCfg = Release|x64
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}.Release|x64.Build.0 = Release|x64
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}.Release|x86.ActiveCfg = Release|Win32
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}.Release|x86.Build.0 = Release|Win32
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Debug|x64.ActiveCfg = Debug|x64
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Debug|x64.Build.0 = Debug|x64
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Debug|x86.ActiveCfg = Debug|Win32
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Debug|x86.Build.0 = Debug|Win32
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x64.ActiveCfg = Release|x64
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x64.Build.0 = Release|x64
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x86.ActiveCfg = Release|Win32
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x86.Build.0 = Release|Win32
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Debug|x64.ActiveCfg = Debug|x64
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Debug|x64.Build.0 = Debug|x64
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Debug|x86.ActiveCfg = Debug|Win32
@ -94,22 +75,14 @@ Global
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Release|x64.Build.0 = Release|x64
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Release|x86.ActiveCfg = Release|Win32
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Release|x86.Build.0 = Release|Win32
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Debug|x64.ActiveCfg = Debug|x64
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Debug|x64.Build.0 = Debug|x64
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Debug|x86.ActiveCfg = Debug|Win32
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Debug|x86.Build.0 = Debug|Win32
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Release|x64.ActiveCfg = Release|x64
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Release|x64.Build.0 = Release|x64
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Release|x86.ActiveCfg = Release|Win32
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Release|x86.Build.0 = Release|Win32
{007FF616-7B99-4CB3-84CD-39C47F64FC7E}.Debug|x64.ActiveCfg = Debug|x64
{007FF616-7B99-4CB3-84CD-39C47F64FC7E}.Debug|x64.Build.0 = Debug|x64
{007FF616-7B99-4CB3-84CD-39C47F64FC7E}.Debug|x86.ActiveCfg = Debug|Win32
{007FF616-7B99-4CB3-84CD-39C47F64FC7E}.Debug|x86.Build.0 = Debug|Win32
{007FF616-7B99-4CB3-84CD-39C47F64FC7E}.Release|x64.ActiveCfg = Release|x64
{007FF616-7B99-4CB3-84CD-39C47F64FC7E}.Release|x64.Build.0 = Release|x64
{007FF616-7B99-4CB3-84CD-39C47F64FC7E}.Release|x86.ActiveCfg = Release|Win32
{007FF616-7B99-4CB3-84CD-39C47F64FC7E}.Release|x86.Build.0 = Release|Win32
{AF09FA96-4463-417D-8FE6-526063F41349}.Debug|x64.ActiveCfg = Debug|x64
{AF09FA96-4463-417D-8FE6-526063F41349}.Debug|x64.Build.0 = Debug|x64
{AF09FA96-4463-417D-8FE6-526063F41349}.Debug|x86.ActiveCfg = Debug|Win32
{AF09FA96-4463-417D-8FE6-526063F41349}.Debug|x86.Build.0 = Debug|Win32
{AF09FA96-4463-417D-8FE6-526063F41349}.Release|x64.ActiveCfg = Release|x64
{AF09FA96-4463-417D-8FE6-526063F41349}.Release|x64.Build.0 = Release|x64
{AF09FA96-4463-417D-8FE6-526063F41349}.Release|x86.ActiveCfg = Release|Win32
{AF09FA96-4463-417D-8FE6-526063F41349}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -118,12 +91,8 @@ Global
{4D27EDB9-5110-44FE-8CE2-D46C5AD3C55B} = {170B4A09-1B67-4A62-93AB-116EBCFF4A8C}
{6ADBB60D-DBA0-411D-BD2D-A355EF8E0FE1} = {170B4A09-1B67-4A62-93AB-116EBCFF4A8C}
{91BA9E79-8242-4F7D-B997-0DFEC95EA22B} = {170B4A09-1B67-4A62-93AB-116EBCFF4A8C}
{7DA88C6F-4470-495D-995A-4F633F3370C1} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
{7BE99936-0D40-410D-944B-4513C2EFF8DC} = {170B4A09-1B67-4A62-93AB-116EBCFF4A8C}
{2200B834-F15A-4C6E-9DDB-6012B9A5C246} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
{007FF616-7B99-4CB3-84CD-39C47F64FC7E} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
{AF09FA96-4463-417D-8FE6-526063F41349} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {07DCCACC-D10D-47C9-85AE-FB9C54DB7D62}

View file

@ -7,8 +7,6 @@ Tools & Libraries for NX (Nintendo Switch).
# Tools
* __nstool__ - read *.npdm, read/extract PartitionFS (PFS0|HFS0) blobs (including *.nsp), read *.xci
* __ncatool__ - read/extract *.nca
* __tiktool__ - read ticket fields.
# Libraries
@ -17,6 +15,12 @@ Tools & Libraries for NX (Nintendo Switch).
* __libes__ - Handling of (NS relevant) eShop file type processing. (eTickets, etc)
* __libnx__ - Handling of NS file types
# Building
On MacOS/Linux/WSL run `make`.
For Windows, Visual Studio 2017 is supported.
# External Keys
Programs/libraries don't embed any keys that are copyright protected. However keys can be imported via a keyset file.

View file

@ -129,6 +129,8 @@
<ClInclude Include="source\libpolarssl\include\polarssl\bignum.h" />
<ClInclude Include="source\libpolarssl\include\polarssl\bn_mul.h" />
<ClInclude Include="source\libpolarssl\include\polarssl\config.h" />
<ClInclude Include="source\libpolarssl\include\polarssl\md.h" />
<ClInclude Include="source\libpolarssl\include\polarssl\md_wrap.h" />
<ClInclude Include="source\libpolarssl\include\polarssl\rsa.h" />
<ClInclude Include="source\libpolarssl\include\polarssl\sha1.h" />
<ClInclude Include="source\libpolarssl\include\polarssl\sha2.h" />
@ -139,6 +141,8 @@
<ClCompile Include="source\libpolarssl\source\polar_aes.c" />
<ClCompile Include="source\libpolarssl\source\polar_base64.c" />
<ClCompile Include="source\libpolarssl\source\polar_bignum.c" />
<ClCompile Include="source\libpolarssl\source\polar_md.c" />
<ClCompile Include="source\libpolarssl\source\polar_md_wrap.c" />
<ClCompile Include="source\libpolarssl\source\polar_rsa.c" />
<ClCompile Include="source\libpolarssl\source\polar_sha1.c" />
<ClCompile Include="source\libpolarssl\source\polar_sha2.c" />

View file

@ -60,6 +60,12 @@
<ClInclude Include="source\libpolarssl\include\polarssl\sha2.h">
<Filter>Header Files\polarssl</Filter>
</ClInclude>
<ClInclude Include="source\libpolarssl\include\polarssl\md.h">
<Filter>Header Files\polarssl</Filter>
</ClInclude>
<ClInclude Include="source\libpolarssl\include\polarssl\md_wrap.h">
<Filter>Header Files\polarssl</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\aes.cpp">
@ -92,6 +98,12 @@
<ClCompile Include="source\libpolarssl\source\polar_sha1.c">
<Filter>Source Files\polarssl</Filter>
</ClCompile>
<ClCompile Include="source\libpolarssl\source\polar_md.c">
<Filter>Source Files\polarssl</Filter>
</ClCompile>
<ClCompile Include="source\libpolarssl\source\polar_md_wrap.c">
<Filter>Source Files\polarssl</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View file

@ -124,10 +124,13 @@
<ClInclude Include="include\fnd\elf.h" />
<ClInclude Include="include\fnd\Endian.h" />
<ClInclude Include="include\fnd\Exception.h" />
<ClInclude Include="include\fnd\IFile.h" />
<ClInclude Include="include\fnd\io.h" />
<ClInclude Include="include\fnd\ISerialiseableBinary.h" />
<ClInclude Include="include\fnd\List.h" />
<ClInclude Include="include\fnd\MemoryBlob.h" />
<ClInclude Include="include\fnd\ResourceFileReader.h" />
<ClInclude Include="include\fnd\SimpleFile.h" />
<ClInclude Include="include\fnd\SimpleTextOutput.h" />
<ClInclude Include="include\fnd\StringConv.h" />
<ClInclude Include="include\fnd\types.h" />
@ -136,6 +139,8 @@
<ClCompile Include="source\Exception.cpp" />
<ClCompile Include="source\io.cpp" />
<ClCompile Include="source\MemoryBlob.cpp" />
<ClCompile Include="source\ResourceFileReader.cpp" />
<ClCompile Include="source\SimpleFile.cpp" />
<ClCompile Include="source\SimpleTextOutput.cpp" />
<ClCompile Include="source\StringConv.cpp" />
</ItemGroup>

View file

@ -48,6 +48,15 @@
<ClInclude Include="include\fnd\SimpleTextOutput.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\IFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\ResourceFileReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\SimpleFile.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\Exception.cpp">
@ -65,6 +74,12 @@
<ClCompile Include="source\SimpleTextOutput.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\ResourceFileReader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\SimpleFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View file

@ -12,5 +12,7 @@ namespace fnd
void writeFile(const std::string& path, const MemoryBlob& blob);
void writeFile(const std::string& path, const byte_t* data, size_t len);
void makeDirectory(const std::string& path);
void getEnvironVar(std::string& var, const std::string& key);
void makePath(std::string& out, const std::vector<std::string>& elements);
}
}

View file

@ -1,7 +1,9 @@
#include <fnd/io.h>
#include <fnd/SimpleFile.h>
#include <fstream>
#ifdef _WIN32
#include <direct.h>
#include <cstdlib>
#else
#include <sys/stat.h>
#endif
@ -24,54 +26,53 @@ size_t io::getFileSize(const std::string& path)
void io::readFile(const std::string& path, MemoryBlob & blob)
{
FILE* fp;
size_t filesz, filepos;
if ((fp = fopen(path.c_str(), "rb")) == NULL)
fnd::SimpleFile file;
try
{
throw Exception(kModuleName, "Failed to open \"" + path + "\"");
file.open(path, file.Read);
}
catch (const fnd::Exception&)
{
throw fnd::Exception(kModuleName, "Failed to open \"" + path + "\": does not exist");
}
fseek(fp, 0, SEEK_END);
filesz = ftell(fp);
rewind(fp);
size_t filesz, filepos;
filesz = file.size();
try {
blob.alloc(filesz);
}
catch (const fnd::Exception& e)
{
fclose(fp);
throw fnd::Exception(kModuleName, "Failed to allocate memory for file: " + std::string(e.what()));
}
for (filepos = 0; filesz > kBlockSize; filesz -= kBlockSize, filepos += kBlockSize)
{
fread(blob.getBytes() + filepos, 1, kBlockSize, fp);
file.read(blob.getBytes() + filepos, kBlockSize);
}
if (filesz)
{
fread(blob.getBytes() + filepos, 1, filesz, fp);
file.read(blob.getBytes() + filepos, filesz);
}
fclose(fp);
}
void fnd::io::readFile(const std::string& path, size_t offset, size_t len, MemoryBlob& blob)
{
FILE* fp;
size_t filesz, filepos;
if ((fp = fopen(path.c_str(), "rb")) == NULL)
fnd::SimpleFile file;
try
{
throw Exception(kModuleName, "Failed to open \"" + path + "\": does not exist");
file.open(path, file.Read);
} catch (const fnd::Exception&)
{
throw fnd::Exception(kModuleName, "Failed to open \"" + path + "\": does not exist");
}
fseek(fp, 0, SEEK_END);
filesz = ftell(fp);
rewind(fp);
fseek(fp, offset, SEEK_SET);
size_t filesz, filepos;
filesz = file.size();
file.seek(offset);
if (filesz < len || filesz < offset || filesz < (offset + len))
{
@ -80,24 +81,21 @@ void fnd::io::readFile(const std::string& path, size_t offset, size_t len, Memor
try
{
blob.alloc(len);
blob.alloc(filesz);
} catch (const fnd::Exception& e)
{
fclose(fp);
throw fnd::Exception(kModuleName, "Failed to allocate memory for file: " + std::string(e.what()));
}
for (filepos = 0; len > kBlockSize; len -= kBlockSize, filepos += kBlockSize)
for (filepos = 0; filesz > kBlockSize; filesz -= kBlockSize, filepos += kBlockSize)
{
fread(blob.getBytes() + filepos, 1, kBlockSize, fp);
file.read(blob.getBytes() + filepos, kBlockSize);
}
if (len)
if (filesz)
{
fread(blob.getBytes() + filepos, 1, len, fp);
file.read(blob.getBytes() + filepos, filesz);
}
fclose(fp);
}
void io::writeFile(const std::string& path, const MemoryBlob & blob)
@ -107,28 +105,29 @@ void io::writeFile(const std::string& path, const MemoryBlob & blob)
void io::writeFile(const std::string & path, const byte_t * data, size_t len)
{
FILE* fp;
size_t filesz, filepos;
if ((fp = fopen(path.c_str(), "wb")) == NULL)
fnd::SimpleFile file;
try
{
throw Exception(kModuleName, "Failed to open \"" + path + "\"");
file.open(path, file.Create);
} catch (const fnd::Exception&)
{
throw fnd::Exception(kModuleName, "Failed to open \"" + path + "\": does not exist");
}
size_t filesz, filepos;
filesz = len;
for (filepos = 0; filesz > kBlockSize; filesz -= kBlockSize, filepos += kBlockSize)
{
fwrite(data + filepos, 1, kBlockSize, fp);
file.write(data + filepos, kBlockSize);
}
if (filesz)
{
fwrite(data + filepos, 1, filesz, fp);
file.write(data + filepos, filesz);
}
fclose(fp);
}
void io::makeDirectory(const std::string& path)
@ -138,4 +137,46 @@ void io::makeDirectory(const std::string& path)
#else
mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
#endif
}
}
void fnd::io::getEnvironVar(std::string & var, const std::string & key)
{
#ifdef _WIN32
char* var_tmp = nullptr;
size_t var_len = 0;
_dupenv_s(&var_tmp, &var_len, key.c_str());
if (var_len > 0)
{
var = std::string(var_tmp);
free(var_tmp);
}
#else
char* var_tmp = nullptr;
var_tmp = getenv(key.c_str());
if (var_tmp != nullptr)
{
var = std::string(var_tmp);
}
#endif
}
void fnd::io::makePath(std::string & out, const std::vector<std::string>& elements)
{
out.clear();
out = "";
for (size_t i = 0; i < elements.size(); i++)
{
if (i > 0)
{
#ifdef _WIN32
out += "\\";
#else
out += "/";
#endif
}
out += elements[i];
}
}

View file

@ -1,159 +0,0 @@
#pragma once
// AES
namespace crypto
{
/*
Keys mentioned in Content Archive Authoring library
private RsaKey m_NcaHeader1SignKey;
private RsaKey m_AcidSignKey;
private RsaKey m_NrrCertificateSignKey;
private AesKey m_ProdKeyAreaEncryptionKey;
private AesKey m_ProdNcaHeaderEncryptionKek;
private RsaKey m_ProdXciHeaderSignKey;
private AesKey m_ProdXciInitialDataEncryptionKey;
private AesKey m_ProdTitleKeyGenarateKey;
private AesKey m_ProdETicketCommonKey;
private RsaKey m_ProdETicketSignKey;
*/
namespace aes
{
/*
public static AesKey GetNcaExternalContentKey(IHashCalculator hashCalculator, ulong titleId)
{
Trace.Assert(hashCalculator != null, "IHashCalculator is null.");
byte[] array = BitConverter.GetBytes(titleId).Reverse<byte>().ToArray<byte>();
byte[] numArray = new byte[hashCalculator.HashSize];
hashCalculator.CalculateHash(array, 0, (int)array.Length, numArray, 0);
return new AesKey(((IEnumerable<byte>)numArray).Where<byte>((byte name, int index) => index < 16).ToArray<byte>());
}
*/
namespace nx
{
enum Aes128KeyId
{
NcaContentKey,
NcaHeader,
XciInitialData,
XciHeader,
ETicketCommonKey
};
enum HmacSha256KeyId
{
TitleKeyGenarateKey
};
namespace dev
{
// aes128-xts keys (seem to use 512 block sizes, aka 0x200 blocks)
byte_t nca_body_key[2][16] =
{
{ 0xE5, 0x64, 0xDB, 0xFE, 0x52, 0x93, 0x3A, 0x65, 0x3C, 0x8B, 0x5E, 0xF8, 0x2C, 0x9D, 0xF4, 0xB5 },
{ 0x60, 0x7B, 0x77, 0x3E, 0x31, 0xE9, 0x6A, 0x8F, 0x8E, 0x44, 0x5C, 0x98, 0x71, 0xC0, 0x57, 0xDB },
};
byte_t nca_header_key[2][16] =
{
{ 0xCB, 0x9A, 0x93, 0x9F, 0x82, 0x72, 0x54, 0x4A, 0x74, 0x5D, 0x28, 0x46, 0x9D, 0xCC, 0x38, 0x12 },
{ 0x06, 0x31, 0x27, 0x06, 0xAE, 0x62, 0x56, 0x8C, 0x5B, 0x7E, 0xE6, 0x9F, 0x7E, 0x01, 0x02, 0x24 },
};
// aeskey, related to m_KeyAreaEncryptionKeyList (first in list?)
byte_t key_area_encryption_key_0[0x10] = { 0x3A, 0x7C, 0x3E, 0x38, 0x4A, 0x8F, 0x22, 0xFF, 0x4B, 0x21, 0x57, 0x19, 0xB7, 0x81, 0xAD, 0x0C };
byte_t titlekey_generate_key[0x20] = { 39, 111, 56, 188, 68, 106, 241, 86, 31, 44, 90, 111, 116, 32, 93, 197, 25, 181, 59, 188, 178, 159, 211, 175, 212, 178, 162, 4, 28, 152, 117, 126 };
// aes128-cbc keys
byte_t xci_header_key[16] = { 0x01, 0xC5, 0x8F, 0xE7, 0x00, 0x2D, 0x13, 0x5A, 0xB2, 0x9A, 0x3F, 0x69, 0x33, 0x95, 0x74, 0xB1 };
byte_t eticket_common_key[16] = { 0x55, 0xA3, 0xF8, 0x72, 0xBD, 0xC8, 0x0C, 0x55, 0x5A, 0x65, 0x43, 0x81, 0x13, 0x9E, 0x15, 0x3B }; // lol this 3ds dev common key
byte_t wii_sd_key[16] = { 0xAB, 0x01, 0xB9, 0xD8, 0xE1, 0x62, 0x2B, 0x08, 0xAF, 0xBA, 0xD8, 0x4D, 0xBF, 0xC2, 0xA5, 0x5D };
}
namespace prod
{
byte_t master_key[0x20][16] =
{
{ 0xC2, 0xCA, 0xAF, 0xF0, 0x89, 0xB9, 0xAE, 0xD5, 0x56, 0x94, 0x87, 0x60, 0x55, 0x27, 0x1C, 0x7D },
{ 0x54, 0xE1, 0xB8, 0xE9, 0x99, 0xC2, 0xFD, 0x16, 0xCD, 0x07, 0xB6, 0x61, 0x09, 0xAC, 0xAA, 0xA6 },
{ 0x4F, 0x6B, 0x10, 0xD3, 0x30, 0x72, 0xAF, 0x2F, 0x25, 0x05, 0x62, 0xBF, 0xF0, 0x6B, 0x6D, 0xA3 },
};
byte_t nca_header_key[2][16] =
{
{ 0xAE, 0xAA, 0xB1, 0xCA, 0x08, 0xAD, 0xF9, 0xBE, 0xF1, 0x29, 0x91, 0xF3, 0x69, 0xE3, 0xC5, 0x67 },
{ 0xD6, 0x88, 0x1E, 0x4E, 0x4A, 0x6A, 0x47, 0xA5, 0x1F, 0x6E, 0x48, 0x77, 0x06, 0x2D, 0x54, 0x2D }
};
byte_t xci_header_key[16] = { 0x01, 0xC5, 0x8F, 0xE7, 0x00, 0x2D, 0x13, 0x5A, 0xB2, 0x9A, 0x3F, 0x69, 0x33, 0x95, 0x74, 0xB1 };
/*
// encrypted with ProdNcaHeaderEncryptionKek
byte_t nca_enc_header_key[2][16] =
{
{ 0x5A, 0x3E, 0xD8, 0x4F, 0xDE, 0xC0, 0xD8, 0x26, 0x31, 0xF7, 0xE2, 0x5D, 0x19, 0x7B, 0xF5, 0xD0 },
{ 0x1C, 0x9B, 0x7B, 0xFA, 0xF6, 0x28, 0x18, 0x3D, 0x71, 0xF6, 0x4D, 0x73, 0xF1, 0x50, 0xB9, 0xD2 }
};
*/
}
}
}
// RSA
namespace rsa
{
namespace nx
{
enum Rsa2048PssKeyId // sign/validate
{
NcaHeader1, // also reference as "sign key data"
Acid,
NrrCertificate
};
enum Rsa2048Pkcs1KeyId // sign/validate
{
XciHeader,
ETicket // XS00000020 or XS00000021 ident
};
enum RsaOaepKeyId // encrypt/decrypt
{
XciKeyArea
};
/*
in regards to etickets
%llx....string too long.invalid string position.CT..TW..NG..VP..PC..%08X....Contents of ticket at 0x%0*lx:.. Ticket ID = 0x%I64x... Version = %hd... Rights ID..... %02hhx..... Device ID = 0x%I64x... Issuer = %s.... SigType = 0x%0x..... AccountId = 0x%x.. LicenseType = %hhd.... CommonKeyId = %hhd.... PropertyMask = 0x%hx.. Title Key (encrypted and may be personalized):. .... sectTotalSize %d.. sectHdrOffset %d.. nSectHdrs %hd..... nSectHdrEntrySize %hd.....V1 Section Header %d:... sectOffset %d..... nRecords %d... recordSize %d..... sectionSize %d....PERMANENT...SUBSCRIPTION....CONTENT.CONTENT CONSUMPTION.ACCESS TITLE....Unknown.LIMITED RESOURCE.... sectionType %s.... V1 Section Records:... refId ..%02hhx .. refIdAttr %x... limit %x.... offset %x... accessMask:..... .... index %hx... code %hx.... accessTitleId %I64x..... accessTitleMask %I64x... Unknown Record Type %hx............
*/
// unknown key "EncryptionKeyData"
byte_t unk_rsa_key_mod[0x100] = { 0x85, 0xF8, 0x8C, 0x41, 0x8A, 0x2D, 0x96, 0xB3, 0xF3, 0x92, 0xD0, 0x6C, 0x9D, 0x90, 0x96, 0x7F, 0x1A, 0x78, 0xD8, 0x17, 0x7A, 0xB8, 0xEC, 0x0E, 0x6E, 0x10, 0x55, 0xC8, 0xCA, 0x7F, 0x18, 0xC7, 0x18, 0x94, 0x75, 0x0D, 0xBA, 0x19, 0x44, 0xDE, 0xFA, 0x93, 0xC8, 0xCB, 0x5F, 0xCA, 0x9B, 0x09, 0x3C, 0x2E, 0x2D, 0x12, 0xB2, 0xFA, 0x0B, 0xB7, 0xC0, 0xFC, 0xD4, 0x05, 0xC4, 0x2B, 0xC7, 0x9F, 0x6A, 0xAC, 0xB5, 0x80, 0xA0, 0x4E, 0x72, 0xCB, 0x8D, 0x5E, 0x85, 0x63, 0xBF, 0x99, 0x16, 0x89, 0x07, 0xFE, 0x3A, 0x09, 0xBC, 0xDF, 0x5C, 0xF3, 0x90, 0x29, 0x33, 0xFF, 0x72, 0xB5, 0x18, 0xD0, 0x08, 0xEB, 0xC3, 0x98, 0xC2, 0x4C, 0x3B, 0xF6, 0xCF, 0xCC, 0xB2, 0x71, 0xDD, 0x8E, 0xEE, 0x13, 0x88, 0x82, 0x79, 0x67, 0xC1, 0x6C, 0x3D, 0x60, 0x9C, 0x7D, 0x1D, 0x43, 0x52, 0xF1, 0x48, 0xBB, 0x5D, 0xCB, 0x39, 0xAA, 0x93, 0x8E, 0x75, 0x76, 0xBE, 0x37, 0x47, 0x9C, 0xAB, 0x2F, 0x22, 0xBF, 0xCA, 0x75, 0xC3, 0x50, 0x99, 0xD4, 0x98, 0x72, 0xC2, 0x62, 0x58, 0xA3, 0xB9, 0xD3, 0xD7, 0xCF, 0xEA, 0x40, 0x02, 0x42, 0x49, 0xC9, 0xBA, 0xFE, 0x83, 0x87, 0x40, 0xF7, 0x87, 0x6A, 0x4D, 0x5A, 0xB7, 0x6F, 0x0C, 0x3C, 0xD7, 0x6C, 0x8B, 0x00, 0x68, 0x65, 0x32, 0x29, 0x70, 0x68, 0x26, 0x91, 0x14, 0x04, 0x58, 0x2A, 0xE8, 0x01, 0x68, 0x41, 0x89, 0x58, 0x87, 0xA3, 0x1D, 0xE4, 0xB9, 0xBF, 0x8B, 0x9C, 0x47, 0x88, 0xA6, 0x79, 0x5A, 0x17, 0xC4, 0xE3, 0xAB, 0x05, 0xA8, 0x31, 0x1E, 0xD1, 0x55, 0xA2, 0xA2, 0x04, 0x85, 0xF1, 0x96, 0x81, 0x23, 0x04, 0x44, 0x57, 0xCC, 0x93, 0x66, 0x0D, 0xC1, 0x9E, 0x34, 0x46, 0x29, 0x12, 0xCD, 0x74, 0x19, 0xCD, 0x1F, 0xD4, 0x26, 0x31, 0xAB, 0xC5 };
byte_t unk_rsa_key_d[0x100] = { 0x1B, 0xC9, 0x6E, 0x85, 0xD5, 0x7C, 0x19, 0x2A, 0xDF, 0xD5, 0x4E, 0xA7, 0x88, 0x92, 0xC9, 0xB4, 0x39, 0x30, 0x61, 0x59, 0x95, 0x59, 0xAF, 0x94, 0x5A, 0x9D, 0xC6, 0xBD, 0x2B, 0xCA, 0xEA, 0xBF, 0xB8, 0xC8, 0x69, 0xF2, 0xDB, 0xEB, 0x8B, 0xCE, 0x57, 0xD8, 0xB9, 0x27, 0xFD, 0x89, 0x4F, 0x58, 0xBE, 0x03, 0xB1, 0xD3, 0x94, 0x0D, 0xAA, 0xCA, 0x85, 0x1B, 0xAB, 0x7A, 0x3A, 0xB2, 0xFD, 0xE7, 0x81, 0xBF, 0xAA, 0xB1, 0xB0, 0x0E, 0x35, 0x5F, 0x24, 0xC6, 0x3B, 0x12, 0x72, 0x55, 0xF5, 0x47, 0x9C, 0xC1, 0xCD, 0x15, 0xE1, 0xF7, 0xCE, 0x16, 0xB2, 0x8A, 0xE9, 0x3F, 0x0D, 0x72, 0xA4, 0x5F, 0xD9, 0xC9, 0xD4, 0xBA, 0xE5, 0x69, 0xDC, 0x72, 0x17, 0xAD, 0x94, 0x41, 0x6B, 0xBB, 0xCE, 0x83, 0x7C, 0xA7, 0xDB, 0x38, 0x7A, 0xF4, 0xD1, 0x52, 0x2D, 0x83, 0x01, 0xC3, 0xC9, 0xFB, 0x43, 0xA3, 0x54, 0x41, 0x3D, 0xBD, 0x78, 0x04, 0x97, 0x9D, 0xA6, 0xAE, 0x1D, 0x34, 0x5E, 0xD6, 0x77, 0x70, 0x08, 0xE4, 0xD6, 0x7F, 0x98, 0x72, 0x1A, 0xF2, 0xFF, 0xAF, 0x86, 0x5E, 0x05, 0x40, 0xA3, 0x51, 0x97, 0x6E, 0x30, 0xBD, 0x06, 0xDF, 0xC1, 0xF7, 0x58, 0xC2, 0x3C, 0x8D, 0x49, 0xAE, 0x13, 0x7D, 0x1E, 0x27, 0x98, 0x92, 0x47, 0xD0, 0x55, 0x62, 0x08, 0x17, 0x34, 0xEB, 0xC5, 0x68, 0x43, 0xFB, 0x6F, 0xA5, 0x3F, 0x28, 0x3A, 0xBB, 0x37, 0x2B, 0xAD, 0xF7, 0x0F, 0x85, 0xB1, 0xDF, 0x6C, 0xC9, 0x9F, 0x85, 0x46, 0xF7, 0x50, 0xC4, 0x87, 0xA1, 0xD4, 0xAA, 0xCB, 0x01, 0x85, 0xFA, 0xC6, 0x79, 0x01, 0x2C, 0x0B, 0x2F, 0xEE, 0x71, 0xFE, 0x5D, 0x86, 0x17, 0xE5, 0x91, 0x5F, 0x44, 0x79, 0x6D, 0xC3, 0x89, 0xE3, 0x8A, 0xDD, 0x03, 0xD4, 0xCA, 0xEA, 0x79, 0xCB, 0x34, 0x61, 0xE7, 0x53, 0x41 };
// rsa2048-pkcs1-sha256 keys
byte_t XS00000020_d[0x100] = { 0x51, 0x02, 0x71, 0x58, 0xCA, 0x69, 0xD9, 0x61, 0x3A, 0x81, 0xDE, 0x76, 0x55, 0xBB, 0xCE, 0xEA, 0x40, 0xE9, 0x9E, 0x66, 0xC7, 0xD5, 0x36, 0x36, 0x8D, 0xD3, 0xCC, 0x75, 0xAF, 0x08, 0x23, 0x9A, 0x8B, 0x07, 0xB0, 0xF4, 0xA8, 0xC9, 0xB6, 0x52, 0xC3, 0xEF, 0x00, 0x4D, 0x0A, 0x58, 0x4F, 0xA2, 0x70, 0xA3, 0xD1, 0x98, 0xE8, 0x56, 0x3B, 0x01, 0x27, 0x4C, 0x1F, 0x97, 0x2F, 0x01, 0x44, 0x86, 0x1C, 0xA9, 0x61, 0x64, 0xDF, 0x73, 0x9E, 0xAA, 0x83, 0x00, 0xA3, 0x97, 0xB9, 0x81, 0xEC, 0x13, 0xCC, 0x8E, 0x34, 0xC3, 0xCC, 0x8F, 0xF7, 0x5E, 0x61, 0xF1, 0xB2, 0x8C, 0x3D, 0xEC, 0xE9, 0x09, 0x54, 0xAA, 0x2C, 0xF4, 0xE8, 0xBC, 0xE5, 0x74, 0x4D, 0x75, 0x97, 0x12, 0xD0, 0x64, 0xFB, 0xB0, 0xAB, 0x9F, 0xE5, 0x2C, 0xE0, 0xDF, 0xD9, 0x3E, 0x89, 0xEB, 0xB7, 0x43, 0xD0, 0xD2, 0x88, 0xD6, 0xE4, 0xB3, 0xD4, 0xC9, 0x23, 0x67, 0xE0, 0xF5, 0xC4, 0x98, 0xDF, 0x4E, 0x12, 0x64, 0x53, 0xC3, 0x92, 0xEB, 0x77, 0x72, 0xDC, 0x83, 0xBF, 0x11, 0xCD, 0x4B, 0x05, 0x1D, 0x43, 0x1C, 0x6A, 0x7D, 0x9F, 0x00, 0x1E, 0x1A, 0xB7, 0x50, 0x03, 0x0A, 0xF0, 0x8C, 0x67, 0x52, 0x7F, 0x3E, 0xAD, 0x72, 0xC4, 0x39, 0x93, 0x3A, 0xB1, 0x66, 0xFC, 0x5F, 0x84, 0xCF, 0x1D, 0x0F, 0x47, 0xDC, 0x7A, 0xDC, 0xEE, 0xAB, 0xB5, 0x5A, 0x44, 0x04, 0x5A, 0xA8, 0x0E, 0x07, 0xF4, 0xED, 0xDF, 0x56, 0x47, 0xCF, 0x8B, 0xDE, 0xA6, 0x26, 0x3C, 0x89, 0xD0, 0xDB, 0xDD, 0xED, 0xD8, 0xF2, 0xA9, 0x76, 0x95, 0x7D, 0xA5, 0xDB, 0xD2, 0x8F, 0x8E, 0xF2, 0x31, 0xC7, 0x6A, 0xFB, 0x9F, 0xA4, 0xA7, 0x95, 0xE0, 0xBF, 0x5F, 0x57, 0x48, 0x3C, 0x65, 0x60, 0x2A, 0x46, 0x2A, 0xDD, 0xA8, 0x58, 0xD8, 0x2F, 0x89, 0x81 };
byte_t XS00000020_mod[0x100] = { 0xBA, 0x27, 0x84, 0x28, 0x76, 0x5D, 0x87, 0x9A, 0x7F, 0x21, 0x54, 0x04, 0xC6, 0xEE, 0x4E, 0x0A, 0x0D, 0x3F, 0x66, 0xC3, 0x3B, 0xC7, 0xF8, 0xA3, 0x2F, 0xD8, 0x98, 0xE5, 0x2C, 0xB7, 0xB6, 0x34, 0x43, 0xCE, 0xD8, 0xB0, 0x05, 0x27, 0xD8, 0x9D, 0xED, 0xC6, 0xBB, 0xF6, 0x0A, 0xD1, 0xC5, 0xC9, 0x92, 0x30, 0x21, 0xDD, 0x55, 0x5F, 0x9B, 0xAD, 0x4B, 0xE0, 0xC0, 0xC4, 0x06, 0xD3, 0x70, 0x29, 0x15, 0xE5, 0xB3, 0x4A, 0xC2, 0xD2, 0xAB, 0xE5, 0x03, 0xC3, 0x2A, 0x3A, 0x23, 0xB4, 0x38, 0x34, 0xC9, 0x15, 0x7B, 0x9A, 0x0A, 0xF2, 0xE4, 0xE9, 0xC0, 0x3B, 0xED, 0xE2, 0xB4, 0xC1, 0x15, 0xF5, 0x35, 0x3D, 0xFC, 0x66, 0xBD, 0x04, 0xA6, 0xC0, 0x79, 0x97, 0x0E, 0x38, 0xCB, 0xDD, 0x5A, 0x50, 0xA2, 0xB9, 0x8F, 0xF2, 0xD7, 0x65, 0xFC, 0xF8, 0x33, 0x81, 0xE9, 0xE0, 0xE8, 0x49, 0xC3, 0x57, 0x35, 0x78, 0x37, 0x8F, 0xF6, 0x59, 0x51, 0x61, 0x3E, 0x95, 0xF7, 0x5E, 0xE8, 0xEF, 0x26, 0x18, 0x3A, 0x40, 0xAA, 0xE4, 0xA7, 0x6D, 0x73, 0x84, 0xEA, 0x47, 0x8D, 0x2C, 0xDC, 0xE8, 0x0F, 0xBA, 0x03, 0x21, 0xA6, 0xBF, 0x8D, 0x69, 0x98, 0x3C, 0x3A, 0xA7, 0xAE, 0x54, 0x43, 0xB7, 0x2B, 0xFE, 0x41, 0x0B, 0xF1, 0x32, 0x3C, 0xBD, 0x88, 0xC3, 0x56, 0x0E, 0xA1, 0x3D, 0x17, 0xD3, 0x8A, 0x2E, 0x34, 0x04, 0x1D, 0xE7, 0xAA, 0xF3, 0x89, 0xDE, 0x43, 0x75, 0x22, 0x5C, 0xA8, 0x7E, 0xE3, 0x49, 0xC7, 0x60, 0xC7, 0xD9, 0x9B, 0xE7, 0xE7, 0x37, 0xC6, 0x26, 0x1C, 0xC7, 0x4E, 0x25, 0xAE, 0x46, 0x52, 0x7A, 0xC9, 0x61, 0x9F, 0x93, 0x90, 0x57, 0x08, 0x8D, 0x74, 0x35, 0xA6, 0xDE, 0x7B, 0x25, 0xAB, 0x82, 0xDD, 0x54, 0x10, 0xF2, 0x57, 0x9C, 0xAE, 0xF1, 0x49, 0x1A, 0x90, 0x9D, 0x30, 0x2B };
// rsa2048-pss-sha256 keys
byte_t nca_header1_d[0x100] = { 0x0C, 0x05, 0xB5, 0x6D, 0xE9, 0x0F, 0xE6, 0x41, 0x55, 0x6D, 0x52, 0x36, 0xC8, 0x57, 0xB3, 0x60, 0x57, 0xDB, 0xCD, 0xB3, 0x03, 0x0F, 0x57, 0xF1, 0x17, 0x8A, 0x30, 0x33, 0x8A, 0x68, 0x92, 0xFB, 0x73, 0x57, 0x04, 0x8A, 0xCB, 0xE3, 0xF4, 0x8A, 0xBF, 0xE3, 0xF2, 0xAC, 0x38, 0x23, 0x30, 0x26, 0x95, 0x42, 0x3D, 0x50, 0xFA, 0xB4, 0xAF, 0x60, 0x21, 0x75, 0xDC, 0xD9, 0x57, 0xB4, 0xC3, 0x6C, 0xE5, 0xF6, 0xE5, 0xE0, 0x55, 0x65, 0x77, 0x4B, 0xC7, 0xA6, 0x7E, 0x0A, 0xFE, 0xDD, 0x80, 0x42, 0x4F, 0x0D, 0x7E, 0x15, 0x8D, 0xF4, 0x27, 0x37, 0x24, 0x99, 0xF2, 0x12, 0x31, 0xDB, 0xD7, 0x7F, 0x1E, 0x92, 0x21, 0x14, 0xCA, 0x21, 0xF6, 0x50, 0x08, 0x92, 0xAE, 0x31, 0xDE, 0xF4, 0x29, 0x24, 0xD6, 0x41, 0xB3, 0x47, 0x18, 0x37, 0x14, 0xF9, 0x8D, 0x5D, 0x95, 0xF4, 0xF5, 0x7F, 0x99, 0xFB, 0x86, 0xDA, 0x65, 0xE9, 0x72, 0xA9, 0x77, 0x65, 0xC8, 0xC5, 0x29, 0x5A, 0x19, 0x2B, 0x51, 0x1C, 0x72, 0xEB, 0x49, 0xD1, 0x0B, 0x73, 0x8B, 0x3E, 0x2E, 0xC8, 0x7E, 0xFF, 0xD8, 0xFE, 0xF4, 0xF4, 0xF6, 0x92, 0x27, 0x7F, 0xA0, 0xDB, 0xC1, 0x25, 0xBC, 0xEC, 0x5F, 0x0B, 0x2D, 0x99, 0xEB, 0xDD, 0x9E, 0x5D, 0x42, 0x75, 0xB5, 0xE3, 0x24, 0xCB, 0xE9, 0xEB, 0xD9, 0x00, 0x4B, 0x12, 0x5D, 0xA3, 0xA6, 0x25, 0xAC, 0x20, 0x82, 0x25, 0x53, 0x1F, 0xC6, 0x2F, 0x27, 0xF1, 0x99, 0x7A, 0x99, 0xDC, 0xA5, 0xC0, 0x5E, 0x63, 0x0F, 0x78, 0x03, 0x2A, 0x18, 0xD9, 0xE1, 0x06, 0x3B, 0xDF, 0xB2, 0x95, 0x19, 0x32, 0xB4, 0x65, 0xD2, 0xD0, 0xFE, 0x18, 0xC7, 0x54, 0x5C, 0xA4, 0xF6, 0xD8, 0xFD, 0xDB, 0x6D, 0xD8, 0xDA, 0xF2, 0x9A, 0x55, 0x5C, 0x3E, 0xEC, 0x17, 0x72, 0x09, 0xA3, 0x1A, 0x0A, 0xC1 };
byte_t nca_header1_mod[0x100] = { 0xD8, 0xF1, 0x18, 0xEF, 0x32, 0x72, 0x4C, 0xA7, 0x47, 0x4C, 0xB9, 0xEA, 0xB3, 0x04, 0xA8, 0xA4, 0xAC, 0x99, 0x08, 0x08, 0x04, 0xBF, 0x68, 0x57, 0xB8, 0x43, 0x94, 0x2B, 0xC7, 0xB9, 0x66, 0x49, 0x85, 0xE5, 0x8A, 0x9B, 0xC1, 0x00, 0x9A, 0x6A, 0x8D, 0xD0, 0xEF, 0xCE, 0xFF, 0x86, 0xC8, 0x5C, 0x5D, 0xE9, 0x53, 0x7B, 0x19, 0x2A, 0xA8, 0xC0, 0x22, 0xD1, 0xF3, 0x22, 0x0A, 0x50, 0xF2, 0x2B, 0x65, 0x05, 0x1B, 0x9E, 0xEC, 0x61, 0xB5, 0x63, 0xA3, 0x6F, 0x3B, 0xBA, 0x63, 0x3A, 0x53, 0xF4, 0x49, 0x2F, 0xCF, 0x03, 0xCC, 0xD7, 0x50, 0x82, 0x1B, 0x29, 0x4F, 0x08, 0xDE, 0x1B, 0x6D, 0x47, 0x4F, 0xA8, 0xB6, 0x6A, 0x26, 0xA0, 0x83, 0x3F, 0x1A, 0xAF, 0x83, 0x8F, 0x0E, 0x17, 0x3F, 0xFE, 0x44, 0x1C, 0x56, 0x94, 0x2E, 0x49, 0x83, 0x83, 0x03, 0xE9, 0xB6, 0xAD, 0xD5, 0xDE, 0xE3, 0x2D, 0xA1, 0xD9, 0x66, 0x20, 0x5D, 0x1F, 0x5E, 0x96, 0x5D, 0x5B, 0x55, 0x0D, 0xD4, 0xB4, 0x77, 0x6E, 0xAE, 0x1B, 0x69, 0xF3, 0xA6, 0x61, 0x0E, 0x51, 0x62, 0x39, 0x28, 0x63, 0x75, 0x76, 0xBF, 0xB0, 0xD2, 0x22, 0xEF, 0x98, 0x25, 0x02, 0x05, 0xC0, 0xD7, 0x6A, 0x06, 0x2C, 0xA5, 0xD8, 0x5A, 0x9D, 0x7A, 0xA4, 0x21, 0x55, 0x9F, 0xF9, 0x3E, 0xBF, 0x16, 0xF6, 0x07, 0xC2, 0xB9, 0x6E, 0x87, 0x9E, 0xB5, 0x1C, 0xBE, 0x97, 0xFA, 0x82, 0x7E, 0xED, 0x30, 0xD4, 0x66, 0x3F, 0xDE, 0xD8, 0x1B, 0x4B, 0x15, 0xD9, 0xFB, 0x2F, 0x50, 0xF0, 0x9D, 0x1D, 0x52, 0x4C, 0x1C, 0x4D, 0x8D, 0xAE, 0x85, 0x1E, 0xEA, 0x7F, 0x86, 0xF3, 0x0B, 0x7B, 0x87, 0x81, 0x98, 0x23, 0x80, 0x63, 0x4F, 0x2F, 0xB0, 0x62, 0xCC, 0x6E, 0xD2, 0x46, 0x13, 0x65, 0x2B, 0xD6, 0x44, 0x33, 0x59, 0xB5, 0x8F, 0xB9, 0x4A, 0xA9 };
byte_t nrr_certificate_d[0x100] = { 0x2C, 0x5E, 0x97, 0x84, 0x97, 0x13, 0x8C, 0xD7, 0xFC, 0x6F, 0x36, 0xC1, 0xC1, 0x2A, 0x87, 0x4B, 0xE0, 0x86, 0xD2, 0xFA, 0xB8, 0x97, 0x77, 0xCF, 0xBB, 0xE8, 0x89, 0x58, 0x28, 0xD9, 0xC0, 0xD8, 0x81, 0x7E, 0x1E, 0x67, 0x16, 0x95, 0xCF, 0x14, 0x24, 0x82, 0xB4, 0xE7, 0x92, 0x08, 0xB4, 0xA7, 0x88, 0xC7, 0xC6, 0x8E, 0x32, 0x1C, 0xE4, 0xBB, 0x39, 0x03, 0xA2, 0xDE, 0x21, 0x9D, 0xB8, 0xA1, 0x69, 0x36, 0x36, 0x9D, 0x11, 0x24, 0xCD, 0xB1, 0x48, 0x6B, 0xD3, 0x4B, 0x4F, 0x9E, 0x38, 0x91, 0xD8, 0xFA, 0xDC, 0x00, 0x67, 0x11, 0xE4, 0xBA, 0x54, 0xC7, 0x47, 0x54, 0xFB, 0x55, 0x2A, 0x41, 0xAD, 0x4F, 0x9F, 0x6D, 0x03, 0xF5, 0xEC, 0x4B, 0x42, 0x78, 0xE2, 0xCD, 0x6E, 0x04, 0xFB, 0x5D, 0x20, 0x94, 0x52, 0xAA, 0xFD, 0x58, 0x3A, 0x85, 0x58, 0x31, 0xAE, 0xDE, 0x16, 0xBE, 0x42, 0x22, 0x85, 0xA1, 0x42, 0xBD, 0xBB, 0xA0, 0x87, 0xEB, 0x3B, 0x25, 0x0F, 0x15, 0x5A, 0xA1, 0x0F, 0x53, 0x0E, 0x51, 0xF5, 0xF0, 0xDB, 0x8E, 0xCC, 0x82, 0x4A, 0x4E, 0x67, 0x5D, 0xC1, 0x4C, 0x62, 0x1A, 0x1D, 0x5E, 0x4A, 0xC4, 0xF3, 0x1D, 0xE6, 0x89, 0x83, 0xCB, 0x00, 0xD0, 0x26, 0xFB, 0x62, 0xF1, 0xD9, 0xC6, 0x18, 0x68, 0x16, 0xF6, 0x35, 0xEE, 0x74, 0xE8, 0xEA, 0xD1, 0xCE, 0x8A, 0xE1, 0x83, 0xDA, 0xE0, 0x30, 0x5F, 0x84, 0x43, 0x0D, 0x10, 0xAB, 0x04, 0x5F, 0x0E, 0xDD, 0x9B, 0xEE, 0x17, 0x73, 0x86, 0x70, 0x32, 0x9A, 0x96, 0xAB, 0x09, 0x54, 0xA7, 0x30, 0x25, 0x41, 0x94, 0xE1, 0x5F, 0x03, 0x4F, 0xEA, 0xBA, 0x7D, 0x2B, 0x9A, 0x41, 0x1C, 0x50, 0x5F, 0x2B, 0xDD, 0x83, 0xFA, 0xF4, 0xEF, 0x57, 0x50, 0xD2, 0x7E, 0xB4, 0x9F, 0x89, 0x84, 0x52, 0x37, 0x63, 0x82, 0x02, 0x69, 0x51 };
byte_t nrr_certificate_mod[0x100] = { 0xC1, 0x15, 0x7C, 0x02, 0x26, 0xE5, 0x35, 0x6F, 0x99, 0xDB, 0xBE, 0xBD, 0xD7, 0x01, 0x07, 0x1C, 0xC2, 0x3D, 0x1E, 0x6B, 0x7E, 0x08, 0x07, 0xBC, 0xE2, 0x6D, 0x49, 0xEC, 0x0B, 0xFF, 0xE4, 0x91, 0x8C, 0x62, 0xB9, 0xFC, 0x69, 0xBF, 0x3A, 0xB6, 0x6C, 0x3A, 0x5D, 0x0E, 0x31, 0x5E, 0x6C, 0x1D, 0x9A, 0x21, 0xD9, 0x9D, 0xD3, 0xB8, 0x50, 0x5F, 0x27, 0x7C, 0x4A, 0xD2, 0xFE, 0xE8, 0xDA, 0x1C, 0xB9, 0x9E, 0x7E, 0x1E, 0x2F, 0x7D, 0xF9, 0x70, 0xA2, 0x98, 0x19, 0x6A, 0x53, 0x40, 0x64, 0xE7, 0xC0, 0x92, 0xAE, 0x64, 0xD2, 0x01, 0xB2, 0x49, 0x30, 0x19, 0x7F, 0xF8, 0x6E, 0x0D, 0x49, 0x35, 0xE9, 0x95, 0x77, 0x00, 0x65, 0xC5, 0x1E, 0xF5, 0x2A, 0xF9, 0xA1, 0x52, 0xA0, 0xA4, 0xFA, 0x87, 0x3D, 0x8F, 0x51, 0xEC, 0x02, 0x80, 0xA4, 0xC7, 0x22, 0x74, 0xEF, 0x56, 0x61, 0x71, 0x39, 0xE2, 0x2F, 0x03, 0x82, 0xDB, 0x50, 0xE9, 0xCC, 0x60, 0x48, 0x46, 0x71, 0xE2, 0xC6, 0x71, 0xF3, 0xF9, 0x85, 0x52, 0x1A, 0xE2, 0xA8, 0x18, 0x77, 0x86, 0xD0, 0x12, 0xEB, 0x4F, 0x81, 0xA0, 0xDF, 0x20, 0x42, 0xF0, 0xF8, 0xE3, 0x00, 0xE6, 0xFC, 0xA7, 0x44, 0xF0, 0xDC, 0x2B, 0x5B, 0xA0, 0xD3, 0x01, 0x34, 0xD0, 0xD7, 0xFD, 0xEF, 0x66, 0x92, 0xB3, 0x87, 0x64, 0xD9, 0x76, 0xDA, 0x6E, 0x3A, 0x19, 0x98, 0x1F, 0xBD, 0x1F, 0x25, 0x69, 0x9F, 0x28, 0xE6, 0x9E, 0xB7, 0x38, 0x92, 0x12, 0x16, 0xDE, 0xDA, 0xE2, 0xB9, 0x7E, 0xFA, 0x98, 0x94, 0xF4, 0x9A, 0xDF, 0x2D, 0xC0, 0x99, 0x83, 0x61, 0xAD, 0xB8, 0x3E, 0x27, 0x3F, 0x0E, 0xB8, 0x9E, 0x9B, 0x11, 0x78, 0xF1, 0x06, 0x30, 0x5B, 0xCA, 0xF4, 0xEB, 0x72, 0x20, 0xD3, 0x15, 0x15, 0xC0, 0xC7, 0x1A, 0x08, 0xAE, 0x6E, 0xB2, 0x02, 0x43, 0xE9 };
// rsa2048-oaep-sha256 key
byte_t xci_keyarea_labledigest[0x20] = { 0xB1, 0x7B, 0x5F, 0x65, 0x0E, 0x75, 0x90, 0xED, 0xFE, 0x3A, 0xF0, 0x75, 0x0B, 0x92, 0x05, 0xB3, 0x0E, 0x7D, 0x49, 0x89, 0x24, 0xD8, 0xE3, 0x85, 0xCB, 0x40, 0xE0, 0xE7, 0xF8, 0xDE, 0xF0, 0x77 };
byte_t xci_keyarea_mod[0x100] = { 0xA6, 0x1A, 0x3F, 0x5E, 0x16, 0x94, 0x4D, 0x5F, 0x88, 0x07, 0x45, 0x92, 0x42, 0x02, 0x5C, 0xF8, 0xF8, 0x01, 0xA6, 0x8F, 0xF0, 0x77, 0x76, 0x06, 0x06, 0x4B, 0x67, 0x02, 0x35, 0x2F, 0xC2, 0xF6, 0xCD, 0x74, 0xBC, 0x57, 0x36, 0xA0, 0x61, 0x1D, 0xD6, 0x66, 0x35, 0x79, 0x6E, 0xB7, 0xFF, 0xC1, 0x05, 0xC6, 0x59, 0xD9, 0x1E, 0xC9, 0xC3, 0x1F, 0x5B, 0x17, 0xA9, 0x24, 0x46, 0xB3, 0xAB, 0x1D, 0x7B, 0x79, 0xA8, 0xF2, 0x80, 0xC8, 0x6F, 0xA7, 0x9B, 0x2D, 0xE8, 0xBF, 0x91, 0xD7, 0xD4, 0xA2, 0x07, 0x53, 0x98, 0x82, 0x7D, 0x91, 0x8A, 0x68, 0x79, 0x9B, 0xB6, 0x8F, 0xA7, 0x05, 0x7B, 0x2B, 0x6C, 0x09, 0x2A, 0x58, 0x8A, 0x21, 0xE5, 0xB6, 0xCD, 0xAC, 0xCB, 0x84, 0x5F, 0x22, 0x16, 0x82, 0x54, 0x14, 0x03, 0xEB, 0xBB, 0x86, 0xEC, 0x59, 0x36, 0x38, 0xF8, 0x41, 0x41, 0xCA, 0x23, 0x8A, 0xF2, 0x98, 0x01, 0xAD, 0x14, 0xB6, 0x65, 0x15, 0x3B, 0x63, 0x42, 0xC1, 0x3E, 0x55, 0x8C, 0xC2, 0x38, 0x4E, 0xC0, 0x57, 0x5E, 0xFA, 0x2A, 0x2C, 0xC7, 0x9C, 0xBE, 0x5C, 0xD7, 0x56, 0x4D, 0xCF, 0x36, 0x31, 0x93, 0xD2, 0xB1, 0x0A, 0x8C, 0x7C, 0x7F, 0xFE, 0x46, 0x20, 0xE3, 0x91, 0x7C, 0x63, 0x3F, 0x24, 0x81, 0xFF, 0x4C, 0x68, 0x4F, 0xBE, 0x16, 0x68, 0x66, 0x1C, 0x90, 0xCD, 0xFE, 0x8D, 0xC5, 0x63, 0x3B, 0x2D, 0x5C, 0x25, 0x95, 0xA8, 0x4B, 0x3C, 0xAF, 0x57, 0x07, 0x84, 0x31, 0x37, 0xFA, 0x63, 0x98, 0x1B, 0xAC, 0xB2, 0x81, 0xB1, 0x29, 0x67, 0x0A, 0x31, 0x3D, 0x7E, 0x2D, 0x7F, 0xFE, 0xA5, 0x29, 0x3D, 0xBF, 0xD3, 0xCC, 0x9D, 0x73, 0x75, 0x40, 0x8B, 0x79, 0x98, 0x39, 0x8A, 0xAD, 0x90, 0x65, 0x82, 0x90, 0x09, 0xA4, 0x74, 0xA2, 0x3F, 0xEE, 0xC7, 0x75, 0x06, 0x29, 0x85 };
}
}
}

View file

@ -14,6 +14,7 @@ namespace nx
static const size_t kProductCodeMaxLen = 0x10;
static const uint32_t kMaxPriority = BIT(6) -1 ;
static const size_t kNpdmAlignSize = 0x10;
static const uint32_t kDefaultMainThreadStackSize = 4096;
enum InstructionType
{
@ -32,62 +33,24 @@ namespace nx
struct sNpdmHeader
{
private:
byte_t signature_[4]; // be"META"
char signature[4];
byte_t reserved_0[8];
byte_t flags_;
byte_t flags;
byte_t reserved_1;
byte_t main_thread_priority_; // 0-63 inclusive
byte_t main_thread_cpu_id_;
byte_t main_thread_priority;
byte_t main_thread_cpu_id;
byte_t reserved_2[8];
uint32_t version_;
uint32_t main_thread_stack_size_; // default 4096
byte_t name_[npdm::kNameMaxLen]; // important
byte_t product_code_[npdm::kProductCodeMaxLen]; // can be empty
le_uint32_t version;
le_uint32_t main_thread_stack_size;
char name[npdm::kNameMaxLen]; // important
char product_code[npdm::kProductCodeMaxLen]; // can be empty
byte_t reserved_3[48];
// Access Control Info
struct sNpdmSection
{
private:
uint32_t offset_;
uint32_t size_;
public:
uint32_t offset() const { return le_word(offset_); }
void set_offset(uint32_t offset) { offset_ = le_word(offset); }
uint32_t size() const { return le_word(size_); }
void set_size(uint32_t size) { size_ = le_word(size); }
} aci_, acid_;
public:
const char* signature() const { return (const char*)signature_; }
void set_signature(const char* signature) { memcpy(signature_, signature, 4); }
byte_t flags() const { return flags_; }
void set_flags(byte_t flags) { flags_ = flags; }
byte_t main_thread_priority() const { return main_thread_priority_; }
void set_main_thread_priority(byte_t priority) { main_thread_priority_ = priority; }
byte_t main_thread_cpu_id() const { return main_thread_cpu_id_; }
void set_main_thread_cpu_id(byte_t cpu_id) { main_thread_cpu_id_ = cpu_id; }
uint32_t version() const { return le_word(version_); }
void set_version(uint32_t version) { version_ = le_word(version); }
uint32_t main_thread_stack_size() const { return le_word(main_thread_stack_size_); }
void set_main_thread_stack_size(uint32_t size) { main_thread_stack_size_ = le_word(size); }
const char* name() const { return (const char*)name_; }
void set_name(const char* name) { strncpy((char*)name_, name, npdm::kNameMaxLen); }
const char* product_code() const { return (const char*)product_code_; }
void set_product_code(const char* product_code) { strncpy((char*)product_code_, product_code, npdm::kProductCodeMaxLen); }
const sNpdmSection& aci() const { return aci_; }
sNpdmSection& aci() { return aci_; }
const sNpdmSection& acid() const { return acid_; }
sNpdmSection& acid() { return acid_; }
le_uint32_t offset;
le_uint32_t size;
} aci, acid;
};
#pragma pack(pop)

View file

@ -19,9 +19,11 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\nx\aci.h" />
<ClInclude Include="include\nx\AciBinary.h" />
<ClInclude Include="include\nx\AcidBinary.h" />
<ClInclude Include="include\nx\AciHeader.h" />
<ClInclude Include="include\nx\AesKeygen.h" />
<ClInclude Include="include\nx\FacBinary.h" />
<ClInclude Include="include\nx\FacHeader.h" />
<ClInclude Include="include\nx\HandleTableSizeEntry.h" />
@ -29,6 +31,7 @@
<ClInclude Include="include\nx\IKernelCapabilityHandler.h" />
<ClInclude Include="include\nx\InteruptEntry.h" />
<ClInclude Include="include\nx\InteruptHandler.h" />
<ClInclude Include="include\nx\ivfc.h" />
<ClInclude Include="include\nx\KcBinary.h" />
<ClInclude Include="include\nx\KernelCapability.h" />
<ClInclude Include="include\nx\KernelVersionEntry.h" />
@ -40,12 +43,15 @@
<ClInclude Include="include\nx\MiscParamsEntry.h" />
<ClInclude Include="include\nx\MiscParamsHandler.h" />
<ClInclude Include="include\nx\nca.h" />
<ClInclude Include="include\nx\NcaUtils.h" />
<ClInclude Include="include\nx\npdm.h" />
<ClInclude Include="include\nx\NpdmBinary.h" />
<ClInclude Include="include\nx\NpdmHeader.h" />
<ClInclude Include="include\nx\NcaHeader.h" />
<ClInclude Include="include\nx\NXCrypto.h" />
<ClInclude Include="include\nx\pfs.h" />
<ClInclude Include="include\nx\PfsHeader.h" />
<ClInclude Include="include\nx\romfs.h" />
<ClInclude Include="include\nx\SacBinary.h" />
<ClInclude Include="include\nx\SacEntry.h" />
<ClInclude Include="include\nx\SystemCallEntry.h" />
@ -53,11 +59,14 @@
<ClInclude Include="include\nx\ThreadInfoEntry.h" />
<ClInclude Include="include\nx\ThreadInfoHandler.h" />
<ClInclude Include="include\nx\xci.h" />
<ClInclude Include="include\nx\XciHeader.h" />
<ClInclude Include="include\nx\XciUtils.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\AciBinary.cpp" />
<ClCompile Include="source\AcidBinary.cpp" />
<ClCompile Include="source\AciHeader.cpp" />
<ClCompile Include="source\AesKeygen.cpp" />
<ClCompile Include="source\FacBinary.cpp" />
<ClCompile Include="source\FacHeader.cpp" />
<ClCompile Include="source\HandleTableSizeEntry.cpp" />
@ -74,6 +83,7 @@
<ClCompile Include="source\MiscFlagsHandler.cpp" />
<ClCompile Include="source\MiscParamsEntry.cpp" />
<ClCompile Include="source\MiscParamsHandler.cpp" />
<ClCompile Include="source\NcaUtils.cpp" />
<ClCompile Include="source\NpdmBinary.cpp" />
<ClCompile Include="source\NpdmHeader.cpp" />
<ClCompile Include="source\NcaHeader.cpp" />
@ -84,6 +94,8 @@
<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>
<ItemGroup>
<None Include="makefile" />

View file

@ -117,6 +117,30 @@
<ClInclude Include="include\nx\xci.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\aci.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\AesKeygen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\ivfc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\NcaUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\npdm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\romfs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\XciHeader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\XciUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\AciBinary.cpp">
@ -206,6 +230,18 @@
<ClCompile Include="source\ThreadInfoHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\AesKeygen.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\NcaUtils.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>
<ItemGroup>
<None Include="makefile" />

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View file

@ -88,21 +88,21 @@ void nx::NpdmHeader::exportBinary()
mBinaryBlob.alloc(sizeof(sNpdmHeader));
sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes();
hdr->set_signature(npdm::kNpdmStructSig.c_str());
memcpy(hdr->signature, npdm::kNpdmStructSig.c_str(), 4);
byte_t flag = ((byte_t)(mInstructionType & 1) | (byte_t)((mProcAddressSpaceType & 3) << 1)) & 0xf;
hdr->set_flags(flag);
hdr->set_main_thread_priority(mMainThreadPriority);
hdr->set_main_thread_cpu_id(mMainThreadCpuId);
hdr->set_version(mVersion);
hdr->set_main_thread_stack_size(mMainThreadStackSize);
hdr->set_name(mName.c_str());
hdr->set_product_code(mProductCode.c_str());
hdr->flags = flag;
hdr->main_thread_priority = mMainThreadPriority;
hdr->main_thread_cpu_id = mMainThreadCpuId;
hdr->version = mVersion;
hdr->main_thread_stack_size = mMainThreadStackSize;
strncpy(hdr->name, mName.c_str(), npdm::kNameMaxLen);
strncpy(hdr->product_code, mProductCode.c_str(), npdm::kProductCodeMaxLen);
calculateOffsets();
hdr->aci().set_offset(mAciPos.offset);
hdr->aci().set_size(mAciPos.size);
hdr->acid().set_offset(mAcidPos.offset);
hdr->acid().set_size(mAcidPos.size);
hdr->aci.offset = mAciPos.offset;
hdr->aci.size = mAciPos.size;
hdr->acid.offset = mAcidPos.offset;
hdr->acid.size = mAcidPos.size;
}
void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len)
@ -118,32 +118,32 @@ void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len)
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes();
if (memcmp(npdm::kNpdmStructSig.c_str(), hdr->signature(), 4) != 0)
if (std::string(hdr->signature, 4) != npdm::kNpdmStructSig)
{
throw fnd::Exception(kModuleName, "NPDM header corrupt");
}
byte_t flag = hdr->flags() & 0xf;
byte_t flag = hdr->flags & 0xf;
mInstructionType = (npdm::InstructionType)(flag & 1);
mProcAddressSpaceType = (npdm::ProcAddrSpaceType)((flag >> 1) & 3);
mMainThreadPriority = hdr->main_thread_priority();
mMainThreadCpuId = hdr->main_thread_cpu_id();
mVersion = hdr->version();
mMainThreadStackSize = hdr->main_thread_stack_size();
mName = std::string(hdr->name(), npdm::kNameMaxLen);
mMainThreadPriority = hdr->main_thread_priority;
mMainThreadCpuId = hdr->main_thread_cpu_id;
mVersion = hdr->version.get();
mMainThreadStackSize = hdr->main_thread_stack_size.get();
mName = std::string(hdr->name, npdm::kNameMaxLen);
if (mName[0] == '\0')
{
mName.clear();
}
mProductCode = std::string(hdr->product_code(), npdm::kProductCodeMaxLen);
mProductCode = std::string(hdr->product_code, npdm::kProductCodeMaxLen);
if (mProductCode[0] == '\0')
{
mProductCode.clear();
}
mAciPos.offset = hdr->aci().offset();
mAciPos.size = hdr->aci().size();
mAcidPos.offset = hdr->acid().offset();
mAcidPos.size = hdr->acid().size();
mAciPos.offset = hdr->aci.offset.get();
mAciPos.size = hdr->aci.size.get();
mAcidPos.offset = hdr->acid.offset.get();
mAcidPos.size = hdr->acid.size.get();
}
void nx::NpdmHeader::clear()

View file

@ -1,4 +1,4 @@
PROGS = nstool ncatool tiktool
PROGS = nstool
BIN_DIR = "../bin"
main: build

View file

@ -1,47 +0,0 @@
# Sources
SRC_DIR = source
OBJS = $(foreach dir,$(SRC_DIR),$(subst .cpp,.o,$(wildcard $(dir)/*.cpp))) $(foreach dir,$(SRC_DIR),$(subst .c,.o,$(wildcard $(dir)/*.c)))
# External dependencies
DEPENDS = nx crypto fnd
LIB_DIR = ../../lib
LIBS = $(foreach dep,$(DEPENDS), -L"$(LIB_DIR)/lib$(dep)" -l$(dep))
INCS = $(foreach dep,$(DEPENDS), -I"$(LIB_DIR)/lib$(dep)/include")
BIN_DIR = bin
OUTPUT = $(BIN_DIR)/$(shell basename $(CURDIR))
# Compiler Settings
CXXFLAGS = -std=c++11 $(INCS) -D__STDC_FORMAT_MACROS -Wall -Wno-unused-value
ifeq ($(OS),Windows_NT)
# Windows Only Flags/Libs
CC = x86_64-w64-mingw32-gcc
CXX = x86_64-w64-mingw32-g++
CFLAGS += -Wno-unused-but-set-variable
CXXFLAGS += -Wno-unused-but-set-variable
LIBS += -static
else
UNAME = $(shell uname -s)
ifeq ($(UNAME), Darwin)
# MacOS Only Flags/Libs
CFLAGS += -Wno-unused-private-field
CXXFLAGS += -Wno-unused-private-field
LIBS +=
else
# *nix Only Flags/Libs
CFLAGS += -Wno-unused-but-set-variable
CXXFLAGS += -Wno-unused-but-set-variable
LIBS +=
endif
endif
all: build
rebuild: clean build
build: $(OBJS)
mkdir -p $(BIN_DIR)
$(CXX) $(OBJS) $(LIBS) -o $(OUTPUT)
clean:
rm -rf $(OBJS) $(OUTPUT) $(BIN_DIR)

View file

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
</Project>

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommandArguments>..\..\sample\nca\gfx\GfxPrimitiveRenderer.nca</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommandArguments>..\..\sample\nca\gfx\GfxPrimitiveRenderer.nca</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>..\..\sample\nca\gfx\GfxPrimitiveRenderer.nca</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>..\..\sample\nca\gfx\GfxPrimitiveRenderer.nca</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

View file

@ -1,237 +0,0 @@
#include <cstdio>
#include <crypto/aes.h>
#include <fnd/io.h>
#include <fnd/MemoryBlob.h>
#include <fnd/SimpleTextOutput.h>
#include <nx/NXCrypto.h>
#include <nx/NcaHeader.h>
#include <nx/NcaUtils.h>
#include <nx/PfsHeader.h>
#include <inttypes.h>
#ifdef _WIN32
#include <direct.h>
#else
#include <sys/stat.h>
#endif
std::string kFormatVersionStr[]
{
"NCA2",
"NCA3"
};
std::string kDistributionTypeStr[]
{
"Download",
"Game Card"
};
std::string kContentTypeStr[]
{
"Program",
"Meta",
"Control",
"Manual",
"Data"
};
std::string kEncryptionTypeStr[]
{
"Auto",
"None",
"AesXts",
"AesCtr",
"AesCtrEx"
};
std::string kHashTypeStr[]
{
"Auto",
"UNKNOWN_1",
"HierarchicalSha256",
"HierarchicalIntegrity"
};
std::string kFormatTypeStr[]
{
"RomFs",
"PartitionFs"
};
std::string kKaekIndexStr[]
{
"Application",
"Ocean",
"System"
};
enum KeysetType
{
KEYSET_DEV,
KEYSET_PROD
};
static const byte_t* kNcaHeaderKey[2][2] =
{
{ crypto::aes::nx::dev::nca_header_key[0], crypto::aes::nx::dev::nca_header_key[1] },
{ crypto::aes::nx::prod::nca_header_key[0], crypto::aes::nx::prod::nca_header_key[1] }
};
inline size_t sectorToOffset(size_t sector_index) { return nx::NcaUtils::sectorToOffset(sector_index); }
void initNcaCtr(byte_t ctr[crypto::aes::kAesBlockSize], uint32_t generation)
{
memset(ctr, 0, crypto::aes::kAesBlockSize);
for (size_t i = 0; i < 4; i++)
{
ctr[7 - i] = (generation >> i * 8) & 0xff;
}
}
void decryptNcaHeader(byte_t header[nx::nca::kHeaderSize], const byte_t* key[2])
{
crypto::aes::sAesXts128Key a;
a.set(key[0],key[1]);
nx::NcaUtils::decryptNcaHeader(header, header, a);
}
bool testNcaHeaderKey(const byte_t* header_src, const byte_t* key[2])
{
bool validKey = false;
byte_t header_dec[nx::nca::kSectorSize];
byte_t tweak[crypto::aes::kAesBlockSize];
// try key
crypto::aes::AesXtsMakeTweak(tweak, 1);
crypto::aes::AesXtsDecryptSector(header_src + sectorToOffset(1), nx::nca::kSectorSize, key[0], key[1], tweak, header_dec);
if (memcmp(header_dec, nx::nca::kNca2Sig.c_str(), 4) == 0 || memcmp(header_dec, nx::nca::kNca3Sig.c_str(), 4) == 0)
{
validKey = true;
}
return validKey;
}
KeysetType getKeysetFromNcaHeader(const byte_t* header_src)
{
for (int i = 0; i < 2; i++)
{
if (testNcaHeaderKey(header_src, kNcaHeaderKey[i]) == true)
{
return (KeysetType)i;
}
}
throw fnd::Exception("Failed to determine NCA header key");
}
void printHeader(const byte_t* header)
{
nx::NcaHeader hdr;
hdr.importBinary(header + sectorToOffset(1), nx::nca::kSectorSize);
printf("[NCA Header]\n");
printf(" Format Type: %s\n", kFormatVersionStr[hdr.getFormatVersion()].c_str());
printf(" Dist. Type: %s\n", kDistributionTypeStr[hdr.getDistributionType()].c_str());
printf(" Content Type: %s\n", kContentTypeStr[hdr.getContentType()].c_str());
printf(" Key Generation: %d\n", hdr.getKeyGeneration());
printf(" Kaek Index: %s (%d)\n", kKaekIndexStr[hdr.getKaekIndex()].c_str(), hdr.getKaekIndex());
printf(" Size: 0x%" PRIx64 "\n", hdr.getContentSize());
printf(" ProgID: 0x%016" PRIx64 "\n", hdr.getProgramId());
printf(" Content Index: %" PRIu32 "\n", hdr.getContentIndex());
uint32_t ver = hdr.getSdkAddonVersion();
printf(" SdkAddon Ver.: v%d.%d.%d (v%" PRIu32 ")\n", (ver>>24 & 0xff),(ver>>16 & 0xff),(ver>>8 & 0xff), ver);
printf(" RightsId: ");
fnd::SimpleTextOutput::hexDump(hdr.getRightsId(), 0x10);
printf("\n");
printf(" Encrypted Key Area:\n");
crypto::aes::sAes128Key zero_key;
memset(zero_key.key, 0, sizeof(zero_key));
for (size_t i = 0; i < hdr.getEncAesKeys().getSize(); i++)
{
if (hdr.getEncAesKeys()[i] != zero_key)
{
printf(" %2lu: ", i);
fnd::SimpleTextOutput::hexDump(hdr.getEncAesKeys()[i].key, crypto::aes::kAes128KeySize);
printf("\n");
}
}
printf(" Sections:\n");
for (size_t i = 0; i < hdr.getPartitions().getSize(); i++)
{
const nx::NcaHeader::sPartition& partition = hdr.getPartitions()[i];
printf(" %lu:\n", i);
//printf(" Start Blk: %" PRId32 "\n", partition.start_blk);
//printf(" End Blk: %" PRId32 "\n", partition.end_blk);
printf(" Index: %d\n", partition.index);
printf(" Offset: 0x%" PRIx64 "\n", partition.offset);
printf(" Size: 0x%" PRIx64 "\n", partition.size);
size_t sector_index = 2 + partition.index;
crypto::sha::sSha256Hash ncaFsHeaderHash;
crypto::sha::Sha256(header + sectorToOffset(sector_index), nx::nca::kSectorSize, ncaFsHeaderHash.bytes);
if (partition.hash.compare(ncaFsHeaderHash) == false)
{
throw fnd::Exception("ncatool", "NcaFsHeader has bad sha256 hash");
}
const nx::sNcaFsHeader* fsHdr = (const nx::sNcaFsHeader*)(header + sectorToOffset(sector_index));
printf(" FsHeader:\n");
printf(" Version: 0x%d\n", fsHdr->version.get());
printf(" Format Type: %s\n", kFormatTypeStr[fsHdr->format_type].c_str());
printf(" Hash Type: %s\n", kHashTypeStr[fsHdr->hash_type].c_str());
printf(" Enc. Type: %s\n", kEncryptionTypeStr[fsHdr->encryption_type].c_str());
if (fsHdr->hash_type == nx::nca::HASH_HIERARCHICAL_INTERGRITY)
{
const nx::sIvfcHeader* hash_hdr = (const nx::sIvfcHeader*)(header + sectorToOffset(sector_index) + sizeof(nx::sNcaFsHeader));
//printf(" HashHierarchicalIntegrity Header:\n");
//printf(" ")
}
else if (fsHdr->hash_type == nx::nca::HASH_HIERARCHICAL_SHA256)
{
const nx::sHierarchicalSha256Header* hash_hdr = (const nx::sHierarchicalSha256Header*)(header + sectorToOffset(sector_index) + sizeof(nx::sNcaFsHeader));
printf(" HashHierarchicalSha256 Header:\n");
printf(" Master Hash: ");
fnd::SimpleTextOutput::hexDump(hash_hdr->master_hash, 0x20);
printf(" HashBlockSize: 0x%x\n", hash_hdr->hash_block_size.get());
printf(" Unknown: 0x%x\n", hash_hdr->unk_0x02.get());
printf(" HashDataOffset: 0x%" PRIx64 "\n", hash_hdr->hash_data.offset.get());
printf(" HashDataSize: 0x%" PRIx64 "\n", hash_hdr->hash_data.size.get());
printf(" HashTargetOffset: 0x%" PRIx64 "\n", hash_hdr->hash_target.offset.get());
printf(" HashTargetSize: 0x%" PRIx64 "\n", hash_hdr->hash_target.size.get());
}
}
}
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("usage: ncatool <nca file>\n");
return 1;
}
try
{
fnd::MemoryBlob nca;
fnd::io::readFile(argv[1], 0x0, nx::nca::kHeaderSize, nca);
KeysetType keyset = getKeysetFromNcaHeader(nca.getBytes());
decryptNcaHeader(nca.getBytes(), kNcaHeaderKey[keyset]);
printHeader(nca.getBytes());
} catch (const fnd::Exception& e)
{
printf("%s\n",e.what());
}
return 0;
}

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@ -20,36 +20,37 @@
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{7DA88C6F-4470-495D-995A-4F633F3370C1}</ProjectGuid>
<RootNamespace>ncatool</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
<ProjectGuid>{AF09FA96-4463-417D-8FE6-526063F41349}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>nstool</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -69,61 +70,86 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="source\main.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\lib\libcrypto\crypto.vcxproj">
<Project>{6adbb60d-dba0-411d-bd2d-a355ef8e0fe1}</Project>
@ -135,6 +161,26 @@
<Project>{91ba9e79-8242-4f7d-b997-0dfec95ea22b}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="source\NcaProcess.h" />
<ClInclude Include="source\NpdmProcess.h" />
<ClInclude Include="source\nstool.h" />
<ClInclude Include="source\PfsProcess.h" />
<ClInclude Include="source\RomfsProcess.h" />
<ClInclude Include="source\UserSettings.h" />
<ClInclude Include="source\version.h" />
<ClInclude Include="source\XciProcess.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\main.cpp" />
<ClCompile Include="source\NpdmProcess.cpp" />
<ClCompile Include="source\PfsProcess.cpp" />
<ClCompile Include="source\UserSettings.cpp" />
<ClCompile Include="source\XciProcess.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="source\NcaProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\NpdmProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\nstool.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\PfsProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\RomfsProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\UserSettings.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\XciProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\NpdmProcess.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\PfsProcess.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\UserSettings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\XciProcess.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View file

@ -5,6 +5,7 @@
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <fnd/io.h>
#include <fnd/SimpleFile.h>
#include <fnd/SimpleTextOutput.h>
#include <fnd/MemoryBlob.h>
@ -256,16 +257,31 @@ void UserSettings::populateKeyset(sCmdArgs& args)
else
{
// open other resource files in $HOME/.switch/prod.keys (or $HOME/.switch/dev.keys if -d/--dev is set).
char* home = nullptr;
if (home == nullptr) home = getenv("HOME");
if (home == nullptr) home = getenv("USERPROFILE");
if (home == nullptr) return;
std::string home;
if (home.empty()) fnd::io::getEnvironVar(home, "HOME");
if (home.empty()) fnd::io::getEnvironVar(home, "USERPROFILE");
if (home.empty()) return;
const std::string kKeysetNameStr[2] = {"prod.keys", "dev.keys"};
const std::string kHomeSwitchDirStr = ".switch";
std::string keyset_path = std::string(home) + std::string("/") + ".switch" + std::string("/") + kKeysetNameStr[args.devkit_keys.isSet ? *args.devkit_keys : 0];
//std::cout << keyset_path << std::endl;
res.processFile(keyset_path);
std::vector<std::string> path_list;
path_list.push_back(home);
path_list.push_back(kHomeSwitchDirStr);
path_list.push_back(kKeysetNameStr[args.devkit_keys.isSet ? *args.devkit_keys : 0]);
std::string keyset_path;
fnd::io::makePath(keyset_path, path_list);
try
{
res.processFile(keyset_path);
}
catch (const fnd::Exception&)
{
return;
}
}
// suffix
@ -552,25 +568,25 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
#define _ASSERT_SIZE(size) (blob.getSize() >= (size))
// test npdm
if (_ASSERT_SIZE(0x100 + sizeof(nx::sXciHeader)) && memcmp(_QUICK_CAST(nx::sXciHeader, 0x100)->signature, nx::xci::kXciSig.c_str(), 4) == 0)
if (_ASSERT_SIZE(sizeof(nx::sXciHeaderPage)) && std::string(_QUICK_CAST(nx::sXciHeaderPage, 0)->header.signature, 4) == nx::xci::kXciSig)
file_type = FILE_XCI;
// test pfs0
else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && memcmp(_QUICK_CAST(nx::sPfsHeader, 0)->signature, nx::pfs::kPfsSig.c_str(), 4) == 0)
else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && std::string(_QUICK_CAST(nx::sPfsHeader, 0)->signature, 4) == nx::pfs::kPfsSig)
file_type = FILE_PARTITIONFS;
// test hfs0
else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && memcmp(_QUICK_CAST(nx::sPfsHeader, 0)->signature, nx::pfs::kHashedPfsSig.c_str(), 4) == 0)
else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && std::string(_QUICK_CAST(nx::sPfsHeader, 0)->signature, 4) == 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)->header_size.get() == _QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].offset.get())
file_type = FILE_ROMFS;
// test nca2
else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && memcmp(nca_header->signature, nx::nca::kNca2Sig.c_str(), 4) == 0)
else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && std::string(nca_header->signature, 4) == nx::nca::kNca2Sig)
file_type = FILE_NCA;
// test nca3
else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && memcmp(nca_header->signature, nx::nca::kNca3Sig.c_str(), 4) == 0)
else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && std::string(nca_header->signature, 4) == nx::nca::kNca3Sig)
file_type = FILE_NCA;
// test npdm
else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && memcmp(_QUICK_CAST(nx::sNpdmHeader, 0)->signature(), nx::npdm::kNpdmStructSig.c_str(), 4) == 0)
else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && std::string(_QUICK_CAST(nx::sNpdmHeader, 0)->signature, 4) == nx::npdm::kNpdmStructSig)
file_type = FILE_NPDM;
// else unrecognised
else

View file

@ -1,4 +1,5 @@
#include <cstdio>
#include <fnd/SimpleFile.h>
#include "UserSettings.h"
#include "XciProcess.h"
#include "PfsProcess.h"

View file

@ -1,47 +0,0 @@
# Sources
SRC_DIR = source
OBJS = $(foreach dir,$(SRC_DIR),$(subst .cpp,.o,$(wildcard $(dir)/*.cpp))) $(foreach dir,$(SRC_DIR),$(subst .c,.o,$(wildcard $(dir)/*.c)))
# External dependencies
DEPENDS = es crypto fnd
LIB_DIR = ../../lib
LIBS = $(foreach dep,$(DEPENDS), -L"$(LIB_DIR)/lib$(dep)" -l$(dep))
INCS = $(foreach dep,$(DEPENDS), -I"$(LIB_DIR)/lib$(dep)/include")
BIN_DIR = bin
OUTPUT = $(BIN_DIR)/$(shell basename $(CURDIR))
# Compiler Settings
CXXFLAGS = -std=c++11 $(INCS) -D__STDC_FORMAT_MACROS -Wall -Wno-unused-value
ifeq ($(OS),Windows_NT)
# Windows Only Flags/Libs
CC = x86_64-w64-mingw32-gcc
CXX = x86_64-w64-mingw32-g++
CFLAGS += -Wno-unused-but-set-variable
CXXFLAGS += -Wno-unused-but-set-variable
LIBS += -static
else
UNAME = $(shell uname -s)
ifeq ($(UNAME), Darwin)
# MacOS Only Flags/Libs
CFLAGS += -Wno-unused-private-field
CXXFLAGS += -Wno-unused-private-field
LIBS +=
else
# *nix Only Flags/Libs
CFLAGS += -Wno-unused-but-set-variable
CXXFLAGS += -Wno-unused-but-set-variable
LIBS +=
endif
endif
all: build
rebuild: clean build
build: $(OBJS)
mkdir -p $(BIN_DIR)
$(CXX) $(OBJS) $(LIBS) -o $(OUTPUT)
clean:
rm -rf $(OBJS) $(OUTPUT) $(BIN_DIR)

View file

@ -1,89 +0,0 @@
#include <cstdio>
#include <inttypes.h>
#include <crypto/aes.h>
#include <fnd/io.h>
#include <fnd/MemoryBlob.h>
#include <fnd/SimpleTextOutput.h>
#include <es/ETicketBody_V2.h>
const std::string kTitleKeyPersonalisation[2] =
{
"Generic (AESCBC)",
"Personalised (AESCBC/RSA2048)"
};
const std::string kLicenseType[6] =
{
"Permanent",
"Demo",
"Trial",
"Rental",
"Subscription",
"Service"
};
const std::string kBooleanStr[2] =
{
"FALSE",
"TRUE"
};
const byte_t eticket_common_key[16] = { 0x55, 0xA3, 0xF8, 0x72, 0xBD, 0xC8, 0x0C, 0x55, 0x5A, 0x65, 0x43, 0x81, 0x13, 0x9E, 0x15, 0x3B }; // lol this 3ds dev common key
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("usage: tiktool <file>\n");
return 1;
}
try
{
fnd::MemoryBlob file;
fnd::io::readFile(argv[1], file);
// import
es::ETicketBody_V2 body;
body.importBinary(file.getBytes() + 0x140, file.getSize() - 0x140);
printf("[ETICKET]\n");
printf(" Issuer: %s\n", body.getIssuer().c_str());
printf(" Title Key:\n");
printf(" EncMode: %s\n", kTitleKeyPersonalisation[body.getTitleKeyEncType()].c_str());
printf(" CommonKeyId: %02X\n", body.getCommonKeyId());
printf(" EncData:\n");
size_t size = body.getTitleKeyEncType() == es::ETicketBody_V2::RSA2048 ? crypto::rsa::kRsa2048Size : crypto::aes::kAes128KeySize;
fnd::SimpleTextOutput::hexDump(body.getEncTitleKey(), size, 0x10, 6);
if (body.getTitleKeyEncType() == es::ETicketBody_V2::AES128_CBC && body.getCommonKeyId() == 0)
{
byte_t iv[crypto::aes::kAesBlockSize];
byte_t key[crypto::aes::kAes128KeySize];
memcpy(iv, body.getRightsId(), crypto::aes::kAesBlockSize);
crypto::aes::AesCbcDecrypt(body.getEncTitleKey(), crypto::aes::kAes128KeySize, eticket_common_key, iv, key);
size = crypto::aes::kAes128KeySize;
printf(" TitleKey:\n");
fnd::SimpleTextOutput::hexDump(key, size, 0x10, 6);
}
printf(" Version: v%d\n", body.getTicketVersion());
printf(" License Type: %s\n", kLicenseType[body.getLicenseType()].c_str());
printf(" Flags:\n");
printf(" PreInstall: %s\n", kBooleanStr[body.isPreInstall()].c_str());
printf(" SharedTitle: %s\n", kBooleanStr[body.isSharedTitle()].c_str());
printf(" AllContent: %s\n", kBooleanStr[body.allowAllContent()].c_str());
printf(" Reserved Region:\n");
fnd::SimpleTextOutput::hexDump(body.getReservedRegion(), 8, 0x10, 4);
printf(" TicketId: 0x%016" PRIx64 "\n", body.getTicketId());
printf(" DeviceId: 0x%016" PRIx64 "\n", body.getDeviceId());
printf(" RightsId: ");
fnd::SimpleTextOutput::hexDump(body.getRightsId(), 16);
} catch (const fnd::Exception& e)
{
printf("%s\n", e.what());
}
return 0;
}

View file

@ -1,140 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{2200B834-F15A-4C6E-9DDB-6012B9A5C246}</ProjectGuid>
<RootNamespace>tiktool</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libes\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libes\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libes\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libes\include;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="source\main.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\lib\libcrypto\crypto.vcxproj">
<Project>{6adbb60d-dba0-411d-bd2d-a355ef8e0fe1}</Project>
</ProjectReference>
<ProjectReference Include="..\..\lib\libes\es.vcxproj">
<Project>{7be99936-0d40-410d-944b-4513c2eff8dc}</Project>
</ProjectReference>
<ProjectReference Include="..\..\lib\libfnd\fnd.vcxproj">
<Project>{4d27edb9-5110-44fe-8ce2-d46c5ad3c55b}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
</Project>