socram8888 / tonyhax

PS1 savegame exploit
Do What The F*ck You Want To Public License
436 stars 24 forks source link

Stuck on Green screen attempting to exploit Castlevania Chronicles (USA) [SLUS-01384] #39

Closed G4Vi closed 3 years ago

G4Vi commented 3 years ago

I found one of the player name stack buffer overflows in Castlevania Chronicles https://playstationdev.wiki/ps1devwiki/index.php?title=Vulnerabilities and successfully used it to boot tonyhax on no$psx. However, it gets stuck on the green screen in the secondary loader, the ExitCriticalSection in reinit_kernel does not return properly.

Video, memory card, and memory dump made in video:

https://drive.google.com/drive/u/0/folders/125LJk4hROzLFuWxQGrVfzYVFRx8fLHfv

Console: no$psx 2.0 BIOS: ps30a.bin SHA256: 11052B6499E466BBF0A709B1F9CB6834A9418E66680387912451E971CF8A1FEF Tonyhax version: built from https://github.com/socram8888/tonyhax/commit/1c94f46ee4b3c21927df91452e875784e2d1834b tonyhax-v1.2.3 (with Castlevania Chronicles (CC) stuff added) using mips-mti-linux-gnu toolchain. The CC mcs is built with entry-full.

socram8888 commented 3 years ago

Alright, that's odd.

I'd start by checking that:

G4Vi commented 3 years ago

I think the stack pointer is okay, if I single step through the syscall / set a breakpoint on 0x1010 (exit of syscall I think), it returns to the correct location (ExitCriticalSection stub then reinit_kernel , back into main. If I continue single stepping the screen goes black.

It appears after it returns from the syscall into ExitCriticalSection stub breakpoints do not work at all! Not sure if that's just a no$psx bug or sign of another issue.

Replacing the mfc/mtc block with the syscall and removing the call to EnterCriticalSection appeared to have no effect. Having the mfc/mtc block AND the syscall in the first stage also did not appear make a difference.

socram8888 commented 3 years ago

Could you please check on the GPU view what the VRAM contents are? For example, is the font loaded?

G4Vi commented 3 years ago

With the VRAM viewer, if I run after the ExitCriticalSection in reinit_kernel and then click into the debugger window to stop it, both 3D/RE and Screen are green. I'm not sure how to check if the font is loaded. X-range is 590..3150. Y-range is 16..256.

socram8888 commented 3 years ago

If you just let it run, where does it get stuck? If it gets stuck in one of the busy loops, you should be able to do a mips-linux-gnu-objdump -D secondary.elf on the tonyhax folder to figure out to which function it corresponds.

Also, I'd recommend going to Options -> Emulation Setup -> Xcept, enabling Custom settings and enabling all exceptions except for "Bad I/O" (many games do it and it's inocuous) and "HC05 Sub-CPU errors" (as the debugging changes to debugging the slave CPU and there's apparently no way to go back to the main CPU). This should make easier to tell if the code is jumping somewhere it shouldn't.

G4Vi commented 3 years ago

I deleted some posts to remove some incorrect/confusing/irrelevant information.

After ExitCriticalSection in reinit_kernel an IRQ runs with I_MASK (1F801074) has CDROM, DMA, and SPU set (0x20C) I_STAT (1F801070) has CDROM and DMA set (0x0C). It proceed to get stuck in an infinite loop inside this IRQ from 0xDF8 to 0xE30, dereferencing s6 waiting for s6 == 0, but s6 == 0x6DA8 which points to 0x6DA8.

If I_MASK is set to 0 at the end of stage one.

li a0, 0
li t1, 0x1F801074
sw a0, 0(t1)

Instead it will proceed all the way until it gets stuck in cd_wait_int (while (CD_REGS[0] & 0x80);) part of unlock_drive, with the screen stuck at "Unlocking CD drive".

I'm not sure what is the easiest way to make unlocking the CD drive work.

socram8888 commented 3 years ago

I've found the posible culprit, which might also be the same reason XS Moto et al aren't working. Could you please try with latest master?

G4Vi commented 3 years ago

I've found the posible culprit, which might also be the same reason XS Moto et al aren't working. Could you please try with latest master?

mips-linux-gnu-ld -EL --gc-sections -T secondary.ld  patcher.o  secondary.o  crc.o  str.o  cfgparse.o  gpu.o  cdrom.o  debugscreen.o bios.o -o secondary.elf
mips-linux-gnu-ld: secondary.elf section `.rodata' will not fit in region `ram'
mips-linux-gnu-ld: region `ram' overflowed by 161 bytes
Makefile:95: recipe for target 'secondary.elf' failed
make: *** [secondary.elf] Error 1
G4Vi commented 3 years ago

Commenting out the orca image, I was able to build. It gets stuck in the first loop of cd_wait_int inside of cd_drive_init.

socram8888 commented 3 years ago

Hmmm that is odd. I was getting the same issue with XS Moto, but the CD init fixed it for me.

socram8888 commented 3 years ago

Could you please try now? Commit db0dbdfbdd80a938d73e22fc162f7aec879cc168: https://github.com/socram8888/tonyhax/files/6267227/tonyhax-v1.2.3b.zip

I am now resetting the I_MASK and I_STAT registers, just like official kernel does before exiting the critical section, which before I didn't. The original assembly used two zero writes outside any function, just there in the WarmBoot, and I assummed they weren't critical or anything.

G4Vi commented 3 years ago

Unfortunately, it still gets stuck in the first loop ofcd_wait_int inside of cd_drive_init. Edit: It appears the CDROM flag in I_STAT gets set in InstallDevices in reset_kernel (after I_STAT and I_MASK) are reset, does this need to be handled somehow? Edit 2: It doesn't always get set there.

socram8888 commented 3 years ago

imagen Getting set in InstallDevices is totally normal, it's how the official kernel does it.

G4Vi commented 3 years ago

The exploit works when background music BGM from OPTION in game is set to off (included in the save in the PR). That fixes this game.

The issue may present itself again in other games. The CDROM ISR likely causes the problem, as with BGM set to off it appears the SPU and CDROM no longer set their flags in I_STAT (0x1F801070) .

socram8888 commented 3 years ago

I really gotta attempt to tweak the I_STAT register on the first stage to disable any interrupt that's not related to controller and memory card, much like FreePSXBoot does.

socram8888 commented 3 years ago

Since this seems to work well in hardware I'm closing this issue. FTR latest master does disable all interrupts except the VBlank one, required for memory card file reading.