diff --git a/code_templates/system_title_dumper.c b/code_templates/system_title_dumper.c index 5d96641..e76fc58 100644 --- a/code_templates/system_title_dumper.c +++ b/code_templates/system_title_dumper.c @@ -65,7 +65,7 @@ static void dumpPartitionFs(TitleInfo *info, NcaFsSectionContext *nca_fs_ctx) } snprintf(path, sizeof(path), OUTPATH "/%016lX - %s/%s (%s)/Section %u (%s)", info->meta_key.id, info->app_metadata->lang_entry.name, ((NcaContext*)nca_fs_ctx->nca_ctx)->content_id_str, \ - titleGetNcmContentTypeName(((NcaContext*)nca_fs_ctx->nca_ctx)->content_type), nca_fs_ctx->section_num, ncaGetFsSectionTypeName(nca_fs_ctx->section_type)); + titleGetNcmContentTypeName(((NcaContext*)nca_fs_ctx->nca_ctx)->content_type), nca_fs_ctx->section_num, ncaGetFsSectionTypeName(nca_fs_ctx)); utilsCreateDirectoryTree(path, true); path_len = strlen(path); @@ -141,7 +141,7 @@ static void dumpRomFs(TitleInfo *info, NcaFsSectionContext *nca_fs_ctx) } snprintf(path, sizeof(path), OUTPATH "/%016lX - %s/%s (%s)/Section %u (%s)", info->meta_key.id, info->app_metadata->lang_entry.name, ((NcaContext*)nca_fs_ctx->nca_ctx)->content_id_str, \ - titleGetNcmContentTypeName(((NcaContext*)nca_fs_ctx->nca_ctx)->content_type), nca_fs_ctx->section_num, ncaGetFsSectionTypeName(nca_fs_ctx->section_type)); + titleGetNcmContentTypeName(((NcaContext*)nca_fs_ctx->nca_ctx)->content_type), nca_fs_ctx->section_num, ncaGetFsSectionTypeName(nca_fs_ctx)); utilsCreateDirectoryTree(path, true); path_len = strlen(path); @@ -306,7 +306,7 @@ int main(int argc, char *argv[]) } else if (menu == 2) { - printf("fs section #%u (%s)\n", i + 1, ncaGetFsSectionTypeName(nca_ctx->fs_contexts[i].section_type)); + printf("fs section #%u (%s)\n", i + 1, ncaGetFsSectionTypeName(&(nca_ctx->fs_contexts[i]))); } } diff --git a/source/nca.c b/source/nca.c index 94c1df2..7cb82ac 100644 --- a/source/nca.c +++ b/source/nca.c @@ -38,14 +38,6 @@ static const u8 g_nca0KeyAreaHash[SHA256_HASH_SIZE] = { 0xFF, 0x6B, 0x25, 0xEF, 0x9F, 0x96, 0x85, 0x28, 0x18, 0x9E, 0x76, 0xB0, 0x92, 0xF0, 0x6A, 0xCB }; -static const char *g_ncaFsSectionTypeNames[] = { - [NcaFsSectionType_PartitionFs] = "Partition FS", - [NcaFsSectionType_RomFs] = "RomFS", - [NcaFsSectionType_PatchRomFs] = "Patch RomFS [BKTR]", - [NcaFsSectionType_Nca0RomFs] = "NCA0 RomFS", - [NcaFsSectionType_Invalid] = "Invalid" -}; - /* Function prototypes. */ NX_INLINE bool ncaIsFsInfoEntryValid(NcaFsInfo *fs_info); @@ -112,6 +104,8 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, memcpy(&(out->content_id), &(content_info->content_id), sizeof(NcmContentId)); utilsGenerateHexStringFromData(out->content_id_str, sizeof(out->content_id_str), out->content_id.c, sizeof(out->content_id.c)); + utilsGenerateHexStringFromData(out->hash_str, sizeof(out->hash_str), out->hash, sizeof(out->hash)); /* Placeholder, needs to be manually calculated. */ + out->content_type = content_info->content_type; out->id_offset = content_info->id_offset; @@ -323,10 +317,31 @@ void ncaWriteHierarchicalIntegrityPatchToMemoryBuffer(NcaContext *ctx, NcaHierar for(u32 i = 0; i < NCA_IVFC_LEVEL_COUNT; i++) ncaWriteHashDataPatchToMemoryBuffer(ctx, &(patch->hash_level_patch[i]), buf, buf_size, buf_offset); } -const char *ncaGetFsSectionTypeName(u8 section_type) +const char *ncaGetFsSectionTypeName(NcaFsSectionContext *ctx) { - u8 idx = (section_type > NcaFsSectionType_Invalid ? NcaFsSectionType_Invalid : section_type); - return g_ncaFsSectionTypeNames[idx]; + NcaContext *nca_ctx = NULL; + const char *str = "Invalid"; + if (!ctx || !ctx->enabled || !(nca_ctx = (NcaContext*)ctx->nca_ctx)) return str; + + switch(ctx->section_type) + { + case NcaFsSectionType_PartitionFs: + str = ((nca_ctx->content_type == NcmContentType_Program && ctx->section_num == 0) ? "ExeFS" : "Partition FS"); + break; + case NcaFsSectionType_RomFs: + str = "RomFS"; + break; + case NcaFsSectionType_PatchRomFs: + str = "Patch RomFS [BKTR]"; + break; + case NcaFsSectionType_Nca0RomFs: + str = "NCA0 RomFS"; + break; + default: + break; + } + + return str; } void ncaRemoveTitlekeyCrypto(NcaContext *ctx) @@ -411,6 +426,17 @@ bool ncaEncryptHeader(NcaContext *ctx) return true; } +void ncaUpdateContentIdAndHash(NcaContext *ctx, u8 hash[SHA256_HASH_SIZE]) +{ + if (!ctx) return; + + memcpy(ctx->content_id.c, hash, sizeof(ctx->content_id.c)); + utilsGenerateHexStringFromData(ctx->content_id_str, sizeof(ctx->content_id_str), ctx->content_id.c, sizeof(ctx->content_id.c)); + + memcpy(ctx->hash, hash, sizeof(ctx->hash)); + utilsGenerateHexStringFromData(ctx->hash_str, sizeof(ctx->hash_str), ctx->hash, sizeof(ctx->hash)); +} + NX_INLINE bool ncaIsFsInfoEntryValid(NcaFsInfo *fs_info) { if (!fs_info) return false; diff --git a/source/nca.h b/source/nca.h index a32d240..700747a 100644 --- a/source/nca.h +++ b/source/nca.h @@ -393,8 +393,8 @@ bool ncaGenerateHierarchicalIntegrityPatch(NcaFsSectionContext *ctx, const void /// 'buf_offset' must hold the raw NCA offset where the data stored in 'buf' was read from. void ncaWriteHierarchicalIntegrityPatchToMemoryBuffer(NcaContext *ctx, NcaHierarchicalIntegrityPatch *patch, void *buf, u64 buf_size, u64 buf_offset); -/// Returns a pointer to a string holding the name of the provided NCA FS section type. -const char *ncaGetFsSectionTypeName(u8 section_type); +/// Returns a pointer to a string holding the name of the section type from the provided NCA FS section context. +const char *ncaGetFsSectionTypeName(NcaFsSectionContext *ctx); @@ -410,6 +410,8 @@ void ncaRemoveTitlekeyCrypto(NcaContext *ctx); /// Encrypts NCA header and NCA FS headers from a NCA context. bool ncaEncryptHeader(NcaContext *ctx); +/// Updates the content ID and hash from a NCA context using a provided SHA-256 checksum. +void ncaUpdateContentIdAndHash(NcaContext *ctx, u8 hash[SHA256_HASH_SIZE]); @@ -424,9 +426,7 @@ bool ncaEncryptHeader(NcaContext *ctx); - - -/// Miscellaneous functions. +/// Helper inline functions. NX_INLINE void ncaSetDownloadDistributionType(NcaContext *ctx) {