Port HBL to your game exploit
Important note: this guide is now somewhat obsolete, and in particular if you plan to port VHBL, I recommend to read the new version of the guide instead. This page is kept for archive purpose.
That’s it. You found a user mode exploit in a game, you were able to write a binary loader, so now what next? Well, as you probably know if you’ve gone that far, the PSP scene doesn’t really like “hello worlds”. A hello world is nice, but it accomplishes nothing, it just draws Sony’s attention to your exploit, and you know the vulnerability will be patched soon, while nobody really used the exploit.
Well, the next step is, ideally, a HEN or a custom firmware. Of course, this requires a kernel exploit, and we know how these are difficult to find. A much more doable task, that will make lots of people happy, is to port HBL to your exploit. HBL opens the door to lots of legal contents on unhackable PSPs, and we designed it so that porting it to your game exploit can be done fairly easily.
This tutorial is valid at the time of its writing, for all games, and up to firmware 6.31. In theory, HBL will work on future firmwares, but of course new kinds of security might be introduced in new firmwares. Additionally, depending on your game, the quality of syscall estimations (and therefore, the compatibility and speed of homebrews) might vary.
0. Easy as pie
HBL was designed to be easily ported to new game exploits. Most Game-specific files (except one) go in a subfolder that I will describe below. To complete this tutorial, you need basic shell skills, a working pspsdk, a working game exploit and the associated binary loader / hello world, a ruby interpreter, and basic ruby skills (usually, if you know any other scripting language, you’ll figure it out easily, there are not so many changes required).
1. Get the HBL sources and compile them
The first step is to get the HBL sources, compile them, and if you’re motivated, test them on an existing game exploit, to make sure the copy you have works correctly.
The sources of HBL can be downloaded here (SVN client required)
In order to compile it, you need the PSPSDK (which you probably already have if you wrote a binary loader). Compilation is fairly easy, but in order to compile the HBL for a specific exploit, you have to specify the folder of the exploit. for example, make FOLDER=hotshots will compile HBL for the hot shots golf (US) exploit. At the time of this writing, 4 such folders exist: minna, patapon2, hotshots, everybody.
2. Create your own exploit’s folder
As you guessed, you will create a folder dedicated to your own exploit. Let’s imagine you game is called wololo, then you can create a subfolder “wololo” in the eLoader folder. Basically, we want to reproduce the files that are in this folder for another exploit, and adapt them to our exploit. Let’s have a look at the patapon2 folder:
The folder contains 6 files and 2 folders, that you will want to adapt to your exploit. I will describe each of them separately (almost)
3. Create your exploit’s files
You don’t really need that folder, but you might want to create tools for your exploit, such as a memory dumper. you can put these tools in this folder.
This is the linker file for h.bin. If you created a binary loader and a hello world, you already have this file from your hello world, and most likely you named it “linker.x”. Copy linker.x from your hello world to linker_loader.x. Done!
This is the sdk for h.bin. If you created a binary loader and a hello world, you probably already have this file, and named it sdk.S. Copy sdk.s to sdk_loader.S. If you don’t have this sdk, you can create it either by running prxtool on the EBOOT.BIN of the game, or by using the moskitool (a ruby version of the moskitool can be found in the eLoader/tools folder of the HBL). Most likely, if you created a hello world, you already have this file so I won’t give more details for now. Done!
config folder, and sdk_hbl.S
create an empty config folder, it is needed afterwards. The contents of this folder, as well as sdk_hbl.S, are automatically generated by a ruby script that you can find in eLoader/tools/imports.config generator/eLoaderconf.rb. Just edit this script with your favorite text editor to see what’s going on there.
We basically have a hash for each exploit, which tells HBL where to find interesting stubs. The theory on how to find these stubs can be found on our /talk forums, but we also happen to have a ruby script that does it for you. That ruby script is eLoader/tools/stubs.rb. You need to have a usermem dump (that you can get either from psplink on a hacked psp, or by running a usermem dumper with your newly found exploit) and name it memdump.bin before you run the file stubs.rb. You need to get one user mem dump per firmware you want to support, so you might need help from other hackers or beta testers to get those.
To know which libraries to get stubs from, you can run “modlist” in psplink. The most important one is the one from your game. it is usually called “main”, but the name can vary. For patapon2, it was called “Labo”.
So, basically, run “stubs.rb” on your memory dump, and this will give you the addresses you need for your firmware. Do that again for as many firmwares as needed, and copy/paste the results accordingly in eLoaderconf.rb
This is the meat of the changes, the part that requires the most work. This include file defines a bunch of exploit-specific variables that will be integrated into HBL when you compile it.
HBL_LOAD_ADDRESS This is where you will load HBL in RAM. You want a value that is outside of the boundaries of the game, and basically, a place where the PSP will accept to alloc roughly 200kB. You can get this value by creating a small h.bin that will just try to alloc 200kB without specifying any address, then retrieve the address created this way:
u32 uid = sceKernelAllocPartitionMemory(2, “test”, PSP_SMEM_Low, size, NULL);
u32 addr = sceKernelGetBlockHeadAddr(uid);
//then log addr in a debug file or something, this is what you’ll use for HBL_LOAD_ADDRESS
TH_ADDR_LIST, EV_ADDR_LIST, SEMA_ADDR_LIST, and GAME_FREEMEM_ADDR can be computed for you by the tool eLoader/tools/freemem.rb. For that you will need a memory dump and a file uidlist.txt which is the output of the uidlist command in psplink (uidlist > uidlist.txt ). It is important to note that the memory dump and the uidlist need to be from the same session, otherwise the addresses will be incorrect. If you’re on windows, also make sure that the uidlist.txt file is in the unix format (use your favorite editor to convert it if needed). For those interested, here are some technical details about those variables, but basically the tool should do it for you
TH_ADDR_LIST, is the list of threads you want to kill. Threads are defined by a SceUID, but since this value changes all the time, what we actually want is the addresses where they are defined. in psplink, while your game (or your hello world) is running, you can get a list of these thread by typing thlist. Then look for each thread’s uid in ram. The address (hopefully unique) where the thid is defined, is what you want to put in this list.
EV_ADDR_LIST is the list of events you want to kill. You get this list by typing evlist in psplink. The rest is similar to the construction of TH_ADDR_LIST
SEMA_ADDR_LIST is the list of semaphores you want to kill. You get this list by typing smlist in psplink. The rest is similar to the construction of TH_ADDR_LIST above
GAME_FREEMEM_ADDR this is the address in Ram where the game’s memory was allocated. Most game have this but for those that don’t have it (patapon2), this value can be commented out. To find this value, type uidlist” PSPLink and look under the SceSysMemMemoryBlock section. You’re looking for blocks that have a 0xFF (user) attribute (not 0x00!), and are not “stack”. In the golf exploit, this block was simply called “block” and was easy to find. Again, you’re interested in the entry address, not the uid.
UNLOAD_ADDITIONAL_MODULES : define this variable if possible. Comment it out only if you run into issues at the “free memory” stage of HBL
Other variables: The variables above are the basics of the config file. With those, HBL should basically work, or at least take you to a step where you can start debugging. But with time, HBL has grown and has been updated by several people. In order to maintain backwards compatibility and increase game coverage, the exploit_config file was added several config values. DISABLE_P5_STUBS is useful if you run into a crash/freeze even before hbl is loaded (just after firmware detection). SYSCALL_* are used for perfect syscall estimation on firmwares where this is available (TODO: explain syscalls estimation), etc… at this point you will probably need to dig in previous exploit_config.h files in order to find more on each macro you can possibly define.
copy linker_loader.x into linker_hbl.x, and replace the address value with the value of HBL_LOAD_ADDRESS that you figured out earlier while creating exploit_config.h. Done.
- run eLoaderconf.rb to generate the sdk and the config files. This will generate config files for ALL exploits defined in eLoaderconf.rb, including yours. (Be sure to have created a “config” subfolder in your exploit’s specific folder)
- run make FOLDER=yourfolder
- You’re done, grab the h.bin and hbl.bin in the root, the config folder from your exploit’s folder, and the libs_… folders from the root. You now have the meat of your HBL port ready.
5. Last but not least
HBL is licensed under the GPL. If you plan to distribute your compiled binaries, it is required that you provide your source code as well. Don’t make us ask for it
This tutorial is voluntarily vague. Porting HBL is fairly easy, but we assume that if you made it that far, you probably are skilled enough to do some research on your own. Nevertheless, don’t hesitate to ask questions if you are running into problems
You are allowed to reproduce this article on other websites and/or translate it on condition that you put a clear link to this page in your copy.
Living outside of the US? Check our technique to buy US PSN Codes at face value and get them instantly