Finding gamesaves exploits on the PSP
This is an article to help you recognize an exploitable vulnerability (e.g MaTiAz’s Gripshift) from a non exploitable (or at least, not easily enough) crash (e.g. yyoossk’s Phantasy star). Is think it can also be seen as a rough tutorial on “how to look for gamesave exploits on the PSP”
If, as me, you badly want your psp3000 to be hacked, it is likely that you follow closely what happens on PSP dedicated websites.
From time to time, some random guy pops up on a forum with an “idea” on how to hack the PSP, or, on better days, someone comes up with a savegame that crashes the PSP, in the hope that it will be useful. Reporting a crash is actually a good thing to do, crashes are the first step to an exploit, and if they don’t lead to an exploit, at least it can help Sony to improve their product 😉
Recently, a guy nicknamed yyoossk tried to reproduce what MaTiAz had done with Gripshift, in the Japanese Demo of “Phantasy star portable” (see here and here). Wow, an exploit in a demo, that would be very cool, no need for expensive ebay UMDs!!! This is why I decided to give it a try. I will try to explain in this article why his crash is only a crash and will probably never be turned into an exploit.
I will compare the Phantasy star portable crash to what happens with the Gripshift exploit.
Before I start, you have to know that I don’t claim to be the best hacker or programmer in the world. I’m just a bit above the “complete Noob” level, with enough experience in IT to understand what I see on my screen. So this text might be inaccurate on some parts.
To read this article, you need strong understanding of basic programming concepts such as variables, addresses, and arrays. You should also have a browser window open on the MIPS assembly list of commands. MIPS assembly knowledge is not really required if you know the basics of programing, but it sure helps to have a general idea of what assembly language is.
The basics of a savegame exploit
Most savegame exploits rely on the concept of “buffer overflow”, which consists in writing more data in an array than you should. For example, if you have an array of size 10, and try to write 11 elements in it, you’ll have a buffer overflow of 1 element. What happens in that case is that you write somewhere in memory you weren’t supposed to, and this can give interesting results that I will talk about later. For more information on buffer overflows, please read this article.
Now, a very popular way of looking for buffer overflows (in savegames but not only) is to put a very long string somewhere. Strings are often represented as an array of char, and are therefore a very easy target. Moreover, a string such as the player name is usually very easy to identify in a decrypted savegame file. You can’t easily tell which number represents the amount of gold coins you have in your inventory, but it is very easy to look for “wololo” inside the file.
Once this string is located, the first step is to try and put a very long name in there. This is what MaTiAz did with gripshift (“spartaaaaaaaaa”), and probably what was attempted in the Phantasy star crash too.
Of course, you cannot do this through the game itself (the interface won’t allow you to input more than, say, 10 characters), so to do this you have to decrypt your savegame, edit the decrypted version, then reencrypt it. A tool such as savegame-deemer is very useful in that case, since it allows you to work directly on decrypted savegames without worrying about the decryption/encryption process.
So basically, you put some garbage into a savegame file, and try to see if this makes the game crash. In most cases, the game will not crash, but simply tell you that your save data is invalid. Game over, you won’t find any exploit with this game and this method (it doesn’t necessarily mean that the game doesn’t have any flaw, just that you’ll have to think more, but that’s beyond what I want to explain in this article)
But what if the game crashes when loading your data? Well it means some programmers didn’t do their job properly, and there is a vulnerability in the game. IT DOESN’T MEAN THERE IS AN EXPLOIT YET, right now it is just a bug. To see if it is interesting for us, we have to run it through PSPLink and analyze the error dump.
Launching the game in PSPLink
This is where the difficulty starts. For that you’ll need a PSP with a custom firmware, and PSPLink installed. I won’t go into the details of installing PSPLink, they can be found pretty much everywhere. PSPLink comes with a few prx files. We need to use PSPLink as a plugin because we will be launching a game. Long story short, you need to have usbhostfs.prx and psplink.prx in your seplugins directory. And they have to be in your seplugins/game.txt file, and you need to activate them in the recovery menu. Again, I won’t go into the details here, you basically need the same setup as if you wanted to run remoteJoy, minus the remote joystick part :p
Once everything is installed, you run usbhostfs_pc and psph from your computer, you connect your psp with a USB cable to your computer, and you launch the game.
If everything works smoothly, usbhostfs_pc should say “connected to device”, and pspsh should say “all modules loaded” then display a prompt “/host0:>”
When you load the savegame, the game will crash, and you should have a memory dump displayed in pspsh, as below
What are we looking for?
Now comes the difficult bit about assembly. PSPLink shows us the state of the various registers just before the crash. register are just 32 bits integers used in any program, and they can represent everything (characters, addresses in memory, integers…) depending on how the program interprets them.
what we want when we write an exploit is to be able to jump to an arbitrary position in the memory. Unfortunately, there are not so many ways to do that. The only solution I know about is to overwrite the contents of the register named “$ra“. ra means “return address”, so you understand why it is so important. This is where the code will go when it leaves a subroutine, with the command “j $ra” (jump to $ra). $ra itself usually gets its data from $sp, so if we can manipulate data related to $sp, that’s a good sign too.
Other registers are not useless, they are the ones that will eventually fill the contents of $sp and $ra, but that becomes too complex to explain here (and, honestly, I don’t know much about it and it requires detailed analysis of the program, which I am not willing to do)
Comparing the Gripshift crash (why it works) and the Phantasy Star crash (why it doesn’t)
Let’s compare our two crashes.
The Gripshift crash
we put lots of letters “a” in the players name. What we see on the crash report is that $ra is now equal to 0x61616161. This is very interesting since 61 is the hexadecimal value of the letter “a”: bingo, we basically found an easy way to jump to an arbitrary location in memory. What’s remaining is to replace the “aaaa” with a regular address, in which we will put some code. (Note that I edited MaTiAz’s original POC to have it actually crash rather than run some code)
The Phantasy star crash:
we see some “61” here and there, but nothing interesting in $sp or $ra. That’s a very bad start. But we can still have a look at the code, see if those $a1, $a2,$a3 will do something good.

Nothing seems to be doing anything with $sp, then the code jumps one time, two times, meh… it’s too complex, that’s usually where you can give up and start looking for flaws in another game.
So, the Phantasy star crash means nothing?
Not exactly, it is a bug, so there might be a way to exploit it, but when a jump is not obvious, you’ll spend less time looking for a crash in another game and try again, really. Looking for a jump that might not even exist is not fun and could take hundreds of hours, it’s just not worth it (If you’re willing to do it, you’d rather be decrypting the firmware and look for exploits in the Kernel!).
This is too complex for me, isn’t there another way for me to tell if a crash is “a good one” or not?
Well, first you can use your brain. You know how the PSP scene has worked so far. When someone comes whith a potential exploit, you can be sure some serious guys will give it a try if it’s worth it. If after a few weeks there is no “serious” discussion on the issue (involving code or “proof of concept”files), you should lower your hopes.
Also, in this specific case, there was another sign that it wouldn’t work: if it were as easy as the Gripshift exploit, the crash would occur when the user name is loaded. This is not the case here, as you can see the player’s name displayed right after you load the savegame.

So Phantasy star’s demo does have a security check on the player’s name length. This is not a proof that the crash is useless, but a huge hint that it can’t be as easy as the gripshift one.
I personally think it is good to report a crash the way yyoossk did. his report was detailed and he provided all the files to reproduce the issue, which is the reason that made me want to try it (that, and the fact that it was on a demo to which everyone has access). If there were dozens of reports like this one every day, some of them would definitely contain useable flaws!






@wololo I have a pspgo with cfw 6.35PRO-B8 and obviously my PSVita. I bought several games on Vita just to play my favorite games on both consoles (originals on Vita though) but now I realized that I might retribute a bit of the joy I got with CFW and that I can take the chance to test a few things like you said using my purchases. I’m a programmer since I was 11yr old, so I quite understand what you explained us and I thought it’s pretty interesting. Am I right if I think you use $ra to point to a compiled routine embedded in the savegame the same way as you put the garbage in the example? I’d like you to guide me a bit to maybe help everybody, even if it’s just a bit 😉
P.D. I don’t know if I suck when it comes to express myself in English, but if that’s the case, tell me plz xD
ProCyoN, your understanding is correct. Once we see proof that we control $ra, we will replace the “garbage” by an actual address which will point to some compiled code that we injected in the save data. You can see an explanation of that step here: http://wololo.net/2010/02/27/writing-a-binary-loader/
Oh my gosh, thank you. That helps me out so much believe it or not 🙂
Spot on with this write-up, I truly believe this website needs far more attention. I’ll probably be back again to read more, thanks for the info!
Wooooooh!That was a BIG one!I should probably try it.Maybe that could alternatively replace what was called ‘Ninja release’ for which I’m waiting for.
How do I know if the exploit I found works on PS Vita?
Can someone please explain the index.lua file to me?
I have psplink running and all good then in the readme file it tells how to start luae but I’m missing the index file.
So I created it in the PC folder for psplink
My problem is the readme file then says “then have it [index.lua] dotfile, your project script in a project folder somewhere on your pc.
Idk how to do this and not completely sure I know what that means.
hi wololo!
I’m trying to find my own exploit and using a PSP will be way better (I gues…) than Vita or jPcSP/PPSSPP
I wanted to ask: Wich one is better to use nowasays? or all the PSP versions works the same? I mean, does PSP1000 has any advantage over other models? or PSP2000 (since it has 64mb on Ram). Is it different with a PSPGo (AFAIK, system changes a little bit due to PSP Go having features other PSP don’t have)
Please, i’ll wait for your answer, also, I will post this twice, one of the with a “bad word” so I make sure you’ll see it.
thanks in advance!
hi wololo!
I’m trying to find my own exploit and using a PSP will be way better (I guess…) than Vita or jPcSP/PPSSPP
I wanted to ask: Wich one is better to use nowadays? or all the PSP versions works the same? I mean, does PSP1000 has any advantage over other models? or PSP2000 is better to find exploits? (since it has 64mb on Ram). Is it different with a PSPGo? (AFAIK, system changes a little bit due to PSP Go having features other PSP don’t have)
Please, i’ll wait for your answer, also, I posted this twice, one of them with a “bad word” so I make sure you’ll see it.
***
thanks in advance!
Nice way of getting my attention, it worked 🙂
I’d personally recommend a PSP1000: cheaper, guaranteed compatibility with pandora batteries (which are extremely useful when you start looking for exploits and mess things up), sturdy, and closer to the psp emu within the Vita (32MB, etc…)
Ok, thanks! (for now i’ve seen where to buy 3000 ang Go very cheap where I live, but I was considering Pandora and toher stuff for PSP1000 so I may get one of those…)
I’m glad it worked :p
–
***
–
If you back our tool have the identical reaction a
encouraging entry a see as well as regarding cam4 token hack tool other to
your liking program!
My brother recommended I would possibly like this blog.
He used to be entirely right. This put up truly made my day.
You can not consider simply how much time I had spent
for this info! Thanks!