ScePfsMgr: Difference between revisions
(→Types) |
(→Types) |
||
Line 37: | Line 37: | ||
vfs_block_dev_info block_dev; | vfs_block_dev_info block_dev; | ||
uint32_t num_authids; | uint32_t num_authids; | ||
}; | |||
union pfs_pmi_buffer_list_ctx_u0 | |||
{ | |||
buffer_list *blist; | |||
int some_flags; | |||
}; | }; | ||
struct pfs_pmi_buffer_list_ctx | struct pfs_pmi_buffer_list_ctx | ||
{ | { | ||
pfs_pmi_buffer_list_ctx_u0 unk_0; | |||
uint32_t unk_4; | uint32_t unk_4; | ||
SceUID ScePfsPmi_mutex_id; // 0x08 | SceUID ScePfsPmi_mutex_id; // 0x08 |
Revision as of 01:12, 20 July 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 pmi_blc_subctx { pmi_blc_subctx *subctx0; pmi_blc_subctx *subctx4; SceUInt64 auth_ids[16]; vfs_block_dev_info block_dev; uint32_t num_authids; }; union pfs_pmi_buffer_list_ctx_u0 { buffer_list *blist; int some_flags; }; struct pfs_pmi_buffer_list_ctx { pfs_pmi_buffer_list_ctx_u0 unk_0; uint32_t unk_4; SceUID ScePfsPmi_mutex_id; // 0x08 char original_path[0x40]; // 0xC char rnd_drive_id1[0x22]; // 0x4C - "/%s" char rnd_drive_id2[0x24]; // 0x6E - "%s0:" - used for pfs_pmi_buffer_list_ctx lookup on mount uint16_t mode_index; //0x92 uint16_t crypto_engine_flag; //0x94 = 0 char klicensee[0x10]; //0x96 uint16_t key_id; uint32_t files_salt; uint32_t unk_AC; // = 0 SceUID ScePfsFilesDb_mutex_id; // 0xB0 char unk_data1[0xBC]; // 0xB4 pmi_blc_subctx subctx; //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* blc; //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* rnd_drive_id, SceUInt64 authid, void *klicensee, uint16_t mode_index);
mount
Version | NID |
---|---|
3.60 | 0x2D48AEA2 |
int mount(char *original_path, char *rnd_drive_id, void *klicensee, uint16_t mode_index);
unmount
Version | NID |
---|---|
3.60 | 0x680BC384 |
int unmount(char* rnd_drive_id);
ioctl_set_klicensee
Version | NID |
---|---|
3.60 | 0x4A4A8243 |
- open mountpoint/dlc_folder directory
- execute ioctl command 0x4402 with klicensee input
- close mountpoint/dlc_folder directory
int ioctl_set_klicensee(const char *mountpoint, const char *dlc_folder, char *klicensee);
ioctl_clear_klicensee
Version | NID |
---|---|
3.60 | 0x8CDA249A |
- open mountpoint/dlc_folder directory
- execute ioctl command 0x4403
- close mountpoint/dlc_folder directory
int ioctl_clear_klicensee(const char *mountpoint, const char *dlc_folder);
ioctl_0x4404
Version | NID |
---|---|
3.60 | 0x00C8AF80 |
- open mountpoint/dlc_folder directory
- execute ioctl command 0x4404
- close mountpoint/dlc_folder directory
int ioctl_0x4404(const char *mountpoint, const char *dlc_folder);
savedata_ioctl_0x4410
Version | NID |
---|---|
3.60 | 0x27FB7618 |
execute 0x4410 command on <device_name>0: get 8 bytes of result
int savedata_ioctl_0x4410(const char *device_name, int *ioctl0_res, int *ioctl1_res);
find_pmi_check_auth_id
Version | NID |
---|---|
3.60 | 0xD8D0FEE5 |
- find pfs_pmi_buffer_list_ctx* by mount_point
- check auth ids
- set unk_94 flag
int find_pmi_check_auth_id(char *rnd_drive_id, SceUInt64 authid);
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);