Please note that you are required to have a exploited PlayStation 4 console on firmware 9.00 or lower to run the patches mentioned in this article.
Intro
There’s a rare bug in Uncharted 2 where if a player goes out of the normal playzone, dies, and quit to the menu, the game would crash.
Affected Consoles:
-
PlayStation 3Unofficially Patched -
PlayStation 4Unofficially Patched
The issue still persists on latest patch 1.02 on PS4
First Sight
Looking at instructions and fault address, assuming that 4b4 is SPU instruction and 0x620 for PS4, seems to be reading from an invalid memory address (access violation)
PS3 Stop Instruction:
00262e04 a0 1c 04 b4 lhz r0,DAT_000004b4(r28)
Log from RPCS3
Thread (main_thread) [0x00262e04]} VM: Access violation reading location 0x4b4 (unmapped memory)
PS4 Stop Instruction:
000ade75 66 41 83 CMP word ptr [R15 + 0x620],0x0
bf 20 06
00 00 00
Mira Log from PS4
# reason: page fault (user read data, page not present)
# fault address: 0000000000000620
# rip: 00000000004ade75
Data stops processing and left the registers with 0 when quitting to the menu during this specific case, causing the game to crash.
RPCS3: Breakpoint runtime.
RPCS3: Crash.
On Playstation 4, this is similar but in register R15 instead.
PS4: Reaper Breakpoint runtime.
PS4: Mira backtrace.
Looking at register data. R28 (PS3) and R15 (PS4) gets used during gameplay and are always executed and have data.
Resolution
We add a check to compare against the base register (28 for PS3 and 15 for PS4 respectively)
Skip to load 1 into their needed register skip and return to normal code if isn’t 0.
# quit to menu fix ppc ver
- [ be32, 0x00262e04, 0x488ce301 ] #Call to code cave
- [ be32, 0x00b31104, 0x2f9c0000 ] #Compare r28 to 0
- [ be32, 0x00b31108, 0x409e000c ] #Skip to lhz if !=0
- [ be32, 0x00b3110c, 0x38000001 ] #r0 = 1
- [ be32, 0x00b31110, 0x48000008 ] #Go to return
- [ be32, 0x00b31114, 0xa01c04b4 ] #Default lhz
- [ be32, 0x00b31118, 0x4e800020 ] #Return
// quit to menu fix x86 ver
000ade75 e8 87 cc CALL SUB_006cab01 // code cave
61 00
SUB_006cab01
006cab01 49 83 ff 00 CMP R15,0x0 // compare r15 to 0
006cab05 0f 85 09 JNZ LAB_006cab14 // go to lea
00 00 00
006cab0b 48 c7 c7 MOV RDI,0x1 // move rdi with 1
01 00 00 00
006cab12 eb 07 JMP LAB_006cab1b // Go to Compare
LAB_006cab14
006cab14 49 8d bf LEA RDI,[R15 + 0x620] // Lea from rdi to r15 + 620, no LEA in original code, does CMP instead
20 06 00 00
LAB_006cab1b
006cab1b 48 83 ff 00 CMP RDI,0x0 // if rdi 0
006cab1f c3 RET // Return
Let’s implement this fix and see the results.
Awesome! No longer crashing when quitting to the menu.
Patch
To apply patch and for use on an exploitable PlayStation 3 or PlayStation 4 console, you’ll to modify the executable with a hex editor and install it back onto the console.
For RPCS3 Users, Simply download and enable through it’s built-in patch manager.
Credits
Thanks to ZEROx for implementing fix in PowerPC Version.