From 7318913f5a11a046748ee852fc6075ab3e96b337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Thu, 22 Aug 2019 17:10:28 +0800 Subject: [PATCH] ncch_container: Fix NCCH decryption heuristic when replacing exheader Fixes a regression from #4862, which caused the NCCH title ID checking heuristic to be skipped whenever the exheader is replaced. I was thinking the heuristic wouldn't be needed in that case, but it turns out that many users still have pathological NCCHs that indicate they are encrypted but are actually decrypted... Now the original exheader is always read and used for the heuristic to determine whether the NCCH is actually encrypted; only then do we load a replacement exheader (if it exists) to avoid affecting the heuristic. --- src/core/file_sys/ncch_container.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/core/file_sys/ncch_container.cpp b/src/core/file_sys/ncch_container.cpp index c3728dfde0..5e02864943 100644 --- a/src/core/file_sys/ncch_container.cpp +++ b/src/core/file_sys/ncch_container.cpp @@ -325,20 +325,11 @@ Loader::ResultStatus NCCHContainer::Load() { return file && file.ReadBytes(&exheader_header, size) == size; }; - FileUtil::IOFile exheader_override_file{filepath + ".exheader", "rb"}; - const bool has_exheader_override = read_exheader(exheader_override_file); - if (has_exheader_override) { - if (exheader_header.system_info.jump_id != - exheader_header.arm11_system_local_caps.program_id) { - LOG_WARNING(Service_FS, "Jump ID and Program ID don't match. " - "The override exheader might not be decrypted."); - } - is_tainted = true; - } else if (!read_exheader(file)) { + if (!read_exheader(file)) { return Loader::ResultStatus::Error; } - if (!has_exheader_override && is_encrypted) { + if (is_encrypted) { // This ID check is masked to low 32-bit as a toleration to ill-formed ROM created // by merging games and its updates. if ((exheader_header.system_info.jump_id & 0xFFFFFFFF) == @@ -358,6 +349,17 @@ Loader::ResultStatus NCCHContainer::Load() { } } + FileUtil::IOFile exheader_override_file{filepath + ".exheader", "rb"}; + const bool has_exheader_override = read_exheader(exheader_override_file); + if (has_exheader_override) { + if (exheader_header.system_info.jump_id != + exheader_header.arm11_system_local_caps.program_id) { + LOG_WARNING(Service_FS, "Jump ID and Program ID don't match. " + "The override exheader might not be decrypted."); + } + is_tainted = true; + } + is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; u32 entry_point = exheader_header.codeset_info.text.address; u32 code_size = exheader_header.codeset_info.text.code_size;