Cheating in PS2 Games with Lua
After jailbreaking my PS4, I searched for a way to play some PS2 games on it. Since HDMI ports are not available on stock PS2s, the obvious solution would be to emulate the games on a PS4.
Years ago, the PS4 homebrew community already found ways to emulate many PS2 games on the console. The main method involves an emulator that was originally developed for the game Jak and Daxter called Jak v2. This emulator can be repurposed to emulate many other PS2 titles on the PS4. This can be done manually with some effort, but the tool PS2FPKG already handles all of the hard stuff. Only a game ISO is required for it to generate a package that is ready to be installed on a jailbroken PS4.
The emulator can be tweaked using a configuration file and Lua script. Both files can be used to do some elaborate stuff like enabling specific emulator options, patching memory and injecting custom hooks into the running game.
Of course, I didn’t even bother playing any game after finding out that it’s possible to run custom Lua scripts to mess with game memory.
Adding Cheat Engine
Live debugging and poking memory of running games is possible on the PS4. However, an easier way to develop cheating functionality for emulated PS2 games involves running them on PC using PCSX2 and attaching Cheat Engine to them.
When using Cheat Engine to attach to PCSX2, considers these pitfalls:
- Using an x64 version of both Cheat Engine and PCSX2 is a good idea.
- In Cheat Engine, enable
mem_mappedin Settings->Scan Settings. If you don’t enable this, CE won’t scan all memory regions - especially the higher address regions. Don’t be like me and waste hours searching for stuff that isn’t being scanned. - The option to enable
mem_mappedobviously makes scanning much much slower. But there’s an easy fix for that: PCSX2 exports a symbol calledEEmemthat points to the start of memory of the PS2 Emotion Engine (the CPU and GPU thingy). This is where interesting game memory starts. - Be sure to disable PCSX2 optimization options like the EE Recompiler and Fast Memory Access in the advanced tabs. Otherwise, the emulator uses caching and additional optimization features that get in your way.
- If you rely on emulator breakpoints for your analysis, you will have to enable the PCSX2 features mentioned above or the breakpoints will not hit.
Using the PCSX2 Debugger
For simple stuff, you most likely won’t need CE that much. As an example, I wanted to get infinite ammo in GTA: Vice City Stories (PAL). The plan was to patch the function that decrements ammo and clip counters.
After some shooting and scanning memory for decremented values, I found the current ammo memory address: 0x1D3F26C. To find out what decrements this value, PCSX2’s write breakpoints were helpful:
So for this simple example, patching the addiu v0, v0, -0x1 instruction seemed like a good plan.
Patching Instructions in Lua
Since this address is static, a simple Lua script to patch it looks as follows:
apiRequest(2.2)
local gpr = require("ee-gpr-alias")
local cpr = require("ee-cpr0-alias")
local hwaddr = require("ee-hwaddr")
local emuObj = getEmuObject()
local eeObj = getEEObject()
[...]
-- Ammo and Clip
eeObj.WriteMem32(0x202C1A64, 0x24420000)
eeObj.WriteMem32(0x202C1AC8, 0x24420000)
For a list of all available methods, you can check PSDev Wiki. The value 0x24420000 changes the instruction to be addiu v0, v0, -0x0, so that ammo never gets depleted:
It’s also possible to define button combinations to enable/disable certain patches or hooks. With some more patching and hooking, even 60FPS patches can be implemented for this game.
The created Lua script can then be bundled with the game ISO using PS2FPKG if you are brave enough to run some random exe downloaded from a console hacking forum :)
Further Reading
This forum post contains an awfully organized mess of interesting patches for PS2 games.