Modifying PS2 game save files
The first step of mast1c0re is to gain arbitrary code execution within the emulated PlayStation 2 environment using a vulnerability within a PlayStation 2 game that is available on the PlayStation 4 and PlayStation 5. Based on the quote “For my chain, I settled on Okage Shadow King, which has a typical stack buffer oveflow if you extend the player/town name.” from CTurtE‘s blog, I began my research on the Okage: Shadow King game.
Obtaining a game save file
Developing the PlayStation 2 exploit on a physical PlayStation 4 or PlayStation 2 adds additional complexity and therefore I opted to use the PlayStation 2 emulator PCSX2. The PCSX2 emulator allows you to rapidly boot PlayStation 2 games and almost mirrors the functionality of the PlayStation 2 and PlayStation 4 emulator. Additionally, it contains a built-in debugger allowing you to step through the exploit as you develop it.
Once the game was booted, I created a new profile with the name “ABCdef”, progressed through the dialog and then navigated to the characters bedroom which allows you to save the game to the memory card.
Once the game was saved to the memory card, the
Mcd001.ps2 file was copied from the PCSX2 memcards directory (
C:\Users\<username>\Documents\PCSX2\memcards\Mcd001.ps2) to another location for analysis.
Game save file extraction
mymc / mymcplus
Upon researching the
.ps2 file extension I came across the ps2dev/mymc project which allows you to manage multiple save files within the
.ps2 file. After some time I decided to use the command line version of the thestr4ng3r/mymcplus project as it is hosted on PyPI and can be installed and included as a Python project.
Using thestr4ng3r/mymcplus we can view the game save files within the
$ mymcplus -i Mcd001.ps2 ls rwx--d----+---- 3 2022-12-22 15:32:50 . -wx--d----+--H- 0 2022-12-22 15:30:06 .. rwx--d----+---- 8 2022-12-22 15:32:52 BASCUS-97129
BASCUS-97129 directory can then be extracted from the
Mcd001.ps2 file and is saved locally as
└─$ mymcplus -i Mcd001.ps2 export BASCUS-97129 Exporing BASCUS-97129 to BASCUS-97129.psu └─$ ls -al total 17052 drwxr-xr-x 2 user user 4096 Dec 22 15:33 . drwxr-xr-x 7 user user 4096 Dec 22 15:33 .. -rw-r--r-- 1 user user 148992 Dec 22 15:33 BASCUS-97129.psu -rw-r--r-- 1 user user 8650752 Dec 22 15:33 Mcd001.ps2
After searching online for information on the
.psu file extension, I came across the post “PS2 save game format for EMS adapter (.psu)” by gothi which describes the EMS adapter file format. I decided to create a Python library and command line tool to manage, import and export files from the
.psu file, as I identified no existing public tool to perform these actions.
.psu file is a container for three directories and multiple files, with each entry having a header, followed by the file’s content if it is a file.
The first entry must be a directory with the name of the file, such as
BASCUS-97129. The entry count is the number of directories and files within this
.psu file. The
Type value states it is a directory when the value is
0x8427. The structure of the directory entry is shown below:
The next two entries must be a
.. directory with the same structure as the first directory entry, however the entry count for these directories should be zero.
All subsequent entries are files with a
0x8497 and can be exported to a standalone file. Each entry contains a header followed by the content of the files. If the file content length is not a multiple of 1,024, then padding bytes are appended to the end of the file contents until the length is a multiple of 1,024. The following structure shows a single file entry:
The Python project McCaulay/pypsu contains a Python library for automating interaction with
.psu files by reading and writing the structures described previously. It additionally contains a command-line utility for manually interacting with
So far, we have obtained an Okage: Shadow King game save file, extracted the
BASCUS-97129.psu file, and built a tool to extract and import individual files within the
BASCUS-97129.psu file, such as
In the next blog post “mast1c0re: Part 2 – Arbitrary PS2 code execution“, we modify the game save profile name, then exploit a traditional stack buffer overflow vulnerability to gain arbitrary code execution on the PlayStation 2.