Since I'm stuck with fever at home and have nothing better to do, I'll start this topic about how HBL works. I'll be referencing latest revision at this time, r116. You can browse the code online here.

NOTE: this is not a C course, so please do not ask C-specific questions. Those can be answered in any decent C book.

First of all, HBL is not a normal homebrew. Since it was aimed to be run through a game exploit, it's designed to be compiled as a plain binary (hbl.bin). It's not an ELF and thus it's not a PRX. Not an EBOOT either. HBL is injected into memory when loading the exploit, ends up in main memory and finally gets executing. Since HBL is way too big to fit inside an exploit, we choose to do a double loading scheme: first the exploit loads a loader which in turn loads HBL in memory. I'll take a tour into HBL's loader in this chapter.

The HBL loader is mainly the file loader.c. Let's take a walk through it. The loader entry point is

So here we first open the HBL binary (hbl.bin) which path defined by the HBL_PATH macro. If we take a look at that macro, we'll find that it actually maps to ms0:/hbl/hbl.bin. So if this file opening succeeds, next we need to load it, which is what load_hbl function performs.

I'm going to explain this line since it happens a lot in HBL. The HBL global variables are stored on the scratchpad (a small 4 KiB RAM). load_hbl is going to store some values there so they can be used later by HBL. Then we get HBL file size, we allocate memory with that size and then this line:

Gets the allocated memory starting address. Keep in mind that sceKernelAllocPartitionMemory does not return a pointer (= memory address) but an SceUID (an 32-bits ID used by the kernel to identify system objects). Then we assign that address to run_eloader, which in fact is a pointer to a function. This function is called later to run HBL. This works because HBL's entry point is put at the start of the binary file, which is the same we did with the loader's entry point (void _start() __attribute__ ((section (".text.start")))).

The rest of the function is pretty well commented and self-explanatory. So when load_hbl ends executing, it's copy_hbl_stubs that comes next. This function resolves HBL imports. And what does this mean? It means it has to prepare HBL so it can execute system calls such as sceWhatever. When loaded HBL will not know where to find such calls, and the loader has to prepare it with a minimum so it can work on its own.

copy_hbl_stubs accesses a configuration file that stores information about HBL's imports, and where you can find the exploited game's stubs (system calls) among other stuff. You can easily follow the function since with all the comments and debugs it's self-explanatory. It first reads the location of the exploited game's stubs and compare them to HBL's stubs. If they match, the address of that stub is stored. Then it writes the resolved stubs to HBL's stubs (which are also stored into the scratchpad).

When copy_hbl_stubs ends run_eloader is next. As we saw before this transfers control to the hbl.bin file which starts HBL execution.

So this is all for now, hope you find it interesting. Any questions are welcome. On the next one I'll begin with the HBL proper.

Thanks. Despite working a lot on HBL, I feel it's very nice to remember how it works with a clear explanation rather than looking directly at the code.
Easy to understand and very detailed tutorial as usual, looking forward to the next one