SaveData: avoid invalid DeS transaction resource pointer (#480)

Demon's Souls treats the small transaction-resource handle as a guest pointer during the fresh-save path. Return a null resource for the observed call shape to prevent the repeatable access violation at address 0x9.

Co-authored-by: RedDv <RedDv@DESKTOP-EVNB4S8>
This commit is contained in:
iExplosiveRage
2026-07-21 02:22:51 +03:00
committed by GitHub
parent 0ae785c617
commit 4bb1af93d7
@@ -787,6 +787,34 @@ public static class SaveDataExports
LibraryName = "libSceSaveData")]
public static int SaveDataCreateTransactionResource(CpuContext ctx)
{
// Demon's Souls first-run call:
// RDI = 0xC0000, RSI = RDX + 8, RDX = resource output.
// Writing integer handle 1 makes the title dereference [1 + 8],
// causing the repeatable access violation at guest address 0x9.
var desWorkSize = ctx[CpuRegister.Rdi];
var desWorkAddress = ctx[CpuRegister.Rsi];
var desResourceAddress = ctx[CpuRegister.Rdx];
if (desWorkSize == 0xC0000 &&
desResourceAddress != 0 &&
desResourceAddress <= ulong.MaxValue - sizeof(ulong) &&
desWorkAddress == desResourceAddress + sizeof(ulong))
{
if (!ctx.TryWriteUInt64(desResourceAddress, 0))
{
return SetReturn(
ctx,
(int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
}
TraceSaveData(
$"create_transaction_resource_des_guard " +
$"work_size=0x{desWorkSize:X} " +
$"work=0x{desWorkAddress:X} " +
$"resource_addr=0x{desResourceAddress:X} resource=0x0");
return SetReturn(ctx, 0);
}
var userId = unchecked((int)ctx[CpuRegister.Rdi]);
var reserved = ctx[CpuRegister.Rsi];