From 97d9603e932f315566253b76c9f6b6f01595fb8e Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Sat, 26 Sep 2020 06:49:18 -0400 Subject: [PATCH] BKTR: add support for games with base Program NCAs without a RomFS section. --- source/bktr.c | 17 ++++++++++++----- source/bktr.h | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/source/bktr.c b/source/bktr.c index f20a8a2..2b41e8b 100644 --- a/source/bktr.c +++ b/source/bktr.c @@ -37,8 +37,8 @@ bool bktrInitializeContext(BktrContext *out, NcaFsSectionContext *base_nca_fs_ct { NcaContext *base_nca_ctx = NULL, *update_nca_ctx = NULL; - if (!out || !base_nca_fs_ctx || !base_nca_fs_ctx->enabled || !(base_nca_ctx = (NcaContext*)base_nca_fs_ctx->nca_ctx) || base_nca_fs_ctx->section_type != NcaFsSectionType_RomFs || \ - base_nca_fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx || !update_nca_fs_ctx || !update_nca_fs_ctx->enabled || !(update_nca_ctx = (NcaContext*)update_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->section_type != NcaFsSectionType_PatchRomFs || update_nca_fs_ctx->encryption_type != NcaEncryptionType_AesCtrEx || \ base_nca_ctx->header.program_id != update_nca_ctx->header.program_id || base_nca_ctx->header.content_type != update_nca_ctx->header.content_type || \ __builtin_bswap32(update_nca_fs_ctx->header.patch_info.indirect_bucket.header.magic) != NCA_BKTR_MAGIC || \ @@ -50,8 +50,11 @@ bool bktrInitializeContext(BktrContext *out, NcaFsSectionContext *base_nca_fs_ct return false; } + /* Update missing base NCA RomFS status. */ + out->missing_base_romfs = (!base_nca_fs_ctx->enabled || base_nca_fs_ctx->section_type != NcaFsSectionType_RomFs || base_nca_fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx); + /* Initialize base NCA RomFS context. */ - if (!romfsInitializeContext(&(out->base_romfs_ctx), base_nca_fs_ctx)) + if (!out->missing_base_romfs && !romfsInitializeContext(&(out->base_romfs_ctx), base_nca_fs_ctx)) { LOGFILE("Failed to initialize base NCA RomFS context!"); return false; @@ -287,7 +290,7 @@ bool bktrIsFileEntryUpdated(BktrContext *ctx, RomFileSystemFileEntry *file_entry static bool bktrPhysicalSectionRead(BktrContext *ctx, void *out, u64 read_size, u64 offset) { - if (!ctx || !ctx->base_romfs_ctx.nca_fs_ctx || !ctx->indirect_block || !out || !read_size) + if (!ctx || (!ctx->missing_base_romfs && !ctx->base_romfs_ctx.nca_fs_ctx) || !ctx->indirect_block || !out || !read_size) { LOGFILE("Invalid parameters!"); return false; @@ -318,9 +321,13 @@ static bool bktrPhysicalSectionRead(BktrContext *ctx, void *out, u64 read_size, { success = bktrAesCtrExStorageRead(ctx, out, read_size, offset, section_offset); if (!success) LOGFILE("Failed to read 0x%lX bytes block from BKTR AesCtrEx storage at offset 0x%lX!", read_size, section_offset); - } else { + } else + if (!ctx->missing_base_romfs) + { success = ncaReadFsSection(ctx->base_romfs_ctx.nca_fs_ctx, out, read_size, section_offset); if (!success) LOGFILE("Failed to read 0x%lX bytes block from base RomFS at offset 0x%lX!", read_size, section_offset); + } else { + LOGFILE("Attempting to read 0x%lX bytes block from non-existent base RomFS at offset 0x%lX!", read_size, section_offset); } } else { /* Handle reads that span multiple indirect storage entries. */ diff --git a/source/bktr.h b/source/bktr.h index 4af2662..38a7431 100644 --- a/source/bktr.h +++ b/source/bktr.h @@ -82,6 +82,7 @@ typedef struct { u64 body_offset; ///< Patched RomFS image file data body offset (relative to the start of the RomFS). BktrIndirectStorageBlock *indirect_block; ///< BKTR Indirect Storage Block. BktrAesCtrExStorageBlock *aes_ctr_ex_block; ///< BKTR AesCtrEx Storage Block. + bool missing_base_romfs; ///< If true, only Patch RomFS data is used. Needed for games with base Program NCAs without a RomFS section (e.g. Fortnite, World of Tanks Blitz, etc.). } BktrContext; /// Initializes a BKTR context.