The Tutorial teaching you how to attempt to create a crash, testing to confirm it is an exploit, creating a Binary loader, creating a helloworld, and porting HBL.
PS wololo: WTF .doc and .rtf can't be uploaded on your site, or .txt!?! Guess I'll just paste it D:
Well, since my demo exploit was kind of wasted, I decided to make several tutorials about finding the exploit, testing it, making a bin loader, making a hello world, and finally porting hbl. These tutorials will probably be very similar to Wololo(which he approved), however, I am going to use Everybody Sukkiri as an example.
Requirements:
PSP with the ability to use plugins
USB cable for the psp
Everybody Sukkiri (only if you're doing this for the first time, if not, use the game or demo you are trying to exploit, download link: http://www.pspdemocenter.com/page.php?id=2615)
PSPSDK
sgdeehmer(for decrypting save data, http://exophase.com/3342/savegame-deemer-v110/)
psplink (comes with pspsdk)
prxtool
PRXdecrypter 2.6b
Part 1, getting the save data, and crashing the game:
Okay, first things first, we need the save data to decrypt and edit. So, enable sgdeehmer for GAME, boot Everybody Sukkiri(from now on, when I say " Everybody Sukkiri", it also means your game), make a new game with the name(or anything else they allow you to input a string, for example pets name) of something similar to "aaaaaa", or even more characters if the game allows it. Now, in Everybody Sukkiri it doesn't save as soon as you make the save data, so you have to play the first level(or in your game it may be several levels). Once you beat the first level, it should save, and then returns to the in game menu.
Check for a folder called UCJS10094(or w/e the game code is for your game) located at ms0:/PSP/SAVEPLAIN. Open SDDATA.BIN with your favorite hex editor, and locate the string you used for the name (most commonly "aaaaaa"). Once you've located this, "extend" the string to about 60 a's (about the amount it took for Everybody Sukkiri, in this demo it has to be enough to overwflow into $ra, if not only the $sX registers will be influenced), make sure you are inserting and NOT overwriting, you may overwrite something needed by the savedata.
Enable psplink, open usbhostfs_pc and pspsh on your computer, plugin your psp through a usb cable, make sure sgdeehmer is still enabled, and then boot the game and click "load game" or "continue", it may be different per each game(in Everybody Sukkiri, it's the second option). Once the save data loads, find the location where the string (most likely the name) would be dispalyed/loaded at(in Everybody Sukkiri, its displays the name as soon as you load the savedata, but with the crash you won't be able to see it). Once it trys to load it, it should crash and display the crash info in pspsh, if $ra is not overwritten, but other registers are (for example $s0, $s1, $s2, ect), try extending your "aaaaaaa" string, with Everybody Sukkiri, if you didn't have enough characters, only the $sX registers would be overwritten. If you think the amount of characters is getting too big (I can't give a number here because I've had an exploit that took ALOT of characters), move onto another game.
Part 2, Testing the exploit:
Now that you have an exploit you need to test it. First, open SDDATA.BIN again, and change all your a's, to every single letter of the alphabet, and then the numbers, and then the alphabet in caps, and then the numbers with shift, this is so you can tell what four characters are overwriting $ra (crappy method, but it works).
[Insert Image]
Once again, boot the game, load the savedata, find where it displays the string and check pspsh for the value of $ra. Then, again in SDDATA.BIN, search for the value of $ra, but switch the endianness (for example, if $ra was "0x44434241"(hex), search for "0x41424344"(hex)), write down the offset just in case something happens.
Next we'll have to make something to test the exploit, I will be using a white and green screen flasher (given to me by n00b81), it's very simple. Make three files, linker.x, main.c, and makefile. I will not explain it because it is really simple, I'll just copy/paste it here:
linker.x:
Code: Select all
OUTPUT_FORMAT("elf32-littlemips")
OUTPUT_ARCH(mips)
ENTRY(_start)
SECTIONS
{
. = 0x08810000;
.text.start : {
*(.text.start)
}
.text : {
*(.text)
}
.rodata : {
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}
Code: Select all
typedef unsigned int u32;
void ColorVRAM(u32 color)
{
int i;
for(i = 0x44000000; i < 0x44100000; i += 4)
{
(((u32 *)i)[0]) = color;
}
}
void _start() __attribute__ ((section (".text.start")));
void _start()
{
ColorVRAM(0x00FFFFFF); // 0x00FFFFFF is white
ColorVRAM(0x0000FF00); // 0x0000FF00 is Pastel Green
}
Code: Select all
PSPSDK=$(shell psp-config --pspsdk-path)
PSPDEV=$(shell psp-config --pspdev-path)
INCLUDE=$(PSPSDK)/include
all: main
clean:
rm -rf *~ *.o *.elf *.bin main.s *.bin hx
CC = psp-gcc
CFLAGS := -D PSP -I $(INCLUDE) -W -Wall -O2 -G0 -fno-pic -mno-abicalls -w -fomit-frame-pointer
ASM = psp-as
main.o: main.c
$(CC) $(CFLAGS) -S main.c -o main.s
$(ASM) main.s -o main.o
main: main.o linker.x
$(PSPDEV)/bin/psp-ld -T linker.x -L$(PSPSDK)/lib main.o -o main.elf
$(PSPDEV)/bin/psp-strip -s main.elf
$(PSPDEV)/bin/psp-objcopy -O binary main.elf h.bin
Trouble shooting:
If it doesn't work, you may need to shift the contents of the green screen flasher to the left or right a bit, and change the jump point to fit the shifting, this is because in the ram it may not land on an offset divisible by 4 (last byte should be 00, 04, 08, or 0C).
Part 3, Binloader
First we need to get the imports of the game, to do this you will need the EBOOT.BIN found inside the iso, however if it is not an iso, you will need EBOOT2ISO, grab the EBOOT.BIN (probably located at PSP_GAME/SYSDIR), make a folder on the root of the memory stick called ENC, and place the EBOOT.BIN in that folder, run PRXdecrypter 2.6b and decrypt the file. If it fails try another EBOOT.BIN found in the ISO. Grab the xml file from http://silverspring.lan.st/, and type this in prxtool, " prxtool -f -n filename.xml EBOOT.BIN". In Everybody Sukkiri, the addresses displayed where not "correct"(for ex, 0x42EC03AC [0x000B9DB0] - sceIoWrite) so I just had to pass them through http://sdk.upsp.ws/. Save the output into a file called sdk.s.
Okay, making the binloader is very easy, it's just a matter of replacing a few addresses from the binloader in the sparta_sdk, here is the binloader for Everybody Sukkiri:
Code: Select all
/* by MaTiAz :) */
.set noat
.set noreorder
/* i can has nopsled lol */
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/*sceIoOpen: Gripshift.text_addr + 0x187B10 */
addiu $a0, $ra, 0xF0 /* filename, plz2hex in the file yourself */
nop
li $a1, 1
li $a2, 31
jal 0x088bdde8 /* sceIoOpen */ //Replace This
nop
move $a0, $v0 /* set the return value of the function for arg0 of the next function */
lui $a1, 0x08E0 /* arg1 is 0x08E00000, load address of the binary file */ //Replace This with where you want to load the h.bin file, I have it at 0x08E00000 for hbl later on
lui $a2, 1 /* arg2, read 0x10000 bytes from the file */
jal 0x088bddc0 /* sceIoRead */ //Replace This
move $s0, $a0 /*Backup $a0 value*/
nop
jal 0x088bddd0 /* sceIoClose */ //Replace This
move $a0, $s0 /*Restore $a0 value*/
nop
lui $a0, 0x08E0 //Replace This with where you want to load the h.bin file, I have it at 0x08E00000 for hbl later on
lui $a1, 0x1
jal 0x088bdf98 /* sceKernelDcacheInvalidateRange */ //Replace This, since Everybody Sukkiri did not import sceKernelDcacheInvalidateRange , I just used sceKernelDcacheWritebackInvalidateAll
nop
nop
nop
li $a0, 0x08E00000 //Replace This with where you want to load the h.bin file, I have it at 0x08E00000 for hbl later on
jr $a0
nop
Code: Select all
psp-as loader.s
psp-objcopy -O binary a.out a.bin
Test the binloader by placing the h.bin file from the green screen flasher in the root of your memory stick.
Part 4, Helloworld:
Okay, since you already have sdk.s, it is really easy to make a Helloworld, however an even quicker shortcut than to modify the sparta sdk helloworld is to download the patapon 2 sdk helloworld, which can be found in hbl's svn. Just copy/replace sdk.s with yours, change the text at the very end of main.c to say w/e you want, change the name of the sdk in sdk.h, change the address in linker.x to wherever your binloader loads the h.bin, and compile.
Part 5, porting HBL(This is where the fun comes in ;P):
Okay, first get the source to hbl, create your own folder, call the name something to do with the game(for ex, I called mine sukkiri). Copy/paste linker.x from helloworld, and rename it linker_loader.x, do the same for sdk.s, and rename it to sdk_loader.s. Go to eLoader/tools/imports.config generator, and open up eLoaderconf.rb with your favorite editor. Bascially what you see here are the stubs of each libraries, you can find your own manually, or you can use stubs.rb found in eLoader/tools. To find them manually make a usermem dump (savemem 0x08800000 0x09FFFFFF memdump.bin), and find a library, for example, main, and then 40 bytes after that is the address you want for eLoaderconf.rb. As for # # Relocated message dialog stubs, I changed it because it was having issues, however it should stay the standard (look at other examples in eLoaderconf.rb) if there is no issues relocating the p5 stubs. Use modlist to know which libraries to look for.
Here is an example for sukkiri:
Code: Select all
"sukkiri" => {
"550" =>
[
0x088BE3AC, #main
0x09d03760, #sceNet_Library
0x09CC6230, #sceATRAC3plus_Library
0x0880046C, #sceKernelLibrary
0x09D150B0, #sceNetAdhoc_Library
0x09D1B400, #sceNetAdhocctl_Library
0x09D25700, #sceNetAdhocDownload_Library
0x09D219F0, #sceNetAdhocMatching_Library
0x09D26B3C, #sceNetAdhocDiscover_Library
0x09CD2570, #sceFont_Library
# # Relocated message dialog stubs
0x08EE0000, # scePaf_Module
0x08F00000, # sceVshCommonUtil_Module
0x08F20000, # sceDialogmain_Module
# # Relocated savegame dialog stub
0x08F40000 # sceVshSDAuto_Module
],
"570" =>
[
0x088BE3AC, #main
0x09D039E0, #sceNet_Library
0x09CC6240, #sceATRAC3plus_Library
0x088005BC, #sceKernelLibrary
0x09D150F0, #sceNetAdhoc_Library
0x09D1B500, #sceNetAdhocctl_Library
0x09D26190, #sceNetAdhocDownload_Library
0x09D21CC0, #sceNetAdhocMatching_Library
0x09D2763C, #sceNetAdhocDiscover_Library
0x09CD2570, #sceFont_Library
# # Relocated message dialog stubs
0x08EE0000, # scePaf_Module
0x08F00000, # sceVshCommonUtil_Module
0x08F20000, # sceDialogmain_Module
# # Relocated savegame dialog stub
0x08F40000 # sceVshSDAuto_Module
],
"6xx" =>
[
0x088BE3AC, #main
0x09D03E40, #sceNet_Library
0x09CC6830, #sceATRAC3plus_Library
0x088009A0, #sceKernelLibrary
0x09D150F0, #sceNetAdhoc_Library
0x09D1B570, #sceNetAdhocctl_Library
0x09D26290, #sceNetAdhocDownload_Library
0x09D21E10, #sceNetAdhocMatching_Library
0x09D2773C, #sceNetAdhocDiscover_Library
0x09CD2598, #sceFont_Library
# # Relocated message dialog stubs
0x08EE0000, # scePaf_Module
0x08F00000, # sceVshCommonUtil_Module
0x08F20000, # sceDialogmain_Module
# # Relocated savegame dialog stub
0x08F40000 # sceVshSDAuto_Module
]
},
HBL_LOAD_ADDRESS, this is where hbl is loaded, I did not use wololo's method, we'll get back to this, but if you want to do this now, go ahead and look at wololo's article about porting hbl.
TH_ADD_LIST/EV_ADDR_LIST/SEMA_ADDR_LIST/GAME_FREEMEM_ADDR, to find these make a mem dump, and also type uidlist > uidlist.txt (both have to be from the same booting of the game), and run eLoader/tools/freemem.rb, which will give you everything you need.
Since there are issues relocating the p5 stubs for everybody sukkiri, you will have to change the addresses where they are relocated to:
Code: Select all
#define RELOC_MODULE_ADDR_1 0x08EE0000
#define RELOC_MODULE_ADDR_2 0x08F00000
#define RELOC_MODULE_ADDR_3 0x08F20000
#define RELOC_MODULE_ADDR_4 0x08F40000
Copy/paste linker_loader.x, put any address(we'll replace this with the address we get very soon), and rename it to linker_hbl.x.
Compile and test it(it should crash right after the alloc), in the dbglog it should say "HBL loaded to allocated memory @ 0xXXXXXXXX" get this address and replace it with HBL_LOAD_ADDRESS and with the address in linker_hbl.x, and also undo the edit we did in loader.c
Finally, we are done, if you have any trouble feel free to ask me, thanks to Wololo for making the original tutorials.