SceKernelModulemgr: Difference between revisions
CelesteBlue (talk | contribs) |
|||
(420 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
SceKernelModulemgr is in charge of loading both user modules and kernel modules. [[SceSblAuthMgr]] | SceKernelModulemgr is in charge of loading both user modules and kernel modules. SceKernelModulemgr calls [[SceSblAuthMgr]] functions for the SELF decryption process. SceKernelModulemgr loads the ELF programs into memory along with linking with NIDs and relocation of ELF in position independent executables. | ||
== Module == | == Module == | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version | ! Version !! World !! Privilege | ||
|- | |- | ||
| | | 0.940-3.60 || Non-secure || Kernel | ||
|} | |} | ||
The SELF can be found in <code> os0:kd/modulemgr.skprx</code>. | |||
Functions of this module are also embedded in NSKBL. | |||
== Libraries == | == Libraries == | ||
This module exports kernel and user libraries. | This module exports kernel and user libraries. | ||
Line 26: | Line 23: | ||
! Version !! Name !! World !! Visibility !! NID | ! Version !! Name !! World !! Visibility !! NID | ||
|- | |- | ||
| | | 0.940-3.61 || [[SceKernelModulemgr#SceModulemgrForKernel|SceModulemgrForKernel]] || Non-secure || Kernel || 0xC445FA63 | ||
|- | |- | ||
| 3.65 || [[SceKernelModulemgr#SceModulemgrForKernel|SceModulemgrForKernel]] || Non-secure || Kernel || 0x92C9FFC2 | | 3.63-3.65 || [[SceKernelModulemgr#SceModulemgrForKernel|SceModulemgrForKernel]] || Non-secure || Kernel || 0x92C9FFC2 | ||
|- | |- | ||
| | | 0.940-3.65 || [[SceKernelModulemgr#SceModulemgrForDriver|SceModulemgrForDriver]] || Non-secure || Kernel || 0xD4A60A52 | ||
|- | |- | ||
| | | 0.940-3.65 || [[SceKernelModulemgr#SceModulemgr|SceModulemgr]] || Non-secure || User || 0xEAED1616 | ||
|- | |- | ||
| 3.57-3. | | 3.57-3.65 || [[SceKernelModulemgr#SceBacktraceForDriver|SceBacktraceForDriver]] || Non-secure || Kernel || 0x77CB3DD6 | ||
|- | |- | ||
| 3.57-3. | | 3.57-3.65 || [[SceKernelModulemgr#SceBacktrace|SceBacktrace]] || Non-secure || User || 0xB07B6A3F | ||
|} | |} | ||
== Types == | == Internal Types == | ||
<source lang = "C"> | <source lang="C"> | ||
// These types are defined in elfutils | |||
// | |||
typedef Elf32_Ehdr Elf32_Ehdr; | typedef Elf32_Ehdr Elf32_Ehdr; | ||
typedef Elf32_Phdr Elf32_Phdr; | typedef Elf32_Phdr Elf32_Phdr; | ||
typedef struct SCE_header | typedef struct SCE_header { | ||
{ | |||
uint32_t magic; /* 53434500 = SCE\0 */ | uint32_t magic; /* 53434500 = SCE\0 */ | ||
uint32_t version; /* header version 3*/ | uint32_t version; /* header version 3*/ | ||
Line 70: | Line 65: | ||
} SCE_header; | } SCE_header; | ||
typedef struct SCE_appinfo | typedef struct SCE_appinfo { | ||
{ | uint64_t program_authority_id; /* program authority id */ | ||
uint64_t program_authority_id; | |||
uint32_t vendor_id; /* vendor id */ | uint32_t vendor_id; /* vendor id */ | ||
uint32_t self_type; /* app type */ | uint32_t self_type; /* app type */ | ||
Line 79: | Line 73: | ||
} SCE_appinfo; | } SCE_appinfo; | ||
typedef struct segment_info | typedef struct segment_info { | ||
{ | |||
uint64_t offset; | uint64_t offset; | ||
uint64_t length; | uint64_t length; | ||
Line 87: | Line 80: | ||
} segment_info; | } segment_info; | ||
typedef struct self_data_buffer | typedef struct self_data_buffer { | ||
{ | |||
SCE_header sce_header; | SCE_header sce_header; | ||
SCE_appinfo sce_appinfo; | SCE_appinfo sce_appinfo; | ||
Line 97: | Line 89: | ||
} self_data_buffer; | } self_data_buffer; | ||
typedef struct | typedef struct SceDecryptCtx { //size is 0x30 | ||
self_data_buffer* self_header; // aligned buffer - based on (buffer_unaligned). | self_data_buffer* self_header; // aligned buffer - based on (buffer_unaligned). | ||
// points at SCE_header followed by SCE_appinfo | // points at SCE_header followed by SCE_appinfo | ||
// size is usually 0x1000 | // size is usually 0x1000 | ||
int self_header_length; | |||
Elf32_Ehdr* elf_ptr; // pointer constructed with elf_offset | Elf32_Ehdr* elf_ptr; // pointer constructed with elf_offset | ||
Elf32_Phdr* phdr_ptr; // pointer constructed with phdr_offset | Elf32_Phdr* phdr_ptr; // pointer constructed with phdr_offset | ||
Line 113: | Line 104: | ||
segment_info* section_info_ptr; // pointer constructed with section_info_offset | segment_info* section_info_ptr; // pointer constructed with section_info_offset | ||
void* buffer_unaligned; // SELF header data - size 0x103F - raw data read from file | void* buffer_unaligned; // SELF header data - size 0x103F - raw data read from file | ||
int sm_ctx; // obtained with | int sm_ctx; // obtained with sceSblAuthMgrOpenForKernel | ||
SceSblSmCommContext130* context_130; | SceSblSmCommContext130* context_130; | ||
Line 119: | Line 110: | ||
SceUID pid; | SceUID pid; | ||
uint32_t max_size; | uint32_t max_size; | ||
} | } SceDecryptCtx; | ||
typedef struct SceDecryptCtxGlobal { // size is 0x4C | |||
uint32_t unk_0; | |||
uint32_t unk_4; // ex:3 | |||
void *module_decrypt_buff_ptr1; | |||
int decrypt_size; // max 0x10000 | |||
int unk_10; // 0 or 1 or 2 | |||
int unk_14; // ex:-1 | |||
void *module_decrypt_buff_ptr2; | |||
int unk_1C; // some size | |||
SceDecryptCtx *decrypt_ctx; | |||
SceUID evid; // SceModuleMgrSelfDecryptComm event flag | |||
SceUID tid; // SceModuleMgrSelfDecrypter thread uid | |||
void *unk_2C; // sceDeflateDecompressPartialForDriver out memblock | |||
int compressed_seg_size; | |||
uint32_t unk_34; // unk_2C out size? | |||
uint16_t segment_number; | |||
uint16_t unk_3A; // ex:0xFFFF | |||
SceDeflatePartialInputParam cbinfo; | |||
} SceDecryptCtxGlobal; | |||
typedef struct SceModuleLinkInfo { // size is 0x48-bytes | |||
struct { | |||
ScePVoid WorkPool; | |||
SceNID *FunctionNID; // in target module | |||
ScePVoid *ImportTable; // in target module | |||
SceNID *VariableNID; // in target module | |||
ScePVoid *RelocaTable; // in target module | |||
SceSize to_link_entry_number; | |||
SceSize to_link_entry_number_for_var; | |||
SceModuleClient *Client; | |||
} i; | |||
struct { | |||
ScePVoid WorkPool; | |||
void *data_0x24; // export func pointer list | |||
int data_0x28; | |||
void *data_0x2C; // export func pointer list? | |||
int data_0x30; | |||
SceSize export_entry_number; | |||
SceSize export_entry_number_for_var; | |||
void *data_0x3C; // export nid list | |||
void *data_0x40; // same to data_0x24? | |||
SceModuleLibEnt *LibEnt; | |||
} e; | |||
} SceModuleLinkInfo; | |||
typedef struct SceModuleLoadCtx { // size is 0x44 | |||
SceModuleCB *Module; | |||
int data_0x04; | |||
int data_0x08; | |||
int data_0x0C; | |||
int data_0x10; | |||
int data_0x14; | |||
int data_0x18; | |||
int data_0x1C; | |||
struct { | |||
SceUIntPtr base; // from elf header | |||
SceUID data_0x24; | |||
void *pKernelMap; | |||
} segments[3]; | |||
} SceModuleLoadCtx; | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_LIBC (0x10000) | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_LIBDBG (0x20000) | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_LIBSHELLSVC (0x80000) | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_LIBCDLG (0x100000) | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_LIBFIOS2 (0x200000) | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_APPUTIL (0x400000) | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_LIBSCEFT2 (0x800000) | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_LIBPVF (0x1000000) | |||
#define SCE_KERNEL_PRELOAD_INHIBIT_LIBPERF (0x2000000) | |||
// used by sceKernelLoadPreloadingModules | |||
typedef struct SceKernelPreloadModuleInfo { // size is 0x24 | |||
const char *module_name; | |||
const char *path[6]; | |||
SceUInt32 inhibit; | |||
int flags; | |||
} SceKernelPreloadModuleInfo; | |||
</source> | |||
== Types == | |||
<source lang="C"> | |||
typedef struct SceKernelSystemSwVersion { // size is 0x28 on FW 0.990.030 | |||
SceSize size; // Size of this structure | |||
char versionString[0x1C]; | |||
SceUInt version; | |||
SceUInt unk_24; | |||
} SceKernelSystemSwVersion; | |||
typedef struct SceKernelSegmentInfo { | |||
SceUInt size; //!< this structure size (0x18) | |||
SceUInt perms; //!< probably rwx in low bits | |||
void *vaddr; //!< address in memory | |||
SceUInt memsz; //!< size in memory | |||
SceUInt flags; //!< meaning unknown | |||
SceUInt res; //!< unused? | |||
} SceKernelSegmentInfo; | |||
typedef struct SceKernelModuleName { | |||
char s[0x1C]; | |||
} SceKernelModuleName; | |||
typedef struct SceKernelModuleInfo { // size is 0x1B8 | |||
SceSize size; //!< sizeof(SceKernelModuleInfo) | |||
SceUID modid; | |||
uint16_t modattr; | |||
uint8_t modver[2]; | |||
char name[0x1C]; | |||
uint32_t unk28; | |||
void *start_entry; | |||
void *stop_entry; | |||
void *exit_entry; | |||
void *exidx_start; | |||
void *exidx_end; | |||
void *extab_start; | |||
void *extab_end; | |||
void *tls_start; | |||
SceSize tls_filesz; | |||
SceSize tls_memsz; | |||
char path[256]; | |||
SceKernelSegmentInfo segments[4]; | |||
SceUInt type; | |||
} SceKernelModuleInfo; | |||
typedef struct SceKernelSegmentInfo2 { // size is 0x14 | |||
SceSize size; // Size of this structure | |||
SceUInt32 perm; | |||
void *pVA; | |||
SceSize memsz; | |||
SceUInt32 alignment; | |||
} SceKernelSegmentInfo2; | |||
// Structure for SceCoredump only? | |||
typedef struct SceKernelModuleListInfo_0945 { | |||
SceSize size; | |||
SceUID modId; | |||
SceUInt8 sdkVer[4]; | |||
SceUInt8 modVer[4]; | |||
SceUInt16 type; | |||
SceUInt16 flags; | |||
void *start; | |||
SceUInt32 refCount; | |||
void *stop; | |||
void *exit; | |||
char modName[0x20]; | |||
SceUInt32 status; | |||
SceUInt32 dbgFingerprint; | |||
int segments_num; | |||
union { | |||
struct { | |||
SceKernelSegmentInfo2 SegmentInfo[1]; | |||
uint32_t addr[4]; | |||
} seg1; | |||
struct { | |||
SceKernelSegmentInfo2 SegmentInfo[2]; | |||
uint32_t addr[4]; | |||
} seg2; | |||
struct { | |||
SceKernelSegmentInfo2 SegmentInfo[3]; | |||
uint32_t addr[4]; | |||
} seg3; | |||
struct { | |||
SceKernelSegmentInfo2 SegmentInfo[4]; | |||
uint32_t addr[4]; | |||
} seg4; | |||
}; | |||
} SceKernelModuleListInfo_0945; | |||
typedef struct SceKernelModuleListInfo_360 { | |||
SceSize size; | |||
SceUID modId; | |||
SceUInt8 sdkVer[4]; | |||
SceUInt8 modVer[4]; | |||
SceUInt16 type; | |||
SceUInt16 flags; | |||
void *start; | |||
void *unk_0x18; // maybe bootstart, but user module is doesn't have module_bootstart. | |||
void *stop; | |||
void *exit; | |||
char modName[0x1A]; | |||
SceUInt16 unk_0x3A; // unused | |||
SceUInt32 unk_0x3C; // unused | |||
SceUInt32 unk_0x40; // unused | |||
SceUInt32 status; | |||
SceUInt32 dbgFingerprint; | |||
int segments_num; | |||
union { | |||
struct { | |||
SceKernelSegmentInfo2 SegmentInfo[1]; | |||
uint32_t addr[4]; | |||
} seg1; | |||
struct { | |||
SceKernelSegmentInfo2 SegmentInfo[2]; | |||
uint32_t addr[4]; | |||
} seg2; | |||
struct { | |||
SceKernelSegmentInfo2 SegmentInfo[3]; | |||
uint32_t addr[4]; | |||
} seg3; | |||
struct { | |||
SceKernelSegmentInfo2 SegmentInfo[4]; | |||
uint32_t addr[4]; | |||
} seg4; | |||
}; | |||
} SceKernelModuleListInfo_360; | |||
typedef struct SceKernelLibraryInfo { // size is 0x1C | |||
SceSize size; //!< sizeof(SceKernelLibraryInfo) | |||
uint16_t libver[2]; | |||
uint32_t libnid; | |||
const char *libname; | |||
uint16_t nfunc; | |||
uint16_t nvar; | |||
uint32_t *nid_table; | |||
uint32_t *entry_table; | |||
} SceKernelLibraryInfo; | |||
typedef struct SceKernelModuleExportEntry { | |||
uint32_t libnid; | |||
const void *entry; // function ptr. or vars? | |||
} SceKernelModuleExportEntry; | |||
typedef struct { | |||
SceUID modid; | |||
uint32_t libnid; | |||
} SceKernelModuleImportNID; | |||
typedef struct SceKernelModuleImportNonlinkedInfo { | |||
SceSize size; // 0x124 | |||
SceUID modid; | |||
uint32_t libnid; | |||
char libname[0x100]; | |||
uint32_t data_0x10C; | |||
uint32_t data_0x110; | |||
uint32_t data_0x114; | |||
uint32_t data_0x118; | |||
uint32_t data_0x11C; | |||
uint32_t data_0x120; | |||
} SceKernelModuleImportNonlinkedInfo; | |||
typedef struct SceKernelModuleLibraryInfo { | |||
SceSize size; //!< sizeof(SceKernelModuleLibraryInfo) : 0x120 | |||
SceUID library_id; | |||
uint32_t libnid; | |||
uint16_t libver[2]; | |||
uint16_t entry_num_function; | |||
uint16_t entry_num_variable; | |||
uint16_t unk_0x14; | |||
uint16_t unk_0x16; | |||
char library_name[0x100]; // offset : 0x18 | |||
uint32_t unk_0x118; | |||
SceUID modid2; | |||
} SceKernelModuleLibraryInfo; | |||
typedef struct SceSelfAppInfo { | |||
int vendor_id; | |||
int self_type; | |||
} SceSelfAppInfo; | |||
typedef int (* SceKernelModuleEntry)(SceSize args, void *argp); | |||
/** | |||
* Module common macro | |||
*/ | |||
#define SCE_KERNEL_START_SUCCESS (0) /**< Successful startup */ | |||
#define SCE_KERNEL_START_RESIDENT SCE_KERNEL_START_SUCCESS /**< Successful startup (resident) */ | |||
#define SCE_KERNEL_START_NO_RESIDENT (1) /**< Successful startup (not resident) */ | |||
#define SCE_KERNEL_START_FAILED (2) /**< Failed to start */ | |||
#define SCE_KERNEL_STOP_SUCCESS (0) /**< Successful stop */ | |||
#define SCE_KERNEL_STOP_FAIL (1) /**< Failed to stop */ | |||
#define SCE_KERNEL_STOP_CANCEL SCE_KERNEL_STOP_FAIL /**< Stop was cancelled */ | |||
/** Module attributes */ | |||
#define SCE_MODULE_ATTR_NONE (0x0000) /**< No attributes specified */ | |||
/** obsolete */ | |||
#define SCE_KERNEL_MODULE_ATTR_NONE SCE_MODULE_ATTR_NONE | |||
/** | |||
* option parameter for load module APIs | |||
*/ | |||
typedef struct SceKernelLoadModuleOpt { | |||
SceSize size; /**< Size of structure itself */ | |||
} SceKernelLoadModuleOpt; | |||
/** | |||
* option parameter for start module API | |||
*/ | |||
typedef struct SceKernelStartModuleOpt { | |||
SceSize size; /**< size of structure itself */ | |||
SceUInt32 flags; /**< should be 0 */ | |||
SceUInt32 prologue; /**< should be 0 */ | |||
SceUInt32 start; /**< should be 0 */ | |||
} SceKernelStartModuleOpt; | |||
/** | |||
* option parameter for stop module API | |||
*/ | |||
typedef struct SceKernelStopModuleOpt { | |||
SceSize size; /**< size of structure itself */ | |||
SceUInt32 flags; /**< should be 0 */ | |||
SceUInt32 epilogue; /**< should be 0 */ | |||
SceUInt32 stop; /**< should be 0 */ | |||
} SceKernelStopModuleOpt; | |||
/** | |||
* option parameter for unload module APIs | |||
*/ | |||
typedef struct SceKernelUnloadModuleOpt { | |||
SceSize size; /**< size of structure itself */ | |||
} SceKernelUnloadModuleOpt; | |||
typedef struct SceLoadProcessParam { // size is 0x7C-bytes | |||
SceUInt32 sysver; | |||
char thread_name[0x20]; | |||
SceUInt32 initial_thread_priority; // ex: 0x100000EC | |||
SceSize initial_thread_stack_size; // ex: 0x6000 | |||
SceUInt32 unk_0x2C; | |||
SceUInt32 unk_0x30; | |||
SceKernelThreadOptParam threadOptParam; | |||
int unk_0x50; | |||
char process_name[0x20]; // not titleid | |||
SceUInt32 preload_disabled; | |||
void *module_proc_param; | |||
} SceLoadProcessParam; | |||
typedef struct SceModuleLibraryInfo { // size is 0x2C | |||
struct SceModuleLibraryInfo *next; | |||
struct SceModuleLibraryInfo *data_0x04; // maybe | |||
SceModuleExport *pExportInfo; | |||
/* | |||
* (syscall_idx & 0xFFF): syscall idx | |||
* (syscall_idx & 0x1000): has syscall flag? | |||
* (syscall_idx == 0): kernel export | |||
*/ | |||
uint16_t syscall_info; | |||
uint16_t data_0x0E; | |||
/* | |||
* Number of times this export was imported into another module | |||
*/ | |||
SceSize number_of_imported; | |||
SceModuleImportedInfo *pImportedInfo; | |||
SceUID libid_kernel; | |||
SceUID libid_user; | |||
SceModuleCB *pModCB; // Temp structure name was SceModuleInfoInternal | |||
int data_0x24; // zero? | |||
int data_0x28; // zero? | |||
} SceModuleLibraryInfo; | |||
typedef struct SceKernelModuleNonlinkedInfo { | |||
SceUID modid; | |||
uint32_t libnid; | |||
} SceKernelModuleNonlinkedInfo; | |||
#define SCE_KERNEL_BACKTRACE_CONTEXT_CURRENT (0x00000000) /**< Backtrace current context */ | |||
#define SCE_KERNEL_BACKTRACE_MODE_USER (0x00000000) /**< User stack backtrace */ | |||
#define SCE_KERNEL_BACKTRACE_MODE_KERNEL (0x00000001) | |||
#define SCE_KERNEL_BACKTRACE_MODE_DONT_EXCEED (0x00000002) /**< Don't get stack depth */ | |||
#define SCE_KERNEL_BACKTRACE_MODE_UNK_0x00000004 (0x00000004) // should exist because 8 exists | |||
#define SCE_KERNEL_BACKTRACE_MODE_UNK_0x00000008 (0x00000008) // exists based on FW 0.931 SceExcpmgr | |||
/** | |||
* Structure that represents one stage of the call stack | |||
*/ | |||
typedef struct _SceKernelCallFrame { | |||
SceUIntVAddr sp; /**< stack pointer */ | |||
SceUIntVAddr pc; /**< program counter */ | |||
} SceKernelCallFrame; | |||
/** | |||
* Structures used for compatibility shim lists (hardcoded in SceProcessmgr) | |||
*/ | |||
typedef struct _SceKernelFunctionShimInfo { | |||
SceUInt32 replaced_function_nid; /**< NID of the function that needs to be replaced */ | |||
SceUInt32 replacing_function_nid; /**< NID of the function that will serve as a replacement - must probably come from same library as replaced function */ | |||
} SceKernelFunctionShimInfo; | |||
typedef struct _SceKernelLibraryShimInfo { | |||
const char *library_name; /**< Name of the library the shimmed functions come from (i.e. SceThreadmgr) */ | |||
SceUInt32 unk_04; /**< Always 0 ? */ | |||
SceUInt32 function_shims_count; /**< Size of the array pointed to by next field */ | |||
SceKernelFunctionShimInfo* function_shims; | |||
} SceKernelLibraryShimInfo; | |||
typedef struct _SceKernelCompatibilityShimInfo { | |||
const char *title_id; /**< TitleID (process name) of the app this shim applies to */ | |||
SceUInt32 unk_04; /**< Always 0 ? */ | |||
SceUInt32 library_shims_count; /**< Size of the array pointed to by next field */ | |||
SceKernelLibraryShimInfo *library_shims; | |||
} SceKernelCompatibilityShimInfo; | |||
</source> | |||
== Notes == | |||
=== Error codes === | |||
==== 0x8002D018 ==== | |||
The shared module is not importable be non-shared module and non-syscall. | |||
==== 0x8002D01E ==== | |||
Attempted to load a module with a start entry as bootfs. | |||
Attempted to load a module that has syscall exports to usermode. | |||
=== module_start no resident/failed === | |||
If module_start returns SCE_KERNEL_START_NO_RESIDENT, the module will start successfully, but it will be unloaded after the module_start call. | |||
However, if the module_start of the module where the syscall export exists is called after boot and returns SCE_KERNEL_START_NO_RESIDENT/SCE_KERNEL_START_FAILED, then a kernel panic is triggered. | |||
=== How to get module info === | |||
modid and SceUIDModuleClass are required to get module information. | |||
Simply call sceGUIDReferObjectForDriver(sceKernelGetObjectForUidForDriver) with these parameters. | |||
=== Module decrypt threads === | |||
SceKernelModulemgr_func_8100910D | |||
This thread keeps waiting at sceKernelWaitEventFlagForDriver until a module decrypt request comes. | |||
bits of sceKernelWaitEventFlagForDriver is 3. | |||
=== Common functions === | |||
Decrypt module to membase with current ctx. | |||
<source lang="c">int SceKernelModulemgr_func_81009309(SceDecryptCtx *ctx, int seg_idx, void *membase, int arg4);</source> | |||
Called whenever a module is loaded. | |||
<source lang="c"> | |||
flags | |||
process image : 0x4 | |||
normal module : 0x1000 | |||
process module shared : 0x8001 | |||
process module : 0x8002 | |||
homebrew plugin : 0x8000002 | |||
shared module : 0x8008001 | |||
normal module ? : 0x8008002 | |||
int SceKernelModulemgr_func_81001519(void *pInfo, const char *path, SceUID fd, void *a4, uint32_t flags); | |||
</source> | |||
Reads the header from the passed fd and performs some checks. | |||
<source lang="c"> | |||
[out] ctx | |||
[in] pid | |||
[in] fd | |||
[in] context_130 | |||
int SceKernelModulemgr_func_81008DC9(void *ctx, SceUID pid, SceUID fd, void *context_130); | |||
</source> | </source> | ||
== Data segment layout == | == Data segment layout == | ||
Offsets are for FW 3.60. | |||
Data section size is 0x203C0. | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! | ! Offset !! Size !! Description | ||
|- | |||
| 0x0000 || 0x30 || unknown | |||
|- | |||
| 0x0030 || 0x4 || some flags. Related to relocation. | |||
|- | |||
| 0x0034 || 0x4 || SceKernelSystemSwVersion data initialized flag | |||
|- | |||
| 0x0038 || 0x4 || pointer of ModulePrivate(9). | |||
|- | |||
| 0x003C || 0x4 || pointer of SceClass. The third class obtained with sceKernelSysrootGetModulePrivateForKernel. SceUIDLibStubClass | |||
|- | |||
| 0x0040 || 0x4 || pointer of SceClass. The second class obtained with sceKernelSysrootGetModulePrivateForKernel. SceUIDLibraryClass | |||
|- | |||
| 0x0044 || 0x4 || Return value of SceThreadmgrForDriver_B645C7EF. | |||
|- | |||
| 0x0048 || 0x4 || pointer of SceClass. The first class obtained with sceKernelSysrootGetModulePrivateForKernel. SceUIDModuleClass | |||
|- | |||
| 0x004C || 0x4 || SceModuleMgr Mutex uid | |||
|- | |||
| 0x0050 || 0x280 (4*0xA0) || unknown. some module data. (process max loadable module number is 0xA0) | |||
|- | |||
| 0x02D0 || 0x28 || SceKernelSystemSwVersion buffer | |||
|- | |||
| 0x02F8 || 0x4 || some thread id, check sceKernelModuleUnloadMySelfForKernel | |||
|- | |||
| 0x02FC || 0x4 || some kernel module uid, check sceKernelModuleUnloadMySelfForKernel | |||
|- | |||
| 0x0300 || 0x4 || unk, used by sceKernelLoadPreloadingModulesForKernel | |||
|- | |||
| 0x0304 || 0x4 || some storage ptr. used by sceKernelMountBootfsForKernel, sceKernelUmountBootfsForKernel | |||
|- | |||
| 0x0308 || 0x4 || pModuleEventDebugHandler | |||
|- | |||
| 0x030C || 0x4 || pointer of SceModuleSharedInfo. | |||
|- | |||
| 0x0310 || 0x4 || cpu_addr out (sceKernelCpuLockSuspendIntrStoreLRForDriver arg1) | |||
|- | |||
| 0x0314 || 0x4 || shared inhibit flag | |||
|- | |||
| 0x0318 || 0x4 || sceKernelGetMemBlockBaseForDriver membase out | |||
|- | |||
| 0x031C || 0x4 || sceKernelAllocMemBlockForDriver ret | |||
|- | |||
| 0x0320 || 0xC || unk | |||
|- | |||
| 0x032C || 0x4 || unk, used by SceModulemgrForKernel_F3CD647F | |||
|- | |||
| 0x0330 || 0x4 || unk, used by SceModulemgrForKernel_F3CD647F | |||
|- | |||
| 0x0334 || 0x4 || Syscall table vaddr. | |||
|- | |- | ||
| | | 0x0338 || 0x4 || unk, related to syscall. used by sceMt19937GlobalUninitForDriver | ||
|- | |- | ||
| | | 0x033C || 0x4 || unk | ||
|- | |- | ||
| | | 0x0340 || 0x4C || SceDecryptCtxGlobal data | ||
|- | |||
| 0x038C || 0x34 || unk, all zero | |||
|- | |||
| 0x03C0 || 0x10000 || module decrypt buff 1 | |||
|- | |||
| 0x103C0 || 0x10000 || module decrypt buff 2 | |||
|} | |} | ||
<source lang = "C"> | |||
typedef struct SceKernelModulemgr_data_t { // size is 0x203C0 on FW 3.60 | |||
char unk_00[0x34]; // unknown, all zero | |||
int is_FwInfo_init; | |||
void *pModulePrivate9; | |||
SceClass *pSceUIDLibStubClass; | |||
SceClass *pSceUIDLibraryClass; | |||
int some_thread_res; | |||
SceClass *pSceUIDModuleClass; | |||
SceUID mutex_id; | |||
char unk_50[0x280]; // unknown | |||
SceKernelSystemSwVersion systemSwVersion; | |||
SceUID some_threadid; | |||
SceUID some_kernel_module_id; | |||
int unk_0x0300; | |||
void *bootfs_info; | |||
int (* pModuleEventDebugHandler)(void *pInfo); | |||
SceModuleSharedInfo *pSharedInfo; | |||
int cpu_addr; | |||
int shared_inhibit_flag; | |||
void *membase; | |||
SceUID memuid; | |||
int unk_0x0320[3]; | |||
int unk_0x032C; | |||
int unk_0x0330; | |||
void *syscall_table; | |||
int some_syscall_info; | |||
int unk_0x033C; | |||
SceDecryptCtxGlobal g_decrypt_ctx; | |||
char unk_0x038C[0x34]; | |||
char module_decrypt_buff1[0x10000]; | |||
char module_decrypt_buff2[0x10000]; | |||
} SceKernelModulemgr_data_t; | |||
</source> | |||
== Loading Sequence == | == Loading Sequence == | ||
Line 173: | Line 693: | ||
When loading a module the sequence creates a SceModule structure to represent it. | When loading a module the sequence creates a SceModule structure to represent it. | ||
<source lang="c">typedef struct | <source lang="c"> | ||
typedef struct SceModule { // ?size is 0x3EC? | |||
const char *filename; // 0x64 | u8 unk0[0x64]; // 0x0 | ||
const char *filename; // 0x64 | |||
u8 unk1[0xC]; // 0x68 | |||
Elf32_Ehdr ehdr; // 0x74 | Elf32_Ehdr ehdr; // 0x74 | ||
Elf32_Phdr phdr; // 0xA8 | Elf32_Phdr phdr; // 0xA8 | ||
Line 183: | Line 705: | ||
void *kernel_addr; // 0x114 | void *kernel_addr; // 0x114 | ||
SceUID kernel_uid; // 0x118 | SceUID kernel_uid; // 0x118 | ||
u8 unk2[0x2C8]; // 0x11C | |||
SceUID parent_pid; // 0x3E4 | |||
SceSblSmCommContext130* context_130; // 0x3E8 | |||
SceSblSmCommContext130* context_130; | |||
} SceModule;</source> | } SceModule;</source> | ||
== SELF Decryption == | == SELF Decryption == | ||
The following code can decrypt a SELF located at <code>path</code>. Set <code> | |||
The following code can decrypt a SELF located at <code>path</code>. | |||
Set <code>self_type</code> to 1 if decrypting a usermode module else 0 for kernel (2 for SM but maybe not allowed). | |||
Set <code>media_type</code> to 0 if you're decrypting the SELF at the right location (for example decrypting <code>sysmem.skprx</code> located in <code>os0:</code>). If you have copied the SELF elsewhere, you need to set the <code>[[SceSblACMgr#Media Type|media_type]]</code> to the right value for where the real path was. | |||
<code>use_cdram</code> is for modules that are too large and won't fit in contiguous regular memory. | |||
<source lang="c"> | <source lang="c"> | ||
int decrypt_self(const char *path, const char * | int decrypt_self(const char *path, const char *out_prefix, int media_type, int use_cdram, int self_type) { | ||
{ | char out_path[256]; | ||
char | int handle; | ||
int | |||
int ret; | int ret; | ||
int pid; | int pid; | ||
int fd = 0, wfd = 0; | int fd = 0, wfd = 0; | ||
char * | char *ctx130 = NULL; | ||
char *hdr_buf = NULL, *hdr_buf_aligned; | char *hdr_buf = NULL, *hdr_buf_aligned; | ||
char *data_buf = NULL, *data_buf_aligned; | char *data_buf = NULL, *data_buf_aligned; | ||
Line 208: | Line 734: | ||
unsigned int hdr_size; | unsigned int hdr_size; | ||
// set up | // set up Auth Mgr | ||
ret = | ret = sceSblAuthMgrOpenForKernel(&handle); | ||
printf(" | printf("sceSblAuthMgrOpenForKernel: 0x%08X, handle: 0x%08X\n", ret, handle); | ||
if (ret < 0) | if (ret < 0) | ||
return 1; | return 1; | ||
// set up | // set up ctx130 | ||
ctx130 = sceKernelLoadcoreKallocForKernel(0x10005, 0x130); | |||
printf(" | printf("Ctx130: 0x%08X\n", ctx130); | ||
if ( | if (ctx130 == NULL) | ||
goto fail; | goto fail; | ||
memset( | memset(ctx130, 0, 0x130); | ||
if (ret < 0) | if (ret < 0) | ||
goto fail; | goto fail; | ||
*(int *)( | *(int *)(ctx130 + 0x4) = self_type; | ||
*(u64_t *)( | *(u64_t *)(ctx130 + 0x8) = 0x2808000000000001LL; | ||
*(u64_t *)( | *(u64_t *)(ctx130 + 0x10) = 0xF000C000000080LL; | ||
*(u64_t *)( | *(u64_t *)(ctx130 + 0x18) = 0xFFFFFFFF00000000LL; | ||
*(u64_t *)( | *(u64_t *)(ctx130 + 0x30) = 0xC300003800980LL; | ||
*(u64_t *)( | *(u64_t *)(ctx130 + 0x38) = 0x8009800000LL; | ||
*(u64_t *)( | *(u64_t *)(ctx130 + 0x48) = 0xFFFFFFFF00000000LL; | ||
if ( | if (media_type) | ||
*(int *)(ctx130 + 0x128) = media_type; | |||
*(int *)( | else { | ||
ret = sceIoGetMediaTypeForDriver(0x10005, path, 1, ctx130 + 0x128); | |||
else | printf("sceIoGetMediaTypeForDriver: 0x%08X\n", ret); | ||
ret = | |||
printf(" | |||
if (ret < 0) | if (ret < 0) | ||
goto fail; | goto fail; | ||
Line 255: | Line 778: | ||
printf("Header read: 0x%08X\n", ret); | printf("Header read: 0x%08X\n", ret); | ||
hdr_size = *(unsigned int *)(hdr_buf_aligned + 0x10); | hdr_size = *(unsigned int *)(hdr_buf_aligned + 0x10); | ||
if (hdr_size > 0x1000) | if (hdr_size > 0x1000) { | ||
printf("Header too large: 0x%08X\n", hdr_size); | printf("Header too large: 0x%08X\n", hdr_size); | ||
goto fail; | goto fail; | ||
Line 264: | Line 786: | ||
// set up SBL decryption for this SELF | // set up SBL decryption for this SELF | ||
ret = | ret = sceSblAuthMgrAuthHeaderForKernel(handle, hdr_buf_aligned, hdr_size, ctx130); | ||
printf(" | printf("sceSblAuthMgrAuthHeaderForKernel: 0x%08X\n", ret); | ||
if (ret < 0) | if (ret < 0) | ||
goto fail; | goto fail; | ||
// set up read buffer | // set up read buffer | ||
Line 288: | Line 808: | ||
// decrypt sections | // decrypt sections | ||
int total, to_read, num_read, off; | int total, to_read, num_read, off; | ||
int aligned_size; | int aligned_size; | ||
int blkid = 0; | int blkid = 0; | ||
void *pgr_buf; | void *pgr_buf; | ||
for (i = 0; i < num_segs; | for (int i = 0; i < num_segs; ++i) { | ||
sprintf(out_path, "%s.seg%u", out_prefix, i); | |||
sprintf( | |||
sceIoCloseForDriver(wfd); | sceIoCloseForDriver(wfd); | ||
wfd = sceIoOpenForDriver( | wfd = sceIoOpenForDriver(out_path, 0x602, 6); | ||
printf("sceIoOpenForDriver(%s): 0x%08X\n", | printf("sceIoOpenForDriver(%s): 0x%08X\n", out_path, wfd); | ||
if (wfd < 0) | if (wfd < 0) | ||
break; | break; | ||
Line 305: | Line 823: | ||
sceKernelFreeMemBlockForKernel(blkid); | sceKernelFreeMemBlockForKernel(blkid); | ||
aligned_size = (phdrs[i].p_filesz + 4095) & 0xFFFFF000; | aligned_size = (phdrs[i].p_filesz + 4095) & 0xFFFFF000; | ||
if ( | if (use_cdram) | ||
blkid = sceKernelAllocMemBlockForKernel("self_decrypt_buffer", 0x40404006, 0x4000000, NULL); | blkid = sceKernelAllocMemBlockForKernel("self_decrypt_buffer", 0x40404006, 0x4000000, NULL); | ||
else | else | ||
Line 316: | Line 834: | ||
// setup buffer for output | // setup buffer for output | ||
ret = | ret = sceSblAuthMgrSetupAuthSegmentForKernel(handle, i, (u32_t)segs[i].length, pgr_buf, phdrs[i].p_filesz); | ||
printf(" | printf("sceSblAuthMgrSetupAuthSegmentForKernel: 0x%08X\n", ret); | ||
if (ret < 0) | if (ret < 0) | ||
break; | break; | ||
ret = sceIoLseekForDriver(fd, segs[i].offset, 0); | ret = sceIoLseekForDriver(fd, segs[i].offset, 0); | ||
Line 330: | Line 846: | ||
to_read = total > 0x10000 ? 0x10000 : total; | to_read = total > 0x10000 ? 0x10000 : total; | ||
off = 0; | off = 0; | ||
while (total > 0 && (num_read = sceIoReadForDriver(fd, data_buf_aligned+off, to_read)) > 0) | while (total > 0 && (num_read = sceIoReadForDriver(fd, data_buf_aligned + off, to_read)) > 0) { | ||
off += num_read; | off += num_read; | ||
total -= num_read; | total -= num_read; | ||
if (num_read < to_read) | if (num_read < to_read) { | ||
to_read -= num_read; | to_read -= num_read; | ||
continue; | continue; | ||
} | } | ||
ret = | ret = sceSblAuthMgrAuthSegmentForKernel(handle, data_buf_aligned, off); // decrypt buffer | ||
printf(" | printf("sceSblAuthMgrAuthSegmentForKernel: 0x%08X\n", ret); | ||
if (ret < 0) | if (ret < 0) | ||
printf("!!! ERROR !!!\n"); | printf("!!! ERROR !!!\n"); | ||
ret = | ret = sceSblAuthMgrLoadSegmentInternalForKernel(handle, data_buf_aligned, off); // copy buffer to output | ||
printf(" | printf("sceSblAuthMgrLoadSegmentInternalForKernel: 0x%08X\n", ret); | ||
if (ret < 0) | if (ret < 0) | ||
printf("!!! ERROR !!!\n"); | printf("!!! ERROR !!!\n"); | ||
off = 0; | off = 0; | ||
Line 357: | Line 869: | ||
// write buffer | // write buffer | ||
off = 0; | off = 0; | ||
while ((off += sceIoWriteForDriver(wfd, pgr_buf+off, phdrs[i].p_filesz-off)) < phdrs[i].p_filesz); | while ((off += sceIoWriteForDriver(wfd, pgr_buf + off, phdrs[i].p_filesz - off)) < phdrs[i].p_filesz); | ||
} | } | ||
if (blkid) | if (blkid) | ||
Line 364: | Line 876: | ||
fail: | fail: | ||
sceSblAuthMgrCloseForKernel(handle); | |||
if (fd) | if (fd) | ||
sceIoCloseForDriver(fd); | sceIoCloseForDriver(fd); | ||
if ( | if (ctx130) | ||
sceKernelLoadcoreKfreeForKernel(ctx130); | |||
if (hdr_buf) | if (hdr_buf) | ||
sceKernelLoadcoreKfreeForKernel(hdr_buf); | |||
if (data_buf) | if (data_buf) | ||
sceKernelLoadcoreKfreeForKernel(data_buf); | |||
return 1; | return 1; | ||
} | } | ||
</source> | </source> | ||
== Module decryption and signature checks ("HENkaku patches" on 1.60) == | == Module decryption and signature checks ("HENkaku patches" on FW 1.60) == | ||
The code below will patch signature checks and bypass module decryption and allow | See also [[SELF_Loading]] to see how these SceSblAuthMgr functions are used to decrypt SELFs. | ||
The code below will patch signature checks and bypass module decryption and allow homebrews to run. The idea is to hook SceSblAuthMgr* calls that are imported to SceKernelModulemgr. The offsets are from FW 1.60, you will probably need to modify functions defines (set to addresses of functions) and INSTALL_HOOK second arguments (set to addresses of imports in SceKernelModulemgr). | |||
For old FWs like 1.60, as there is no kASLR, you can set hardcoded addresses, else take HENkaku code. As a bonus there is also patch_npdrm functions that patches [[SceNpDrm]] to bypass some DRM checks and allow unsigned packages to be installed, which you also need to modify addresses. See [[SceNpDrm#Package_integrity_checks]]. | |||
<source lang="c"> | <source lang="c"> | ||
#define G_OUR_EBOOT *(unsigned*)( | // hardcoded addresses for FW 1.60 | ||
#define G_BUF *(unsigned*)( | #define G_OUR_EBOOT *(unsigned*)(0x01E60000 - 0x14) | ||
#define G_WRITTEN *(unsigned*)( | #define G_BUF *(unsigned*)(0x01E60000 - 0xC) | ||
#define G_WRITTEN *(unsigned*)(0x01E60000 - 0x10) | |||
#define Func(addr) ((unsigned(*)())(addr)) | #define Func(addr) ((unsigned(*)())(addr)) | ||
#define | // Hardcoded addresses for FW 1.60 | ||
#define | #define sceSblAuthMgrAuthHeaderForKernel Func(0x4BC6C9) | ||
#define | #define sceSblAuthMgrSetupAuthSegmentForKernel Func(0x4BC851) | ||
#define | #define sceSblAuthMgrAuthSegmentForKernel Func(0x4BC909) | ||
#define sceSblAuthMgrLoadSegmentInternalForKernel Func(0x4BCA89) | |||
// setup file decryption | // setup file decryption | ||
unsigned | unsigned sceSblAuthMgrAuthHeaderForKernel_patched(unsigned a1, unsigned a2, unsigned a3, unsigned a4) { | ||
unsigned res = | unsigned res = sceSblAuthMgrAuthHeaderForKernel(a1, a2, a3, a4); | ||
if (res == 0x800f0624 || res == 0x800f0616 || res == 0x800f0024) { | if (res == 0x800f0624 || res == 0x800f0616 || res == 0x800f0024) { | ||
Line 414: | Line 930: | ||
// setup output buffer | // setup output buffer | ||
unsigned | unsigned sceSblAuthMgrSetupAuthSegmentForKernel_patched(unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5) { | ||
G_BUF = a4; | G_BUF = a4; | ||
G_WRITTEN = 0; | G_WRITTEN = 0; | ||
Line 420: | Line 936: | ||
return 0; | return 0; | ||
} | } | ||
return | return sceSblAuthMgrSetupAuthSegmentForKernel(a1, a2, a3, a4, a5); | ||
} | } | ||
// decrypt | // decrypt | ||
unsigned | unsigned sceSblAuthMgrAuthSegmentForKernel_patched(unsigned a1, unsigned a2, unsigned a3) { | ||
if (G_OUR_EBOOT == 1) { | if (G_OUR_EBOOT == 1) { | ||
return 0; | return 0; | ||
} | } | ||
return | return sceSblAuthMgrAuthSegmentForKernel(a1, a2, a3); | ||
} | } | ||
// copy to output | // copy to output - not present on 3.60 | ||
unsigned | unsigned sceSblAuthMgrLoadSegmentInternalForKernel_patched(unsigned a1, unsigned a2, unsigned a3) { | ||
if (G_OUR_EBOOT == 1) { | if (G_OUR_EBOOT == 1) { | ||
memcpy((void*)(G_BUF + G_WRITTEN), (void*)a2, a3); | memcpy((void*)(G_BUF + G_WRITTEN), (void*)a2, a3); | ||
Line 438: | Line 954: | ||
return 0; | return 0; | ||
} | } | ||
return | return sceSblAuthMgrLoadSegmentInternalForKernel(a1, a2, a3); | ||
} | } | ||
Line 449: | Line 965: | ||
} | } | ||
// hardcoded addresses for FW 1.60 | |||
void hook_install(void) { | void hook_install(void) { | ||
INSTALL_HOOK( | INSTALL_HOOK(sceSblAuthMgrLoadSegmentInternalForKernel_patched, 0x5BA9CC); | ||
INSTALL_HOOK( | INSTALL_HOOK(sceSblAuthMgrSetupAuthSegmentForKernel_patched, 0x5BA9DC); | ||
INSTALL_HOOK( | INSTALL_HOOK(sceSblAuthMgrAuthSegmentForKernel_patched, 0x5BAA0C); | ||
INSTALL_HOOK( | INSTALL_HOOK(sceSblAuthMgrAuthHeaderForKernel_patched, 0x5BAA1C); | ||
} | } | ||
Line 460: | Line 977: | ||
int modlist_records; | int modlist_records; | ||
int res; | int res; | ||
SceKernelModuleInfo modinfo; | |||
memset(modlist, 0, sizeof(modlist)); | memset(modlist, 0, sizeof(modlist)); | ||
Line 468: | Line 985: | ||
for(int j = 0; j < modlist_records; j++) { | for(int j = 0; j < modlist_records; j++) { | ||
memset(&modinfo, 0, sizeof(modinfo)); | memset(&modinfo, 0, sizeof(modinfo)); | ||
res=sceKernelGetModuleInfoForKernel(modlist[j], &modinfo); | res = sceKernelGetModuleInfoForKernel(modlist[j], &modinfo); | ||
if (strcmp(modinfo.name, name) == 0) | if (strcmp(modinfo.name, name) == 0) | ||
return (unsigned)modinfo.module_top; | return (unsigned)modinfo.module_top; | ||
Line 475: | Line 992: | ||
} | } | ||
// Hardcoded addresses for FW 1.60 | |||
void patch_npdrm(unsigned base) { | void patch_npdrm(unsigned base) { | ||
unsigned *patch; | unsigned *patch; | ||
Line 495: | Line 1,013: | ||
} | } | ||
// | // Call this function from a thread | ||
int hook(void) { | int hook(void) { | ||
fprintf("Hook start\n"); | fprintf("Hook start\n"); | ||
Line 512: | Line 1,030: | ||
__asm__ volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (prev_dacr)); | __asm__ volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (prev_dacr)); | ||
sceKernelDelayThread( | sceKernelDelayThread(4*1000*1000); | ||
return 0; | return 0; | ||
Line 520: | Line 1,038: | ||
== SceModulemgrForKernel == | == SceModulemgrForKernel == | ||
=== | === sceKernelRegisterModulesAfterBootForKernel === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 0. | | 0.931.010-2.120.011 || not present | ||
|- | |||
| 2.500.071-3.610.011 || 0x3382952B | |||
|- | |||
| 3.630.011-3.740.011 || 0xD0AF9DB7 | |||
|} | |} | ||
<source lang="C"> | Temp name was sceKernelSetupForModulemgrForKernel. | ||
<source lang="C">void sceKernelRegisterModulesAfterBootForKernel(void);</source> | |||
=== sceKernelFinalizeKblForKernel === | === sceKernelFinalizeKblForKernel === | ||
Line 535: | Line 1,059: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 0.990-3.60 || | | 0.990-3.61 || 0xFDD7F646 | ||
|- | |||
| 3.63-3.65 || 0xB911516F | |||
|} | |||
Unloads [[ScePsp2BootConfig]]. | |||
<source lang="C">void sceKernelFinalizeKblForKernel(void);</source> | |||
=== sceKernelRegisterSyscallForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-3.610.011 || 0xB427025E | |||
|- | |||
| 3.630.011-3.740.011 || 0x2E4A10A0 | |||
|} | |||
This is a guessed name. | |||
<source lang="C">void sceKernelRegisterSyscallForKernel(SceUInt32 index, void *function);</source> | |||
=== sceKernelLoadPtLoadSegForFwloaderForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990-3.61 || 0x448810D5 | |||
|- | |||
| 3.63-3.65 || 0xA07063EA | |||
|} | |||
This is an easy way of decrypting SELF files but you are limited to the kinds of SELF files that you can load in the current context (for example, you cannot load user modules from kernel context). It is also susceptible to limitations of where the SELF can be loaded from. For example, you are not allowed to load SELFs found in <code>os0:</code> from <code>ux0:</code> because [[Secure Kernel]] checks the [[SceSblACMgr#Media Type|Media Type]]. | |||
On FW 3.60, statically compiled SELF files give an error. | |||
<source lang="c">int sceKernelLoadPtLoadSegForFwloaderForKernel(const char *path, int e_phnum, void *buffer, uint32_t bufsize, int zero_unk, uint32_t *bytes_read);</source> | |||
=== sceKernelMountBootimageFSForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-0.990.000 || not present | |||
|- | |||
| 0.996.090-3.610.011 || 0x01360661 | |||
|- | |||
| 3.630.011-3.740.011 || 0x185FF1BC | |||
|} | |||
Temp name was sceKernelMountBootfsForKernel. | |||
<source lang="C">int sceKernelMountBootimageFSForKernel(const char *bootImagePath);</source> | |||
=== sceKernelUmountBootimageFSForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-0.990.000 || not present | |||
|- | |||
| 0.996.090-3.610.011 || 0x9C838A6B | |||
|- | |||
| 3.630.011-3.740.011 || 0xBD61AD4D | |||
|} | |||
Temp name was sceKernelUmountBootfsForKernel. | |||
<source lang="C">int sceKernelUmountBootimageFSForKernel(void);</source> | |||
=== sceKernelLoadRemoteModuleForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.011-2.060.011 || not present | |||
|- | |||
| 2.100.081-3.610.011 || 0xFA21D8CB | |||
|- | |||
| 3.630.011-3.740.011 || 0x4E85022D | |||
|} | |} | ||
Temp name was sceKernelLoadModuleForPidForKernel. | |||
<source lang="C"> | <source lang="C"> | ||
/** | |||
* @brief Load module | |||
* | |||
* moduleFileName Loads the module specified by moduleFileName. | |||
* If the load is successful, the module identifier is returned as the return value. | |||
* | |||
* @param[in] moduleFileName file name | |||
* @param[in] flags flags | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @retval (>0) module uid | |||
* @retval (<0) Error code | |||
*/ | |||
SceUID sceKernelLoadRemoteModuleForKernel(SceUID pid, const char *moduleFileName, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt); | |||
</source> | </source> | ||
<source lang="C"> | === sceKernelUnloadRemoteModuleForKernel === | ||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-3.610.011 || 0x5972E2CC | |||
|- | |||
| 3.630.011-3.740.011 || 0xFCA9FDB1 | |||
|} | |||
Temp name was sceKernelUnloadModuleForPidForKernel. | |||
<source lang="C"> | |||
/** | |||
* @brief Unload module | |||
* | |||
* Unloads the module specified by uid. | |||
* | |||
* @param[in] pid process id | |||
* @param[in] uid module id | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter | |||
* | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
int sceKernelUnloadRemoteModuleForKernel(SceUID pid, SceUID uid, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt); | |||
</source> | |||
=== | === sceKernelStartRemoteModuleForKernel === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 0.990-3. | | 0.990.000-3.610.011 || 0x6DF745D5 | ||
|- | |||
| 3.630.011-3.740.011 || 0x3FE47DDF | |||
|} | |} | ||
=== | Temp name was sceKernelStartModuleForPidForKernel. | ||
<source lang="C"> | |||
/** | |||
* @brief start module for process | |||
* | |||
* Starts the module specified by uid. When calling the start entry function, | |||
* the value specified by the args and argp arguments is passed as an argument. | |||
* | |||
* If the start process is successful, the library declared with AUTO_EXPORT will be registered. | |||
* Public processing is performed and the return value of the start entry function is stored in the area indicated by pRes. | |||
* If the start process fails, library registration and publishing will not be performed. | |||
* | |||
* SCE_KERNEL_START_NO_RESIDENT is returned as the return value of the start entry function | |||
* only if the module is automatically unloaded after executing the start entry function. | |||
* If SCE_KERNEL_START_FAILED is returned, the start process will fail. | |||
* At this time, the module is not unloaded. Modules that failed to start | |||
* It can be restarted with sceKernelStartRemoteModuleForKernel(). | |||
* | |||
* @param[in] pid process id | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of start entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
int sceKernelStartRemoteModuleForKernel(SceUID pid, SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStartModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== sceKernelStopRemoteModuleForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-3.610.011 || 0x7BB4CE54 | ||
|- | |- | ||
| 3. | | 3.630.011-3.740.011 || 0xBDBD391D | ||
|} | |} | ||
Temp name was sceKernelStopModuleForPidForKernel. | |||
=== | <source lang="C"> | ||
/** | |||
* @brief Stop module | |||
* | |||
* Stops the module specified by uid. When calling the stop entry function, | |||
* the values specified by the args and argp arguments are passed as arguments. | |||
* | |||
* If the stop process is successful, the library released from the module is deleted, | |||
* and the return value of the stop entry function is stored in the area indicated by pRes. | |||
* If stop processing fails, library deletion processing is not performed. | |||
* | |||
* Only when SCE_KERNEL_STOP_SUCCESS is returned as the return value of the | |||
* stop entry function, module stop processing succeeds. | |||
* If any other value is returned, module stop processing will fail. | |||
* The module that failed to stop can be restarted with sceKernelStopModuleForPidForKernel(). | |||
* | |||
* @param[in] pid process id | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of stop entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
int sceKernelStopRemoteModuleForKernel(SceUID pid, SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStopModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== sceKernelModuleUnloadMySelfForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 0. | | 0.931.011-2.060.011 || not present | ||
|- | |||
| 2.100.081-3.610.011 || 0x2A69385E | |||
|- | |||
| 3.630.011-3.740.011 || 0x2F82EEBC | |||
|} | |} | ||
<source lang=" | This is a guessed name. | ||
<source lang="C">int sceKernelModuleUnloadMySelfForKernel(void);</source> | |||
=== sceKernelLoadProcessImageForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-3.610.011 || 0xAC4EABDB | |||
|- | |||
| 3.630.011-3.740.011 || 0xA85A44D7 | |||
|} | |||
<source lang="c"> | |||
/** | |||
* @brief load process image | |||
* | |||
* @param[in] pid - target pid | |||
* @param[in] path - path | |||
* @param[in] flags - generally 0 - 0x10000 added if flag 0x40000000 is passed to sceKernelCreateProcess, 0x4000 added if an option is passed to sceKernelCreateProcess via the Opt argument | |||
* @param[out] auth_info | |||
* @param[out] param | |||
* @param[in] shim_info - compatibility shim information, only used for one game (PCSG00063/PCSB000144) in 3.65 | |||
* | |||
* @return modid, < 0 on error. | |||
*/ | |||
SceUID sceKernelLoadProcessImageForKernel(SceUID pid, const char *path, int flags, SceSelfAuthInfo *auth_info, SceLoadProcessParam *param, SceKernelCompatibilityShimInfo* shim_info); | |||
</source> | |||
=== | === sceKernelLoadPreloadingModulesForKernel === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931.010-3.610.011 || 0x3AD26B43 | ||
|- | |- | ||
| 3. | | 3.630.011-3.740.011 || 0xE3C1AAA1 | ||
|} | |} | ||
<source lang=" | Temp name was sceKernelLoadProcessModulesForKernel, sceKernelLoadStartDefaultSharedModulesForPidForKernel. | ||
int | |||
Loads the preloading modules for a process. This includes, for instance, <code>SceLibKernel</code>. | |||
If dipsw 210 is set, it checks if the preloading module flag and 0x8 are set, OR the flag 0x20 of sceKernelLoadModule. If that is the case, the module is loaded into DevKit Additional Memory (DRAM). | |||
<source lang="c"> | |||
param[in] flags - process modules flags. | |||
1:inhibit shared and load libgxm_dbg_es4.suprx Instead of libgxm_es4.suprx | |||
2:not use default lib | |||
int sceKernelLoadPreloadingModulesForKernel(SceUID pid, const SceLoadProcessParam *pParam, int flags); | |||
</source> | </source> | ||
=== | === sceKernelUnloadProcessModulesForKernel === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-3.610.011 || 0x0E33258E | ||
|- | |||
| 3.630.011-3.740.011 || 0xE71530D7 | |||
|} | |} | ||
Temp name was sceKernelStopUnloadPreloadingModulesForKernel. | |||
=== | <source lang="C">int sceKernelUnloadProcessModulesForKernel(SceUID pid);</source> | ||
=== sceKernelStartPreloadingModulesForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.931.010-3.610.011 || 0x432DCC7A | ||
|- | |||
| 3.630.011-3.740.011 || 0x998C7AE9 | |||
|} | |} | ||
Temp name was sceKernelStartProcessModulesForKernel. | |||
<source lang="c">int sceKernelStartPreloadingModulesForKernel(SceUID pid);</source> | |||
=== | === sceKernelGetModuleListForKernel === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-3.610.011 || 0x97CF7B4E | ||
|- | |||
| 3.630.011-3.740.011 || 0xB72C75A4 | |||
|} | |} | ||
This is a guessed name. | |||
<source lang="C">int sceKernelGetModuleListForKernel(SceUID pid, int flags1, int flags2, SceUID *modids, SceSize *num);</source> | |||
=== sceKernelGetModuleInfoForKernel === | === sceKernelGetModuleInfoForKernel === | ||
Line 628: | Line 1,384: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-3.610.011 || 0xD269F915 | ||
|- | |||
| 3.630.011-3.740.011 || 0xDAA90093 | |||
|} | |} | ||
=== | This is a guessed name. | ||
<source lang="C">int sceKernelGetModuleInfoForKernel(SceUID pid, SceUID modid, SceKernelModuleInfo *info);</source> | |||
=== sceKernelGetModuleInfoForDebuggerForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-3.610.011 || 0x410E1D2E | ||
|- | |||
| 3.630.011-3.740.011 || 0x0155FE40 | |||
|} | |} | ||
Temp name was sceKernelGetModuleList2ForKernel. | |||
=== | <source>int sceKernelGetModuleInfoForDebuggerForKernel(SceUID pid, SceKernelModuleListInfo *infolists, SceSize *num);</source> | ||
=== sceKernelGetModuleInfoMinByAddrForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.931.010-2.060.011 || not present | ||
|- | |||
| 2.100.081-3.610.011 || 0x8309E043 | |||
|- | |||
| 3.630.011-3.740.011 || 0x5564A860 | |||
|} | |} | ||
<source lang=" | This is a guessed name. | ||
int | |||
</source> | <source lang="c">int sceKernelGetModuleInfoMinByAddrForKernel(SceUID pid, void *addr, SceUInt32 *puiDbgFingerprint, void **pProgramTextAddr, SceKernelModuleName *pModuleName);</source> | ||
=== | === sceKernelGetModuleCBForKernel === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-3.610.011 || 0xFE303863 | ||
|- | |||
| 3.630.011-3.740.011 || 0x37512E29 | |||
|} | |} | ||
This is a guessed name. Temp name was sceKernelGetModuleInternalForKernel, sceKernelGetModuleCBForDebuggerForKernel. | |||
This function returns a pointer to the "ModuleCB" (module control block) for specified module UID. | |||
=== | 0.990: | ||
<source lang="C">void **sceKernelGetModuleCBForKernel(SceUID modid);</source> | |||
3.60: | |||
<source lang="C">int sceKernelGetModuleCBForKernel(SceUID modid, void **ppModCB);</source> | |||
=== sceKernelGetModuleIdByPidForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.931.010-2.060.011 || not present | ||
|- | |||
| 2.100.081-3.610.011 || 0x20A27FA9 | |||
|- | |||
| 3.630.011-3.740.011 || 0x679F5144 | |||
|} | |} | ||
<source lang ="C"> | <source lang ="C"> | ||
/** | /** | ||
* @brief Get the | * @brief Get the module ID for a given process. | ||
* @param pid The process to query. | * @param pid The process to query. | ||
* @return the UID of the module else < 0 for an error. | * @return the UID of the module else < 0 for an error. | ||
*/ | */ | ||
SceUID | SceUID sceKernelGetModuleIdByPidForKernel(SceUID pid); | ||
</source> | </source> | ||
=== sceKernelGetProcessMainModulePathForKernel === | === sceKernelGetModuleIsSharedByAddrForKernel === | ||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-2.060.011 || not present | |||
|- | |||
| 2.100.081-3.610.011 || 0x99890202 | |||
|- | |||
| 3.630.011-3.740.011 || 0xF1DE6949 | |||
|} | |||
This is a guessed name. | |||
<source lang="C">int sceKernelGetModuleIsSharedByAddrForKernel(SceUID pid, void *addr);</source> | |||
=== sceKernelGetModulePathForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 3.60-3.61 || 0x779A1025 | |||
|- | |||
| 3.63-3.65 || 0x79E761B5 | |||
|} | |||
This is a guessed name. Temp name was sceKernelGetProcessMainModulePathForKernel. | |||
<source lang="C">int sceKernelGetModulePathForKernel(SceUID modid, char *path, SceSize pathlen);</source> | |||
=== sceKernelGetModuleFingerprintForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 3.60-3.61 || 0xEEA92F1F | |||
|- | |||
| 3.63-3.65 || 0x337A3908 | |||
|} | |||
This is a guessed name. | |||
<source lang="C">int sceKernelGetModuleFingerprintForKernel(SceUID moduleId, SceUInt32 *pFingerprint);</source> | |||
=== sceKernelGetModuleCBByAddrForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-3.610.011 || 0x2C2618D9 | |||
|- | |||
| 3.630.011-3.740.011 || 0x1728612F | |||
|} | |||
This is a guessed name. Temp name was sceKernelGetModuleInternalByAddrForKernel, sceKernelGetProcessEntryPointByAddrForKernel. | |||
Used by [[#sceKernelPrintBacktraceForDriver|sceKernelPrintBacktraceForDriver]]. | |||
<source lang="C">int sceKernelGetModuleCBByAddrForKernel(SceUID pid, void *addr, SceModuleCB **ppModuleCB);</source> | |||
=== sceKernelGetModuleIdByAddrForDebuggerForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-3.610.011 || 0x0053BA4A | |||
|- | |||
| 3.630.011-3.740.011 || 0x0C668636 | |||
|} | |||
Temp name was sceKernelGetModuleIdByAddrForKernel. | |||
<source lang="C">SceUID sceKernelGetModuleIdByAddrForDebuggerForKernel(SceUID pid, ScePVoid addr);</source> | |||
=== sceKernelGetModuleEntryPointForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-2.060.011 || not present | |||
|- | |||
| 2.100.081-3.610.011 || 0x66606301 | |||
|- | |||
| 3.630.011-3.740.011 || 0x7B302C5D | |||
|} | |||
This is a guessed name. | |||
<source lang="c">SceKernelModuleEntry sceKernelGetModuleEntryPointForKernel(SceUID modid);</source> | |||
=== sceKernelGetLibraryListForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 3.60-3.61 || 0x1FDEAE16 | |||
|- | |||
| 3.63-3.65 || 0x12AD6DE3 | |||
|} | |||
This is a guessed name. Temp name was sceKernelGetModuleUidListForKernel, sceKernelGetProcessLibraryIdListForKernel. | |||
<source lang="C">int sceKernelGetLibraryListForKernel(SceUID pid, SceUID *library_ids, SceSize *num);</source> | |||
=== sceKernelGetImportedLibraryListInModuleForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 3.60-3.61 || 0x2DD3B511 | |||
|- | |||
| 3.63-3.65 || 0x1360E9A8 | |||
|} | |||
<source lang="C">int sceKernelGetImportedLibraryListInModuleForKernel(SceUID pid, SceUID modid, SceUID *library_ids, SceSize *num);</source> | |||
=== sceKernelGetExportedLibraryListInModuleForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3.60 || | | 3.60-3.61 || 0x619925F1 | ||
|- | |||
| 3.63-3.65 || 0x7E3F9F55 | |||
|} | |} | ||
<source lang="C">int sceKernelGetExportedLibraryListInModuleForKernel(SceUID pid, SceUID modid, SceUID *library_ids, SceSize *num);</source> | |||
=== | === sceKernelGetLibraryDBFlagsForKernel === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3.60 || | | 3.60-3.61 || 0x7A1E882D | ||
|- | |||
| 3.63-3.65 || 0x1C82E9F7 | |||
|} | |} | ||
=== | Temp name was sceKernelGetModuleInhibitStateForKernel. | ||
<source lang="c">int sceKernelGetLibraryDBFlagsForKernel(SceUID pid, int *pFlags);</source> | |||
=== sceKernelGetLibraryClientListForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3.60 || | | 3.60-3.61 || 0x3B93CF88 | ||
|- | |||
| 3.63-3.65 || 0xAAF6E971 | |||
|} | |} | ||
=== | Temp name was sceKernelGetModuleUidForKernel. | ||
<source>int sceKernelGetLibraryClientListForKernel(SceUID pid, SceUID library_id, SceUID *modids, SceSize *num, SceSize cpy_skip_num);</source> | |||
=== sceKernelGetLibEntCBListForSyslibtraceForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3.60 || | | 3.60-3.61 || 0x8D1AA624 | ||
|- | |||
| 3.63-3.65 || 0x534519CD | |||
|} | |} | ||
=== | <source lang="C">int sceKernelGetLibEntCBListForSyslibtraceForKernel(SceModuleLibraryInfo **ppList, SceSize *num);</source> | ||
=== sceKernelGetLibraryExportInfoForDebuggerForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3.60 || | | 3.60-3.61 || 0xD4BF409C | ||
|- | |||
| 3.63-3.65 || 0xACDB6FEF | |||
|} | |} | ||
=== | <source lang="C">int sceKernelGetLibraryExportInfoForDebuggerForKernel(SceUID pid, SceUID library_id, SceKernelModuleExportEntry *list, SceSize *num, SceSize cpy_skip_num);</source> | ||
=== sceKernelGetLibraryInfoForDebuggerForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3.60 || | | 3.60-3.61 || 0x6A655255 | ||
|- | |||
| 3.63-3.65 || 0xB54482AF | |||
|} | |} | ||
=== | Temp name was sceKernelGetModuleLibraryInfoForKernel. | ||
<source lang="C">int sceKernelGetLibraryInfoForDebuggerForKernel(SceUID pid, SceUID library_id, SceKernelModuleLibraryInfo *info);</source> | |||
=== sceKernelGetStubListForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.931.010-3.010.031 || not present | ||
|- | |||
| 3.100.081-3.610.011 || 0x1D341231 | |||
|- | |||
| 3.630.011-3.740.011 || 0xE48CDE07 | |||
|} | |} | ||
=== | <source lang="C">int sceKernelGetStubListForKernel(SceUID pid, SceUID *stub, SceSize *num);</source> | ||
=== sceKernelGetStubInfoForDebuggerForKernel === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931.010-3.010.031 || not present | ||
|- | |||
| 3.100.081-3.610.011 || 0xB73BE671 | |||
|- | |||
| 3.630.011-3.740.011 || 0x07DBB649 | |||
|} | |} | ||
<source lang="C"> | |||
// a3 size is 0x128 | |||
int sceKernelGetStubInfoForDebuggerForKernel(SceUID pid, SceUID stubid, void *a3); | |||
</source> | |||
=== sceKernelGetStubNidTableForDebuggerForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-3.010.031 || not present | |||
|- | |||
| 3.100.081-3.610.011 || 0xFB251B7A | |||
|- | |||
| 3.630.011-3.740.011 || 0xCE201AFC | |||
|} | |||
<source lang=" | <source lang="C"> | ||
int | // a3 size is 8 * num | ||
int sceKernelGetStubNidTableForDebuggerForKernel(SceUID pid, SceUID stubid, void *a3, SceSize *num, SceSize cpy_skip_num); | |||
</source> | </source> | ||
=== | === sceKernelGetProgramIdentificationInfoForKernel === | ||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-3.010.031 || not present | |||
|- | |||
| 2.000.081-3.610.011 || 0xF95D09C2 | |||
|- | |||
| 3.630.011-3.740.011 || 0x5D60CD77 | |||
|} | |||
<source lang="C">int sceKernelGetProgramIdentificationInfoForKernel(const char *path, SceUInt64 *pAuthid, SceSelfAppInfo *pInfo);</source> | |||
=== sceKernelGetMetaDataForDebuggerForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-3.610.011 || 0x78DBC027 | |||
|- | |||
| 3.630.011-3.740.011 || 0x2E6569F3 | |||
|} | |||
<source lang="c">int sceKernelGetMetaDataForDebuggerForKernel(SceUID pid, SceUID userModuleId, SceKernelModuleEntry *start, SceKernelModuleEntry *stop);</source> | |||
=== sceKernelGetLostLibraryInfoForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-1.692.000 || not present | |||
|- | |||
| 1.800.071-3.610.011 || 0x952535A3 | |||
|- | |||
| 3.630.011-3.740.011 || 0x388D4DE0 | |||
|} | |||
<source lang="C">int sceKernelGetLostLibraryInfoForKernel(SceUID pid, SceUID modid, SceNID libnid, SceKernelModuleImportNonlinkedInfo *info);</source> | |||
=== sceKernelGetLostLibraryListInModuleForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-1.692.000 || not present | |||
|- | |||
| 1.800.071-3.610.011 || 0xFF2264BB | |||
|- | |||
| 3.630.011-3.740.011 || 0x6A5DFBBA | |||
|} | |||
<source lang="C">int sceKernelGetLostLibraryListInModuleForKernel(SceUID pid, SceUID modid, SceKernelModuleNonlinkedInfo *pList, SceSize *num);</source> | |||
=== sceKernelGetLostLibraryListForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-1.692.000 || not present | |||
|- | |||
| 1.800.071-3.610.011 || 0x1BDE2ED2 | |||
|- | |||
| 3.630.011-3.740.011 || 0x7D71892B | |||
|} | |||
<source lang="C">int sceKernelGetLostLibraryListForKernel(SceUID pid, SceKernelModuleImportNID *a2, SceSize *num);</source> | |||
=== sceKernelRegisterDebugCBForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.931.010-3.010.031 || not present | |||
|- | |||
| 3.100.081-3.610.011 || 0x60E176C8 | |||
|- | |||
| 3.630.011-3.740.011 || 0x74A4E0EE | |||
|} | |||
This is a guessed name. | |||
Used by [[SceDeci4pDtracep]]. | |||
<source lang="C">int sceKernelRegisterDebugCBForKernel(const void *pHandler);</source> | |||
=== sceKernelUnregisterDebugCBForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 3.60-3.61 || 0x9D20C9BB | |||
|- | |||
| 3.63-3.65 || 0xACBC97C9 | |||
|} | |||
This is a guessed name. | |||
<source lang="C">int sceKernelUnregisterDebugCBForKernel(const void *pHandler);</source> | |||
=== sceKernelUnlinkNormalSyscallForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 3.60-3.61 || 0x29CB2771 | |||
|- | |||
| 3.63-3.65 || 0x353821B2 | |||
|} | |||
<source lang="C">int sceKernelUnlinkNormalSyscallForKernel(SceUID pid);</source> | |||
=== sceKernelLinkWeakLibraryByLibnameForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 3.60-3.61 || 0x4865C72C | |||
|- | |||
| 3.63-3.65 || 0x26C28FA4 | |||
|} | |||
<source lang="C">int sceKernelLinkWeakLibraryByLibnameForKernel(SceUID pid, const char *libname);</source> | |||
=== SceModulemgrForKernel_F3CD647F === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 3.60-3.61 || 0xF3CD647F | |||
|- | |||
| 3.63-3.65 || 0xB23286B8 | |||
|} | |||
Set two param. Maybe related to syscall. | |||
Used by [[SceSysLibTrace]]. | |||
<source lang="C">void SceModulemgrForKernel_F3CD647F(void *a1, const void *func);</source> | |||
=== sceKernelLibraryDBGetSyslibtraceCBForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990 || 0x3AE7F62F | |||
|- | |||
| 3.60 || not present | |||
|} | |||
=== sceKernelLibraryDBSetSyslibtraceCBForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990 || 0x7E68D6EC | |||
|} | |||
=== SceModulemgrForKernel_06D9392A === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-1.692.000 || 0x06D9392A | |||
|- | |||
| 1.800.071-3.740.011 || not present | |||
|} | |||
<source lang="C">SceModulemgrForKernel_06D9392A(int modid, void *addr, int *out);</source> | |||
=== sceModulemgrLockLibDBForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990 || 0x37C2A1A5 | |||
|} | |||
=== sceModulemgrUnlockLibDBForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990 || 0x0751F162 | |||
|} | |||
=== SceModulemgrForKernel_04ADDA3E === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990 || 0x04ADDA3E | |||
|} | |||
=== sceKernelGetProcessEntryPointForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-2.060.011 || 0xC72CA412 | |||
|- | |||
| 2.100.081-3.740.011 || not present | |||
|} | |||
=== sceKernelLoadcoreKallocForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990 || 0xB4A1DE31 | |||
|} | |||
<source lang="C">void *sceKernelLoadcoreKallocForKernel(SceSize len);</source> | |||
=== sceKernelLoadcoreKfreeForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-1.692.000 || 0xF4B2D8B8 | |||
|- | |||
| 1.800.071-3.740.011 || 0xF4B2D8B8 | |||
|} | |||
Calls [[SceSysmem#sceKernelFreeHeapMemoryForDriver|sceKernelFreeHeapMemoryForDriver]]. | |||
=== sceKernelCallModuleSuspendEntryForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990 || 0x829E1C94 | |||
|} | |||
=== sceKernelLibraryDBGetLibEntHeadForKernel === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990 || 0x1100A1B8 | |||
|} | |||
=== SceModulemgrForKernel_19A65337 === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.990 || 0x19A65337 | ||
|} | |} | ||
== SceModulemgrForDriver == | == SceModulemgrForDriver == | ||
=== sceKernelGetModuleInfoByAddrForDriver === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990-3.60 || 0x1D9E0F7E | |||
|} | |||
Note that this function is for kernel only. | |||
<source lang="C">int sceKernelGetModuleInfoByAddrForDriver(const void *module_addr, SceKernelModuleInfo *info);</source> | |||
=== sceKernelRegisterLibaryForDriver === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990-3.60 || 0x861638AD | |||
|} | |||
Note that this function is for kernel only. | |||
<source lang="C">int sceKernelRegisterLibaryForDriver(const void *module_addr);</source> | |||
=== sceKernelUnregisterLibraryForDriver === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990-3.60 || 0x0975B104 | |||
|} | |||
In old firmware versions (<= 1.70 - maybe even later), this function is named <code>sceKernelReleaseLibary</code> instead. | |||
Note that this function is for kernel only. | |||
<source lang="C"> | |||
//libent is a pointer to a LibEnt structure (export library structure) | |||
int sceKernelUnregisterLibraryForDriver(const void *libent); | |||
</source> | |||
=== sceKernelGetModuleInfoForDriver === | === sceKernelGetModuleInfoForDriver === | ||
Line 769: | Line 2,004: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1.69 || 0x36585DAF | | 0.990-1.69 || 0x36585DAF | ||
|- | |- | ||
| 3.60 || moved to [[SceKernelModulemgr#sceKernelGetModuleInfoForKernel|SceModulemgrForKernel]] | | 3.60 || moved to [[SceKernelModulemgr#sceKernelGetModuleInfoForKernel|SceModulemgrForKernel]] | ||
Line 779: | Line 2,014: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3.60 || 0xBBE1771C | | 1.03 || Not in ForDriver. On ForKernel. | ||
|- | |||
| 0.940-3.60 || 0xBBE1771C | |||
|} | |} | ||
<source lang="C"> | |||
// Returns (<0) if error or module is not loaded | |||
SceUID sceKernelSearchModuleByNameForDriver(const char *module_name); | |||
</source> | |||
=== sceKernelGetSystemSwVersionForDriver === | === sceKernelGetSystemSwVersionForDriver === | ||
Line 787: | Line 2,029: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.940 || not present. In non ForDriver though. | ||
|- | |- | ||
| 3. | | 0.990.000-3.740.011 || 0x5182E212 | ||
|} | |} | ||
Used in [[SceError]]. | |||
<source lang="C">int sceKernelGetSystemSwVersionForDriver(SceKernelSystemSwVersion *data);</source> | |||
=== sceKernelSetSystemSwVersionForDriver === | === sceKernelSetSystemSwVersionForDriver === | ||
Line 797: | Line 2,043: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.940 || not present. In non ForDriver though. | ||
|- | |- | ||
| 3. | | 0.990.000-2.060.011 || 0x912AEB73 | ||
|- | |||
| 2.100.081-3.740.011 || not present. Integrated with sceKernelGetSystemSwVersionForDriver | |||
|} | |} | ||
<source lang="C">int sceKernelSetSystemSwVersionForDriver(SceKernelSystemSwVersion *data);</source> | |||
=== sceKernelLoadStartModuleForDriver === | === sceKernelLoadStartModuleForDriver === | ||
Line 807: | Line 2,057: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1.69 | | 1.69-3.60 || 0x189BFBBB | ||
|} | |} | ||
<source lang=" | |||
<source lang="C"> | |||
/** | |||
* @brief PRX Load and start PRX | |||
* | |||
* moduleFileName After loading the PRX specified by the moduleFileName argument, start processing | |||
* is performed. | |||
* | |||
* During start processing, module_start () is called by a thread | |||
* that is initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority | |||
* and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. | |||
* When it is done, the argument block specified by the args and argp arguments are | |||
* copied to the thread stack and then passed to module_start(). | |||
* | |||
* If loading and start processing is successful, the return value | |||
* of the start entry function is stored in the area indicated by pRes. | |||
* | |||
* If SCE_KERNEL_START_NO_RESIDENT is returned as the return value of module_start() | |||
* the module is not resident in memory and is automatically unloaded after module_start() is executed. | |||
* If SCE_KERNEL_START_FAILED is returned, | |||
* the PRX has failed to load. A PRX is resident (loaded) only if it | |||
* returns a value other than SCE_KERNEL_START_NO_RESIDENT | |||
* or SCE_KERNEL_START_FAILED, including SCE_KERNEL_START_RESIDENT. | |||
* | |||
* @param[in] moduleFileName file name | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of start entry | |||
* | |||
* @retval (>0) module uid | |||
* @retval (<0) Error code | |||
*/ | |||
SceUID sceKernelLoadStartModuleForDriver(const char *moduleFileName, SceSize args, const void *argp, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== sceKernelLoadStartModuleForPidForDriver === | === sceKernelLoadStartModuleForPidForDriver === | ||
Line 820: | Line 2,103: | ||
| 3.60 || 0x9D953C22 | | 3.60 || 0x9D953C22 | ||
|} | |} | ||
<source lang="C"> | |||
<source lang="C"> | |||
/** | |||
* @brief PRX Load and start PRX | |||
* | |||
* moduleFileName After loading the PRX specified by the moduleFileName argument, start processing | |||
* is performed. | |||
* | |||
* During start processing, module_start () is called by a thread | |||
* that is initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority | |||
* and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. | |||
* When it is done, the argument block specified by the args and argp arguments are | |||
* copied to the thread stack and then passed to module_start(). | |||
* | |||
* If loading and start processing is successful, the return value | |||
* of the start entry function is stored in the area indicated by pRes. | |||
* | |||
* If SCE_KERNEL_START_NO_RESIDENT is returned as the return value of module_start() | |||
* the module is not resident in memory and is automatically unloaded after module_start() is executed. | |||
* If SCE_KERNEL_START_FAILED is returned, | |||
* the PRX has failed to load. A PRX is resident (loaded) only if it | |||
* returns a value other than SCE_KERNEL_START_NO_RESIDENT | |||
* or SCE_KERNEL_START_FAILED, including SCE_KERNEL_START_RESIDENT. | |||
* | |||
* @param[in] pid process id | |||
* @param[in] moduleFileName file name | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of start entry | |||
* | |||
* @retval (>0) module uid | |||
* @retval (<0) Error code | |||
*/ | |||
SceUID sceKernelLoadStartModuleForPidForDriver(SceUID pid, const char *moduleFileName, SceSize args, const void *argp, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== sceKernelLoadStartSharedModuleForPidForDriver === | === sceKernelLoadStartSharedModuleForPidForDriver === | ||
Line 829: | Line 2,148: | ||
| 3.60 || 0xE2ADEF8D | | 3.60 || 0xE2ADEF8D | ||
|} | |} | ||
<source lang="C">SceUID sceKernelLoadStartSharedModuleForPidForDriver(SceUID pid, const char * | |||
<source lang="C"> | |||
/** | |||
* @brief PRX Load and start PRX | |||
* | |||
* moduleFileName After loading the PRX specified by the moduleFileName argument, start processing | |||
* is performed. | |||
* | |||
* During start processing, module_start () is called by a thread | |||
* that is initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority | |||
* and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. | |||
* When it is done, the argument block specified by the args and argp arguments are | |||
* copied to the thread stack and then passed to module_start(). | |||
* | |||
* If loading and start processing is successful, the return value | |||
* of the start entry function is stored in the area indicated by pRes. | |||
* | |||
* If SCE_KERNEL_START_NO_RESIDENT is returned as the return value of module_start() | |||
* the module is not resident in memory and is automatically unloaded after module_start() is executed. | |||
* If SCE_KERNEL_START_FAILED is returned, | |||
* the PRX has failed to load. A PRX is resident (loaded) only if it | |||
* returns a value other than SCE_KERNEL_START_NO_RESIDENT | |||
* or SCE_KERNEL_START_FAILED, including SCE_KERNEL_START_RESIDENT. | |||
* | |||
* @param[in] pid process id | |||
* @param[in] moduleFileName file name | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of start entry | |||
* | |||
* @retval (>0) module uid | |||
* @retval (<0) Error code | |||
*/ | |||
SceUID sceKernelLoadStartSharedModuleForPidForDriver(SceUID pid, const char *moduleFileName, SceSize args, const void *argp, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== sceKernelLoadModuleWithoutStartForDriver / sceKernelLoadModuleForDriver === | === sceKernelLoadModuleWithoutStartForDriver / sceKernelLoadModuleForDriver === | ||
Line 836: | Line 2,191: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1.69 | | 1.69-3.60 || 0x86D8D634 | ||
|} | |} | ||
<source lang=" | |||
<source lang="C"> | |||
SceUID sceKernelLoadModuleForDriver(const char * | /** | ||
* @brief Load module | |||
* | |||
* moduleFileName Loads the module specified by moduleFileName. | |||
* If the load is successful, the module identifier is returned as the return value. | |||
* | |||
* @param[in] moduleFileName file name | |||
* @param[in] flags flags | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @retval (>0) module uid | |||
* @retval (<0) Error code | |||
*/ | |||
SceUID sceKernelLoadModuleForDriver(const char *moduleFileName, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt); | |||
</source> | </source> | ||
=== sceKernelStartModuleForDriver === | === sceKernelStartModuleForDriver === | ||
{| class="wikitable" | {| class="wikitable" | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1.69 | | 1.69-3.60 || 0x0675B682 | ||
|} | |} | ||
<source lang="c"> | <source lang="c"> | ||
// flags must be 0 | // flags must be 0 | ||
// | // pOpt can be null | ||
int sceKernelStartModuleForDriver(SceUID | |||
/** | |||
* @brief start module | |||
* | |||
* Starts the module specified by uid. When calling the start entry function, | |||
* the value specified by the args and argp arguments is passed as an argument. | |||
* | |||
* If the start process is successful, the library declared with AUTO_EXPORT will be registered. | |||
* Public processing is performed and the return value of the start entry function is stored in the area indicated by pRes. | |||
* If the start process fails, library registration and publishing will not be performed. | |||
* | |||
* SCE_KERNEL_START_NO_RESIDENT is returned as the return value of the start entry function | |||
* only if the module is automatically unloaded after executing the start entry function. | |||
* If SCE_KERNEL_START_FAILED is returned, the start process will fail. | |||
* At this time, the module is not unloaded. Modules that failed to start | |||
* It can be restarted with sceKernelStartModuleForDriver(). | |||
* | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of start entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
int sceKernelStartModuleForDriver(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStartModuleOpt *pOpt, int *pRes); | |||
</source> | </source> | ||
=== sceKernelStopUnloadModuleForDriver === | === sceKernelStopUnloadModuleForDriver === | ||
{| class="wikitable" | {| class="wikitable" | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1.69 | | 1.69-3.60 || 0x03B30B7E | ||
|} | |} | ||
<source lang=" | |||
<source lang="C"> | |||
// flags must be 0 | // flags must be 0 | ||
// opt can be null | // opt can be null | ||
int sceKernelStopUnloadModuleForDriver(SceUID | |||
/** | |||
* @brief Stop and unload PRX | |||
* | |||
* After stopping the PRX specified by the uid argument, unloading is performed. | |||
* | |||
* During stop processing, module_stop() is called by a thread that is | |||
* initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority | |||
* and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. | |||
* When it is done, the argument blocks specified by the args and argp | |||
* arguments are copied onto the thread stack and then passed to module_stop(). | |||
* | |||
* If the stop process is successful, the library released from PRX | |||
* is deleted and then unloaded, and the return value of | |||
* the stop entry function is stored in the area indicated by pRes. | |||
* | |||
* PRX stop and unload processing has failed only if SCE_KERNEL_STOP_CANCEL | |||
* is returned as the return value of module_stop(). | |||
* If any other value is returned, stop and unload processing has succeeded. | |||
* | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of stop entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
int sceKernelStopUnloadModuleForDriver(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt, int *pRes); | |||
</source> | </source> | ||
Line 883: | Line 2,298: | ||
| 3.60 || 0x49A3EDC7 | | 3.60 || 0x49A3EDC7 | ||
|} | |} | ||
<source lang="C">int sceKernelStopUnloadModuleForPidForDriver(SceUID pid, SceUID | |||
<source lang="C"> | |||
/** | |||
* @brief Stop and unload PRX | |||
* | |||
* After stopping the PRX specified by the uid argument, unloading is performed. | |||
* | |||
* During stop processing, module_stop() is called by a thread that is | |||
* initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority | |||
* and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. | |||
* When it is done, the argument blocks specified by the args and argp | |||
* arguments are copied onto the thread stack and then passed to module_stop(). | |||
* | |||
* If the stop process is successful, the library released from PRX | |||
* is deleted and then unloaded, and the return value of | |||
* the stop entry function is stored in the area indicated by pRes. | |||
* | |||
* PRX stop and unload processing has failed only if SCE_KERNEL_STOP_CANCEL | |||
* is returned as the return value of module_stop(). | |||
* If any other value is returned, stop and unload processing has succeeded. | |||
* | |||
* @param[in] pid process id | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of stop entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
int sceKernelStopUnloadModuleForPidForDriver(SceUID pid, SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== sceKernelStopUnloadSharedModuleForPidForDriver === | === sceKernelStopUnloadSharedModuleForPidForDriver === | ||
Line 899: | Line 2,346: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1.69 | | 1.69-3.60 || 0x100DAEB9 | ||
|} | |} | ||
<source lang=" | |||
<source lang="C"> | |||
/** | |||
* @brief Stop module | |||
* | |||
* Stops the module specified by uid. When calling the stop entry function, | |||
* the values specified by the args and argp arguments are passed as arguments. | |||
* | |||
* If the stop process is successful, the library released from the module is deleted, | |||
* and the return value of the stop entry function is stored in the area indicated by pRes. | |||
* If stop processing fails, library deletion processing is not performed. | |||
* | |||
* Only when SCE_KERNEL_STOP_SUCCESS is returned as the return value of the | |||
* stop entry function, module stop processing succeeds. | |||
* If any other value is returned, module stop processing will fail. | |||
* The module that failed to stop can be restarted with sceKernelStopModuleForDriver(). | |||
* | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of stop entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
int sceKernelStopModuleForDriver(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStopModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== sceKernelUnloadModuleForDriver === | === sceKernelUnloadModuleForDriver === | ||
Line 910: | Line 2,382: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1.69 || 0x728E72A6 | | 1.69-3.60 || 0x728E72A6 | ||
|} | |||
In 1.69 existed in SceModulemgrForKernel | |||
<source lang="C"> | |||
/** | |||
* @brief Unload module | |||
* | |||
* Unloads the module specified by uid. | |||
* | |||
* @param[in] uid module id | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter | |||
* | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
int sceKernelUnloadModuleForDriver(SceUID uid, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt); | |||
</source> | |||
=== load_with_logs === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |- | ||
| | | 0.990 || 0x57EE2372 | ||
|} | |} | ||
== SceModulemgr == | == SceModulemgr == | ||
=== | === sceKernelKttyWrite === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1. | | 0.940-1.692.000 || 0x4D76CF9E | ||
|- | |- | ||
| 3. | | 1.80-3.740.011 || not present | ||
|} | |} | ||
=== | === sceKernelPutc === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1. | | 0.931-1.692.000 || 0x9D2FE122 | ||
|- | |- | ||
| 3. | | 1.80-3.740.011 || not present | ||
|} | |} | ||
=== | <source lang="C">int sceKernelPutc(char c);</source> | ||
=== sceKernelGetSystemSwVersion === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.940-3.740.011 || 0x5182E212 | ||
|} | |} | ||
=== | <source lang="C">int sceKernelGetSystemSwVersion(SceKernelSystemSwVersion *data);</source> | ||
=== sceKernelSetSystemSwVersion === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.990-2.060.011 || 0x912AEB73 | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || not present | ||
|} | |} | ||
=== | This function can only be called in System program. | ||
This function was maybe removed because it represented a security threat: an exploit giving usermode code execution in a System program (for example PSPemu sandbox escape) could change the System Software version in SceKernelModulemgr data segment. The impact depends on which modules relied on that version buffer. | |||
<source lang="C">int sceKernelSetSystemSwVersion(SceKernelSystemSwVersion *data);</source> | |||
=== __sceKernelLoadModuleWithoutStart === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.990-2.060.011 || 0xA4E6DA4D | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || not present | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Load a module | |||
* | |||
* moduleFileName Loads the module specified by moduleFileName. | |||
* If the load is successful, the module identifier is returned as the return value. | |||
* | |||
* @param[in] moduleFileName file name | |||
* @param[in] flags flags | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @retval (>0) module uid | |||
* @retval (<0) Error code | |||
*/ | |||
SceUID __sceKernelLoadModuleWithoutStart(const char *moduleFileName, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt); | |||
</source> | |||
=== __sceKernelStartModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.990-2.060.011 || 0x1FD99C9F | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || not present | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Start a module | |||
* | |||
* Starts the module specified by uid. The module must have been loaded using __sceKernelLoadModuleWithoutStart. When calling the start entry function, | |||
* the value specified by the args and argp arguments is passed as an argument. | |||
* | |||
* If the start process is successful, the library declared with AUTO_EXPORT will be registered. | |||
* Public processing is performed and the return value of the start entry function is stored in the area indicated by pRes. | |||
* If the start process fails, library registration and publishing will not be performed. | |||
* | |||
* SCE_KERNEL_START_NO_RESIDENT is returned as the return value of the start entry function | |||
* only if the module is automatically unloaded after executing the start entry function. | |||
* If SCE_KERNEL_START_FAILED is returned, the start process will fail. | |||
* At this time, the module is not unloaded. Modules that failed to start | |||
* It can be restarted with __sceKernelStartModule(). | |||
* | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of start entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
int __sceKernelStartModule(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStartModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== __sceKernelStopModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.990-2.060.011 || 0xBA49EA5C | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || not present | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Stop a module | |||
* | |||
* Stops the module specified by uid. When calling the stop entry function, | |||
* the values specified by the args and argp arguments are passed as arguments. | |||
* | |||
* If the stop process is successful, the library released from the module is deleted, | |||
* and the return value of the stop entry function is stored in the area indicated by pRes. | |||
* If stop processing fails, library deletion processing is not performed. | |||
* | |||
* Only when SCE_KERNEL_STOP_SUCCESS is returned as the return value of the | |||
* stop entry function, module stop processing succeeds. | |||
* If any other value is returned, module stop processing will fail. | |||
* The module that failed to stop can be restarted with __sceKernelStopModule(). | |||
* | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of stop entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
int __sceKernelStopModule(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStopModuleOpt *pOpt, int *pRes); | |||
</source> | |||
=== __sceKernelUnloadModuleWithoutStop === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.990-2.060.011 || 0xE439E26B | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || not present | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Unload a module | |||
* | |||
* Unloads the module specified by uid. The module must have been stopped using __sceKernelStopModule if it was started using __sceKernelStartModule. | |||
* | |||
* @param[in] uid module id | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter | |||
* | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
int __sceKernelUnloadModuleWithoutStop(SceUID uid, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt); | |||
</source> | |||
=== __sceKernelOpenModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.990-2.060.011 || 0x9C2A9A49 | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || not present | ||
|} | |} | ||
=== | === __sceKernelCloseModule === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.990-2.060.011 || 0x5303C52F | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || not present | ||
|} | |} | ||
=== | === sceKernelGetModuleList === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1. | | 1.000.071-3.740.011 || 0x2EF2581F | ||
|} | |} | ||
=== | <source lang="C">int sceKernelGetModuleList(int flags, SceUID *modids, SceSize *num);</source> | ||
=== sceKernelGetModuleIdByAddr === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1. | | 1.000.071-3.740.011 || 0xF5798C7C | ||
|} | |} | ||
=== | <source lang="C">SceUID sceKernelGetModuleIdByAddr(const void *module_addr);</source> | ||
=== sceKernelGetModuleInfo === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1. | | 1.000.071-3.740.011 || 0x36585DAF | ||
|} | |} | ||
=== | <source lang="C">int sceKernelGetModuleInfo(SceUID modid, SceKernelModuleInfo *pInfo);</source> | ||
=== sceKernelGetAllowedSdkVersionOnSystem === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1. | | 0.931-1.06 || not present | ||
|- | |- | ||
| 3. | | 1.500.151-3.740.011 || 0x4397FC4E | ||
|} | |} | ||
=== | <source lang="C">int sceKernelGetAllowedSdkVersionOnSystem(void);</source> | ||
=== sceKernelGetLibraryInfoByNID === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 1. | | 0.931.010-1.06 || not present | ||
|- | |- | ||
| 3. | | 1.500.151-3.740.011 || 0xEAEB1312 | ||
|} | |} | ||
=== | Note that NONAME libraries (NID 0) are not supported by this function. sceKernelGetLibraryInfoByNID lookups the process libdb but libdb does not keep NONAME libraries. | ||
Note also that due to a bug, pInfo->libname is a pointer to kernel memory so dereferencing it causes an exception. | |||
<source lang="C">int sceKernelGetLibraryInfoByNID(SceUID modid, SceUInt32 libnid, SceKernelLibraryInfo *pInfo);</source> | |||
=== _sceKernelLoadModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0xB4C5EF9E | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Load a module | |||
* | |||
* moduleFileName Loads the module specified by moduleFileName. | |||
* If the load is successful, the module identifier is returned as the return value. | |||
* | |||
* @param[in] moduleFileName file name | |||
* @param[in] flags flags | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @retval (>0) module uid | |||
* @retval (<0) Error code | |||
*/ | |||
SceUID _sceKernelLoadModule(const char *moduleFileName, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt); | |||
</source> | |||
=== _sceKernelStartModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0x72CD301F | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Start a module | |||
* | |||
* Starts the module specified by uid. When calling the start entry function, | |||
* the value specified by the args and argp arguments is passed as an argument. | |||
* | |||
* If the start process is successful, the library declared with AUTO_EXPORT will be registered. | |||
* Public processing is performed and the return value of the start entry function is stored in the area indicated by pRes. | |||
* If the start process fails, library registration and publishing will not be performed. | |||
* | |||
* SCE_KERNEL_START_NO_RESIDENT is returned as the return value of the start entry function | |||
* only if the module is automatically unloaded after executing the start entry function. | |||
* If SCE_KERNEL_START_FAILED is returned, the start process will fail. | |||
* At this time, the module is not unloaded. Modules that failed to start | |||
* It can be restarted with _sceKernelStartModule(). | |||
* | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of start entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
typedef struct SceKernelModuleStartParam { | |||
SceUInt32 flags; | |||
int *status; | |||
const SceKernelStartModuleOpt *pOpt; | |||
int a4; // not used | |||
} SceKernelModuleStartParam; | |||
int _sceKernelStartModule(SceUID uid, SceSize args, const void *argp, const SceKernelModuleStartParam *pParam); | |||
</source> | |||
=== _sceKernelLoadStartModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0x60647592 | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Load and start a module | |||
* | |||
* moduleFileName After loading the module specified by the moduleFileName argument, start processing | |||
* is performed. | |||
* | |||
* During start processing, module_start () is called by a thread | |||
* that is initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority | |||
* and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. | |||
* When it is done, the argument block specified by the args and argp arguments are | |||
* copied to the thread stack and then passed to module_start(). | |||
* | |||
* If loading and start processing is successful, the return value | |||
* of the start entry function is stored in the area indicated by pRes. | |||
* | |||
* If SCE_KERNEL_START_NO_RESIDENT is returned as the return value of module_start() | |||
* the module is not resident in memory and is automatically unloaded after module_start() is executed. | |||
* If SCE_KERNEL_START_FAILED is returned, | |||
* the module has failed to load. A module is resident (loaded) only if it | |||
* returns a value other than SCE_KERNEL_START_NO_RESIDENT | |||
* or SCE_KERNEL_START_FAILED, including SCE_KERNEL_START_RESIDENT. | |||
* | |||
* @param[in] moduleFileName file name | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of start entry | |||
* | |||
* @retval (>0) module uid | |||
* @retval (<0) Error code | |||
*/ | |||
typedef struct SceKernelModuleLoadStartParam { | |||
SceUInt32 flags; | |||
int *status; | |||
const SceKernelLoadModuleOpt *option; | |||
int a4; // not used | |||
} SceKernelModuleLoadStartParam; | |||
SceUID _sceKernelLoadStartModule(const char *moduleFileName, SceSize args, const void *argp, const SceKernelModuleLoadStartParam *pParam); | |||
</source> | |||
=== _sceKernelStopModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0x086867A8 | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Stop a module | |||
* | |||
* Stops the module specified by uid. When calling the stop entry function, | |||
* the values specified by the args and argp arguments are passed as arguments. | |||
* | |||
* If the stop process is successful, the library released from the module is deleted, | |||
* and the return value of the stop entry function is stored in the area indicated by pRes. | |||
* If stop processing fails, library deletion processing is not performed. | |||
* | |||
* Only when SCE_KERNEL_STOP_SUCCESS is returned as the return value of the | |||
* stop entry function, module stop processing succeeds. | |||
* If any other value is returned, module stop processing will fail. | |||
* The module that failed to stop can be restarted with _sceKernelStopModule(). | |||
* | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of stop entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
typedef struct SceKernelModuleStopParam { | |||
SceUInt32 flags; | |||
int *status; | |||
const SceKernelStopModuleOpt *pOpt; | |||
int a4; // not used | |||
} SceKernelModuleStopParam; | |||
int _sceKernelStopModule(SceUID uid, SceSize args, const void *argp, const SceKernelModuleStopParam *pParam); | |||
</source> | |||
=== _sceKernelUnloadModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0x8E4A7716 | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Unload a module | |||
* | |||
* Unloads the module specified by uid. | |||
* | |||
* @param[in] uid module id | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter | |||
* | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
int _sceKernelUnloadModule(SceUID uid, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt); | |||
</source> | |||
=== _sceKernelStopUnloadModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0x86EAEA0A | ||
|} | |} | ||
=== | <source lang="C"> | ||
/** | |||
* @brief Stop and unload a module | |||
* | |||
* After stopping the module specified by the uid argument, unloading is performed. | |||
* | |||
* During stop processing, module_stop() is called by a thread that is | |||
* initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority | |||
* and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. | |||
* When it is done, the argument blocks specified by the args and argp | |||
* arguments are copied onto the thread stack and then passed to module_stop(). | |||
* | |||
* If the stop process is successful, the library released from module | |||
* is deleted and then unloaded, and the return value of | |||
* the stop entry function is stored in the area indicated by pRes. | |||
* | |||
* module stop and unload processing has failed only if SCE_KERNEL_STOP_CANCEL | |||
* is returned as the return value of module_stop(). | |||
* If any other value is returned, stop and unload processing has succeeded. | |||
* | |||
* @param[in] uid module id | |||
* @param[in] args argument block size | |||
* @param[in] argp argument block address | |||
* @param[in] flags flags, should be 0 | |||
* @param[in] pOpt option parameter, should be SCE_NULL | |||
* @param[out] pRes result of stop entry | |||
* @retval SCE_OK success | |||
* @retval (<0) Error code | |||
*/ | |||
typedef struct SceKernelModuleStopUnloadParam { | |||
SceUInt32 flags; | |||
int *status; | |||
const SceKernelUnloadModuleOpt *pOpt; | |||
int a4; // not used | |||
} SceKernelModuleStopUnloadParam; | |||
int _sceKernelStopUnloadModule(SceUID uid, SceSize args, const void *argp, const SceKernelModuleStopUnloadParam *pParam); | |||
</source> | |||
=== _sceKernelOpenModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0x9D674F45 | ||
|} | |} | ||
=== | <source lang="C"> | ||
typedef struct SceKernelModuleLoadStartParam { | |||
SceUInt32 flags; | |||
int *status; | |||
const SceKernelLoadModuleOpt *option; | |||
int a4; // not used | |||
} SceKernelModuleLoadStartParam; | |||
SceUID _sceKernelOpenModule(const char *moduleFileName, SceSize args, const void *argp, const SceKernelModuleLoadStartParam *pParam); | |||
</source> | |||
=== _sceKernelCloseModule === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0x849E78BE | ||
|} | |} | ||
<source lang="C"> | |||
typedef struct SceKernelModuleStopUnloadParam { | |||
SceUInt32 flags; | |||
int *status; | |||
const SceKernelUnloadModuleOpt *pOpt; | |||
int a4; // not used | |||
} SceKernelModuleStopUnloadParam; | |||
SceUID _sceKernelCloseModule(SceUID uid, SceSize args, const void *argp, const SceKernelModuleStopUnloadParam *pParam); | |||
</source> | |||
=== sceKernelIsCalledFromSysModule === | === sceKernelIsCalledFromSysModule === | ||
Line 1,156: | Line 2,962: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931-2.060.011 || not present | ||
|- | |- | ||
| 3. | | 2.100.081-3.740.011 || 0x85E6D2BB | ||
|} | |} | ||
<source lang="C">int sceKernelIsCalledFromSysModule(const void *module_addr);</source> | |||
=== sceKernelInhibitLoadingModule === | === sceKernelInhibitLoadingModule === | ||
Line 1,166: | Line 2,974: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| | | 0.931.010-3.36 || not present | ||
|- | |- | ||
| 3. | | 3.500.011-3.740.011 || 0x6CED1F63 | ||
|} | |} | ||
Introduced in System Software version 3.50 to prevent loading Sysmodules from the webbrowser. It is a security feature that makes kernel exploitation harder because it reduces the number of accessible syscalls from a WebKit usermode exploit. | |||
See also Vitasploit 2.00-3.36 post-WebKit-exploit API and h-encore 3.65-3.68 writeup by TheFloW. | |||
In [https://github.com/TheOfficialFloW/Trinity/blob/master/eboot/arm.c#L203 Trinity source code], a module is loaded with flags = 0x10 to bypass sceKernelInhibitLoadingModule(0x20) restriction. | |||
Used in [[ScePspemu]] (probably level 0x20), [[SceWebKitProcess]], [[SceWebKitProcessMini]]. | |||
Returns 0 on success. Returns 0x80020005 if level is invalid. | |||
Level must be strictly increasing: loading a module becomes more and more inhibited. | |||
<source lang="C"> | |||
#define SCE_MODULE_LOADING_INHIBIT_TO_FLAGS_0x8000_AND_SHARED 0x10 | |||
#define SCE_MODULE_LOADING_INHIBIT_TO_FLAGS_0x10 0x20 | |||
// level: Only values 0x10, 0x20, 0x30 are supported. | |||
int sceKernelInhibitLoadingModule(SceUInt16 level); | |||
</source> | |||
== SceBacktraceForDriver == | == SceBacktraceForDriver == | ||
Line 1,180: | Line 3,006: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-3.740.011 || 0x166B9C8C | ||
|} | |} | ||
<source lang="C"> | <source lang="C">int sceKernelBacktraceForDriver(SceUID threadId, SceKernelCallFrame *pCallFrameBuffer, SceSize numBytesBuffer, SceUInt32 *pNumReturn, SceInt32 mode);</source> | ||
int | === sceKernelPrintBacktraceForDriver === | ||
</source> | {| class="wikitable" | ||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-1.692.000 || 0xC5608386 | |||
|- | |||
| 1.800.071-3.740.011 || not present | |||
|} | |||
This is a guessed name. | |||
<source lang="C">int sceKernelPrintBacktraceForDriver(SceUID processId, const SceKernelCallFrame *pCallFrame, SceUInt32 numFrames);</source> | |||
=== | === sceKernelPrintBacktrace2ForDriver === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-1.692.000 || not present | ||
|- | |||
| 1.800.071-3.740.011 || 0x7C878F90 | |||
|} | |} | ||
=== | This is a guessed name. | ||
<source lang="C">int sceKernelPrintBacktrace2ForDriver(SceUID processId, const SceKernelCallFrame *pCallFrame, SceUInt32 numFrames);</source> | |||
=== sceKernelBacktraceForKernelForDriver === | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 0.990.000-2.060.011 || 0xCECD5584 | ||
|- | |||
| 2.100.081-3.740.011 || not present | |||
|} | |} | ||
This is a guessed name. Temp name was sceKernelBacktraceInternalForDriver. | |||
It does not have devmode/QAF check. It allows kernel trace. | |||
<source lang="C">int sceKernelBacktraceForKernelForDriver(SceUID threadId, SceKernelCallFrame *pCallFrameBuffer, SceSize numBytesBuffer, SceUInt32 *pNumReturn, SceInt32 mode);</source> | |||
=== sceKernelBacktraceForKernel2ForDriver === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990.000-2.060.011 || not present | |||
|- | |||
| 2.100.081-3.740.011 || 0x888E99B8 | |||
|} | |||
This is a guessed name. Temp name was sceKernelBacktraceInternal2ForDriver. | |||
It does not have devmode/QAF check. It allows kernel trace. | |||
<source lang="C">int sceKernelBacktraceForKernel2ForDriver(SceUID threadId, SceKernelCallFrame *pCallFrameBuffer, SceSize numBytesBuffer, SceUInt32 *pNumReturn, SceInt32 mode);</source> | |||
== SceBacktrace == | == SceBacktrace == | ||
Line 1,211: | Line 3,078: | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3. | | 1.000.071-3.740.011 || 0xBF371A98 | ||
|} | |} | ||
Calls [[ | Calls [[#sceKernelBacktraceForDriver|sceKernelBacktraceForDriver]]. | ||
<source lang="C"> | <source lang="C"> | ||
typedef struct SceBacktraceArgs { | |||
SceUInt32 *pNumReturn; /**< number of frames gathered. */ | |||
SceInt32 mode; /**< KERNEL or USER mode. / DONT_EXCEED */ | |||
} SceBacktraceArgs; | |||
/** | |||
* Get backtrace | |||
* - When called with pCallFrameBuffer=NULL, numBytesBuffer=0, | |||
* only the depth of the call stack can be obtained as a return value. | |||
* | |||
* @param threadId Thread ID, or SCE_KERNEL_BACKTRACE_CONTEXT_xxx | |||
* @param pCallFrameBuffer Buffer to get call frame | |||
* @param numBytesBuffer Buffer size (byte) | |||
* @param pNumReturn Pointer that receives the acquired number of frames | |||
* @param mode Action mode | |||
* @retval (0) Call stack depth, or SCE_OK | |||
* @retval (<0) Error code | |||
* @note Callable only with TOOL | |||
*/ | |||
SceInt32 _sceKernelBacktrace( | |||
SceUID threadId, /**< Thread ID, SCE_KERNEL_BACKTRACE_* can be used. */ | |||
SceKernelCallFrame *pCallFrameBuffer, /**< buffer for frames */ | |||
SceSize numBytesBuffer, /**< buffer size */ | |||
SceBacktraceArgs *pArgs | |||
); | |||
</source> | |||
=== _sceKernelPrintBacktrace === | |||
{| class="wikitable" | |||
|- | |||
! Version !! NID | |||
|- | |||
| 0.990-1.520.011 || 0x21F00CF2 | |||
|- | |||
| 1.60-3.740.011 || not present | |||
|} | |||
Calls [[#sceKernelPrintBacktraceForDriver|sceKernelPrintBacktraceForDriver]]. | |||
<source lang="C"> | |||
/** | |||
* Display backtrace | |||
* @param processId Process ID to which the frame belongs | |||
* @param pCallFrame Stack frame data | |||
* @param numFrames Maximum step | |||
* @retval (0) Success | |||
* @retval (<0) Error code | |||
*/ | |||
SceInt32 _sceKernelPrintBacktrace( | |||
SceUID processId, | |||
const SceKernelCallFrame *pCallFrame, | |||
SceUInt32 numFrames | |||
); | |||
</source> | |||
[[Category:ARM]] | |||
[[Category:Kernel]] | |||
[[Category:Modules]] | [[Category:Modules]] | ||
[[Category: | [[Category:Library]] |
Latest revision as of 06:25, 11 November 2023
SceKernelModulemgr is in charge of loading both user modules and kernel modules. SceKernelModulemgr calls SceSblAuthMgr functions for the SELF decryption process. SceKernelModulemgr loads the ELF programs into memory along with linking with NIDs and relocation of ELF in position independent executables.
Module
Version | World | Privilege |
---|---|---|
0.940-3.60 | Non-secure | Kernel |
The SELF can be found in os0:kd/modulemgr.skprx
.
Functions of this module are also embedded in NSKBL.
Libraries
This module exports kernel and user libraries.
Known NIDs
Version | Name | World | Visibility | NID |
---|---|---|---|---|
0.940-3.61 | SceModulemgrForKernel | Non-secure | Kernel | 0xC445FA63 |
3.63-3.65 | SceModulemgrForKernel | Non-secure | Kernel | 0x92C9FFC2 |
0.940-3.65 | SceModulemgrForDriver | Non-secure | Kernel | 0xD4A60A52 |
0.940-3.65 | SceModulemgr | Non-secure | User | 0xEAED1616 |
3.57-3.65 | SceBacktraceForDriver | Non-secure | Kernel | 0x77CB3DD6 |
3.57-3.65 | SceBacktrace | Non-secure | User | 0xB07B6A3F |
Internal Types
// These types are defined in elfutils typedef Elf32_Ehdr Elf32_Ehdr; typedef Elf32_Phdr Elf32_Phdr; typedef struct SCE_header { uint32_t magic; /* 53434500 = SCE\0 */ uint32_t version; /* header version 3*/ uint16_t sdk_type; /* */ uint16_t header_type; /* 1 self, 2 unknown, 3 pkg */ uint32_t metadata_offset; /* metadata offset */ uint64_t header_len; /* self header length */ uint64_t elf_filesize; /* ELF file length */ uint64_t self_filesize; /* SELF file length */ uint64_t unknown; /* UNKNOWN */ uint64_t self_offset; /* SELF offset */ uint64_t appinfo_offset; /* app info offset */ uint64_t elf_offset; /* ELF #1 offset */ uint64_t phdr_offset; /* program header offset */ uint64_t shdr_offset; /* section header offset */ uint64_t section_info_offset; /* section info offset */ uint64_t sceversion_offset; /* version offset */ uint64_t controlinfo_offset; /* control info offset */ uint64_t controlinfo_size; /* control info size */ uint64_t padding; } SCE_header; typedef struct SCE_appinfo { uint64_t program_authority_id; /* program authority id */ uint32_t vendor_id; /* vendor id */ uint32_t self_type; /* app type */ uint64_t version; /* app version */ uint64_t padding; /* UNKNOWN */ } SCE_appinfo; typedef struct segment_info { uint64_t offset; uint64_t length; uint64_t compression; // 1 = uncompressed, 2 = compressed uint64_t encryption; // 1 = encrypted, 2 = plain } segment_info; typedef struct self_data_buffer { SCE_header sce_header; SCE_appinfo sce_appinfo; Elf32_Ehdr elf_hdr; //... data goes } self_data_buffer; typedef struct SceDecryptCtx { //size is 0x30 self_data_buffer* self_header; // aligned buffer - based on (buffer_unaligned). // points at SCE_header followed by SCE_appinfo // size is usually 0x1000 int self_header_length; Elf32_Ehdr* elf_ptr; // pointer constructed with elf_offset Elf32_Phdr* phdr_ptr; // pointer constructed with phdr_offset uint8_t type; // ex: 2 uint8_t init_completed; uint8_t unk_12; uint8_t unk_13; segment_info* section_info_ptr; // pointer constructed with section_info_offset void* buffer_unaligned; // SELF header data - size 0x103F - raw data read from file int sm_ctx; // obtained with sceSblAuthMgrOpenForKernel SceSblSmCommContext130* context_130; SceUID fd; // file descriptor of SELF file - obtained with sceIoOpenForDriver SceUID pid; uint32_t max_size; } SceDecryptCtx; typedef struct SceDecryptCtxGlobal { // size is 0x4C uint32_t unk_0; uint32_t unk_4; // ex:3 void *module_decrypt_buff_ptr1; int decrypt_size; // max 0x10000 int unk_10; // 0 or 1 or 2 int unk_14; // ex:-1 void *module_decrypt_buff_ptr2; int unk_1C; // some size SceDecryptCtx *decrypt_ctx; SceUID evid; // SceModuleMgrSelfDecryptComm event flag SceUID tid; // SceModuleMgrSelfDecrypter thread uid void *unk_2C; // sceDeflateDecompressPartialForDriver out memblock int compressed_seg_size; uint32_t unk_34; // unk_2C out size? uint16_t segment_number; uint16_t unk_3A; // ex:0xFFFF SceDeflatePartialInputParam cbinfo; } SceDecryptCtxGlobal; typedef struct SceModuleLinkInfo { // size is 0x48-bytes struct { ScePVoid WorkPool; SceNID *FunctionNID; // in target module ScePVoid *ImportTable; // in target module SceNID *VariableNID; // in target module ScePVoid *RelocaTable; // in target module SceSize to_link_entry_number; SceSize to_link_entry_number_for_var; SceModuleClient *Client; } i; struct { ScePVoid WorkPool; void *data_0x24; // export func pointer list int data_0x28; void *data_0x2C; // export func pointer list? int data_0x30; SceSize export_entry_number; SceSize export_entry_number_for_var; void *data_0x3C; // export nid list void *data_0x40; // same to data_0x24? SceModuleLibEnt *LibEnt; } e; } SceModuleLinkInfo; typedef struct SceModuleLoadCtx { // size is 0x44 SceModuleCB *Module; int data_0x04; int data_0x08; int data_0x0C; int data_0x10; int data_0x14; int data_0x18; int data_0x1C; struct { SceUIntPtr base; // from elf header SceUID data_0x24; void *pKernelMap; } segments[3]; } SceModuleLoadCtx; #define SCE_KERNEL_PRELOAD_INHIBIT_LIBC (0x10000) #define SCE_KERNEL_PRELOAD_INHIBIT_LIBDBG (0x20000) #define SCE_KERNEL_PRELOAD_INHIBIT_LIBSHELLSVC (0x80000) #define SCE_KERNEL_PRELOAD_INHIBIT_LIBCDLG (0x100000) #define SCE_KERNEL_PRELOAD_INHIBIT_LIBFIOS2 (0x200000) #define SCE_KERNEL_PRELOAD_INHIBIT_APPUTIL (0x400000) #define SCE_KERNEL_PRELOAD_INHIBIT_LIBSCEFT2 (0x800000) #define SCE_KERNEL_PRELOAD_INHIBIT_LIBPVF (0x1000000) #define SCE_KERNEL_PRELOAD_INHIBIT_LIBPERF (0x2000000) // used by sceKernelLoadPreloadingModules typedef struct SceKernelPreloadModuleInfo { // size is 0x24 const char *module_name; const char *path[6]; SceUInt32 inhibit; int flags; } SceKernelPreloadModuleInfo;
Types
typedef struct SceKernelSystemSwVersion { // size is 0x28 on FW 0.990.030 SceSize size; // Size of this structure char versionString[0x1C]; SceUInt version; SceUInt unk_24; } SceKernelSystemSwVersion; typedef struct SceKernelSegmentInfo { SceUInt size; //!< this structure size (0x18) SceUInt perms; //!< probably rwx in low bits void *vaddr; //!< address in memory SceUInt memsz; //!< size in memory SceUInt flags; //!< meaning unknown SceUInt res; //!< unused? } SceKernelSegmentInfo; typedef struct SceKernelModuleName { char s[0x1C]; } SceKernelModuleName; typedef struct SceKernelModuleInfo { // size is 0x1B8 SceSize size; //!< sizeof(SceKernelModuleInfo) SceUID modid; uint16_t modattr; uint8_t modver[2]; char name[0x1C]; uint32_t unk28; void *start_entry; void *stop_entry; void *exit_entry; void *exidx_start; void *exidx_end; void *extab_start; void *extab_end; void *tls_start; SceSize tls_filesz; SceSize tls_memsz; char path[256]; SceKernelSegmentInfo segments[4]; SceUInt type; } SceKernelModuleInfo; typedef struct SceKernelSegmentInfo2 { // size is 0x14 SceSize size; // Size of this structure SceUInt32 perm; void *pVA; SceSize memsz; SceUInt32 alignment; } SceKernelSegmentInfo2; // Structure for SceCoredump only? typedef struct SceKernelModuleListInfo_0945 { SceSize size; SceUID modId; SceUInt8 sdkVer[4]; SceUInt8 modVer[4]; SceUInt16 type; SceUInt16 flags; void *start; SceUInt32 refCount; void *stop; void *exit; char modName[0x20]; SceUInt32 status; SceUInt32 dbgFingerprint; int segments_num; union { struct { SceKernelSegmentInfo2 SegmentInfo[1]; uint32_t addr[4]; } seg1; struct { SceKernelSegmentInfo2 SegmentInfo[2]; uint32_t addr[4]; } seg2; struct { SceKernelSegmentInfo2 SegmentInfo[3]; uint32_t addr[4]; } seg3; struct { SceKernelSegmentInfo2 SegmentInfo[4]; uint32_t addr[4]; } seg4; }; } SceKernelModuleListInfo_0945; typedef struct SceKernelModuleListInfo_360 { SceSize size; SceUID modId; SceUInt8 sdkVer[4]; SceUInt8 modVer[4]; SceUInt16 type; SceUInt16 flags; void *start; void *unk_0x18; // maybe bootstart, but user module is doesn't have module_bootstart. void *stop; void *exit; char modName[0x1A]; SceUInt16 unk_0x3A; // unused SceUInt32 unk_0x3C; // unused SceUInt32 unk_0x40; // unused SceUInt32 status; SceUInt32 dbgFingerprint; int segments_num; union { struct { SceKernelSegmentInfo2 SegmentInfo[1]; uint32_t addr[4]; } seg1; struct { SceKernelSegmentInfo2 SegmentInfo[2]; uint32_t addr[4]; } seg2; struct { SceKernelSegmentInfo2 SegmentInfo[3]; uint32_t addr[4]; } seg3; struct { SceKernelSegmentInfo2 SegmentInfo[4]; uint32_t addr[4]; } seg4; }; } SceKernelModuleListInfo_360; typedef struct SceKernelLibraryInfo { // size is 0x1C SceSize size; //!< sizeof(SceKernelLibraryInfo) uint16_t libver[2]; uint32_t libnid; const char *libname; uint16_t nfunc; uint16_t nvar; uint32_t *nid_table; uint32_t *entry_table; } SceKernelLibraryInfo; typedef struct SceKernelModuleExportEntry { uint32_t libnid; const void *entry; // function ptr. or vars? } SceKernelModuleExportEntry; typedef struct { SceUID modid; uint32_t libnid; } SceKernelModuleImportNID; typedef struct SceKernelModuleImportNonlinkedInfo { SceSize size; // 0x124 SceUID modid; uint32_t libnid; char libname[0x100]; uint32_t data_0x10C; uint32_t data_0x110; uint32_t data_0x114; uint32_t data_0x118; uint32_t data_0x11C; uint32_t data_0x120; } SceKernelModuleImportNonlinkedInfo; typedef struct SceKernelModuleLibraryInfo { SceSize size; //!< sizeof(SceKernelModuleLibraryInfo) : 0x120 SceUID library_id; uint32_t libnid; uint16_t libver[2]; uint16_t entry_num_function; uint16_t entry_num_variable; uint16_t unk_0x14; uint16_t unk_0x16; char library_name[0x100]; // offset : 0x18 uint32_t unk_0x118; SceUID modid2; } SceKernelModuleLibraryInfo; typedef struct SceSelfAppInfo { int vendor_id; int self_type; } SceSelfAppInfo; typedef int (* SceKernelModuleEntry)(SceSize args, void *argp); /** * Module common macro */ #define SCE_KERNEL_START_SUCCESS (0) /**< Successful startup */ #define SCE_KERNEL_START_RESIDENT SCE_KERNEL_START_SUCCESS /**< Successful startup (resident) */ #define SCE_KERNEL_START_NO_RESIDENT (1) /**< Successful startup (not resident) */ #define SCE_KERNEL_START_FAILED (2) /**< Failed to start */ #define SCE_KERNEL_STOP_SUCCESS (0) /**< Successful stop */ #define SCE_KERNEL_STOP_FAIL (1) /**< Failed to stop */ #define SCE_KERNEL_STOP_CANCEL SCE_KERNEL_STOP_FAIL /**< Stop was cancelled */ /** Module attributes */ #define SCE_MODULE_ATTR_NONE (0x0000) /**< No attributes specified */ /** obsolete */ #define SCE_KERNEL_MODULE_ATTR_NONE SCE_MODULE_ATTR_NONE /** * option parameter for load module APIs */ typedef struct SceKernelLoadModuleOpt { SceSize size; /**< Size of structure itself */ } SceKernelLoadModuleOpt; /** * option parameter for start module API */ typedef struct SceKernelStartModuleOpt { SceSize size; /**< size of structure itself */ SceUInt32 flags; /**< should be 0 */ SceUInt32 prologue; /**< should be 0 */ SceUInt32 start; /**< should be 0 */ } SceKernelStartModuleOpt; /** * option parameter for stop module API */ typedef struct SceKernelStopModuleOpt { SceSize size; /**< size of structure itself */ SceUInt32 flags; /**< should be 0 */ SceUInt32 epilogue; /**< should be 0 */ SceUInt32 stop; /**< should be 0 */ } SceKernelStopModuleOpt; /** * option parameter for unload module APIs */ typedef struct SceKernelUnloadModuleOpt { SceSize size; /**< size of structure itself */ } SceKernelUnloadModuleOpt; typedef struct SceLoadProcessParam { // size is 0x7C-bytes SceUInt32 sysver; char thread_name[0x20]; SceUInt32 initial_thread_priority; // ex: 0x100000EC SceSize initial_thread_stack_size; // ex: 0x6000 SceUInt32 unk_0x2C; SceUInt32 unk_0x30; SceKernelThreadOptParam threadOptParam; int unk_0x50; char process_name[0x20]; // not titleid SceUInt32 preload_disabled; void *module_proc_param; } SceLoadProcessParam; typedef struct SceModuleLibraryInfo { // size is 0x2C struct SceModuleLibraryInfo *next; struct SceModuleLibraryInfo *data_0x04; // maybe SceModuleExport *pExportInfo; /* * (syscall_idx & 0xFFF): syscall idx * (syscall_idx & 0x1000): has syscall flag? * (syscall_idx == 0): kernel export */ uint16_t syscall_info; uint16_t data_0x0E; /* * Number of times this export was imported into another module */ SceSize number_of_imported; SceModuleImportedInfo *pImportedInfo; SceUID libid_kernel; SceUID libid_user; SceModuleCB *pModCB; // Temp structure name was SceModuleInfoInternal int data_0x24; // zero? int data_0x28; // zero? } SceModuleLibraryInfo; typedef struct SceKernelModuleNonlinkedInfo { SceUID modid; uint32_t libnid; } SceKernelModuleNonlinkedInfo; #define SCE_KERNEL_BACKTRACE_CONTEXT_CURRENT (0x00000000) /**< Backtrace current context */ #define SCE_KERNEL_BACKTRACE_MODE_USER (0x00000000) /**< User stack backtrace */ #define SCE_KERNEL_BACKTRACE_MODE_KERNEL (0x00000001) #define SCE_KERNEL_BACKTRACE_MODE_DONT_EXCEED (0x00000002) /**< Don't get stack depth */ #define SCE_KERNEL_BACKTRACE_MODE_UNK_0x00000004 (0x00000004) // should exist because 8 exists #define SCE_KERNEL_BACKTRACE_MODE_UNK_0x00000008 (0x00000008) // exists based on FW 0.931 SceExcpmgr /** * Structure that represents one stage of the call stack */ typedef struct _SceKernelCallFrame { SceUIntVAddr sp; /**< stack pointer */ SceUIntVAddr pc; /**< program counter */ } SceKernelCallFrame; /** * Structures used for compatibility shim lists (hardcoded in SceProcessmgr) */ typedef struct _SceKernelFunctionShimInfo { SceUInt32 replaced_function_nid; /**< NID of the function that needs to be replaced */ SceUInt32 replacing_function_nid; /**< NID of the function that will serve as a replacement - must probably come from same library as replaced function */ } SceKernelFunctionShimInfo; typedef struct _SceKernelLibraryShimInfo { const char *library_name; /**< Name of the library the shimmed functions come from (i.e. SceThreadmgr) */ SceUInt32 unk_04; /**< Always 0 ? */ SceUInt32 function_shims_count; /**< Size of the array pointed to by next field */ SceKernelFunctionShimInfo* function_shims; } SceKernelLibraryShimInfo; typedef struct _SceKernelCompatibilityShimInfo { const char *title_id; /**< TitleID (process name) of the app this shim applies to */ SceUInt32 unk_04; /**< Always 0 ? */ SceUInt32 library_shims_count; /**< Size of the array pointed to by next field */ SceKernelLibraryShimInfo *library_shims; } SceKernelCompatibilityShimInfo;
Notes
Error codes
0x8002D018
The shared module is not importable be non-shared module and non-syscall.
0x8002D01E
Attempted to load a module with a start entry as bootfs.
Attempted to load a module that has syscall exports to usermode.
module_start no resident/failed
If module_start returns SCE_KERNEL_START_NO_RESIDENT, the module will start successfully, but it will be unloaded after the module_start call.
However, if the module_start of the module where the syscall export exists is called after boot and returns SCE_KERNEL_START_NO_RESIDENT/SCE_KERNEL_START_FAILED, then a kernel panic is triggered.
How to get module info
modid and SceUIDModuleClass are required to get module information.
Simply call sceGUIDReferObjectForDriver(sceKernelGetObjectForUidForDriver) with these parameters.
Module decrypt threads
SceKernelModulemgr_func_8100910D
This thread keeps waiting at sceKernelWaitEventFlagForDriver until a module decrypt request comes.
bits of sceKernelWaitEventFlagForDriver is 3.
Common functions
Decrypt module to membase with current ctx.
int SceKernelModulemgr_func_81009309(SceDecryptCtx *ctx, int seg_idx, void *membase, int arg4);
Called whenever a module is loaded.
flags process image : 0x4 normal module : 0x1000 process module shared : 0x8001 process module : 0x8002 homebrew plugin : 0x8000002 shared module : 0x8008001 normal module ? : 0x8008002 int SceKernelModulemgr_func_81001519(void *pInfo, const char *path, SceUID fd, void *a4, uint32_t flags);
Reads the header from the passed fd and performs some checks.
[out] ctx [in] pid [in] fd [in] context_130 int SceKernelModulemgr_func_81008DC9(void *ctx, SceUID pid, SceUID fd, void *context_130);
Data segment layout
Offsets are for FW 3.60.
Data section size is 0x203C0.
Offset | Size | Description |
---|---|---|
0x0000 | 0x30 | unknown |
0x0030 | 0x4 | some flags. Related to relocation. |
0x0034 | 0x4 | SceKernelSystemSwVersion data initialized flag |
0x0038 | 0x4 | pointer of ModulePrivate(9). |
0x003C | 0x4 | pointer of SceClass. The third class obtained with sceKernelSysrootGetModulePrivateForKernel. SceUIDLibStubClass |
0x0040 | 0x4 | pointer of SceClass. The second class obtained with sceKernelSysrootGetModulePrivateForKernel. SceUIDLibraryClass |
0x0044 | 0x4 | Return value of SceThreadmgrForDriver_B645C7EF. |
0x0048 | 0x4 | pointer of SceClass. The first class obtained with sceKernelSysrootGetModulePrivateForKernel. SceUIDModuleClass |
0x004C | 0x4 | SceModuleMgr Mutex uid |
0x0050 | 0x280 (4*0xA0) | unknown. some module data. (process max loadable module number is 0xA0) |
0x02D0 | 0x28 | SceKernelSystemSwVersion buffer |
0x02F8 | 0x4 | some thread id, check sceKernelModuleUnloadMySelfForKernel |
0x02FC | 0x4 | some kernel module uid, check sceKernelModuleUnloadMySelfForKernel |
0x0300 | 0x4 | unk, used by sceKernelLoadPreloadingModulesForKernel |
0x0304 | 0x4 | some storage ptr. used by sceKernelMountBootfsForKernel, sceKernelUmountBootfsForKernel |
0x0308 | 0x4 | pModuleEventDebugHandler |
0x030C | 0x4 | pointer of SceModuleSharedInfo. |
0x0310 | 0x4 | cpu_addr out (sceKernelCpuLockSuspendIntrStoreLRForDriver arg1) |
0x0314 | 0x4 | shared inhibit flag |
0x0318 | 0x4 | sceKernelGetMemBlockBaseForDriver membase out |
0x031C | 0x4 | sceKernelAllocMemBlockForDriver ret |
0x0320 | 0xC | unk |
0x032C | 0x4 | unk, used by SceModulemgrForKernel_F3CD647F |
0x0330 | 0x4 | unk, used by SceModulemgrForKernel_F3CD647F |
0x0334 | 0x4 | Syscall table vaddr. |
0x0338 | 0x4 | unk, related to syscall. used by sceMt19937GlobalUninitForDriver |
0x033C | 0x4 | unk |
0x0340 | 0x4C | SceDecryptCtxGlobal data |
0x038C | 0x34 | unk, all zero |
0x03C0 | 0x10000 | module decrypt buff 1 |
0x103C0 | 0x10000 | module decrypt buff 2 |
typedef struct SceKernelModulemgr_data_t { // size is 0x203C0 on FW 3.60 char unk_00[0x34]; // unknown, all zero int is_FwInfo_init; void *pModulePrivate9; SceClass *pSceUIDLibStubClass; SceClass *pSceUIDLibraryClass; int some_thread_res; SceClass *pSceUIDModuleClass; SceUID mutex_id; char unk_50[0x280]; // unknown SceKernelSystemSwVersion systemSwVersion; SceUID some_threadid; SceUID some_kernel_module_id; int unk_0x0300; void *bootfs_info; int (* pModuleEventDebugHandler)(void *pInfo); SceModuleSharedInfo *pSharedInfo; int cpu_addr; int shared_inhibit_flag; void *membase; SceUID memuid; int unk_0x0320[3]; int unk_0x032C; int unk_0x0330; void *syscall_table; int some_syscall_info; int unk_0x033C; SceDecryptCtxGlobal g_decrypt_ctx; char unk_0x038C[0x34]; char module_decrypt_buff1[0x10000]; char module_decrypt_buff2[0x10000]; } SceKernelModulemgr_data_t;
Loading Sequence
When loading a module the sequence creates a SceModule structure to represent it.
typedef struct SceModule { // ?size is 0x3EC? u8 unk0[0x64]; // 0x0 const char *filename; // 0x64 u8 unk1[0xC]; // 0x68 Elf32_Ehdr ehdr; // 0x74 Elf32_Phdr phdr; // 0xA8 void *text_addr; // 0x108 SceUID text_uid; // 0x10C u32 text_size; // 0x110 void *kernel_addr; // 0x114 SceUID kernel_uid; // 0x118 u8 unk2[0x2C8]; // 0x11C SceUID parent_pid; // 0x3E4 SceSblSmCommContext130* context_130; // 0x3E8 } SceModule;
SELF Decryption
The following code can decrypt a SELF located at path
.
Set self_type
to 1 if decrypting a usermode module else 0 for kernel (2 for SM but maybe not allowed).
Set media_type
to 0 if you're decrypting the SELF at the right location (for example decrypting sysmem.skprx
located in os0:
). If you have copied the SELF elsewhere, you need to set the media_type
to the right value for where the real path was.
use_cdram
is for modules that are too large and won't fit in contiguous regular memory.
int decrypt_self(const char *path, const char *out_prefix, int media_type, int use_cdram, int self_type) { char out_path[256]; int handle; int ret; int pid; int fd = 0, wfd = 0; char *ctx130 = NULL; char *hdr_buf = NULL, *hdr_buf_aligned; char *data_buf = NULL, *data_buf_aligned; int phdr; unsigned int hdr_size; // set up Auth Mgr ret = sceSblAuthMgrOpenForKernel(&handle); printf("sceSblAuthMgrOpenForKernel: 0x%08X, handle: 0x%08X\n", ret, handle); if (ret < 0) return 1; // set up ctx130 ctx130 = sceKernelLoadcoreKallocForKernel(0x10005, 0x130); printf("Ctx130: 0x%08X\n", ctx130); if (ctx130 == NULL) goto fail; memset(ctx130, 0, 0x130); if (ret < 0) goto fail; *(int *)(ctx130 + 0x4) = self_type; *(u64_t *)(ctx130 + 0x8) = 0x2808000000000001LL; *(u64_t *)(ctx130 + 0x10) = 0xF000C000000080LL; *(u64_t *)(ctx130 + 0x18) = 0xFFFFFFFF00000000LL; *(u64_t *)(ctx130 + 0x30) = 0xC300003800980LL; *(u64_t *)(ctx130 + 0x38) = 0x8009800000LL; *(u64_t *)(ctx130 + 0x48) = 0xFFFFFFFF00000000LL; if (media_type) *(int *)(ctx130 + 0x128) = media_type; else { ret = sceIoGetMediaTypeForDriver(0x10005, path, 1, ctx130 + 0x128); printf("sceIoGetMediaTypeForDriver: 0x%08X\n", ret); if (ret < 0) goto fail; } // read header fd = sceIoOpenForDriver(path, 1, 0); printf("sceIoOpenForDriver: 0x%08X\n", fd); if (fd < 0) goto fail; hdr_buf = sceKernelLoadcoreKallocForKernel(0x10005, 0x1000+63); hdr_buf_aligned = (char *)(((int)hdr_buf + 63) & 0xFFFFFFC0); printf("Header buffer: 0x%08X, aligned: 0x%08X\n", hdr_buf, hdr_buf_aligned); if (hdr_buf == NULL) goto fail; ret = sceIoReadForDriver(fd, hdr_buf_aligned, 0x1000); printf("Header read: 0x%08X\n", ret); hdr_size = *(unsigned int *)(hdr_buf_aligned + 0x10); if (hdr_size > 0x1000) { printf("Header too large: 0x%08X\n", hdr_size); goto fail; } ret = sceIoLseekForDriver(fd, 0LL, 0); printf("Header rewind: 0x%08X\n", ret); // set up SBL decryption for this SELF ret = sceSblAuthMgrAuthHeaderForKernel(handle, hdr_buf_aligned, hdr_size, ctx130); printf("sceSblAuthMgrAuthHeaderForKernel: 0x%08X\n", ret); if (ret < 0) goto fail; // set up read buffer data_buf = sceKernelLoadcoreKallocForKernel(0x10005, 0x10000+63); data_buf_aligned = (char *)(((int)data_buf + 63) & 0xFFFFFFC0); printf("Data buffer: 0x%08X, aligned: 0x%08X\n", data_buf, data_buf_aligned); if (data_buf == NULL) goto fail; // get sections int elf_offset = *(int*)(hdr_buf_aligned + 0x40); int num_segs = *(short*)(hdr_buf_aligned + elf_offset + 0x2C); printf("Number of segments to read: 0x%04X\n", num_segs); int info_offset = *(int*)(hdr_buf_aligned + 0x58); struct seg_info *segs = (struct seg_info *)(hdr_buf_aligned + info_offset); int phdr_offset = *(int*)(hdr_buf_aligned + 0x48); struct e_phdr *phdrs = (struct e_phdr *)(hdr_buf_aligned + phdr_offset); // decrypt sections int total, to_read, num_read, off; int aligned_size; int blkid = 0; void *pgr_buf; for (int i = 0; i < num_segs; ++i) { sprintf(out_path, "%s.seg%u", out_prefix, i); sceIoCloseForDriver(wfd); wfd = sceIoOpenForDriver(out_path, 0x602, 6); printf("sceIoOpenForDriver(%s): 0x%08X\n", out_path, wfd); if (wfd < 0) break; if (blkid) sceKernelFreeMemBlockForKernel(blkid); aligned_size = (phdrs[i].p_filesz + 4095) & 0xFFFFF000; if (use_cdram) blkid = sceKernelAllocMemBlockForKernel("self_decrypt_buffer", 0x40404006, 0x4000000, NULL); else blkid = sceKernelAllocMemBlockForKernel("self_decrypt_buffer", 0x1020D006, aligned_size, NULL); printf("sceKernelAllocMemBlockForKernel: 0x%08X, size: 0x%08X\n", blkid, aligned_size); ret = sceKernelGetMemBlockBaseForKernel(blkid, &pgr_buf); printf("sceKernelGetMemBlockBaseForKernel: 0x%08X, base: 0x%08X\n", ret, pgr_buf); if (ret < 0) break; // setup buffer for output ret = sceSblAuthMgrSetupAuthSegmentForKernel(handle, i, (u32_t)segs[i].length, pgr_buf, phdrs[i].p_filesz); printf("sceSblAuthMgrSetupAuthSegmentForKernel: 0x%08X\n", ret); if (ret < 0) break; ret = sceIoLseekForDriver(fd, segs[i].offset, 0); printf("sceIoLseekForDriver(0x%08X): 0x%08X\n", (u32_t)segs[i].offset, ret); if (ret < 0) break; total = (u32_t)segs[i].length; to_read = total > 0x10000 ? 0x10000 : total; off = 0; while (total > 0 && (num_read = sceIoReadForDriver(fd, data_buf_aligned + off, to_read)) > 0) { off += num_read; total -= num_read; if (num_read < to_read) { to_read -= num_read; continue; } ret = sceSblAuthMgrAuthSegmentForKernel(handle, data_buf_aligned, off); // decrypt buffer printf("sceSblAuthMgrAuthSegmentForKernel: 0x%08X\n", ret); if (ret < 0) printf("!!! ERROR !!!\n"); ret = sceSblAuthMgrLoadSegmentInternalForKernel(handle, data_buf_aligned, off); // copy buffer to output printf("sceSblAuthMgrLoadSegmentInternalForKernel: 0x%08X\n", ret); if (ret < 0) printf("!!! ERROR !!!\n"); off = 0; to_read = total > 0x10000 ? 0x10000 : total; } // write buffer off = 0; while ((off += sceIoWriteForDriver(wfd, pgr_buf + off, phdrs[i].p_filesz - off)) < phdrs[i].p_filesz); } if (blkid) sceKernelFreeMemBlockForKernel(blkid); sceIoCloseForDriver(wfd); fail: sceSblAuthMgrCloseForKernel(handle); if (fd) sceIoCloseForDriver(fd); if (ctx130) sceKernelLoadcoreKfreeForKernel(ctx130); if (hdr_buf) sceKernelLoadcoreKfreeForKernel(hdr_buf); if (data_buf) sceKernelLoadcoreKfreeForKernel(data_buf); return 1; }
Module decryption and signature checks ("HENkaku patches" on FW 1.60)
See also SELF_Loading to see how these SceSblAuthMgr functions are used to decrypt SELFs.
The code below will patch signature checks and bypass module decryption and allow homebrews to run. The idea is to hook SceSblAuthMgr* calls that are imported to SceKernelModulemgr. The offsets are from FW 1.60, you will probably need to modify functions defines (set to addresses of functions) and INSTALL_HOOK second arguments (set to addresses of imports in SceKernelModulemgr). For old FWs like 1.60, as there is no kASLR, you can set hardcoded addresses, else take HENkaku code. As a bonus there is also patch_npdrm functions that patches SceNpDrm to bypass some DRM checks and allow unsigned packages to be installed, which you also need to modify addresses. See SceNpDrm#Package_integrity_checks.
// hardcoded addresses for FW 1.60 #define G_OUR_EBOOT *(unsigned*)(0x01E60000 - 0x14) #define G_BUF *(unsigned*)(0x01E60000 - 0xC) #define G_WRITTEN *(unsigned*)(0x01E60000 - 0x10) #define Func(addr) ((unsigned(*)())(addr)) // Hardcoded addresses for FW 1.60 #define sceSblAuthMgrAuthHeaderForKernel Func(0x4BC6C9) #define sceSblAuthMgrSetupAuthSegmentForKernel Func(0x4BC851) #define sceSblAuthMgrAuthSegmentForKernel Func(0x4BC909) #define sceSblAuthMgrLoadSegmentInternalForKernel Func(0x4BCA89) // setup file decryption unsigned sceSblAuthMgrAuthHeaderForKernel_patched(unsigned a1, unsigned a2, unsigned a3, unsigned a4) { unsigned res = sceSblAuthMgrAuthHeaderForKernel(a1, a2, a3, a4); if (res == 0x800f0624 || res == 0x800f0616 || res == 0x800f0024) { G_OUR_EBOOT = 1; // patch somebuf so our module actually runs unsigned *somebuf = (unsigned*)a4; somebuf[42] = 0x40; return 0; } else { G_OUR_EBOOT = 0; } return res; } // setup output buffer unsigned sceSblAuthMgrSetupAuthSegmentForKernel_patched(unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5) { G_BUF = a4; G_WRITTEN = 0; if (G_OUR_EBOOT == 1) { return 0; } return sceSblAuthMgrSetupAuthSegmentForKernel(a1, a2, a3, a4, a5); } // decrypt unsigned sceSblAuthMgrAuthSegmentForKernel_patched(unsigned a1, unsigned a2, unsigned a3) { if (G_OUR_EBOOT == 1) { return 0; } return sceSblAuthMgrAuthSegmentForKernel(a1, a2, a3); } // copy to output - not present on 3.60 unsigned sceSblAuthMgrLoadSegmentInternalForKernel_patched(unsigned a1, unsigned a2, unsigned a3) { if (G_OUR_EBOOT == 1) { memcpy((void*)(G_BUF + G_WRITTEN), (void*)a2, a3); G_WRITTEN += a3; return 0; } return sceSblAuthMgrLoadSegmentInternalForKernel(a1, a2, a3); } #define INSTALL_HOOK(func, addr) \ { unsigned *target; \ target = (unsigned*)addr; \ *target++ = 0xE59FF000; /* ldr pc, [pc, #0] */ \ *target++; /* doesn't matter */ \ *target = (unsigned)func; \ } // hardcoded addresses for FW 1.60 void hook_install(void) { INSTALL_HOOK(sceSblAuthMgrLoadSegmentInternalForKernel_patched, 0x5BA9CC); INSTALL_HOOK(sceSblAuthMgrSetupAuthSegmentForKernel_patched, 0x5BA9DC); INSTALL_HOOK(sceSblAuthMgrAuthSegmentForKernel_patched, 0x5BAA0C); INSTALL_HOOK(sceSblAuthMgrAuthHeaderForKernel_patched, 0x5BAA1C); } unsigned get_module_base(const char *name) { int * modlist[MOD_LIST_SIZE]; int modlist_records; int res; SceKernelModuleInfo modinfo; memset(modlist, 0, sizeof(modlist)); modlist_records = MOD_LIST_SIZE; sceKernelGetModuleListForKernel(0x10005, 0x7FFFFFFF, 1, modlist, &modlist_records); for(int j = 0; j < modlist_records; j++) { memset(&modinfo, 0, sizeof(modinfo)); res = sceKernelGetModuleInfoForKernel(modlist[j], &modinfo); if (strcmp(modinfo.name, name) == 0) return (unsigned)modinfo.module_top; } return 0; } // Hardcoded addresses for FW 1.60 void patch_npdrm(unsigned base) { unsigned *patch; // check where check_func[0] is called patch = (unsigned*)(base + 0x310); *patch = 0x47702001; // check where check_func[1] is called patch = (unsigned*)(base + 0xaa4); *patch = 0x47702001; // always return 1 in install_allowed patch = (unsigned*)(base + 0x2d64); *patch = 0x47702001; // patch error code 0x80870003 patch = (unsigned*)(base + 0x4856); *patch = 0x2500; // second same error code patch = (unsigned*)(base + 0x35fe); *patch = 0x2600; } // Call this function from a thread int hook(void) { fprintf("Hook start\n"); unsigned prev_dacr; __asm__ volatile("mrc p15, 0, %0, c3, c0, 0" : "=r" (prev_dacr)); __asm__ volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (-1)); unsigned base_npdrm = get_module_base("SceNpDrm"); fprintf("SceNpDrm base: 0x%08x\n", base_npdrm); patch_npdrm(base_npdrm); hook_install(); __asm__ volatile("MCR p15, 0, %0, c7, c5, 0" : : "r" (0)); // flush icache __asm__ volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (prev_dacr)); sceKernelDelayThread(4*1000*1000); return 0; }
SceModulemgrForKernel
sceKernelRegisterModulesAfterBootForKernel
Version | NID |
---|---|
0.931.010-2.120.011 | not present |
2.500.071-3.610.011 | 0x3382952B |
3.630.011-3.740.011 | 0xD0AF9DB7 |
Temp name was sceKernelSetupForModulemgrForKernel.
void sceKernelRegisterModulesAfterBootForKernel(void);
sceKernelFinalizeKblForKernel
Version | NID |
---|---|
0.990-3.61 | 0xFDD7F646 |
3.63-3.65 | 0xB911516F |
Unloads ScePsp2BootConfig.
void sceKernelFinalizeKblForKernel(void);
sceKernelRegisterSyscallForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0xB427025E |
3.630.011-3.740.011 | 0x2E4A10A0 |
This is a guessed name.
void sceKernelRegisterSyscallForKernel(SceUInt32 index, void *function);
sceKernelLoadPtLoadSegForFwloaderForKernel
Version | NID |
---|---|
0.990-3.61 | 0x448810D5 |
3.63-3.65 | 0xA07063EA |
This is an easy way of decrypting SELF files but you are limited to the kinds of SELF files that you can load in the current context (for example, you cannot load user modules from kernel context). It is also susceptible to limitations of where the SELF can be loaded from. For example, you are not allowed to load SELFs found in os0:
from ux0:
because Secure Kernel checks the Media Type.
On FW 3.60, statically compiled SELF files give an error.
int sceKernelLoadPtLoadSegForFwloaderForKernel(const char *path, int e_phnum, void *buffer, uint32_t bufsize, int zero_unk, uint32_t *bytes_read);
sceKernelMountBootimageFSForKernel
Version | NID |
---|---|
0.931.010-0.990.000 | not present |
0.996.090-3.610.011 | 0x01360661 |
3.630.011-3.740.011 | 0x185FF1BC |
Temp name was sceKernelMountBootfsForKernel.
int sceKernelMountBootimageFSForKernel(const char *bootImagePath);
sceKernelUmountBootimageFSForKernel
Version | NID |
---|---|
0.931.010-0.990.000 | not present |
0.996.090-3.610.011 | 0x9C838A6B |
3.630.011-3.740.011 | 0xBD61AD4D |
Temp name was sceKernelUmountBootfsForKernel.
int sceKernelUmountBootimageFSForKernel(void);
sceKernelLoadRemoteModuleForKernel
Version | NID |
---|---|
0.931.011-2.060.011 | not present |
2.100.081-3.610.011 | 0xFA21D8CB |
3.630.011-3.740.011 | 0x4E85022D |
Temp name was sceKernelLoadModuleForPidForKernel.
/** * @brief Load module * * moduleFileName Loads the module specified by moduleFileName. * If the load is successful, the module identifier is returned as the return value. * * @param[in] moduleFileName file name * @param[in] flags flags * @param[in] pOpt option parameter, should be SCE_NULL * @retval (>0) module uid * @retval (<0) Error code */ SceUID sceKernelLoadRemoteModuleForKernel(SceUID pid, const char *moduleFileName, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt);
sceKernelUnloadRemoteModuleForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x5972E2CC |
3.630.011-3.740.011 | 0xFCA9FDB1 |
Temp name was sceKernelUnloadModuleForPidForKernel.
/** * @brief Unload module * * Unloads the module specified by uid. * * @param[in] pid process id * @param[in] uid module id * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter * * @retval SCE_OK success * @retval (<0) Error code int sceKernelUnloadRemoteModuleForKernel(SceUID pid, SceUID uid, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt);
sceKernelStartRemoteModuleForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x6DF745D5 |
3.630.011-3.740.011 | 0x3FE47DDF |
Temp name was sceKernelStartModuleForPidForKernel.
/** * @brief start module for process * * Starts the module specified by uid. When calling the start entry function, * the value specified by the args and argp arguments is passed as an argument. * * If the start process is successful, the library declared with AUTO_EXPORT will be registered. * Public processing is performed and the return value of the start entry function is stored in the area indicated by pRes. * If the start process fails, library registration and publishing will not be performed. * * SCE_KERNEL_START_NO_RESIDENT is returned as the return value of the start entry function * only if the module is automatically unloaded after executing the start entry function. * If SCE_KERNEL_START_FAILED is returned, the start process will fail. * At this time, the module is not unloaded. Modules that failed to start * It can be restarted with sceKernelStartRemoteModuleForKernel(). * * @param[in] pid process id * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of start entry * @retval SCE_OK success * @retval (<0) Error code */ int sceKernelStartRemoteModuleForKernel(SceUID pid, SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStartModuleOpt *pOpt, int *pRes);
sceKernelStopRemoteModuleForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x7BB4CE54 |
3.630.011-3.740.011 | 0xBDBD391D |
Temp name was sceKernelStopModuleForPidForKernel.
/** * @brief Stop module * * Stops the module specified by uid. When calling the stop entry function, * the values specified by the args and argp arguments are passed as arguments. * * If the stop process is successful, the library released from the module is deleted, * and the return value of the stop entry function is stored in the area indicated by pRes. * If stop processing fails, library deletion processing is not performed. * * Only when SCE_KERNEL_STOP_SUCCESS is returned as the return value of the * stop entry function, module stop processing succeeds. * If any other value is returned, module stop processing will fail. * The module that failed to stop can be restarted with sceKernelStopModuleForPidForKernel(). * * @param[in] pid process id * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of stop entry * @retval SCE_OK success * @retval (<0) Error code */ int sceKernelStopRemoteModuleForKernel(SceUID pid, SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStopModuleOpt *pOpt, int *pRes);
sceKernelModuleUnloadMySelfForKernel
Version | NID |
---|---|
0.931.011-2.060.011 | not present |
2.100.081-3.610.011 | 0x2A69385E |
3.630.011-3.740.011 | 0x2F82EEBC |
This is a guessed name.
int sceKernelModuleUnloadMySelfForKernel(void);
sceKernelLoadProcessImageForKernel
Version | NID |
---|---|
0.931.010-3.610.011 | 0xAC4EABDB |
3.630.011-3.740.011 | 0xA85A44D7 |
/** * @brief load process image * * @param[in] pid - target pid * @param[in] path - path * @param[in] flags - generally 0 - 0x10000 added if flag 0x40000000 is passed to sceKernelCreateProcess, 0x4000 added if an option is passed to sceKernelCreateProcess via the Opt argument * @param[out] auth_info * @param[out] param * @param[in] shim_info - compatibility shim information, only used for one game (PCSG00063/PCSB000144) in 3.65 * * @return modid, < 0 on error. */ SceUID sceKernelLoadProcessImageForKernel(SceUID pid, const char *path, int flags, SceSelfAuthInfo *auth_info, SceLoadProcessParam *param, SceKernelCompatibilityShimInfo* shim_info);
sceKernelLoadPreloadingModulesForKernel
Version | NID |
---|---|
0.931.010-3.610.011 | 0x3AD26B43 |
3.630.011-3.740.011 | 0xE3C1AAA1 |
Temp name was sceKernelLoadProcessModulesForKernel, sceKernelLoadStartDefaultSharedModulesForPidForKernel.
Loads the preloading modules for a process. This includes, for instance, SceLibKernel
.
If dipsw 210 is set, it checks if the preloading module flag and 0x8 are set, OR the flag 0x20 of sceKernelLoadModule. If that is the case, the module is loaded into DevKit Additional Memory (DRAM).
param[in] flags - process modules flags. 1:inhibit shared and load libgxm_dbg_es4.suprx Instead of libgxm_es4.suprx 2:not use default lib int sceKernelLoadPreloadingModulesForKernel(SceUID pid, const SceLoadProcessParam *pParam, int flags);
sceKernelUnloadProcessModulesForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x0E33258E |
3.630.011-3.740.011 | 0xE71530D7 |
Temp name was sceKernelStopUnloadPreloadingModulesForKernel.
int sceKernelUnloadProcessModulesForKernel(SceUID pid);
sceKernelStartPreloadingModulesForKernel
Version | NID |
---|---|
0.931.010-3.610.011 | 0x432DCC7A |
3.630.011-3.740.011 | 0x998C7AE9 |
Temp name was sceKernelStartProcessModulesForKernel.
int sceKernelStartPreloadingModulesForKernel(SceUID pid);
sceKernelGetModuleListForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x97CF7B4E |
3.630.011-3.740.011 | 0xB72C75A4 |
This is a guessed name.
int sceKernelGetModuleListForKernel(SceUID pid, int flags1, int flags2, SceUID *modids, SceSize *num);
sceKernelGetModuleInfoForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0xD269F915 |
3.630.011-3.740.011 | 0xDAA90093 |
This is a guessed name.
int sceKernelGetModuleInfoForKernel(SceUID pid, SceUID modid, SceKernelModuleInfo *info);
sceKernelGetModuleInfoForDebuggerForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x410E1D2E |
3.630.011-3.740.011 | 0x0155FE40 |
Temp name was sceKernelGetModuleList2ForKernel.
int sceKernelGetModuleInfoForDebuggerForKernel(SceUID pid, SceKernelModuleListInfo *infolists, SceSize *num);
sceKernelGetModuleInfoMinByAddrForKernel
Version | NID |
---|---|
0.931.010-2.060.011 | not present |
2.100.081-3.610.011 | 0x8309E043 |
3.630.011-3.740.011 | 0x5564A860 |
This is a guessed name.
int sceKernelGetModuleInfoMinByAddrForKernel(SceUID pid, void *addr, SceUInt32 *puiDbgFingerprint, void **pProgramTextAddr, SceKernelModuleName *pModuleName);
sceKernelGetModuleCBForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0xFE303863 |
3.630.011-3.740.011 | 0x37512E29 |
This is a guessed name. Temp name was sceKernelGetModuleInternalForKernel, sceKernelGetModuleCBForDebuggerForKernel.
This function returns a pointer to the "ModuleCB" (module control block) for specified module UID.
0.990:
void **sceKernelGetModuleCBForKernel(SceUID modid);
3.60:
int sceKernelGetModuleCBForKernel(SceUID modid, void **ppModCB);
sceKernelGetModuleIdByPidForKernel
Version | NID |
---|---|
0.931.010-2.060.011 | not present |
2.100.081-3.610.011 | 0x20A27FA9 |
3.630.011-3.740.011 | 0x679F5144 |
/** * @brief Get the module ID for a given process. * @param pid The process to query. * @return the UID of the module else < 0 for an error. */ SceUID sceKernelGetModuleIdByPidForKernel(SceUID pid);
Version | NID |
---|---|
0.931.010-2.060.011 | not present |
2.100.081-3.610.011 | 0x99890202 |
3.630.011-3.740.011 | 0xF1DE6949 |
This is a guessed name.
int sceKernelGetModuleIsSharedByAddrForKernel(SceUID pid, void *addr);
sceKernelGetModulePathForKernel
Version | NID |
---|---|
3.60-3.61 | 0x779A1025 |
3.63-3.65 | 0x79E761B5 |
This is a guessed name. Temp name was sceKernelGetProcessMainModulePathForKernel.
int sceKernelGetModulePathForKernel(SceUID modid, char *path, SceSize pathlen);
sceKernelGetModuleFingerprintForKernel
Version | NID |
---|---|
3.60-3.61 | 0xEEA92F1F |
3.63-3.65 | 0x337A3908 |
This is a guessed name.
int sceKernelGetModuleFingerprintForKernel(SceUID moduleId, SceUInt32 *pFingerprint);
sceKernelGetModuleCBByAddrForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x2C2618D9 |
3.630.011-3.740.011 | 0x1728612F |
This is a guessed name. Temp name was sceKernelGetModuleInternalByAddrForKernel, sceKernelGetProcessEntryPointByAddrForKernel.
Used by sceKernelPrintBacktraceForDriver.
int sceKernelGetModuleCBByAddrForKernel(SceUID pid, void *addr, SceModuleCB **ppModuleCB);
sceKernelGetModuleIdByAddrForDebuggerForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x0053BA4A |
3.630.011-3.740.011 | 0x0C668636 |
Temp name was sceKernelGetModuleIdByAddrForKernel.
SceUID sceKernelGetModuleIdByAddrForDebuggerForKernel(SceUID pid, ScePVoid addr);
sceKernelGetModuleEntryPointForKernel
Version | NID |
---|---|
0.931.010-2.060.011 | not present |
2.100.081-3.610.011 | 0x66606301 |
3.630.011-3.740.011 | 0x7B302C5D |
This is a guessed name.
SceKernelModuleEntry sceKernelGetModuleEntryPointForKernel(SceUID modid);
sceKernelGetLibraryListForKernel
Version | NID |
---|---|
3.60-3.61 | 0x1FDEAE16 |
3.63-3.65 | 0x12AD6DE3 |
This is a guessed name. Temp name was sceKernelGetModuleUidListForKernel, sceKernelGetProcessLibraryIdListForKernel.
int sceKernelGetLibraryListForKernel(SceUID pid, SceUID *library_ids, SceSize *num);
sceKernelGetImportedLibraryListInModuleForKernel
Version | NID |
---|---|
3.60-3.61 | 0x2DD3B511 |
3.63-3.65 | 0x1360E9A8 |
int sceKernelGetImportedLibraryListInModuleForKernel(SceUID pid, SceUID modid, SceUID *library_ids, SceSize *num);
sceKernelGetExportedLibraryListInModuleForKernel
Version | NID |
---|---|
3.60-3.61 | 0x619925F1 |
3.63-3.65 | 0x7E3F9F55 |
int sceKernelGetExportedLibraryListInModuleForKernel(SceUID pid, SceUID modid, SceUID *library_ids, SceSize *num);
sceKernelGetLibraryDBFlagsForKernel
Version | NID |
---|---|
3.60-3.61 | 0x7A1E882D |
3.63-3.65 | 0x1C82E9F7 |
Temp name was sceKernelGetModuleInhibitStateForKernel.
int sceKernelGetLibraryDBFlagsForKernel(SceUID pid, int *pFlags);
sceKernelGetLibraryClientListForKernel
Version | NID |
---|---|
3.60-3.61 | 0x3B93CF88 |
3.63-3.65 | 0xAAF6E971 |
Temp name was sceKernelGetModuleUidForKernel.
int sceKernelGetLibraryClientListForKernel(SceUID pid, SceUID library_id, SceUID *modids, SceSize *num, SceSize cpy_skip_num);
sceKernelGetLibEntCBListForSyslibtraceForKernel
Version | NID |
---|---|
3.60-3.61 | 0x8D1AA624 |
3.63-3.65 | 0x534519CD |
int sceKernelGetLibEntCBListForSyslibtraceForKernel(SceModuleLibraryInfo **ppList, SceSize *num);
sceKernelGetLibraryExportInfoForDebuggerForKernel
Version | NID |
---|---|
3.60-3.61 | 0xD4BF409C |
3.63-3.65 | 0xACDB6FEF |
int sceKernelGetLibraryExportInfoForDebuggerForKernel(SceUID pid, SceUID library_id, SceKernelModuleExportEntry *list, SceSize *num, SceSize cpy_skip_num);
sceKernelGetLibraryInfoForDebuggerForKernel
Version | NID |
---|---|
3.60-3.61 | 0x6A655255 |
3.63-3.65 | 0xB54482AF |
Temp name was sceKernelGetModuleLibraryInfoForKernel.
int sceKernelGetLibraryInfoForDebuggerForKernel(SceUID pid, SceUID library_id, SceKernelModuleLibraryInfo *info);
sceKernelGetStubListForKernel
Version | NID |
---|---|
0.931.010-3.010.031 | not present |
3.100.081-3.610.011 | 0x1D341231 |
3.630.011-3.740.011 | 0xE48CDE07 |
int sceKernelGetStubListForKernel(SceUID pid, SceUID *stub, SceSize *num);
sceKernelGetStubInfoForDebuggerForKernel
Version | NID |
---|---|
0.931.010-3.010.031 | not present |
3.100.081-3.610.011 | 0xB73BE671 |
3.630.011-3.740.011 | 0x07DBB649 |
// a3 size is 0x128 int sceKernelGetStubInfoForDebuggerForKernel(SceUID pid, SceUID stubid, void *a3);
sceKernelGetStubNidTableForDebuggerForKernel
Version | NID |
---|---|
0.931.010-3.010.031 | not present |
3.100.081-3.610.011 | 0xFB251B7A |
3.630.011-3.740.011 | 0xCE201AFC |
// a3 size is 8 * num int sceKernelGetStubNidTableForDebuggerForKernel(SceUID pid, SceUID stubid, void *a3, SceSize *num, SceSize cpy_skip_num);
sceKernelGetProgramIdentificationInfoForKernel
Version | NID |
---|---|
0.931.010-3.010.031 | not present |
2.000.081-3.610.011 | 0xF95D09C2 |
3.630.011-3.740.011 | 0x5D60CD77 |
int sceKernelGetProgramIdentificationInfoForKernel(const char *path, SceUInt64 *pAuthid, SceSelfAppInfo *pInfo);
sceKernelGetMetaDataForDebuggerForKernel
Version | NID |
---|---|
0.990.000-3.610.011 | 0x78DBC027 |
3.630.011-3.740.011 | 0x2E6569F3 |
int sceKernelGetMetaDataForDebuggerForKernel(SceUID pid, SceUID userModuleId, SceKernelModuleEntry *start, SceKernelModuleEntry *stop);
sceKernelGetLostLibraryInfoForKernel
Version | NID |
---|---|
0.931.010-1.692.000 | not present |
1.800.071-3.610.011 | 0x952535A3 |
3.630.011-3.740.011 | 0x388D4DE0 |
int sceKernelGetLostLibraryInfoForKernel(SceUID pid, SceUID modid, SceNID libnid, SceKernelModuleImportNonlinkedInfo *info);
sceKernelGetLostLibraryListInModuleForKernel
Version | NID |
---|---|
0.931.010-1.692.000 | not present |
1.800.071-3.610.011 | 0xFF2264BB |
3.630.011-3.740.011 | 0x6A5DFBBA |
int sceKernelGetLostLibraryListInModuleForKernel(SceUID pid, SceUID modid, SceKernelModuleNonlinkedInfo *pList, SceSize *num);
sceKernelGetLostLibraryListForKernel
Version | NID |
---|---|
0.931.010-1.692.000 | not present |
1.800.071-3.610.011 | 0x1BDE2ED2 |
3.630.011-3.740.011 | 0x7D71892B |
int sceKernelGetLostLibraryListForKernel(SceUID pid, SceKernelModuleImportNID *a2, SceSize *num);
sceKernelRegisterDebugCBForKernel
Version | NID |
---|---|
0.931.010-3.010.031 | not present |
3.100.081-3.610.011 | 0x60E176C8 |
3.630.011-3.740.011 | 0x74A4E0EE |
This is a guessed name.
Used by SceDeci4pDtracep.
int sceKernelRegisterDebugCBForKernel(const void *pHandler);
sceKernelUnregisterDebugCBForKernel
Version | NID |
---|---|
3.60-3.61 | 0x9D20C9BB |
3.63-3.65 | 0xACBC97C9 |
This is a guessed name.
int sceKernelUnregisterDebugCBForKernel(const void *pHandler);
sceKernelUnlinkNormalSyscallForKernel
Version | NID |
---|---|
3.60-3.61 | 0x29CB2771 |
3.63-3.65 | 0x353821B2 |
int sceKernelUnlinkNormalSyscallForKernel(SceUID pid);
sceKernelLinkWeakLibraryByLibnameForKernel
Version | NID |
---|---|
3.60-3.61 | 0x4865C72C |
3.63-3.65 | 0x26C28FA4 |
int sceKernelLinkWeakLibraryByLibnameForKernel(SceUID pid, const char *libname);
SceModulemgrForKernel_F3CD647F
Version | NID |
---|---|
3.60-3.61 | 0xF3CD647F |
3.63-3.65 | 0xB23286B8 |
Set two param. Maybe related to syscall.
Used by SceSysLibTrace.
void SceModulemgrForKernel_F3CD647F(void *a1, const void *func);
sceKernelLibraryDBGetSyslibtraceCBForKernel
Version | NID |
---|---|
0.990 | 0x3AE7F62F |
3.60 | not present |
sceKernelLibraryDBSetSyslibtraceCBForKernel
Version | NID |
---|---|
0.990 | 0x7E68D6EC |
SceModulemgrForKernel_06D9392A
Version | NID |
---|---|
0.990.000-1.692.000 | 0x06D9392A |
1.800.071-3.740.011 | not present |
SceModulemgrForKernel_06D9392A(int modid, void *addr, int *out);
sceModulemgrLockLibDBForKernel
Version | NID |
---|---|
0.990 | 0x37C2A1A5 |
sceModulemgrUnlockLibDBForKernel
Version | NID |
---|---|
0.990 | 0x0751F162 |
SceModulemgrForKernel_04ADDA3E
Version | NID |
---|---|
0.990 | 0x04ADDA3E |
sceKernelGetProcessEntryPointForKernel
Version | NID |
---|---|
0.990.000-2.060.011 | 0xC72CA412 |
2.100.081-3.740.011 | not present |
sceKernelLoadcoreKallocForKernel
Version | NID |
---|---|
0.990 | 0xB4A1DE31 |
void *sceKernelLoadcoreKallocForKernel(SceSize len);
sceKernelLoadcoreKfreeForKernel
Version | NID |
---|---|
0.990.000-1.692.000 | 0xF4B2D8B8 |
1.800.071-3.740.011 | 0xF4B2D8B8 |
Calls sceKernelFreeHeapMemoryForDriver.
sceKernelCallModuleSuspendEntryForKernel
Version | NID |
---|---|
0.990 | 0x829E1C94 |
sceKernelLibraryDBGetLibEntHeadForKernel
Version | NID |
---|---|
0.990 | 0x1100A1B8 |
SceModulemgrForKernel_19A65337
Version | NID |
---|---|
0.990 | 0x19A65337 |
SceModulemgrForDriver
sceKernelGetModuleInfoByAddrForDriver
Version | NID |
---|---|
0.990-3.60 | 0x1D9E0F7E |
Note that this function is for kernel only.
int sceKernelGetModuleInfoByAddrForDriver(const void *module_addr, SceKernelModuleInfo *info);
sceKernelRegisterLibaryForDriver
Version | NID |
---|---|
0.990-3.60 | 0x861638AD |
Note that this function is for kernel only.
int sceKernelRegisterLibaryForDriver(const void *module_addr);
sceKernelUnregisterLibraryForDriver
Version | NID |
---|---|
0.990-3.60 | 0x0975B104 |
In old firmware versions (<= 1.70 - maybe even later), this function is named sceKernelReleaseLibary
instead.
Note that this function is for kernel only.
//libent is a pointer to a LibEnt structure (export library structure) int sceKernelUnregisterLibraryForDriver(const void *libent);
sceKernelGetModuleInfoForDriver
Version | NID |
---|---|
0.990-1.69 | 0x36585DAF |
3.60 | moved to SceModulemgrForKernel |
sceKernelSearchModuleByNameForDriver
Version | NID |
---|---|
1.03 | Not in ForDriver. On ForKernel. |
0.940-3.60 | 0xBBE1771C |
// Returns (<0) if error or module is not loaded SceUID sceKernelSearchModuleByNameForDriver(const char *module_name);
sceKernelGetSystemSwVersionForDriver
Version | NID |
---|---|
0.940 | not present. In non ForDriver though. |
0.990.000-3.740.011 | 0x5182E212 |
Used in SceError.
int sceKernelGetSystemSwVersionForDriver(SceKernelSystemSwVersion *data);
sceKernelSetSystemSwVersionForDriver
Version | NID |
---|---|
0.940 | not present. In non ForDriver though. |
0.990.000-2.060.011 | 0x912AEB73 |
2.100.081-3.740.011 | not present. Integrated with sceKernelGetSystemSwVersionForDriver |
int sceKernelSetSystemSwVersionForDriver(SceKernelSystemSwVersion *data);
sceKernelLoadStartModuleForDriver
Version | NID |
---|---|
1.69-3.60 | 0x189BFBBB |
/** * @brief PRX Load and start PRX * * moduleFileName After loading the PRX specified by the moduleFileName argument, start processing * is performed. * * During start processing, module_start () is called by a thread * that is initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority * and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. * When it is done, the argument block specified by the args and argp arguments are * copied to the thread stack and then passed to module_start(). * * If loading and start processing is successful, the return value * of the start entry function is stored in the area indicated by pRes. * * If SCE_KERNEL_START_NO_RESIDENT is returned as the return value of module_start() * the module is not resident in memory and is automatically unloaded after module_start() is executed. * If SCE_KERNEL_START_FAILED is returned, * the PRX has failed to load. A PRX is resident (loaded) only if it * returns a value other than SCE_KERNEL_START_NO_RESIDENT * or SCE_KERNEL_START_FAILED, including SCE_KERNEL_START_RESIDENT. * * @param[in] moduleFileName file name * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of start entry * * @retval (>0) module uid * @retval (<0) Error code */ SceUID sceKernelLoadStartModuleForDriver(const char *moduleFileName, SceSize args, const void *argp, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt, int *pRes);
sceKernelLoadStartModuleForPidForDriver
Version | NID |
---|---|
3.60 | 0x9D953C22 |
/** * @brief PRX Load and start PRX * * moduleFileName After loading the PRX specified by the moduleFileName argument, start processing * is performed. * * During start processing, module_start () is called by a thread * that is initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority * and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. * When it is done, the argument block specified by the args and argp arguments are * copied to the thread stack and then passed to module_start(). * * If loading and start processing is successful, the return value * of the start entry function is stored in the area indicated by pRes. * * If SCE_KERNEL_START_NO_RESIDENT is returned as the return value of module_start() * the module is not resident in memory and is automatically unloaded after module_start() is executed. * If SCE_KERNEL_START_FAILED is returned, * the PRX has failed to load. A PRX is resident (loaded) only if it * returns a value other than SCE_KERNEL_START_NO_RESIDENT * or SCE_KERNEL_START_FAILED, including SCE_KERNEL_START_RESIDENT. * * @param[in] pid process id * @param[in] moduleFileName file name * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of start entry * * @retval (>0) module uid * @retval (<0) Error code */ SceUID sceKernelLoadStartModuleForPidForDriver(SceUID pid, const char *moduleFileName, SceSize args, const void *argp, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt, int *pRes);
Version | NID |
---|---|
3.60 | 0xE2ADEF8D |
/** * @brief PRX Load and start PRX * * moduleFileName After loading the PRX specified by the moduleFileName argument, start processing * is performed. * * During start processing, module_start () is called by a thread * that is initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority * and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. * When it is done, the argument block specified by the args and argp arguments are * copied to the thread stack and then passed to module_start(). * * If loading and start processing is successful, the return value * of the start entry function is stored in the area indicated by pRes. * * If SCE_KERNEL_START_NO_RESIDENT is returned as the return value of module_start() * the module is not resident in memory and is automatically unloaded after module_start() is executed. * If SCE_KERNEL_START_FAILED is returned, * the PRX has failed to load. A PRX is resident (loaded) only if it * returns a value other than SCE_KERNEL_START_NO_RESIDENT * or SCE_KERNEL_START_FAILED, including SCE_KERNEL_START_RESIDENT. * * @param[in] pid process id * @param[in] moduleFileName file name * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of start entry * * @retval (>0) module uid * @retval (<0) Error code */ SceUID sceKernelLoadStartSharedModuleForPidForDriver(SceUID pid, const char *moduleFileName, SceSize args, const void *argp, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt, int *pRes);
sceKernelLoadModuleWithoutStartForDriver / sceKernelLoadModuleForDriver
Version | NID |
---|---|
1.69-3.60 | 0x86D8D634 |
/** * @brief Load module * * moduleFileName Loads the module specified by moduleFileName. * If the load is successful, the module identifier is returned as the return value. * * @param[in] moduleFileName file name * @param[in] flags flags * @param[in] pOpt option parameter, should be SCE_NULL * @retval (>0) module uid * @retval (<0) Error code */ SceUID sceKernelLoadModuleForDriver(const char *moduleFileName, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt);
sceKernelStartModuleForDriver
Version | NID |
---|---|
1.69-3.60 | 0x0675B682 |
// flags must be 0 // pOpt can be null /** * @brief start module * * Starts the module specified by uid. When calling the start entry function, * the value specified by the args and argp arguments is passed as an argument. * * If the start process is successful, the library declared with AUTO_EXPORT will be registered. * Public processing is performed and the return value of the start entry function is stored in the area indicated by pRes. * If the start process fails, library registration and publishing will not be performed. * * SCE_KERNEL_START_NO_RESIDENT is returned as the return value of the start entry function * only if the module is automatically unloaded after executing the start entry function. * If SCE_KERNEL_START_FAILED is returned, the start process will fail. * At this time, the module is not unloaded. Modules that failed to start * It can be restarted with sceKernelStartModuleForDriver(). * * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of start entry * @retval SCE_OK success * @retval (<0) Error code */ int sceKernelStartModuleForDriver(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStartModuleOpt *pOpt, int *pRes);
sceKernelStopUnloadModuleForDriver
Version | NID |
---|---|
1.69-3.60 | 0x03B30B7E |
// flags must be 0 // opt can be null /** * @brief Stop and unload PRX * * After stopping the PRX specified by the uid argument, unloading is performed. * * During stop processing, module_stop() is called by a thread that is * initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority * and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. * When it is done, the argument blocks specified by the args and argp * arguments are copied onto the thread stack and then passed to module_stop(). * * If the stop process is successful, the library released from PRX * is deleted and then unloaded, and the return value of * the stop entry function is stored in the area indicated by pRes. * * PRX stop and unload processing has failed only if SCE_KERNEL_STOP_CANCEL * is returned as the return value of module_stop(). * If any other value is returned, stop and unload processing has succeeded. * * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of stop entry * @retval SCE_OK success * @retval (<0) Error code */ int sceKernelStopUnloadModuleForDriver(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt, int *pRes);
sceKernelStopUnloadModuleForPidForDriver
Version | NID |
---|---|
3.60 | 0x49A3EDC7 |
/** * @brief Stop and unload PRX * * After stopping the PRX specified by the uid argument, unloading is performed. * * During stop processing, module_stop() is called by a thread that is * initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority * and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. * When it is done, the argument blocks specified by the args and argp * arguments are copied onto the thread stack and then passed to module_stop(). * * If the stop process is successful, the library released from PRX * is deleted and then unloaded, and the return value of * the stop entry function is stored in the area indicated by pRes. * * PRX stop and unload processing has failed only if SCE_KERNEL_STOP_CANCEL * is returned as the return value of module_stop(). * If any other value is returned, stop and unload processing has succeeded. * * @param[in] pid process id * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of stop entry * @retval SCE_OK success * @retval (<0) Error code */ int sceKernelStopUnloadModuleForPidForDriver(SceUID pid, SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt, int *pRes);
Version | NID |
---|---|
3.60 | 0x02D3D0C1 |
int sceKernelStopUnloadSharedModuleForPidForDriver(SceUID pid, SceUID modid, SceSize args, void *argp, int flags, SceKernelULMOption *option, int *status);
sceKernelStopModuleForDriver
Version | NID |
---|---|
1.69-3.60 | 0x100DAEB9 |
/** * @brief Stop module * * Stops the module specified by uid. When calling the stop entry function, * the values specified by the args and argp arguments are passed as arguments. * * If the stop process is successful, the library released from the module is deleted, * and the return value of the stop entry function is stored in the area indicated by pRes. * If stop processing fails, library deletion processing is not performed. * * Only when SCE_KERNEL_STOP_SUCCESS is returned as the return value of the * stop entry function, module stop processing succeeds. * If any other value is returned, module stop processing will fail. * The module that failed to stop can be restarted with sceKernelStopModuleForDriver(). * * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of stop entry * @retval SCE_OK success * @retval (<0) Error code */ int sceKernelStopModuleForDriver(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStopModuleOpt *pOpt, int *pRes);
sceKernelUnloadModuleForDriver
Version | NID |
---|---|
1.69-3.60 | 0x728E72A6 |
In 1.69 existed in SceModulemgrForKernel
/** * @brief Unload module * * Unloads the module specified by uid. * * @param[in] uid module id * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter * * @retval SCE_OK success * @retval (<0) Error code int sceKernelUnloadModuleForDriver(SceUID uid, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt);
load_with_logs
Version | NID |
---|---|
0.990 | 0x57EE2372 |
SceModulemgr
sceKernelKttyWrite
Version | NID |
---|---|
0.940-1.692.000 | 0x4D76CF9E |
1.80-3.740.011 | not present |
sceKernelPutc
Version | NID |
---|---|
0.931-1.692.000 | 0x9D2FE122 |
1.80-3.740.011 | not present |
int sceKernelPutc(char c);
sceKernelGetSystemSwVersion
Version | NID |
---|---|
0.940-3.740.011 | 0x5182E212 |
int sceKernelGetSystemSwVersion(SceKernelSystemSwVersion *data);
sceKernelSetSystemSwVersion
Version | NID |
---|---|
0.990-2.060.011 | 0x912AEB73 |
2.100.081-3.740.011 | not present |
This function can only be called in System program.
This function was maybe removed because it represented a security threat: an exploit giving usermode code execution in a System program (for example PSPemu sandbox escape) could change the System Software version in SceKernelModulemgr data segment. The impact depends on which modules relied on that version buffer.
int sceKernelSetSystemSwVersion(SceKernelSystemSwVersion *data);
__sceKernelLoadModuleWithoutStart
Version | NID |
---|---|
0.990-2.060.011 | 0xA4E6DA4D |
2.100.081-3.740.011 | not present |
/** * @brief Load a module * * moduleFileName Loads the module specified by moduleFileName. * If the load is successful, the module identifier is returned as the return value. * * @param[in] moduleFileName file name * @param[in] flags flags * @param[in] pOpt option parameter, should be SCE_NULL * @retval (>0) module uid * @retval (<0) Error code */ SceUID __sceKernelLoadModuleWithoutStart(const char *moduleFileName, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt);
__sceKernelStartModule
Version | NID |
---|---|
0.990-2.060.011 | 0x1FD99C9F |
2.100.081-3.740.011 | not present |
/** * @brief Start a module * * Starts the module specified by uid. The module must have been loaded using __sceKernelLoadModuleWithoutStart. When calling the start entry function, * the value specified by the args and argp arguments is passed as an argument. * * If the start process is successful, the library declared with AUTO_EXPORT will be registered. * Public processing is performed and the return value of the start entry function is stored in the area indicated by pRes. * If the start process fails, library registration and publishing will not be performed. * * SCE_KERNEL_START_NO_RESIDENT is returned as the return value of the start entry function * only if the module is automatically unloaded after executing the start entry function. * If SCE_KERNEL_START_FAILED is returned, the start process will fail. * At this time, the module is not unloaded. Modules that failed to start * It can be restarted with __sceKernelStartModule(). * * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of start entry * @retval SCE_OK success * @retval (<0) Error code */ int __sceKernelStartModule(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStartModuleOpt *pOpt, int *pRes);
__sceKernelStopModule
Version | NID |
---|---|
0.990-2.060.011 | 0xBA49EA5C |
2.100.081-3.740.011 | not present |
/** * @brief Stop a module * * Stops the module specified by uid. When calling the stop entry function, * the values specified by the args and argp arguments are passed as arguments. * * If the stop process is successful, the library released from the module is deleted, * and the return value of the stop entry function is stored in the area indicated by pRes. * If stop processing fails, library deletion processing is not performed. * * Only when SCE_KERNEL_STOP_SUCCESS is returned as the return value of the * stop entry function, module stop processing succeeds. * If any other value is returned, module stop processing will fail. * The module that failed to stop can be restarted with __sceKernelStopModule(). * * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of stop entry * @retval SCE_OK success * @retval (<0) Error code */ int __sceKernelStopModule(SceUID uid, SceSize args, const void *argp, SceUInt32 flags, const SceKernelStopModuleOpt *pOpt, int *pRes);
__sceKernelUnloadModuleWithoutStop
Version | NID |
---|---|
0.990-2.060.011 | 0xE439E26B |
2.100.081-3.740.011 | not present |
/** * @brief Unload a module * * Unloads the module specified by uid. The module must have been stopped using __sceKernelStopModule if it was started using __sceKernelStartModule. * * @param[in] uid module id * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter * * @retval SCE_OK success * @retval (<0) Error code int __sceKernelUnloadModuleWithoutStop(SceUID uid, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt);
__sceKernelOpenModule
Version | NID |
---|---|
0.990-2.060.011 | 0x9C2A9A49 |
2.100.081-3.740.011 | not present |
__sceKernelCloseModule
Version | NID |
---|---|
0.990-2.060.011 | 0x5303C52F |
2.100.081-3.740.011 | not present |
sceKernelGetModuleList
Version | NID |
---|---|
1.000.071-3.740.011 | 0x2EF2581F |
int sceKernelGetModuleList(int flags, SceUID *modids, SceSize *num);
sceKernelGetModuleIdByAddr
Version | NID |
---|---|
1.000.071-3.740.011 | 0xF5798C7C |
SceUID sceKernelGetModuleIdByAddr(const void *module_addr);
sceKernelGetModuleInfo
Version | NID |
---|---|
1.000.071-3.740.011 | 0x36585DAF |
int sceKernelGetModuleInfo(SceUID modid, SceKernelModuleInfo *pInfo);
sceKernelGetAllowedSdkVersionOnSystem
Version | NID |
---|---|
0.931-1.06 | not present |
1.500.151-3.740.011 | 0x4397FC4E |
int sceKernelGetAllowedSdkVersionOnSystem(void);
sceKernelGetLibraryInfoByNID
Version | NID |
---|---|
0.931.010-1.06 | not present |
1.500.151-3.740.011 | 0xEAEB1312 |
Note that NONAME libraries (NID 0) are not supported by this function. sceKernelGetLibraryInfoByNID lookups the process libdb but libdb does not keep NONAME libraries.
Note also that due to a bug, pInfo->libname is a pointer to kernel memory so dereferencing it causes an exception.
int sceKernelGetLibraryInfoByNID(SceUID modid, SceUInt32 libnid, SceKernelLibraryInfo *pInfo);
_sceKernelLoadModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0xB4C5EF9E |
/** * @brief Load a module * * moduleFileName Loads the module specified by moduleFileName. * If the load is successful, the module identifier is returned as the return value. * * @param[in] moduleFileName file name * @param[in] flags flags * @param[in] pOpt option parameter, should be SCE_NULL * @retval (>0) module uid * @retval (<0) Error code */ SceUID _sceKernelLoadModule(const char *moduleFileName, SceUInt32 flags, const SceKernelLoadModuleOpt *pOpt);
_sceKernelStartModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0x72CD301F |
/** * @brief Start a module * * Starts the module specified by uid. When calling the start entry function, * the value specified by the args and argp arguments is passed as an argument. * * If the start process is successful, the library declared with AUTO_EXPORT will be registered. * Public processing is performed and the return value of the start entry function is stored in the area indicated by pRes. * If the start process fails, library registration and publishing will not be performed. * * SCE_KERNEL_START_NO_RESIDENT is returned as the return value of the start entry function * only if the module is automatically unloaded after executing the start entry function. * If SCE_KERNEL_START_FAILED is returned, the start process will fail. * At this time, the module is not unloaded. Modules that failed to start * It can be restarted with _sceKernelStartModule(). * * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of start entry * @retval SCE_OK success * @retval (<0) Error code */ typedef struct SceKernelModuleStartParam { SceUInt32 flags; int *status; const SceKernelStartModuleOpt *pOpt; int a4; // not used } SceKernelModuleStartParam; int _sceKernelStartModule(SceUID uid, SceSize args, const void *argp, const SceKernelModuleStartParam *pParam);
_sceKernelLoadStartModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0x60647592 |
/** * @brief Load and start a module * * moduleFileName After loading the module specified by the moduleFileName argument, start processing * is performed. * * During start processing, module_start () is called by a thread * that is initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority * and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. * When it is done, the argument block specified by the args and argp arguments are * copied to the thread stack and then passed to module_start(). * * If loading and start processing is successful, the return value * of the start entry function is stored in the area indicated by pRes. * * If SCE_KERNEL_START_NO_RESIDENT is returned as the return value of module_start() * the module is not resident in memory and is automatically unloaded after module_start() is executed. * If SCE_KERNEL_START_FAILED is returned, * the module has failed to load. A module is resident (loaded) only if it * returns a value other than SCE_KERNEL_START_NO_RESIDENT * or SCE_KERNEL_START_FAILED, including SCE_KERNEL_START_RESIDENT. * * @param[in] moduleFileName file name * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of start entry * * @retval (>0) module uid * @retval (<0) Error code */ typedef struct SceKernelModuleLoadStartParam { SceUInt32 flags; int *status; const SceKernelLoadModuleOpt *option; int a4; // not used } SceKernelModuleLoadStartParam; SceUID _sceKernelLoadStartModule(const char *moduleFileName, SceSize args, const void *argp, const SceKernelModuleLoadStartParam *pParam);
_sceKernelStopModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0x086867A8 |
/** * @brief Stop a module * * Stops the module specified by uid. When calling the stop entry function, * the values specified by the args and argp arguments are passed as arguments. * * If the stop process is successful, the library released from the module is deleted, * and the return value of the stop entry function is stored in the area indicated by pRes. * If stop processing fails, library deletion processing is not performed. * * Only when SCE_KERNEL_STOP_SUCCESS is returned as the return value of the * stop entry function, module stop processing succeeds. * If any other value is returned, module stop processing will fail. * The module that failed to stop can be restarted with _sceKernelStopModule(). * * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of stop entry * @retval SCE_OK success * @retval (<0) Error code */ typedef struct SceKernelModuleStopParam { SceUInt32 flags; int *status; const SceKernelStopModuleOpt *pOpt; int a4; // not used } SceKernelModuleStopParam; int _sceKernelStopModule(SceUID uid, SceSize args, const void *argp, const SceKernelModuleStopParam *pParam);
_sceKernelUnloadModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0x8E4A7716 |
/** * @brief Unload a module * * Unloads the module specified by uid. * * @param[in] uid module id * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter * * @retval SCE_OK success * @retval (<0) Error code int _sceKernelUnloadModule(SceUID uid, SceUInt32 flags, const SceKernelUnloadModuleOpt *pOpt);
_sceKernelStopUnloadModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0x86EAEA0A |
/** * @brief Stop and unload a module * * After stopping the module specified by the uid argument, unloading is performed. * * During stop processing, module_stop() is called by a thread that is * initialized with SCE_KERNEL_DEFAULT_PRIORITY_USER as the priority * and SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN as the stack size. * When it is done, the argument blocks specified by the args and argp * arguments are copied onto the thread stack and then passed to module_stop(). * * If the stop process is successful, the library released from module * is deleted and then unloaded, and the return value of * the stop entry function is stored in the area indicated by pRes. * * module stop and unload processing has failed only if SCE_KERNEL_STOP_CANCEL * is returned as the return value of module_stop(). * If any other value is returned, stop and unload processing has succeeded. * * @param[in] uid module id * @param[in] args argument block size * @param[in] argp argument block address * @param[in] flags flags, should be 0 * @param[in] pOpt option parameter, should be SCE_NULL * @param[out] pRes result of stop entry * @retval SCE_OK success * @retval (<0) Error code */ typedef struct SceKernelModuleStopUnloadParam { SceUInt32 flags; int *status; const SceKernelUnloadModuleOpt *pOpt; int a4; // not used } SceKernelModuleStopUnloadParam; int _sceKernelStopUnloadModule(SceUID uid, SceSize args, const void *argp, const SceKernelModuleStopUnloadParam *pParam);
_sceKernelOpenModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0x9D674F45 |
typedef struct SceKernelModuleLoadStartParam { SceUInt32 flags; int *status; const SceKernelLoadModuleOpt *option; int a4; // not used } SceKernelModuleLoadStartParam; SceUID _sceKernelOpenModule(const char *moduleFileName, SceSize args, const void *argp, const SceKernelModuleLoadStartParam *pParam);
_sceKernelCloseModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0x849E78BE |
typedef struct SceKernelModuleStopUnloadParam { SceUInt32 flags; int *status; const SceKernelUnloadModuleOpt *pOpt; int a4; // not used } SceKernelModuleStopUnloadParam; SceUID _sceKernelCloseModule(SceUID uid, SceSize args, const void *argp, const SceKernelModuleStopUnloadParam *pParam);
sceKernelIsCalledFromSysModule
Version | NID |
---|---|
0.931-2.060.011 | not present |
2.100.081-3.740.011 | 0x85E6D2BB |
int sceKernelIsCalledFromSysModule(const void *module_addr);
sceKernelInhibitLoadingModule
Version | NID |
---|---|
0.931.010-3.36 | not present |
3.500.011-3.740.011 | 0x6CED1F63 |
Introduced in System Software version 3.50 to prevent loading Sysmodules from the webbrowser. It is a security feature that makes kernel exploitation harder because it reduces the number of accessible syscalls from a WebKit usermode exploit.
See also Vitasploit 2.00-3.36 post-WebKit-exploit API and h-encore 3.65-3.68 writeup by TheFloW.
In Trinity source code, a module is loaded with flags = 0x10 to bypass sceKernelInhibitLoadingModule(0x20) restriction.
Used in ScePspemu (probably level 0x20), SceWebKitProcess, SceWebKitProcessMini.
Returns 0 on success. Returns 0x80020005 if level is invalid.
Level must be strictly increasing: loading a module becomes more and more inhibited.
#define SCE_MODULE_LOADING_INHIBIT_TO_FLAGS_0x8000_AND_SHARED 0x10 #define SCE_MODULE_LOADING_INHIBIT_TO_FLAGS_0x10 0x20 // level: Only values 0x10, 0x20, 0x30 are supported. int sceKernelInhibitLoadingModule(SceUInt16 level);
SceBacktraceForDriver
sceKernelBacktraceForDriver
Version | NID |
---|---|
0.990.000-3.740.011 | 0x166B9C8C |
int sceKernelBacktraceForDriver(SceUID threadId, SceKernelCallFrame *pCallFrameBuffer, SceSize numBytesBuffer, SceUInt32 *pNumReturn, SceInt32 mode);
sceKernelPrintBacktraceForDriver
Version | NID |
---|---|
0.990.000-1.692.000 | 0xC5608386 |
1.800.071-3.740.011 | not present |
This is a guessed name.
int sceKernelPrintBacktraceForDriver(SceUID processId, const SceKernelCallFrame *pCallFrame, SceUInt32 numFrames);
sceKernelPrintBacktrace2ForDriver
Version | NID |
---|---|
0.990.000-1.692.000 | not present |
1.800.071-3.740.011 | 0x7C878F90 |
This is a guessed name.
int sceKernelPrintBacktrace2ForDriver(SceUID processId, const SceKernelCallFrame *pCallFrame, SceUInt32 numFrames);
sceKernelBacktraceForKernelForDriver
Version | NID |
---|---|
0.990.000-2.060.011 | 0xCECD5584 |
2.100.081-3.740.011 | not present |
This is a guessed name. Temp name was sceKernelBacktraceInternalForDriver.
It does not have devmode/QAF check. It allows kernel trace.
int sceKernelBacktraceForKernelForDriver(SceUID threadId, SceKernelCallFrame *pCallFrameBuffer, SceSize numBytesBuffer, SceUInt32 *pNumReturn, SceInt32 mode);
sceKernelBacktraceForKernel2ForDriver
Version | NID |
---|---|
0.990.000-2.060.011 | not present |
2.100.081-3.740.011 | 0x888E99B8 |
This is a guessed name. Temp name was sceKernelBacktraceInternal2ForDriver.
It does not have devmode/QAF check. It allows kernel trace.
int sceKernelBacktraceForKernel2ForDriver(SceUID threadId, SceKernelCallFrame *pCallFrameBuffer, SceSize numBytesBuffer, SceUInt32 *pNumReturn, SceInt32 mode);
SceBacktrace
_sceKernelBacktrace
Version | NID |
---|---|
1.000.071-3.740.011 | 0xBF371A98 |
Calls sceKernelBacktraceForDriver.
typedef struct SceBacktraceArgs { SceUInt32 *pNumReturn; /**< number of frames gathered. */ SceInt32 mode; /**< KERNEL or USER mode. / DONT_EXCEED */ } SceBacktraceArgs; /** * Get backtrace * - When called with pCallFrameBuffer=NULL, numBytesBuffer=0, * only the depth of the call stack can be obtained as a return value. * * @param threadId Thread ID, or SCE_KERNEL_BACKTRACE_CONTEXT_xxx * @param pCallFrameBuffer Buffer to get call frame * @param numBytesBuffer Buffer size (byte) * @param pNumReturn Pointer that receives the acquired number of frames * @param mode Action mode * @retval (0) Call stack depth, or SCE_OK * @retval (<0) Error code * @note Callable only with TOOL */ SceInt32 _sceKernelBacktrace( SceUID threadId, /**< Thread ID, SCE_KERNEL_BACKTRACE_* can be used. */ SceKernelCallFrame *pCallFrameBuffer, /**< buffer for frames */ SceSize numBytesBuffer, /**< buffer size */ SceBacktraceArgs *pArgs );
_sceKernelPrintBacktrace
Version | NID |
---|---|
0.990-1.520.011 | 0x21F00CF2 |
1.60-3.740.011 | not present |
Calls sceKernelPrintBacktraceForDriver.
/** * Display backtrace * @param processId Process ID to which the frame belongs * @param pCallFrame Stack frame data * @param numFrames Maximum step * @retval (0) Success * @retval (<0) Error code */ SceInt32 _sceKernelPrintBacktrace( SceUID processId, const SceKernelCallFrame *pCallFrame, SceUInt32 numFrames );