From 90c2dec02d6104dd4c9c358c5665d06bf864383f Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 1 Dec 2016 06:50:19 +0900 Subject: [PATCH] Wii IPC HLE: do not clobber memory when launching a new title It's questionable whether ES_LAUNCH should write *anything* to the command structure at all, ever, given that it never actually returns it back through the mailbox. But it *definitely* shouldn't write anything to it if it has just launched a DOL, because otherwise it might clobber code/data from the just-loaded application. --- .../Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp index 376bebe327..2c514aecd8 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -937,6 +937,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) { _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2); bool bSuccess = false; + bool bReset = false; u16 IOSv = 0xffff; u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); @@ -975,6 +976,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) MSR = 0; PC = 0x3400; bSuccess = true; + bReset = true; } else { @@ -1045,7 +1047,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) Memory::Write_U32(Memory::Read_U32(0x00003140), 0x00003188); // TODO: provide correct return code when bSuccess= false - Memory::Write_U32(0, _CommandAddress + 0x4); + // Note: If we just reset the PPC, don't write anything to the command buffer. This + // could clobber the DOL we just loaded. + if (!bReset) + { + Memory::Write_U32(0, _CommandAddress + 0x4); + } ERROR_LOG(WII_IPC_ES, "IOCTL_ES_LAUNCH %016" PRIx64 " %08x %016" PRIx64 " %08x %016" PRIx64 " %04x", @@ -1055,10 +1062,13 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // This is necessary because Reset(true) above deleted this object. Ew. - // The original hardware overwrites the command type with the async reply type. - Memory::Write_U32(IPC_REP_ASYNC, _CommandAddress); - // IOS also seems to write back the command that was responded to in the FD field. - Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8); + if (!bReset) + { + // The original hardware overwrites the command type with the async reply type. + Memory::Write_U32(IPC_REP_ASYNC, _CommandAddress); + // IOS also seems to write back the command that was responded to in the FD field. + Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8); + } // Generate a "reply" to the IPC command. ES_LAUNCH is unique because it // involves restarting IOS; IOS generates two acknowledgements in a row.