mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-31 23:19:44 +08:00
Prevent invalid SaveData writes from damaging guest memory (#444)
Add an optional write monitor so the team can find future memory damage on each supported desktop system.
This commit is contained in:
@@ -2984,6 +2984,7 @@ public static partial class KernelMemoryCompatExports
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
|
||||
}
|
||||
|
||||
GuestWriteWatch.OnDirectMapping(mappedAddress, length, protection);
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -792,28 +792,15 @@ public static class SaveDataExports
|
||||
|
||||
var id = (uint)Interlocked.Increment(ref _nextTransactionResource);
|
||||
|
||||
// The resource-out pointer's argument slot varies by SDK revision: some
|
||||
// callers pass it in rdx, others in rcx (a 4-arg form where rdx holds a
|
||||
// count/flag). Void Terrarium passes rdx=0x1 (not a pointer) and the
|
||||
// real out-pointer in rcx. Probe the plausible candidates and write the
|
||||
// handle to the first writable one instead of faulting on a bad rdx.
|
||||
// This is a stub-level create (matches shadPS4's return-OK semantics);
|
||||
// never return MEMORY_FAULT for it, or the guest treats savedata init as
|
||||
// failed and never advances.
|
||||
// A small RDX value is a flag, and RCX contains the output address.
|
||||
// A larger RDX value is the output address for the older ABI.
|
||||
var resourceAddress = 0UL;
|
||||
foreach (var candidate in new[]
|
||||
{
|
||||
ctx[CpuRegister.Rdx],
|
||||
ctx[CpuRegister.Rcx],
|
||||
ctx[CpuRegister.R8],
|
||||
ctx[CpuRegister.R9],
|
||||
})
|
||||
var selectedAddress = SelectTransactionResourceAddress(
|
||||
ctx[CpuRegister.Rdx],
|
||||
ctx[CpuRegister.Rcx]);
|
||||
if (selectedAddress != 0 && TryWriteUInt32(ctx, selectedAddress, id))
|
||||
{
|
||||
if (candidate != 0 && TryWriteUInt32(ctx, candidate, id))
|
||||
{
|
||||
resourceAddress = candidate;
|
||||
break;
|
||||
}
|
||||
resourceAddress = selectedAddress;
|
||||
}
|
||||
|
||||
TraceSaveData(
|
||||
@@ -822,6 +809,16 @@ public static class SaveDataExports
|
||||
return SetReturn(ctx, 0);
|
||||
}
|
||||
|
||||
internal static ulong SelectTransactionResourceAddress(ulong rdx, ulong rcx)
|
||||
{
|
||||
if (rdx == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rdx <= ushort.MaxValue ? rcx : rdx;
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "lJUQuaKqoKY",
|
||||
ExportName = "sceSaveDataDeleteTransactionResource",
|
||||
|
||||
Reference in New Issue
Block a user