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.
This commit is contained in:
Léo Lam 2019-08-22 17:10:28 +08:00
parent 8fa6be5b15
commit 7318913f5a

View file

@ -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;