1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-11-22 18:26:39 +00:00

bktr: added ID offset and title version checks.

This commit is contained in:
Pablo Curiel 2022-06-29 09:55:46 +02:00
parent c1e3dc719f
commit 590495d012
11 changed files with 35 additions and 20 deletions

View file

@ -257,7 +257,7 @@ static void dump_thread_func(void *arg)
meta_nca_ctx = &(nca_ctx[title_info->content_count - 1]); meta_nca_ctx = &(nca_ctx[title_info->content_count - 1]);
if (!ncaInitializeContext(meta_nca_ctx, title_info->storage_id, (title_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \ if (!ncaInitializeContext(meta_nca_ctx, title_info->storage_id, (title_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
titleGetContentInfoByTypeAndIdOffset(title_info, NcmContentType_Meta, 0), &tik)) titleGetContentInfoByTypeAndIdOffset(title_info, NcmContentType_Meta, 0), title_info->version.value, &tik))
{ {
consolePrint("Meta nca initialize ctx failed\n"); consolePrint("Meta nca initialize ctx failed\n");
goto end; goto end;
@ -284,7 +284,7 @@ static void dump_thread_func(void *arg)
if (content_info->content_type == NcmContentType_Meta) continue; if (content_info->content_type == NcmContentType_Meta) continue;
NcaContext *cur_nca_ctx = &(nca_ctx[j]); NcaContext *cur_nca_ctx = &(nca_ctx[j]);
if (!ncaInitializeContext(cur_nca_ctx, title_info->storage_id, (title_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), content_info, &tik)) if (!ncaInitializeContext(cur_nca_ctx, title_info->storage_id, (title_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), content_info, title_info->version.value, &tik))
{ {
consolePrint("%s #%u initialize nca ctx failed\n", titleGetNcmContentTypeName(content_info->content_type), content_info->id_offset); consolePrint("%s #%u initialize nca ctx failed\n", titleGetNcmContentTypeName(content_info->content_type), content_info->id_offset);
goto end; goto end;

View file

@ -580,7 +580,7 @@ int main(int argc, char *argv[])
consolePrint("selected title:\n%s (%016lX)\n\n", app_metadata[selected_idx]->lang_entry.name, app_metadata[selected_idx]->title_id + program_id_offset); consolePrint("selected title:\n%s (%016lX)\n\n", app_metadata[selected_idx]->lang_entry.name, app_metadata[selected_idx]->title_id + program_id_offset);
if (!ncaInitializeContext(base_nca_ctx, user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \ if (!ncaInitializeContext(base_nca_ctx, user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Program, program_id_offset), NULL)) titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Program, program_id_offset), user_app_data.app_info->version.value, NULL))
{ {
consolePrint("nca initialize base ctx failed\n"); consolePrint("nca initialize base ctx failed\n");
goto out2; goto out2;
@ -591,7 +591,7 @@ int main(int argc, char *argv[])
TitleInfo *latest_patch = get_latest_patch_info(user_app_data.patch_info); TitleInfo *latest_patch = get_latest_patch_info(user_app_data.patch_info);
if (!ncaInitializeContext(update_nca_ctx, latest_patch->storage_id, (latest_patch->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \ if (!ncaInitializeContext(update_nca_ctx, latest_patch->storage_id, (latest_patch->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
titleGetContentInfoByTypeAndIdOffset(latest_patch, NcmContentType_Program, program_id_offset), NULL)) titleGetContentInfoByTypeAndIdOffset(latest_patch, NcmContentType_Program, program_id_offset), latest_patch->version.value, NULL))
{ {
consolePrint("nca initialize update ctx failed\n"); consolePrint("nca initialize update ctx failed\n");
goto out2; goto out2;

View file

@ -392,7 +392,7 @@ int main(int argc, char *argv[])
} else } else
if (menu == 2) if (menu == 2)
{ {
if (!ncaInitializeContext(nca_ctx, cur_title_info->storage_id, 0, &(cur_title_info->content_infos[nca_idx]), NULL)) if (!ncaInitializeContext(nca_ctx, cur_title_info->storage_id, 0, &(cur_title_info->content_infos[nca_idx]), cur_title_info->version.value, NULL))
{ {
consolePrint("nca initialize ctx failed\n"); consolePrint("nca initialize ctx failed\n");
error = true; error = true;

View file

@ -553,7 +553,7 @@ int main(int argc, char *argv[])
consolePrint("selected title:\n%s (%016lX)\n\n", app_metadata[selected_idx]->lang_entry.name, app_metadata[selected_idx]->title_id + program_id_offset); consolePrint("selected title:\n%s (%016lX)\n\n", app_metadata[selected_idx]->lang_entry.name, app_metadata[selected_idx]->title_id + program_id_offset);
if (!ncaInitializeContext(base_nca_ctx, user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \ if (!ncaInitializeContext(base_nca_ctx, user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Program, program_id_offset), NULL)) titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Program, program_id_offset), user_app_data.app_info->version.value, NULL))
{ {
consolePrint("nca initialize base ctx failed\n"); consolePrint("nca initialize base ctx failed\n");
goto out2; goto out2;
@ -564,7 +564,7 @@ int main(int argc, char *argv[])
TitleInfo *latest_patch = get_latest_patch_info(user_app_data.patch_info); TitleInfo *latest_patch = get_latest_patch_info(user_app_data.patch_info);
if (!ncaInitializeContext(update_nca_ctx, latest_patch->storage_id, (latest_patch->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \ if (!ncaInitializeContext(update_nca_ctx, latest_patch->storage_id, (latest_patch->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
titleGetContentInfoByTypeAndIdOffset(latest_patch, NcmContentType_Program, program_id_offset), NULL)) titleGetContentInfoByTypeAndIdOffset(latest_patch, NcmContentType_Program, program_id_offset), latest_patch->version.value, NULL))
{ {
consolePrint("nca initialize update ctx failed\n"); consolePrint("nca initialize update ctx failed\n");
goto out2; goto out2;

View file

@ -281,7 +281,7 @@ int main(int argc, char *argv[])
if (content_info->content_type == NcmContentType_Meta) continue; if (content_info->content_type == NcmContentType_Meta) continue;
if (!ncaInitializeContext(&(nca_ctx[j]), user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \ if (!ncaInitializeContext(&(nca_ctx[j]), user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
content_info, &tik)) content_info, user_app_data.app_info->version.value, &tik))
{ {
consolePrint("%s #%u initialize nca ctx failed\n", titleGetNcmContentTypeName(content_info->content_type), content_info->id_offset); consolePrint("%s #%u initialize nca ctx failed\n", titleGetNcmContentTypeName(content_info->content_type), content_info->id_offset);
goto out2; goto out2;
@ -329,7 +329,7 @@ int main(int argc, char *argv[])
} }
if (!ncaInitializeContext(&(nca_ctx[meta_idx]), user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \ if (!ncaInitializeContext(&(nca_ctx[meta_idx]), user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Meta, 0), &tik)) titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Meta, 0), user_app_data.app_info->version.value, &tik))
{ {
consolePrint("Meta nca initialize ctx failed\n"); consolePrint("Meta nca initialize ctx failed\n");
goto out2; goto out2;

View file

@ -372,7 +372,7 @@ typedef struct {
u8 hash_type; ///< NcaHashType. u8 hash_type; ///< NcaHashType.
u8 encryption_type; ///< NcaEncryptionType. u8 encryption_type; ///< NcaEncryptionType.
u8 section_type; ///< NcaFsSectionType. u8 section_type; ///< NcaFsSectionType.
bool skip_hash_layer_crypto; ///< Set to true if hash layer encryption should be skipped while reading section data. bool skip_hash_layer_crypto; ///< Set to true if hash layer decryption should be skipped while reading section data.
NcaRegion hash_region; /// Holds the properties for the full hash layer region that precedes the actual FS section data. NcaRegion hash_region; /// Holds the properties for the full hash layer region that precedes the actual FS section data.
///< Crypto-related fields. ///< Crypto-related fields.
@ -424,6 +424,7 @@ typedef struct {
u64 content_size; ///< Retrieved from NcmContentInfo. u64 content_size; ///< Retrieved from NcmContentInfo.
u8 key_generation; ///< NcaKeyGeneration. Retrieved from the decrypted header. u8 key_generation; ///< NcaKeyGeneration. Retrieved from the decrypted header.
u8 id_offset; ///< Retrieved from NcmContentInfo. u8 id_offset; ///< Retrieved from NcmContentInfo.
u32 title_version;
bool rights_id_available; bool rights_id_available;
bool titlekey_retrieved; bool titlekey_retrieved;
bool valid_main_signature; bool valid_main_signature;
@ -473,7 +474,7 @@ void ncaFreeCryptoBuffer(void);
/// If the 'tik' argument points to a valid Ticket element, it will either be updated (if it's empty) or be used to read ticket data that has already been retrieved. /// If the 'tik' argument points to a valid Ticket element, it will either be updated (if it's empty) or be used to read ticket data that has already been retrieved.
/// If the 'tik' argument is NULL, the function will just retrieve the necessary ticket data on its own. /// If the 'tik' argument is NULL, the function will just retrieve the necessary ticket data on its own.
/// If ticket data can't be retrieved, the context will still be initialized, but anything that involves working with encrypted NCA FS section blocks won't be possible (e.g. ncaReadFsSection()). /// If ticket data can't be retrieved, the context will still be initialized, but anything that involves working with encrypted NCA FS section blocks won't be possible (e.g. ncaReadFsSection()).
bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, const NcmContentInfo *content_info, Ticket *tik); bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, const NcmContentInfo *content_info, u32 title_version, Ticket *tik);
/// Reads raw encrypted data from a NCA using an input context, previously initialized by ncaInitializeContext(). /// Reads raw encrypted data from a NCA using an input context, previously initialized by ncaInitializeContext().
/// Input offset must be relative to the start of the NCA content file. /// Input offset must be relative to the start of the NCA content file.

View file

@ -98,7 +98,8 @@ bool bfttfInitialize(void)
/* Initialize NCA context. */ /* Initialize NCA context. */
/* NCA contexts don't need to be freed beforehand. */ /* NCA contexts don't need to be freed beforehand. */
bool nca_ctx_init = ncaInitializeContext(nca_ctx, NcmStorageId_BuiltInSystem, 0, titleGetContentInfoByTypeAndIdOffset(title_info, NcmContentType_Data, 0), NULL); bool nca_ctx_init = ncaInitializeContext(nca_ctx, NcmStorageId_BuiltInSystem, 0, titleGetContentInfoByTypeAndIdOffset(title_info, NcmContentType_Data, 0), \
title_info->version.value, NULL);
/* Free title info. */ /* Free title info. */
titleFreeTitleInfo(&title_info); titleFreeTitleInfo(&title_info);

View file

@ -41,7 +41,8 @@ bool bktrInitializeContext(BktrContext *out, NcaFsSectionContext *base_nca_fs_ct
if (!out || !base_nca_fs_ctx || !(base_nca_ctx = (NcaContext*)base_nca_fs_ctx->nca_ctx) || \ if (!out || !base_nca_fs_ctx || !(base_nca_ctx = (NcaContext*)base_nca_fs_ctx->nca_ctx) || \
!update_nca_fs_ctx || !update_nca_fs_ctx->enabled || !(update_nca_ctx = (NcaContext*)update_nca_fs_ctx->nca_ctx) || \ !update_nca_fs_ctx || !update_nca_fs_ctx->enabled || !(update_nca_ctx = (NcaContext*)update_nca_fs_ctx->nca_ctx) || \
update_nca_fs_ctx->section_type != NcaFsSectionType_PatchRomFs || base_nca_ctx->header.program_id != update_nca_ctx->header.program_id || \ update_nca_fs_ctx->section_type != NcaFsSectionType_PatchRomFs || base_nca_ctx->header.program_id != update_nca_ctx->header.program_id || \
base_nca_ctx->header.content_type != update_nca_ctx->header.content_type || \ base_nca_ctx->header.content_type != update_nca_ctx->header.content_type || base_nca_ctx->id_offset != update_nca_ctx->id_offset || \
base_nca_ctx->title_version > update_nca_ctx->title_version || \
__builtin_bswap32(update_nca_fs_ctx->header.patch_info.indirect_bucket.header.magic) != NCA_BKTR_MAGIC || \ __builtin_bswap32(update_nca_fs_ctx->header.patch_info.indirect_bucket.header.magic) != NCA_BKTR_MAGIC || \
update_nca_fs_ctx->header.patch_info.indirect_bucket.header.version != NCA_BKTR_VERSION || \ update_nca_fs_ctx->header.patch_info.indirect_bucket.header.version != NCA_BKTR_VERSION || \
__builtin_bswap32(update_nca_fs_ctx->header.patch_info.aes_ctr_ex_bucket.header.magic) != NCA_BKTR_MAGIC || \ __builtin_bswap32(update_nca_fs_ctx->header.patch_info.aes_ctr_ex_bucket.header.magic) != NCA_BKTR_MAGIC || \
@ -60,11 +61,22 @@ bool bktrInitializeContext(BktrContext *out, NcaFsSectionContext *base_nca_fs_ct
/* Update missing base NCA RomFS status. */ /* Update missing base NCA RomFS status. */
out->missing_base_romfs = (!base_nca_fs_ctx->enabled || base_nca_fs_ctx->section_type != NcaFsSectionType_RomFs); out->missing_base_romfs = (!base_nca_fs_ctx->enabled || base_nca_fs_ctx->section_type != NcaFsSectionType_RomFs);
/* Initialize base NCA RomFS context. */ if (!out->missing_base_romfs)
if (!out->missing_base_romfs && !romfsInitializeContext(&(out->base_romfs_ctx), base_nca_fs_ctx))
{ {
LOG_MSG("Failed to initialize base NCA RomFS context!"); if (!base_nca_fs_ctx->has_sparse_layer)
return false; {
/* Initialize base NCA RomFS context. */
if (!romfsInitializeContext(&(out->base_romfs_ctx), base_nca_fs_ctx))
{
LOG_MSG("Failed to initialize base NCA RomFS context!");
return false;
}
} else {
/* Initializing the base NCA RomFS on its own is impossible if we're dealing with a sparse layer. */
/* Let's just handle everything here. */
LOG_MSG("We got here, that's gotta be something.");
return false;
}
} }
/* Fill context. */ /* Fill context. */

View file

@ -94,7 +94,7 @@ void ncaFreeCryptoBuffer(void)
} }
} }
bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, const NcmContentInfo *content_info, Ticket *tik) bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, const NcmContentInfo *content_info, u32 title_version, Ticket *tik)
{ {
NcmContentStorage *ncm_storage = NULL; NcmContentStorage *ncm_storage = NULL;
u8 valid_fs_section_cnt = 0; u8 valid_fs_section_cnt = 0;
@ -121,6 +121,7 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
out->content_type = content_info->content_type; out->content_type = content_info->content_type;
out->id_offset = content_info->id_offset; out->id_offset = content_info->id_offset;
out->title_version = title_version;
titleConvertNcmContentSizeToU64(content_info->size, &(out->content_size)); titleConvertNcmContentSizeToU64(content_info->size, &(out->content_size));
if (out->content_size < NCA_FULL_HEADER_LENGTH) if (out->content_size < NCA_FULL_HEADER_LENGTH)

View file

@ -106,7 +106,7 @@ bool bfsarInitialize(void)
} }
/* Initialize NCA context. */ /* Initialize NCA context. */
if (!ncaInitializeContext(nca_ctx, NcmStorageId_BuiltInSystem, 0, titleGetContentInfoByTypeAndIdOffset(title_info, NcmContentType_Program, 0), NULL)) if (!ncaInitializeContext(nca_ctx, NcmStorageId_BuiltInSystem, 0, titleGetContentInfoByTypeAndIdOffset(title_info, NcmContentType_Program, 0), title_info->version.value, NULL))
{ {
LOG_MSG("Failed to initialize qlaunch Program NCA context!"); LOG_MSG("Failed to initialize qlaunch Program NCA context!");
break; break;

View file

@ -2513,7 +2513,7 @@ static char *titleGetPatchVersionString(TitleInfo *title_info)
} }
/* Initialize NCA context. */ /* Initialize NCA context. */
if (!ncaInitializeContext(nca_ctx, storage_id, hfs_partition_type, nacp_content, NULL)) if (!ncaInitializeContext(nca_ctx, storage_id, hfs_partition_type, nacp_content, title_info->version.value, NULL))
{ {
LOG_MSG("Failed to initialize NCA context for Control NCA from %016lX!", title_info->meta_key.id); LOG_MSG("Failed to initialize NCA context for Control NCA from %016lX!", title_info->meta_key.id);
goto end; goto end;