diff --git a/src/core/file_sys/ncch_container.cpp b/src/core/file_sys/ncch_container.cpp index 5efd5e54d..cf050e74e 100644 --- a/src/core/file_sys/ncch_container.cpp +++ b/src/core/file_sys/ncch_container.cpp @@ -539,26 +539,28 @@ Loader::ResultStatus NCCHContainer::LoadSectionExeFS(const char* name, std::vect } } - std::string override_ips = filepath + ".exefsdir/code.ips"; - - if (FileUtil::Exists(override_ips) && strcmp(name, ".code") == 0) { - FileUtil::IOFile ips_file(override_ips, "rb"); - std::size_t ips_file_size = ips_file.GetSize(); - std::vector ips(ips_file_size); - - if (ips_file.IsOpen() && - ips_file.ReadBytes(&ips[0], ips_file_size) == ips_file_size) { - LOG_INFO(Service_FS, "File {} patching code.bin", override_ips); - ApplyIPS(ips, buffer); - } - } - return Loader::ResultStatus::Success; } } return Loader::ResultStatus::ErrorNotUsed; } +bool NCCHContainer::ApplyIPSPatch(std::vector& code) const { + const std::string override_ips = filepath + ".exefsdir/code.ips"; + + FileUtil::IOFile ips_file{override_ips, "rb"}; + if (!ips_file) + return false; + + std::vector ips(ips_file.GetSize()); + if (ips_file.ReadBytes(ips.data(), ips.size()) != ips.size()) + return false; + + LOG_INFO(Service_FS, "File {} patching code.bin", override_ips); + ApplyIPS(ips, code); + return true; +} + Loader::ResultStatus NCCHContainer::LoadOverrideExeFSSection(const char* name, std::vector& buffer) { std::string override_name; diff --git a/src/core/file_sys/ncch_container.h b/src/core/file_sys/ncch_container.h index 89a2d1289..00d44c818 100644 --- a/src/core/file_sys/ncch_container.h +++ b/src/core/file_sys/ncch_container.h @@ -271,6 +271,13 @@ public: */ Loader::ResultStatus ReadExtdataId(u64& extdata_id); + /** + * Apply an IPS patch for .code (if it exists). + * This should only be called after allocating .bss. + * @return bool true if a patch was applied, false otherwise + */ + bool ApplyIPSPatch(std::vector& code) const; + /** * Checks whether the NCCH container contains an ExeFS * @return bool check result diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 9ece9c69e..286eadaab 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -100,6 +100,9 @@ ResultStatus AppLoader_NCCH::LoadExec(std::shared_ptr& process) overlay_ncch->exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size; + // Apply any IPS patch now that the entire codeset (including .bss) has been allocated + overlay_ncch->ApplyIPSPatch(code); + codeset->entrypoint = codeset->CodeSegment().addr; codeset->memory = std::move(code);