From 76266b8e55514e61d14e1f0297db22353899e1a0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 6 Feb 2018 00:40:37 -0800 Subject: [PATCH] Add support for parsing plain NPDM (#4). --- README.md | 2 +- main.c | 32 +++++++++++++++++++++++++++++++- settings.h | 1 + 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e4e74d3..d3f2aa2 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Options: -y, --verify Verify hashes and signatures. -d, --dev Decrypt with development keys instead of retail. -k, --keyset Load keys from an external file. - -t, --intype=type Specify input file type [nca, xci, pfs0, romfs, hfs0] + -t, --intype=type Specify input file type [nca, xci, pfs0, romfs, hfs0, npdm] --titlekey=key Set title key for Rights ID crypto titles. --contentkey=key Set raw key for NCA body decryption. NCA options: diff --git a/main.c b/main.c index b0e7201..4893f9a 100644 --- a/main.c +++ b/main.c @@ -29,7 +29,7 @@ static void usage(void) { " -y, --verify Verify hashes and signatures.\n" " -d, --dev Decrypt with development keys instead of retail.\n" " -k, --keyset Load keys from an external file.\n" - " -t, --intype=type Specify input file type [nca, xci, pfs0, romfs, hfs0]\n" + " -t, --intype=type Specify input file type [nca, xci, pfs0, romfs, hfs0, npdm]\n" " --titlekey=key Set title key for Rights ID crypto titles.\n" " --contentkey=key Set raw key for NCA body decryption.\n" "NCA options:\n" @@ -171,6 +171,8 @@ int main(int argc, char **argv) { nca_ctx.tool_ctx->file_type = FILETYPE_HFS0; } else if (!strcmp(optarg, "xci") || !strcmp(optarg, "gamecard") || !strcmp(optarg, "gc")) { nca_ctx.tool_ctx->file_type = FILETYPE_XCI; + } else if (!strcmp(optarg, "npdm") || !strcmp(optarg, "meta")) { + nca_ctx.tool_ctx->file_type = FILETYPE_NPDM; } /* } else if (!strcmp(optarg, "package2") || !strcmp(optarg, "pk21")) { * nca_ctx.tool_ctx->file_type = FILETYPE_PACKAGE2; @@ -377,6 +379,34 @@ int main(int argc, char **argv) { } break; } + case FILETYPE_NPDM: { + npdm_t raw_hdr; + memset(&raw_hdr, 0, sizeof(raw_hdr)); + if (fread(&raw_hdr, 1, sizeof(raw_hdr), tool_ctx.file) != sizeof(raw_hdr)) { + fprintf(stderr, "Failed to read NPDM header!\n"); + exit(EXIT_FAILURE); + } + if (raw_hdr.magic != MAGIC_META) { + fprintf(stderr, "NPDM seems corrupt!\n"); + exit(EXIT_FAILURE); + } + uint64_t npdm_size = raw_hdr.aci0_size + raw_hdr.aci0_offset; + if (raw_hdr.acid_offset + raw_hdr.acid_size > npdm_size) { + npdm_size = raw_hdr.acid_offset + raw_hdr.acid_size; + } + fseeko64(tool_ctx.file, 0, SEEK_SET); + npdm_t *npdm = malloc(npdm_size); + if (npdm == NULL) { + fprintf(stderr, "Failed to allocate NPDM!\n"); + exit(EXIT_FAILURE); + } + if (fread(npdm, 1, npdm_size, tool_ctx.file) != npdm_size) { + fprintf(stderr, "Failed to read NPDM!\n"); + exit(EXIT_FAILURE); + } + npdm_print(npdm, &tool_ctx); + break; + } case FILETYPE_HFS0: { hfs0_ctx_t hfs0_ctx; memset(&hfs0_ctx, 0, sizeof(hfs0_ctx)); diff --git a/settings.h b/settings.h index 70d7480..57945e0 100644 --- a/settings.h +++ b/settings.h @@ -67,6 +67,7 @@ enum hactool_file_type FILETYPE_ROMFS, FILETYPE_HFS0, FILETYPE_XCI, + FILETYPE_NPDM /* FILETYPE_PACKAGE2, */ /* FILETYPE_PACKAGE1, */ };