From 7dbb107a81921a0ac2566ef3811e6d79db083398 Mon Sep 17 00:00:00 2001 From: 3DSGuy Date: Mon, 14 Apr 2014 11:57:35 +0800 Subject: [PATCH] ctrtool: updated ncch/exheader code updated ncch/exheader specs to latest format. --- ctrtool/ctrtool.vcxproj | 159 ++++++++++++++++++++++++ ctrtool/ctrtool.vcxproj.filters | 207 ++++++++++++++++++++++++++++++++ ctrtool/exheader.c | 118 +++++++++++++++++- ctrtool/exheader.h | 5 +- ctrtool/main.c | 4 +- ctrtool/ncch.c | 61 ++++++++-- ctrtool/ncch.h | 13 +- ctrtool/settings.c | 13 ++ ctrtool/settings.h | 3 + 9 files changed, 561 insertions(+), 22 deletions(-) create mode 100644 ctrtool/ctrtool.vcxproj create mode 100644 ctrtool/ctrtool.vcxproj.filters diff --git a/ctrtool/ctrtool.vcxproj b/ctrtool/ctrtool.vcxproj new file mode 100644 index 0000000..75b7288 --- /dev/null +++ b/ctrtool/ctrtool.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {96F5CA15-30DA-4DF5-9DFF-523D58D38001} + ctrtooltje + Win32Proj + + + + Application + v110 + Unicode + true + + + Application + v110 + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + Disabled + windows;.;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + 4996;%(DisableSpecificWarnings) + false + + + true + Console + MachineX86 + + + + + MaxSpeed + true + windows;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + c:\dev\tools\bin\ctrtool.exe + true + Console + true + true + MachineX86 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ctrtool/ctrtool.vcxproj.filters b/ctrtool/ctrtool.vcxproj.filters new file mode 100644 index 0000000..c51e94e --- /dev/null +++ b/ctrtool/ctrtool.vcxproj.filters @@ -0,0 +1,207 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {dfec7c2d-ac92-481f-a1eb-732b0669b7d1} + + + {dd509a5e-b804-4879-b0b7-876718c9621a} + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {d16b9918-7159-4a81-a0b7-521c2b2f8a30} + + + {492dc50f-e790-426b-b991-86306ad69fd4} + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\polarssl + + + Source Files\polarssl + + + Source Files\polarssl + + + Source Files\polarssl + + + Source Files\tinyxml + + + Source Files\tinyxml + + + Source Files\tinyxml + + + Source Files\tinyxml + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\polarssl + + + Header Files\polarssl + + + Header Files\polarssl + + + Header Files\polarssl + + + Header Files\polarssl + + + Header Files\polarssl + + + Header Files\tinyxml + + + Header Files\tinyxml + + + \ No newline at end of file diff --git a/ctrtool/exheader.c b/ctrtool/exheader.c index 1fe0347..d96c571 100644 --- a/ctrtool/exheader.c +++ b/ctrtool/exheader.c @@ -299,6 +299,114 @@ void exheader_print_arm11kernelcapabilities(exheader_context* ctx) } } +void exheader_print_arm11accessinfo(exheader_context* ctx) +{ + u32 accessinfo = getle32(ctx->header.arm11systemlocalcaps.storageinfo.accessinfo); + if((accessinfo & (1 << 0) )== (1 << 0)) + fprintf(stdout, " > Category System Application\n"); + if((accessinfo & (1 << 1) )== (1 << 1)) + fprintf(stdout, " > Category Hardware Check\n"); + if((accessinfo & (1 << 2) )== (1 << 2)) + fprintf(stdout, " > Category File System Tool\n"); + if((accessinfo & (1 << 3) )== (1 << 3)) + fprintf(stdout, " > Debug\n"); + if((accessinfo & (1 << 4) )== (1 << 4)) + fprintf(stdout, " > TWL Card Backup\n"); + if((accessinfo & (1 << 5) )== (1 << 5)) + fprintf(stdout, " > TWL Nand Data\n"); + if((accessinfo & (1 << 6) )== (1 << 6)) + fprintf(stdout, " > BOSS\n"); + if((accessinfo & (1 << 7) )== (1 << 7)) + fprintf(stdout, " > Direct SDMC\n"); + if((accessinfo & (1 << 8) )== (1 << 8)) + fprintf(stdout, " > Core\n"); + if((accessinfo & (1 << 9) )== (1 << 9)) + fprintf(stdout, " > CTR NAND RO\n"); + if((accessinfo & (1 << 10) )== (1 << 10)) + fprintf(stdout, " > CTR NAND RW\n"); + if((accessinfo & (1 << 11) )== (1 << 11)) + fprintf(stdout, " > CTR NAND RO (Write Access)\n"); + if((accessinfo & (1 << 12) )== (1 << 12)) + fprintf(stdout, " > Category System Settings\n"); + if((accessinfo & (1 << 13) )== (1 << 13)) + fprintf(stdout, " > CARD BOARD\n"); + if((accessinfo & (1 << 14) )== (1 << 14)) + fprintf(stdout, " > Export Import IVS\n"); + if((accessinfo & (1 << 15) )== (1 << 15)) + fprintf(stdout, " > Direct SDMC (Write Only)\n"); + if((accessinfo & (1 << 16) )== (1 << 16)) + fprintf(stdout, " > Switch Cleanup\n"); + if((accessinfo & (1 << 17) )== (1 << 17)) + fprintf(stdout, " > Save Data Move\n"); + if((accessinfo & (1 << 18) )== (1 << 18)) + fprintf(stdout, " > Shop\n"); + if((accessinfo & (1 << 19) )== (1 << 19)) + fprintf(stdout, " > Shell\n"); + if((accessinfo & (1 << 20) )== (1 << 20)) + fprintf(stdout, " > Category HomeMenu\n"); +} + +void exheader_print_arm11storageinfo(exheader_context* ctx) +{ + u32 i; + // Storage Info + u32 systemsaveID[2]; + u64 extdataID; + u32 otherusersaveID[3]; + u32 accessiblesaveID[6]; + + u8 otherattibutes = ctx->header.arm11systemlocalcaps.storageinfo.otherattributes; + u8 accessOtherVariationSavedata = (getle64(ctx->header.arm11systemlocalcaps.storageinfo.accessibleuniqueids) & 0x1000000000000000) == 0x1000000000000000; + + systemsaveID[0] = getle32(ctx->header.arm11systemlocalcaps.storageinfo.systemsavedataid); + systemsaveID[1] = getle32(ctx->header.arm11systemlocalcaps.storageinfo.systemsavedataid+4); + + extdataID = getle64(ctx->header.arm11systemlocalcaps.storageinfo.extsavedataid); + + for(i = 0; i < 3; i++) + { + accessiblesaveID[i] = 0xfffff & (getle64(ctx->header.arm11systemlocalcaps.storageinfo.accessibleuniqueids) >> 20*(2-i)); + otherusersaveID[i] = 0xfffff & (getle64(ctx->header.arm11systemlocalcaps.storageinfo.accessibleuniqueids) >> 20*(2-i)); + } + + for(i = 0; i < 3; i++) + { + accessiblesaveID[i+3] = 0xfffff & (getle64(ctx->header.arm11systemlocalcaps.storageinfo.extsavedataid) >> 20*(2-i)); + } + + if(otherattibutes & 2) + { + extdataID = 0; + for(i = 0; i < 3; i++) + otherusersaveID[i] = 0; + } + else + { + for(i = 0; i < 6; i++) + accessiblesaveID[i] = 0; + } + + fprintf(stdout, "Ext savedata id: 0x%llX\n",extdataID); + for(i = 0; i < 2; i++) + fprintf(stdout, "System savedata id %d: 0x%08x\n",i+1,systemsaveID[i]); + for(i = 0; i < 3; i++) + fprintf(stdout, "OtherUserSaveDataId%d: 0x%05x\n",i+1,otherusersaveID[i]); + fprintf(stdout, "Accessible Savedata Ids:\n"); + for(i = 0; i < 6; i++) + fprintf(stdout, " > 0x%05x\n",accessiblesaveID[i]); + + fprintf(stdout, "Other Variation Saves: %s\n", accessOtherVariationSavedata ? "Accessible" : "Inaccessible"); + memdump(stdout, "Access info: ", ctx->header.arm11systemlocalcaps.storageinfo.accessinfo, 7); + exheader_print_arm11accessinfo(ctx); + + fprintf(stdout, "Other attributes: %02X", ctx->header.arm11systemlocalcaps.storageinfo.otherattributes); + if(otherattibutes & 1) + fprintf(stdout," [no use romfs]"); + if(otherattibutes & 2) + fprintf(stdout," [use extended savedata access control]"); + printf("\n"); +} + int exheader_signature_verify(exheader_context* ctx, rsakey2048* key) { u8 hash[0x20]; @@ -368,6 +476,8 @@ void exheader_print(exheader_context* ctx) fprintf(stdout, "Flag: %02X ", codesetinfo->flags.flag); if (codesetinfo->flags.flag & 1) fprintf(stdout, "[compressed]"); + if (codesetinfo->flags.flag & 2) + fprintf(stdout, "[sd application]"); fprintf(stdout, "\n"); fprintf(stdout, "Remaster version: %04X\n", getle16(codesetinfo->flags.remasterversion)); @@ -389,7 +499,7 @@ void exheader_print(exheader_context* ctx) fprintf(stdout, "Dependency: %016llX\n", getle64(ctx->header.deplist.programid[i])); } - fprintf(stdout, "Savedata size: 0x%08X\n", getle32(ctx->header.systeminfo.savedatasize)); + fprintf(stdout, "Savedata size: 0x%016X\n", getle64(ctx->header.systeminfo.savedatasize)); fprintf(stdout, "Jump id: %016llX\n", getle64(ctx->header.systeminfo.jumpid)); fprintf(stdout, "Program id: %016llX %s\n", getle64(ctx->header.arm11systemlocalcaps.programid), exheader_getvalidstring(ctx->validprogramid)); @@ -400,11 +510,7 @@ void exheader_print(exheader_context* ctx) fprintf(stdout, "Affinity mask: %d %s\n", (ctx->header.arm11systemlocalcaps.flags[6]>>2)&0x3, exheader_getvalidstring(ctx->validaffinitymask)); fprintf(stdout, "Main thread priority: %d %s\n", ctx->header.arm11systemlocalcaps.flags[7], exheader_getvalidstring(ctx->validpriority)); // print resource limit descriptor too? currently mostly zeroes... - fprintf(stdout, "Ext savedata id: %016llX\n", getle64(ctx->header.arm11systemlocalcaps.storageinfo.extsavedataid)); - fprintf(stdout, "System savedata id: %016llX\n", getle64(ctx->header.arm11systemlocalcaps.storageinfo.systemsavedataid)); - memdump(stdout, "Access info: ", ctx->header.arm11systemlocalcaps.storageinfo.accessinfo, 7); - fprintf(stdout, "Other attributes: %02X\n", ctx->header.arm11systemlocalcaps.storageinfo.otherattributes); - + exheader_print_arm11storageinfo(ctx); exheader_print_arm11kernelcapabilities(ctx); exheader_print_arm9accesscontrol(ctx); diff --git a/ctrtool/exheader.h b/ctrtool/exheader.h index 2673918..12fc66d 100644 --- a/ctrtool/exheader.h +++ b/ctrtool/exheader.h @@ -39,8 +39,7 @@ typedef struct typedef struct { - u8 savedatasize[4]; - u8 reserved[4]; + u8 savedatasize[8]; u8 jumpid[8]; u8 reserved2[0x30]; } exheader_systeminfo; @@ -49,7 +48,7 @@ typedef struct { u8 extsavedataid[8]; u8 systemsavedataid[8]; - u8 reserved[8]; + u8 accessibleuniqueids[8]; u8 accessinfo[7]; u8 otherattributes; } exheader_storageinfo; diff --git a/ctrtool/main.c b/ctrtool/main.c index a432aa3..07ad779 100644 --- a/ctrtool/main.c +++ b/ctrtool/main.c @@ -66,6 +66,7 @@ static void usage(const char *argv0) " --exefsdir=dir Specify ExeFS directory path.\n" " --romfs=file Specify RomFS file path.\n" " --exheader=file Specify Extended Header file path.\n" + " --logo=file Specify Logo file path.\n" "CIA options:\n" " --certs=file Specify Certificate chain file path.\n" " --tik=file Specify Ticket file path.\n" @@ -140,6 +141,7 @@ int main(int argc, char* argv[]) {"romfsdir", 1, NULL, 17}, {"listromfs", 0, NULL, 18}, {"wavloops", 1, NULL, 19}, + {"logo", 1, NULL, 20}, {NULL}, }; @@ -223,7 +225,7 @@ int main(int argc, char* argv[]) case 17: settings_set_romfs_dir_path(&ctx.usersettings, optarg); break; case 18: settings_set_list_romfs_files(&ctx.usersettings, 1); break; case 19: settings_set_cwav_loopcount(&ctx.usersettings, strtoul(optarg, 0, 0)); break; - + case 20: settings_set_logo_path(&ctx.usersettings, optarg); break; default: usage(argv[0]); diff --git a/ctrtool/ncch.c b/ctrtool/ncch.c index a36a7d6..1a0f974 100644 --- a/ctrtool/ncch.c +++ b/ctrtool/ncch.c @@ -108,6 +108,13 @@ int ncch_extract_prepare(ncch_context* ctx, u32 type, u32 flags) } break; + case NCCHTYPE_LOGO: + { + offset = ncch_get_logo_offset(ctx); + size = ncch_get_logo_size(ctx); + } + break; + default: { fprintf(stderr, "Error invalid NCCH type\n"); @@ -128,7 +135,7 @@ clean: return 0; } -int ncch_extract_buffer(ncch_context* ctx, u8* buffer, u32 buffersize, u32* outsize) +int ncch_extract_buffer(ncch_context* ctx, u8* buffer, u32 buffersize, u32* outsize, u8 nocrypto) { u32 max = buffersize; @@ -145,7 +152,7 @@ int ncch_extract_buffer(ncch_context* ctx, u8* buffer, u32 buffersize, u32* outs goto clean; } - if (ctx->encrypted) + if (ctx->encrypted && !nocrypto) ctr_crypt_counter(&ctx->aes, buffer, buffer, max); ctx->extractsize -= max; @@ -172,6 +179,7 @@ void ncch_save(ncch_context* ctx, u32 type, u32 flags) case NCCHTYPE_EXEFS: path = settings_get_exefs_path(ctx->usersettings); break; case NCCHTYPE_ROMFS: path = settings_get_romfs_path(ctx->usersettings); break; case NCCHTYPE_EXHEADER: path = settings_get_exheader_path(ctx->usersettings); break; + case NCCHTYPE_LOGO: path = settings_get_logo_path(ctx->usersettings); break; } if (path == 0 || path->valid == 0) @@ -189,13 +197,14 @@ void ncch_save(ncch_context* ctx, u32 type, u32 flags) case NCCHTYPE_EXEFS: fprintf(stdout, "Saving ExeFS...\n"); break; case NCCHTYPE_ROMFS: fprintf(stdout, "Saving RomFS...\n"); break; case NCCHTYPE_EXHEADER: fprintf(stdout, "Saving Extended Header...\n"); break; + case NCCHTYPE_LOGO: fprintf(stdout, "Saving Logo...\n"); break; } while(1) { u32 max; - if (0 == ncch_extract_buffer(ctx, buffer, sizeof(buffer), &max)) + if (0 == ncch_extract_buffer(ctx, buffer, sizeof(buffer), &max, type == NCCHTYPE_LOGO)) goto clean; if (max == 0) @@ -219,17 +228,21 @@ void ncch_verify(ncch_context* ctx, u32 flags) u32 exefshashregionsize = getle32(ctx->header.exefshashregionsize) * mediaunitsize; u32 romfshashregionsize = getle32(ctx->header.romfshashregionsize) * mediaunitsize; u32 exheaderhashregionsize = getle32(ctx->header.extendedheadersize); + u32 logohashregionsize = getle32(ctx->header.logosize) * mediaunitsize; u8* exefshashregion = 0; u8* romfshashregion = 0; u8* exheaderhashregion = 0; + u8* logohashregion = 0; + u8* tmphash = 0; rsakey2048 ncchrsakey; - if (exefshashregionsize >= SIZE_128MB || romfshashregionsize >= SIZE_128MB || exheaderhashregionsize >= SIZE_128MB) + if (exefshashregionsize >= SIZE_128MB || romfshashregionsize >= SIZE_128MB || exheaderhashregionsize >= SIZE_128MB || logohashregionsize >= SIZE_128MB) goto clean; exefshashregion = malloc(exefshashregionsize); romfshashregion = malloc(romfshashregionsize); exheaderhashregion = malloc(exheaderhashregionsize); + logohashregion = malloc(logohashregionsize); if (ctx->usersettings) @@ -247,7 +260,7 @@ void ncch_verify(ncch_context* ctx, u32 flags) { if (0 == ncch_extract_prepare(ctx, NCCHTYPE_EXEFS, flags)) goto clean; - if (0 == ncch_extract_buffer(ctx, exefshashregion, exefshashregionsize, &exefshashregionsize)) + if (0 == ncch_extract_buffer(ctx, exefshashregion, exefshashregionsize, &exefshashregionsize,0)) goto clean; ctx->exefshashcheck = ctr_sha_256_verify(exefshashregion, exefshashregionsize, ctx->header.exefssuperblockhash); } @@ -255,7 +268,7 @@ void ncch_verify(ncch_context* ctx, u32 flags) { if (0 == ncch_extract_prepare(ctx, NCCHTYPE_ROMFS, flags)) goto clean; - if (0 == ncch_extract_buffer(ctx, romfshashregion, romfshashregionsize, &romfshashregionsize)) + if (0 == ncch_extract_buffer(ctx, romfshashregion, romfshashregionsize, &romfshashregionsize,0)) goto clean; ctx->romfshashcheck = ctr_sha_256_verify(romfshashregion, romfshashregionsize, ctx->header.romfssuperblockhash); } @@ -263,14 +276,24 @@ void ncch_verify(ncch_context* ctx, u32 flags) { if (0 == ncch_extract_prepare(ctx, NCCHTYPE_EXHEADER, flags)) goto clean; - if (0 == ncch_extract_buffer(ctx, exheaderhashregion, exheaderhashregionsize, &exheaderhashregionsize)) + if (0 == ncch_extract_buffer(ctx, exheaderhashregion, exheaderhashregionsize, &exheaderhashregionsize,0)) goto clean; ctx->exheaderhashcheck = ctr_sha_256_verify(exheaderhashregion, exheaderhashregionsize, ctx->header.extendedheaderhash); } + if (logohashregionsize) + { + if (0 == ncch_extract_prepare(ctx, NCCHTYPE_LOGO, flags)) + goto clean; + if (0 == ncch_extract_buffer(ctx, logohashregion, logohashregionsize, &logohashregionsize,1)) + goto clean; + ctx->logohashcheck = ctr_sha_256_verify(logohashregion, logohashregionsize, ctx->header.logohash); + } + free(exefshashregion); free(romfshashregion); free(exheaderhashregion); + free(logohashregion); clean: return; } @@ -331,6 +354,7 @@ void ncch_process(ncch_context* ctx, u32 actions) ncch_save(ctx, NCCHTYPE_EXEFS, actions); ncch_save(ctx, NCCHTYPE_ROMFS, actions); ncch_save(ctx, NCCHTYPE_EXHEADER, actions); + ncch_save(ctx, NCCHTYPE_LOGO, actions); } @@ -392,6 +416,18 @@ u32 ncch_get_exheader_size(ncch_context* ctx) return getle32(ctx->header.extendedheadersize); } +u32 ncch_get_logo_offset(ncch_context* ctx) +{ + u32 mediaunitsize = ncch_get_mediaunit_size(ctx); + return ctx->offset + getle32(ctx->header.logooffset) * mediaunitsize; +} + +u32 ncch_get_logo_size(ncch_context* ctx) +{ + u32 mediaunitsize = ncch_get_mediaunit_size(ctx); + return getle32(ctx->header.logosize) * mediaunitsize; +} + u32 ncch_get_mediaunit_size(ncch_context* ctx) { unsigned int mediaunitsize = settings_get_mediaunit_size(ctx->usersettings); @@ -534,7 +570,12 @@ void ncch_print(ncch_context* ctx) fprintf(stdout, "Maker code: %04x\n", getle16(header->makercode)); fprintf(stdout, "Version: %04x\n", getle16(header->version)); fprintf(stdout, "Program id: %016llx\n", getle64(header->programid)); - fprintf(stdout, "Temp flag: %02x\n", header->tempflag); + if(ctx->logohashcheck == Unchecked) + memdump(stdout, "Logo hash: ", header->logohash, 0x20); + else if(ctx->logohashcheck == Good) + memdump(stdout, "Logo hash (GOOD): ", header->logohash, 0x20); + else + memdump(stdout, "Logo hash (FAIL): ", header->logohash, 0x20); fprintf(stdout, "Product code: %s\n", productcode); fprintf(stdout, "Exheader size: %08x\n", getle32(header->extendedheadersize)); if (ctx->exheaderhashcheck == Unchecked) @@ -549,6 +590,8 @@ void ncch_print(ncch_context* ctx) fprintf(stdout, " > Crypto key: None\n"); else if (header->flags[7] & 1) fprintf(stdout, " > Crypto key: %s\n", programid_is_system(header->programid)? "Fixed":"Zeros"); + else if (header->flags[3] & 1) + fprintf(stdout, " > Crypto key: Secure2\n"); else fprintf(stdout, " > Crypto key: Secure\n"); fprintf(stdout, " > Form type: %s\n", formtypetostring(header->flags[5])); @@ -561,6 +604,8 @@ void ncch_print(ncch_context* ctx) fprintf(stdout, "Plain region offset: 0x%08x\n", getle32(header->plainregionsize)? offset+getle32(header->plainregionoffset)*mediaunitsize : 0); fprintf(stdout, "Plain region size: 0x%08x\n", getle32(header->plainregionsize)*mediaunitsize); + fprintf(stdout, "Logo offset: 0x%08x\n", getle32(header->logosize)? offset+getle32(header->logooffset)*mediaunitsize : 0); + fprintf(stdout, "Logo size: 0x%08x\n", getle32(header->logosize)*mediaunitsize); fprintf(stdout, "ExeFS offset: 0x%08x\n", getle32(header->exefssize)? offset+getle32(header->exefsoffset)*mediaunitsize : 0); fprintf(stdout, "ExeFS size: 0x%08x\n", getle32(header->exefssize)*mediaunitsize); fprintf(stdout, "ExeFS hash region size: 0x%08x\n", getle32(header->exefshashregionsize)*mediaunitsize); diff --git a/ctrtool/ncch.h b/ctrtool/ncch.h index 3d15dbf..b6539e0 100644 --- a/ctrtool/ncch.h +++ b/ctrtool/ncch.h @@ -15,6 +15,7 @@ typedef enum NCCHTYPE_EXHEADER = 1, NCCHTYPE_EXEFS = 2, NCCHTYPE_ROMFS = 3, + NCCHTYPE_LOGO = 4, } ctr_ncchtypes; typedef struct @@ -27,8 +28,8 @@ typedef struct u8 version[2]; u8 reserved0[4]; u8 programid[8]; - u8 tempflag; - u8 reserved1[0x2f]; + u8 reserved1[0x10]; + u8 logohash[0x20]; u8 productcode[0x10]; u8 extendedheaderhash[0x20]; u8 extendedheadersize[4]; @@ -36,7 +37,8 @@ typedef struct u8 flags[8]; u8 plainregionoffset[4]; u8 plainregionsize[4]; - u8 reserved3[8]; + u8 logooffset[4]; + u8 logosize[4]; u8 exefsoffset[4]; u8 exefssize[4]; u8 exefshashregionsize[4]; @@ -65,6 +67,7 @@ typedef struct int exefshashcheck; int romfshashcheck; int exheaderhashcheck; + int logohashcheck; int headersigcheck; u32 extractsize; u32 extractflags; @@ -82,12 +85,14 @@ u32 ncch_get_romfs_offset(ncch_context* ctx); u32 ncch_get_romfs_size(ncch_context* ctx); u32 ncch_get_exheader_offset(ncch_context* ctx); u32 ncch_get_exheader_size(ncch_context* ctx); +u32 ncch_get_logo_offset(ncch_context* ctx); +u32 ncch_get_logo_size(ncch_context* ctx); void ncch_print(ncch_context* ctx); int ncch_signature_verify(ncch_context* ctx, rsakey2048* key); void ncch_verify(ncch_context* ctx, u32 flags); void ncch_save(ncch_context* ctx, u32 type, u32 flags); int ncch_extract_prepare(ncch_context* ctx, u32 type, u32 flags); -int ncch_extract_buffer(ncch_context* ctx, u8* buffer, u32 buffersize, u32* outsize); +int ncch_extract_buffer(ncch_context* ctx, u8* buffer, u32 buffersize, u32* outsize, u8 nocrypto); u32 ncch_get_mediaunit_size(ncch_context* ctx); void ncch_get_counter(ncch_context* ctx, u8 counter[16], u8 type); void ncch_determine_key(ncch_context* ctx, u32 actions); diff --git a/ctrtool/settings.c b/ctrtool/settings.c index cd3f9bf..888bdc9 100644 --- a/ctrtool/settings.c +++ b/ctrtool/settings.c @@ -47,6 +47,14 @@ filepath* settings_get_exheader_path(settings* usersettings) return 0; } +filepath* settings_get_logo_path(settings* usersettings) +{ + if (usersettings) + return &usersettings->logopath; + else + return 0; +} + filepath* settings_get_exefs_dir_path(settings* usersettings) { if (usersettings) @@ -200,6 +208,11 @@ void settings_set_exheader_path(settings* usersettings, const char* path) filepath_set(&usersettings->exheaderpath, path); } +void settings_set_logo_path(settings* usersettings, const char* path) +{ + filepath_set(&usersettings->logopath, path); +} + void settings_set_certs_path(settings* usersettings, const char* path) { filepath_set(&usersettings->certspath, path); diff --git a/ctrtool/settings.h b/ctrtool/settings.h index f45bdc6..39d3c2d 100644 --- a/ctrtool/settings.h +++ b/ctrtool/settings.h @@ -14,6 +14,7 @@ typedef struct filepath romfspath; filepath romfsdirpath; filepath exheaderpath; + filepath logopath; filepath certspath; filepath contentpath; filepath tikpath; @@ -32,6 +33,7 @@ filepath* settings_get_lzss_path(settings* usersettings); filepath* settings_get_exefs_path(settings* usersettings); filepath* settings_get_romfs_path(settings* usersettings); filepath* settings_get_exheader_path(settings* usersettings); +filepath* settings_get_logo_path(settings* usersettings); filepath* settings_get_certs_path(settings* usersettings); filepath* settings_get_tik_path(settings* usersettings); filepath* settings_get_tmd_path(settings* usersettings); @@ -53,6 +55,7 @@ void settings_set_lzss_path(settings* usersettings, const char* path); void settings_set_exefs_path(settings* usersettings, const char* path); void settings_set_romfs_path(settings* usersettings, const char* path); void settings_set_exheader_path(settings* usersettings, const char* path); +void settings_set_logo_path(settings* usersettings, const char* path); void settings_set_certs_path(settings* usersettings, const char* path); void settings_set_tik_path(settings* usersettings, const char* path); void settings_set_tmd_path(settings* usersettings, const char* path);