diff --git a/NXTools.sln b/NXTools.sln
index 7e78817..89167ac 100644
--- a/NXTools.sln
+++ b/NXTools.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.27428.2015
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfnd", "lib\libfnd\fnd.vcxproj", "{4D27EDB9-5110-44FE-8CE2-D46C5AD3C55B}"
EndProject
@@ -36,6 +36,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libes", "lib\libes\es.vcxpr
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tiktool", "programs\tiktool\tiktool.vcxproj", "{2200B834-F15A-4C6E-9DDB-6012B9A5C246}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xcitool", "programs\xcitool\xcitool.vcxproj", "{007FF616-7B99-4CB3-84CD-39C47F64FC7E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -108,6 +110,14 @@ Global
{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -121,5 +131,9 @@ Global
{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}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {07DCCACC-D10D-47C9-85AE-FB9C54DB7D62}
EndGlobalSection
EndGlobal
diff --git a/programs/xcitool/main.cpp b/programs/xcitool/source/main.cpp
similarity index 75%
rename from programs/xcitool/main.cpp
rename to programs/xcitool/source/main.cpp
index def7778..7d66829 100644
--- a/programs/xcitool/main.cpp
+++ b/programs/xcitool/source/main.cpp
@@ -30,9 +30,10 @@ enum CardClockRate
};
static const size_t kXciPageSize = 0x200;
-static const size_t kXciHeaderEncOffset = 0xA0;
+static const size_t kXciHeaderEncOffset = 0x90;
static const size_t kXciHeaderEncSize = 0x70;
+#pragma pack (push, 1)
struct sXciHeader
{
char signature[4]; // 0x00 // "HEAD"
@@ -86,13 +87,15 @@ struct sKeyDataArea
byte_t reserved_01[0x100];
}; // sizeof() = 512*8 (8 pages)
-static struct sXciKeyData
+#pragma pack (pop)
+
+struct sXciKeyData
{
crypto::aes::sAes128Key xci_header_encryption_key;
crypto::aes::sAes128Key initial_data_key;
crypto::rsa::sRsa2048Key xci_header_signer_key;
crypto::rsa::sRsa2048Key card_key_area_oeap_key;
-} key_data;
+};
/*
void getTitleKeyFromInitialData(const byte_t* initialData, crypto::aes::sAes128Key& titleKey)
@@ -116,7 +119,7 @@ inline const char* getBoolStr(bool isTrue)
inline const char* getRomSizeStr(byte_t rom_size)
{
- char* str = "unknown";
+ const char* str = "unknown";
switch (rom_size)
{
case (ROM_SIZE_1GB) :
@@ -143,7 +146,7 @@ inline const char* getRomSizeStr(byte_t rom_size)
inline const char* getCardClockRate(uint32_t acc_ctrl_1)
{
- char* str = "unknown";
+ const char* str = "unknown";
switch (acc_ctrl_1)
{
case (CLOCK_RATE_25) :
@@ -157,18 +160,52 @@ inline const char* getCardClockRate(uint32_t acc_ctrl_1)
return str;
}
+void dumpHxdStyleSector(byte_t* out, size_t len)
+{
+ // iterate over 0x10 blocks
+ for (size_t i = 0; i < (len / crypto::aes::kAesBlockSize); i++)
+ {
+ // for block i print each byte
+ for (size_t j = 0; j < crypto::aes::kAesBlockSize; j++)
+ {
+ printf("%02X ", out[i*crypto::aes::kAesBlockSize + j]);
+ }
+ printf(" ");
+ for (size_t j = 0; j < crypto::aes::kAesBlockSize; j++)
+ {
+ printf("%c", isalnum(out[i*crypto::aes::kAesBlockSize + j]) ? out[i*crypto::aes::kAesBlockSize + j] : '.');
+ }
+ printf("\n");
+ }
+
+ /*
+ for (size_t i = 0; i < len % crypto::aes::kAesBlockSize; i++)
+ {
+ printf("%02X ", out[(len / crypto::aes::kAesBlockSize)*crypto::aes::kAesBlockSize + i]);
+ }
+ for (size_t i = 0; i < crypto::aes::kAesBlockSize - (len % crypto::aes::kAesBlockSize); i++)
+ {
+ printf(" ");
+ }
+ for (size_t i = 0; i < len % crypto::aes::kAesBlockSize; i++)
+ {
+ printf("%c", out[(len / crypto::aes::kAesBlockSize)*crypto::aes::kAesBlockSize + i]);
+ }
+ */
+}
+
void printXciHeader(const sXciHeader& hdr, bool is_decrypted)
{
be_uint64_t *aes_iv, *hash;
printf("[XCI HEADER]\n");
printf(" Magic: HEAD\n");
- printf(" RomAreaStartPage: 0x%0x (0x" PRIx64 ")\n", hdr.rom_area_start_page.get(), blockToAddr(hdr.rom_area_start_page.get()));
+ printf(" RomAreaStartPage: 0x%0x (0x%" PRIx64 ")\n", hdr.rom_area_start_page.get(), blockToAddr(hdr.rom_area_start_page.get()));
printf(" BackupAreaStartPage: 0x%0x\n", hdr.backup_area_start_page.get());
- printf(" KeyFlag: 0x%x\n", hdr.key_flag);
+ printf(" KeyFlag: 0x%x\n", hdr.key_flag);
printf(" KekIndex: %d\n", hdr.key_flag & 7);
printf(" TitleKeyDecIndex: %d\n", (hdr.key_flag >> 4) & 7);
- printf(" RomSize: 0x%x (%s)\n", hdr.rom_size, getRomSizeStr(hdr.rom_size));
+ printf(" RomSize: 0x%x (%s)\n", hdr.rom_size, getRomSizeStr(hdr.rom_size));
printf(" CardHeaderVersion: %d\n", hdr.card_header_version);
printf(" Flags: 0x%x\n", hdr.flags);
printf(" AutoBoot: %s\n", getBoolStr(_HAS_BIT(hdr.flags, XCI_FLAG_AUTOBOOT)));
@@ -176,15 +213,15 @@ void printXciHeader(const sXciHeader& hdr, bool is_decrypted)
printf(" PackageId: 0x%" PRIx64 "\n", hdr.package_id.get());
printf(" ValidDataEndPage: 0x%x (0x%" PRIx64 ")\n", hdr.valid_data_end_page.get(), blockToAddr(hdr.valid_data_end_page.get()));
aes_iv = (be_uint64_t*)hdr.encryption_iv;
- printf(" AesIv: %" PRIX64 "%" PRIX64"\n", aes_iv[0].get(), aes_iv[1].get());
+ printf(" AesIv: %016" PRIX64 "%016" PRIX64"\n", aes_iv[0].get(), aes_iv[1].get());
printf(" PartitionFs:\n");
printf(" Offset: 0x%" PRIx64 "\n", hdr.partition_fs_header_address.get());
printf(" Size: 0x%" PRIx64 "\n", hdr.partition_fs_header_size.get());
hash = (be_uint64_t*)hdr.partition_fs_header_hash;
- printf(" Hash: %" PRIX64 "%" PRIX64 "%" PRIX64 "%" PRIX64"\n", hash[0].get(),hash[1].get(),hash[2].get(),hash[3].get());
+ printf(" Hash: %016" PRIX64 "%016" PRIX64 "%016" PRIX64 "%016" PRIX64"\n", hash[0].get(),hash[1].get(),hash[2].get(),hash[3].get());
printf(" InitialData:\n");
hash = (be_uint64_t*)hdr.initial_data_hash;
- printf(" Hash: %" PRIX64 "%" PRIX64 "%" PRIX64 "%" PRIX64"\n", hash[0].get(),hash[1].get(),hash[2].get(),hash[3].get());
+ printf(" Hash: %016" PRIX64 "%016" PRIX64 "%016" PRIX64 "%016" PRIX64"\n", hash[0].get(),hash[1].get(),hash[2].get(),hash[3].get());
printf(" SelSec: 0x%x\n", hdr.sel_sec.get());
printf(" SelT1Key: 0x%x\n", hdr.sel_t1_key.get());
printf(" SelKey: 0x%x\n", hdr.sel_key.get());
@@ -192,7 +229,7 @@ void printXciHeader(const sXciHeader& hdr, bool is_decrypted)
if (is_decrypted == true)
{
- printf(" FwVersion: v%d.%d\n", hdr.fw_version[0].get(), hdr.fw_version[1].get());
+ printf(" FwVersion: v%d.%d\n", hdr.fw_version[1].get(), hdr.fw_version[0].get());
printf(" AccCtrl1: 0x%x\n", hdr.acc_ctrl_1.get());
printf(" CardClockRate: %s\n", getCardClockRate(hdr.acc_ctrl_1.get()));
printf(" Wait1TimeRead: 0x%x\n", hdr.wait_1_time_read.get());
@@ -202,15 +239,21 @@ void printXciHeader(const sXciHeader& hdr, bool is_decrypted)
printf(" FwMode: 0x%x\n", hdr.fw_mode.get());
printf(" CupVersion: %d\n", hdr.cup_version.get());
hash = (be_uint64_t*)hdr.upp_hash;
- printf(" UppHash: %" PRIX64 "\n", hash[0].get());
- printf(" CupId: %" PRIx64 "\n", hdr.cup_id.get());
+ printf(" UppHash: %016" PRIX64 "\n", hash[0].get());
+ printf(" CupId: %016" PRIx64 "\n", hdr.cup_id.get());
+
}
}
void decryptXciHeader(const byte_t* src, byte_t* dst)
{
+ const byte_t* src_iv = ((const sXciHeader*)src)->encryption_iv;
byte_t iv[crypto::aes::kAesBlockSize];
- memcpy(iv, ((const sXciHeader*)src)->encryption_iv, crypto::aes::kAesBlockSize);
+
+ for (int i = 0; i < crypto::aes::kAesBlockSize; i++)
+ {
+ iv[i] = src_iv[15 - i];
+ }
// copy plain
memcpy(dst, src, kXciHeaderEncOffset);
diff --git a/programs/xcitool/xcitool.vcxproj b/programs/xcitool/xcitool.vcxproj
new file mode 100644
index 0000000..affaa78
--- /dev/null
+++ b/programs/xcitool/xcitool.vcxproj
@@ -0,0 +1,130 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {007FF616-7B99-4CB3-84CD-39C47F64FC7E}
+ xcitool
+ 10.0.16299.0
+
+
+
+ Application
+ true
+ v141
+ MultiByte
+
+
+ Application
+ false
+ v141
+ true
+ MultiByte
+
+
+ Application
+ true
+ v141
+ MultiByte
+
+
+ Application
+ false
+ v141
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ Disabled
+ true
+ true
+ ..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;
+
+
+
+
+ Level3
+ Disabled
+ true
+ true
+ ..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ true
+ ..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;
+
+
+ true
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ true
+ ..\..\lib\libfnd\include;..\..\lib\libcrypto\include;..\..\lib\libnx\include;
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/programs/xcitool/xcitool.vcxproj.filters b/programs/xcitool/xcitool.vcxproj.filters
new file mode 100644
index 0000000..bd54fe4
--- /dev/null
+++ b/programs/xcitool/xcitool.vcxproj.filters
@@ -0,0 +1,25 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/programs/xcitool/xcitool.vcxproj.user b/programs/xcitool/xcitool.vcxproj.user
new file mode 100644
index 0000000..be25078
--- /dev/null
+++ b/programs/xcitool/xcitool.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file