Modules

A PSP/PS3/PS Vita ELF is called a module.

A module is distinctive by its fingerprint (a sort of hash) and in most cases its name, but the same module name can be used in both the non-secure kernel and the secure kernel, for instance SceSysmem.

On PS Vita, most modules are loaded by the SceKernelModulemgr module, itself loaded by the NSKBL.

SceModuleInfo
It contains information on the module, and on its imports/exports.

Location

 * For non-stripped modules, SceModuleInfo structure is located in ".sceModuleInfo.rodata" memory block.


 * For ET_SCE_EXEC modules, when e_entry is not null, SceModuleInfo structure is located in text segment at offset e_entry. Else it is located in text segment (first LOAD segment) at offset Elf32_Phdr[text_seg_id].p_paddr - Elf32_Phdr[text_seg_id].p_offset.


 * For ET_SCE_RELEXEC modules, SceModuleInfo structure is located in the segment indexed by the upper two bits of e_entry of the ELF header. The structure is stored at the base offset of the segment plus the offset defined by the bottom 30 bits of e_entry.

Structure
Some fields are optional and can be set to zero. The other fields determine how this module is loaded and linked. All offset fields are formatted as follows: top 2 bits is an index to the segment to start at and bottom 30 bits is an offset from the segment start. Currently, the segment start index must match the segment that the module information structure is in.

Module attribute
The attributes of a module (PSP, PS Vita, ?PS3 to check?). Bitwise OR'ed values from ::SceModuleAttribute and ::SceModulePrivilegeLevel. Since PS Vita SDK 0.940, SceModulePrivilegeLevel are not set anymore and unused in PS Vita OS.


 * Most usermode modules and a few kernel modules have it set to 0.
 * Most kernel modules have it set to 7.
 * Attribute 0x800 was seen in FW 0.902 cui_update_starter_module.self and FW 0.995 debug comicreader.elf. That attribute was set because these ELFs were compiled with an old PS Vita SDK (<= 0.930) that inherited privilege level attributes from the PSP SDK.

Modules imports-exports
Each module contains zero or more library exports and zero or more library imports. An exported library groups together related functions along with their NID and exports it for SceKernelModulemgr to link with a library import in another module.

Exports
An array of export entries defines all the libraries exported by the module.

Structure
Kernel modules that export syscalls (user accessible libraries) also get entries added to the syscall table. The syscall table is randomized on each boot so the same function will likely get a different syscall number assigned each time.

Hash Info
Hash info is a number which depends of the number of exports. It can have values: 0, 2, 4 or 6.

It is related to NID Hash Table, which is still a mystery.

NONAME exports
Old name was "syslib", short name for "system library".

There is a special export entry that always shows up (even when the module exports no libraries) with attribute 0x8000 and NID 0x00000000 that exports the module_start, module_stop, module_exit functions for example.

The NIDs for these exports are common for all modules. See here for NID generation algorithm.

For PS Vita:

For PSP:

Imports
Each module can import any number of libraries from other modules by specifying the library NID to import along with a list of functions/variables NIDs to import. SceKernelModulemgr does the dynamic linking by either jumping to an address if the two modules are in the same privilege level, or making a syscall if it is usermode module importing a library exported by a kernel module. Kernel modules cannot import user libraries.

(Variable/function-address imports)
Variable imports are handled differently from function imports. While the entry in the function import table points to an import thunk, the entry in the variable import table points to a so-called  (probably reference table). If an imported function is used for other purposes than a function call, a  can also be generated for this function.

For example, the following C code verifies if a weakly imported function has been successfully bound to before calling it:

There are two  formats corresponding to the two executable formats supported by the OS.

Prx1 format
Prx1 is the old format of exectuables. These executables use either the standard ELF types  and , or the legacy 0xFFA5  as the value in the ELF header's.

In this format, the  is simply an array of  s terminated by a NULL entry.

Prx2 format
Prx2 is the new format of executables, in use since firmware ?0.940?. These executables use 0xFE00 or 0xFE04  as.

In this format, a 32-bit value is prepended to the table and there are two possible forms for  instead of a single one.

There are two revisions of the  that change the meaning of this 32-bit value (note that the   includes the 32-bit value in it):

Function s
To obtain the pointer to a function's associated, use the following code:

Library attribute
Library attribute flags are ORed together and identified as follows:

Relocations
See for more information on how PS Vita relocations work.

Relocations are stored within the PT_SCE_RELA segment.

There are 10 relocation entry formats. It is determined by r_format (the first 4 bits of the relocation entry).

Warning! In PS Vita FWs <= 3.00, only relocation entry format 0 is available. Using any other relocation entry format gives error 0x8002D019.

Program Authority Id
See also

System Software Version independant usermode system modules
These system usermode modules can be decrypted on any firmware version and are identified by kprx_auth_sm.self by their program-authority-id.

List of Modules
Below is a list of all known Modules in the system along with the lowest version number it was seen on.