diff options
author | Michael Scire <SciresM@gmail.com> | 2020-01-22 20:14:06 -0800 |
---|---|---|
committer | Michael Scire <SciresM@gmail.com> | 2020-01-22 20:14:06 -0800 |
commit | 5a7eecc3adfb179335d921725a3b60c622e92836 (patch) | |
tree | 5be51ae470df6428478da91f1e8454e3c18b0955 /src/core/loader/nso.cpp | |
parent | d8e0d839bd9c958233e6c57ff7e35b783daaf2d5 (diff) |
loader: provide default arguments (zero byte) to NSOs
Certain newer unity games (Terraria, Pokemon Mystery Dungeon) require
that the argument region be populated. Failure to do so results in
an integer underflow in argument count, and eventually an unmapped
read at 0x800000000. Providing this default fixes this.
Note that the behavior of official software is as yet unverified,
arguments-wise.
Diffstat (limited to 'src/core/loader/nso.cpp')
-rw-r--r-- | src/core/loader/nso.cpp | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 515c5accb..044067a5b 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -97,7 +97,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, if (nso_header.IsSegmentCompressed(i)) { data = DecompressSegment(data, nso_header.segments[i]); } - program_image.resize(nso_header.segments[i].location + data.size()); + program_image.resize(nso_header.segments[i].location + + PageAlignSize(static_cast<u32>(data.size()))); std::memcpy(program_image.data() + nso_header.segments[i].location, data.data(), data.size()); codeset.segments[i].addr = nso_header.segments[i].location; @@ -105,8 +106,12 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size())); } - if (should_pass_arguments && !Settings::values.program_args.empty()) { - const auto arg_data = Settings::values.program_args; + if (should_pass_arguments) { + std::vector<u8> arg_data{Settings::values.program_args.begin(), + Settings::values.program_args.end()}; + if (arg_data.empty()) { + arg_data.resize(NSO_ARGUMENT_DEFAULT_SIZE); + } codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; NSOArgumentHeader args_header{ NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}}; |