diff --git a/src/SharpEmu.Libs/SaveData/SaveDataExports.cs b/src/SharpEmu.Libs/SaveData/SaveDataExports.cs index 0496a36e..a3a9e16e 100644 --- a/src/SharpEmu.Libs/SaveData/SaveDataExports.cs +++ b/src/SharpEmu.Libs/SaveData/SaveDataExports.cs @@ -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];