ScePfsMgr: Difference between revisions
Line 423: | Line 423: | ||
| 3.60 || 0x8CDA249A | | 3.60 || 0x8CDA249A | ||
|} | |} | ||
* open mountpoint/suffix_dir directory | |||
* execute ioctl command 0x4403 | |||
* close mountpoint/suffix_dir directory | |||
<source lang="C"> | |||
int ioctl_clear_klicensee(const char *mountpoint, const char *suffix_dir); | |||
</source> | |||
== ScePfsFacadeForKernel == | == ScePfsFacadeForKernel == |
Revision as of 13:25, 8 April 2018
Module
Known NIDs
Version | Name | World | Privilege | NID |
---|---|---|---|---|
1.69 | ScePfsMgr | Non-secure | Kernel | 0x3CF10F0 |
3.60 | ScePfsMgr | ? | Kernel | 0x538BA86B |
Libraries
Known NIDs
Version | Name | World | Visibility | NID |
---|---|---|---|---|
1.69 | ScePfsMgrForKernel | Non-secure | Kernel | 0xA067B56F |
3.60 | ScePfsMgrForKernel | ? | Kernel | 0xA067B56F |
3.60 | ScePfsFacadeForKernel | ? | Kernel | 0xC26DC7BD |
Types
struct pfs_pmi_buffer_list_ctx { buffer_list* blist; uint32_t unk_4; SceUID ScePfsPmi_mutex_id; // 0x08 char original_path[0x3F]; // 0xC char mount_point1[0x22]; // 0x4C - /%s char mount_point2[0x23]; // 0x6E - %s0: char unk_91; uint16_t type; //0x92 uint16_t unk_94; //0x94 = 0 char klicensee[0x10]; //0x96 uint16_t unk_A6; // = 0 uint32_t unk_A8; // = 0 uint32_t unk_AC; // = 0 SceUID ScePfsFilesDb_mutex_id; // 0xB0 char unk_data1[0xBC]; // 0xB4 pfs_pmi_buffer_list_ctx *bcl; //0x170 uint32_t unk_174; SceUInt64 auth_id; char unk_data2[0x78]; // 0x180 vfs_block_dev_info block_dev; // 0x1F8 uint32_t unk_20C; //further fields are unknown } pfs_pmi_buffer_list_ctx; struct buffer_list { SceUID mutex_id; uint32_t unk_4; uint32_t unk_8; uint32_t unk_C; uint32_t unk_10; void* bcl; //0x14 - one of versions is pfs_pmi_buffer_list_ctx }buffer_list; typedef struct CryptEngineData //size is 0x60 { uint32_t unk_0; uint32_t unk_4; uint32_t unk_8; uint16_t unk_C; uint16_t flag; // 0xE - flag that selects decryption type ? uint16_t key_id; //0x10 uint16_t seed1_base; //iv seed uint32_t unk_14; uint32_t unk_18; uint32_t unk_1C; uint32_t unk_20; uint32_t unk_24; uint32_t size1; char key[0x10]; //0x2C char iv_xor_key[0x10]; //0x3C char hmac_key[0x14]; //0x4C }CryptEngineData; typedef struct CryptEngineSubctx //size is 0x58 { uint32_t unk_0; uint32_t unk_4; uint32_t opt_code; // 0x8 - if 3 then decrypt, if 4 then encrypt, if 2 then encrypt CryptEngineData* data; // 0xC uint32_t unk_10; uint32_t source; // 0x14 uint32_t unk_18; uint32_t unk_1C; uint32_t unk_20; uint32_t unk_24; uint32_t size2; //0x28 uint32_t nDigests; // 0x2C - also digest table index uint32_t unk_30; uint32_t seed0_base; // 0x34 uint32_t dest_offset; // 0x38 uint32_t size0; // 0x3C uint32_t size1; uint32_t unk_44; uint32_t size3; //0x48 char* hmac_sha1_digest; // digest to verify (possibly table) void* buffer0; // 0x50 void* buffer1; // 0x54 }CryptEngineSubctx; typedef struct CryptEngineWorkCtx //size is 0x18 { void* unk_0; // pointer to data 0x140 + 0x18 ? void* unk_4; // pointer to data 0x140 + 0x18 ? CryptEngineSubctx* subctx; // 0x8 uint32_t error; //set to 0 or error code after executing crypto task SceUID threadId; // = set with sceKernelGetThreadIdForDriver. used with ksceKernelSignalCondTo uint32_t unk_14; }CryptEngineWorkCtx;
Data segment layout
Address | Size | Description |
---|---|---|
0x0000 | 0x20 | vfs_add_data PFS_REDIRECT_INF node (Redirect Pseudo Drive. )
|
0x0020 | 0x20 | vfs_add_data PFS_GDSD_INF node (Gamedata/Savedata Pseudo Drive. )
|
0x0040 | 0x20 | vfs_add_data PFS_AC_INF node (AC Pseudo Drive. )
|
0x0060 | 0x20 | unknown |
0x0080 | 0x4 | mutex SceUID ScePfsFiBufferList
|
0x0084 | 0x4 | memblock SceUID ScePfsFiBufferList
|
0x0088 | 0x4 | char* ScePfsFiBufferList
|
0x008C | 0x4 | some offset or size |
0x0090 | 0x4 | some offset or size |
0x0094 | 0x4 | void* |
0x0098 | 0x4 | mutex SceUID ScePfsVdBufferList
|
0x009C | 0x4 | memblock SceUID ScePfsVdBufferList
|
0x00A0 | 0x4 | char* ScePfsVdBufferList
|
0x00A4 | 0x4 | some offset or size |
0x00A8 | 0x4 | some offset or size |
0x00AC | 0x4 | void* |
0x00B0 | 0x4 | mutex SceUID ScePfsLruPoolBufferList
|
0x00B4 | 0x4 | memblock SceUID ScePfsLruPoolBufferList
|
0x00B8 | 0x4 | char* ScePfsLruPoolBufferList
|
0x00BC | 0x4 | some offset or size |
0x00C0 | 0x4 | some offset or size |
0x00C4 | 0x4 | void* |
0x00C8 | 0x4 | mutex SceUID ScePfsLruTblHdrBufferList
|
0x00CC | 0x4 | memblock SceUID ScePfsLruTblHdrBufferList
|
0x00D0 | 0x4 | char* ScePfsLruTblHdrBufferList
|
0x00D4 | 0x4 | some offset or size |
0x00D8 | 0x4 | some offset or size |
0x00DC | 0x4 | void* |
0x00E0 | 0x20 | unknown |
0x0100 | 0x10 | CMAC buffer used in ScePfsCryptEngineThread subroutines |
0x0110 | 0x4 | mutex SceUID ScePfsThePmi
|
0x0114 | 0x4 | unknown |
0x0118 | 0x4 | pfs_pmi_buffer_list_ctx* root |
0x011C | 0x4 | unknown |
0x0120 | 0x4 | buffer_list* with mutex SceUID ScePfsPmiBufferList
|
0x0124 | 0x4 | memblock SceUID ScePfsPmiBufferList
|
0x0128 | 0x4 | char* ScePfsPmiBufferList
|
0x012C | 0x4 | some offset or size |
0x0130 | 0x4 | some offset or size |
0x0134 | 0x4 | void* |
0x0138 | 0x4 | unknown |
0x013C | 0x4 | unknown |
0x0140 | 0x4 | 0 |
0x0144 | 0x4 | thread SceUID ScePfsCryptEngineThread
|
0x0148 | 0x4 | mutex SceUID ScePfsCryptEngineTodoMtx
|
0x014C | 0x4 | cond SceUID ScePfsCryptEngineTodoCnd
|
0x0150 | 0x4 | mutex SceUID ScePfsCryptEngineDoneMtx
|
0x0154 | 0x4 | cond SceUID ScePfsCryptEngineDoneCnd
|
0x0158 | 0x4 | pointer to 0x158 |
0x015C | 0x4 | pointer to 0x158 |
0x0160 | 0x4 | pointer to 0x160 |
0x0164 | 0x4 | pointer to 0x160 |
0x0168 | 0x9D8 | unknown |
0x0B40 | 0xC0 | data chunk of size 0xC0 |
0x0C00 | 180 | unknown |
0x0D80 | 0x4 | mutex SceUID ScePfsCryptBufMutexVC
|
0x0D84 | 0x4 | mutex SceUID ScePfsCryptBufMutexRM
|
0x0D88 | 0x4 | mutex SceUID ScePfsCryptBufMutexEMMC
|
0x0D8C | 0x4 | memblock SceUID ScePfsCryptBufVC - size 0x40000
|
0x0D90 | 0x4 | memblock SceUID ScePfsCryptBufVCForShared
|
0x0D94 | 0x4 | memblock base of ScePfsCryptBufVC
|
0x0D98 | 0x4 | memblock base of ScePfsCryptBufVCForShared
|
0x0D9C | 0x4 | 0x000000FF |
0x0DA0 | 0x4 | memblock SceUID ScePfsCryptBufRM - size 0x40000
|
0x0DA4 | 0x4 | memblock SceUID ScePfsCryptBufRMForShared
|
0x0DA8 | 0x4 | memblock base of ScePfsCryptBufRM
|
0x0DAC | 0x4 | memblock base of ScePfsCryptBufRMForShared
|
0x0DB0 | 0x4 | 0x000000FF |
0x0DB4 | 0x4 | memblock SceUID ScePfsCryptBufEMM - size 0x40000
|
0x0DB8 | 0x4 | memblock SceUID ScePfsCryptBufEMMCForShared
|
0x0DBC | 0x4 | memblock base of ScePfsCryptBufEMM
|
0x0DC0 | 0x4 | memblock base of ScePfsCryptBufEMMCForShared
|
0x0DC4 | 0x4 | 0x000000FF |
0x0DC8 | 0x4 | cond SceUID ScePfsCryptBufCondVarVC
|
0x0DCC | 0x4 | cond SceUID ScePfsCryptBufCondVarRM
|
0x0DD0 | 0x4 | cond SceUID ScePfsCryptBufCondVarEMMC
|
Decryption process
Crypto engine
ScePfsMgr
heavily uses crypto API from SceSblSsMgrForDriver.
There is a separate thread in ScePfsMgr
that is called ScePfsCryptEngineThread
.
Almost all calls to the crypto API are done from this single thread.
ScePfsMgr
uses a crypto task dispatch mechanism based on mutexes and conditions.
It uses a CryptEngineWorkCtx
structure for dispatching the task.
Pointer to that structure is written at offset 0x158 of data section (this needs confirmation).
For dispatching the task ScePfsMgr
uses subroutine located at offset 0xBD88.
When task is dispatched ScePfsCryptEngineTodoMtx
mutex is locked, ScePfsCryptEngineTodoCnd
condition is signaled, ScePfsCryptEngineTodoMtx
is unlocked.
For waiting till task is completed ScePfsMgr
uses subroutine located at offset 0xBEA0.
Then ScePfsCryptEngineDoneMtx
mutex is locked, wait happens on ScePfsCryptEngineDoneCnd
condition, ScePfsCryptEngineDoneMtx
mutex is unlocked.
Meanwhile ScePfsCryptEngineThread
runs.
It locks ScePfsCryptEngineTodoMtx
mutex, waits for ScePfsCryptEngineTodoCnd
condition, unlocks ScePfsCryptEngineTodoMtx
mutex.
When task is finished ScePfsCryptEngineThread
locks ScePfsCryptEngineDoneCnd
mutex, signals ScePfsCryptEngineDoneCnd
to specific thread, unlocks ScePfsCryptEngineDoneCnd
mutex.
Thread id for signaling ScePfsCryptEngineDoneCnd
is stored in CryptEngineWorkCtx
.
VFS node functions
Dispatching mechanism is used only by VFS node functions.
Nodes that are used:
- PFS_GDSD_INF
- PFS_AC_INF
Node functions that are used:
- 5 - sceIoReadForDriver
- 6 - sceIoWriteForDriver
- 16 - sceIoChstatForDriver
- 19 - sceIoPreadForDriver
- 20 - sceIoPwriteForDriver
- 26 - sceIoChstatByFdForDriver
ScePfsMgrForKernel
mount
Version | NID |
---|---|
3.60 | 0xA772209C |
int mount(char* original_path, char* mount_point, SceUInt64 authid, void *klicensee, unsigned int type);
mount
Version | NID |
---|---|
3.60 | 0x2D48AEA2 |
int mount(char *original_path, char *mount_point, void *klicensee, unsigned int type);
unmount
Version | NID |
---|---|
3.60 | 0x680BC384 |
int unmount(char* mount_point);
ioctl_set_klicensee
Version | NID |
---|---|
3.60 | 0x4A4A8243 |
- open mountpoint/suffix_dir directory
- execute ioctl command 0x4402 with klicensee input
- close mountpoint/suffix_dir directory
int ioctl_set_klicensee(const char *mountpoint, const char *suffix_dir, char *klicensee);
ioctl_clear_klicensee
Version | NID |
---|---|
3.60 | 0x8CDA249A |
- open mountpoint/suffix_dir directory
- execute ioctl command 0x4403
- close mountpoint/suffix_dir directory
int ioctl_clear_klicensee(const char *mountpoint, const char *suffix_dir);
ScePfsFacadeForKernel
t_scePfsFacadeReadForDriver
Version | NID |
---|---|
3.60 | 0xBD5B21F6 |
This is a thread callback used by SceIofilemgr
This function is not implemented and throws 0x8014231C
error
int t_scePfsFacadeReadForDriver(sceIoReadForDriver_args *args);
t_scePfsFacadeWriteForDriver
Version | NID |
---|---|
3.60 | 0xCB622FFE |
This is a thread callback used by SceIofilemgr
int t_scePfsFacadeWriteForDriver(sceIoWriteForDriver_args *args);
t_scePfsFacadePreadForDriver
Version | NID |
---|---|
3.60 | 0x4238D2D2 |
This is a thread callback used by SceIofilemgr
int t_scePfsFacadePreadForDriver(sceIoPreadForDriver_args *args);
t_scePfsFacadePwriteForDriver
Version | NID |
---|---|
3.60 | 0x58E643C5 |
This is a thread callback used by SceIofilemgr
int t_scePfsFacadePwriteForDriver(sceIoPwriteForDriver_args *args);