http://wiki.henkaku.xyz/vita/api.php?action=feedcontributions&user=Frangarcj&feedformat=atom
Vita Development Wiki - User contributions [en]
2024-03-28T22:47:56Z
User contributions
MediaWiki 1.35.13
http://wiki.henkaku.xyz/vita/index.php?title=SceNpDrm&diff=4655
SceNpDrm
2017-09-15T11:03:45Z
<p>Frangarcj: /* _get_info_2 */</p>
<hr />
<div>== Module ==<br />
<br />
=== Known NIDs ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! Name !! World !! Privilege !! NID<br />
|-<br />
| 1.69 || SceNpDrm || Non-secure || Kernel || 0xACCB4845<br />
|-<br />
| 3.60 || SceNpDrm || ? || Kernel || 0xE7E2CE05<br />
|}<br />
<br />
== Libraries ==<br />
<br />
=== Known NIDs ===<br />
<br />
{| class="wikitable"<br />
|-<br />
! Version !! Name !! World !! Visibility !! NID<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrm|SceNpDrm]] || Non-secure || User || 0xF2799B1B<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrm|SceNpDrm]] || ? || User || 0xF2799B1B<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrmForDriver|SceNpDrmForDriver]] || Non-secure || Kernel || 0xD84DC44A<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrmForDriver|SceNpDrmForDriver]] || ? || Kernel || 0xD84DC44A<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrmPackage|SceNpDrmPackage]] || Non-secure || User || 0x88514DB2<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrmPackage|SceNpDrmPackage]] || ? || User || 0x88514DB2<br />
|-<br />
| 3.60 || [[SceNpDrm#ScePsmDrm|ScePsmDrm]] || ? || User || 0x3F2B0888<br />
|-<br />
| 3.60 || [[SceNpDrm#ScePsmDrmForDriver|ScePsmDrmForDriver]] || ? || Kernel || 0x9F4924F2<br />
|}<br />
<br />
== Data segment layout ==<br />
<br />
{| class="wikitable"<br />
|-<br />
! Address !! Size !! Description<br />
|-<br />
| 0x0000 || 0x4 || SceNpDrm mutex SceUID<br />
|-<br />
| 0x0004 || 0x4 || ScePsmDrm mutex SceUID<br />
|-<br />
| 0x0008 || 0x8 || unknown<br />
|-<br />
| 0x0010 || 0xC0 || static keys decrypted with [[SceSblAuthMgr#sceSblAuthMgrGetEKc|sceSblAuthMgrGetEKc]] key 0. <br />
<br />
First 0x10 bytes are reencrypted with [[SceSblSsMgr#sceSblSsMgrGetConsoleId|CID]].<br />
<br />
First 0x10 bytes are aes_key used to decrypt 0x800 bytes of Primary Key Table from act.dat<br />
<br />
Second 0x10 bytes are aes_key used to decrypt Primary Key Table index from rif.<br />
|-<br />
| 0x00D0 || 0xCF8 || unknown<br />
|-<br />
| 0x0DC8 || 0x4 || Game Exist flag<br />
|-<br />
| 0x0DCC || 0x4 || Is DEX flag or Is Tool flag<br />
|-<br />
| 0x0DD0 || 0x30 || unknown<br />
|-<br />
| 0x0E00 || 0x1040 || tm0:/npdrm/act.dat data<br />
|-<br />
| 0x1E40 || 0x400 || tm0:/psmdrm/act.dat data<br />
|-<br />
| 0x2240 || 0x10 || [[SceSblSsMgr#sceKernelGetOpenPsIdForDriver|OpenPsId]]<br />
<br />
This key is compared against OpenPsId from act.dat<br />
<br />
This key is compared to data in rif file at offset 0xC0<br />
|-<br />
| 0x2250 || 0x4 || act data Is Valid flag<br />
|-<br />
| 0x2254 || 0x4 || unknown<br />
|-<br />
| 0x2258 || 0x8 || /CONFIG/NP/account_id reg key<br />
|-<br />
| 0x2260 || 0x4 || Loose Account Bind flag<br />
|-<br />
| 0x2264 || 0x4 || /CONFIG/NP/debug_upgradable reg key<br />
|-<br />
| 0x2268 || 0x20 || sha 256 digest of [[SceSblGcAuthMgr#get_act_data|get_act_data]]<br />
|-<br />
| 0x2288 || 0x20 || hmac sha 256 digest of [[SceSblGcAuthMgr#get_act_data|get_act_data]]<br />
|-<br />
| 0x22A8 || 0x8 || unknown<br />
|-<br />
| 0x22B0 || 0x8 || account_id<br />
|-<br />
| 0x22B8 || 0x8 || psm activation start date<br />
|-<br />
| 0x22C0 || 0x8 || psm activation end date<br />
|-<br />
| 0x22C8 || 0x20 || some key decrypted with 0x2288<br />
|-<br />
|}<br />
<br />
== Obtaining klicensee ==<br />
<br />
1. Get 0xC0 bytes from SceNpDrm code segment at offset 0x111D0. This is the list of static keys.<br />
<br />
2. Decrypt 0xC0 bytes of static keys using [[SceSblAuthMgr#sceSblAuthMgrGetEKc|sceSblAuthMgrGetEKc]] key 0.<br />
<br />
3. Get 0x10 bytes of CID with [[SceSblSsMgr#sceSblSsMgrGetConsoleIdForDriver| sceSblSsMgrGetConsoleIdForDriver]].<br />
<br />
4. Encrypt first 0x10 bytes of static keys with CID using AES (need to figure out which AES exactly).<br />
<br />
5. Read 0x800 bytes of Primary Key Table from act.dat<br />
<br />
6. Decrypt 0x800 bytes of Primary Key Table with reencrypted static key using AES (need to figure out which AES exactly).<br />
<br />
7. Get 0x97 / 0x200 bytes of rif data and select one of 5 scenarios for decrypting RIF Key based on license flags (need to figure out).<br />
<br />
=== Scenario 1 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take static keys 3, 4<br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 2 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take primary keys 1, 2<br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 3 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take cmd56 handshake keys with [[SceSblGcAuthMgr#get_5018_data|get_5018_data]] <br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 4 ===<br />
<br />
Take RIF Key 1<br />
<br />
Take cmd56 handshake keys with [[SceSblGcAuthMgr#get_5018_data|get_5018_data]] <br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Erase RIF Key 1 from rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 1 and obtain klicensee.<br />
<br />
=== Scenario 5 ===<br />
<br />
Decrypt Primary Table Key index from rif data with static key 2 using AES (need to figure out which AES exactly).<br />
<br />
Take primary key using decrypted index.<br />
<br />
Decrypt RIF key 1 with obtained primary key using AES (need to figure out which AES exactly).<br />
<br />
== Get rif name ==<br />
<br />
<source lang="C"><br />
uint8_t rif_name_keys[0x10] = {<br />
0x19, 0xDD, 0x4F, 0xB9, 0x89, 0x48, 0x2B, 0xD4,<br />
0xCB, 0x9E, 0xC9, 0xC7, 0x9A, 0x2E, 0xFB, 0xD0<br />
};<br />
<br />
int aes_encrypt(const void *buf, int size, uint8_t *keys) {<br />
AES_ctx ctx;<br />
AES_set_key(&ctx, rif_name_keys, 0x80);<br />
<br />
int i;<br />
for (i = 0; i < size; i += 0x10) {<br />
AES_encrypt(&ctx, buf+i, buf+i);<br />
}<br />
}<br />
<br />
typedef struct {<br />
uint64_t mode; // 0: bounded, 1: fixed<br />
uint64_t aid;<br />
} SceNpDrmRifName;<br />
<br />
int getRifName(char *name, int length, uint64_t aid, uint64_t mode) {<br />
SceNpDrmRifName rif_name;<br />
rif_name.mode = mode;<br />
rif_name.aid = aid;<br />
aes_encrypt(&rif_name, sizeof(SceNpDrmRifName), rif_name_keys);<br />
<br />
snprintf(name, length, "%016llx%016llx.rif", __builtin_bswap64(((uint64_t *)&rif_name)[0]), __builtin_bswap64(((uint64_t *)&rif_name)[1])); <br />
}<br />
</source><br />
<br />
== SceNpDrm ==<br />
<br />
=== _sceNpDrmCheckDrmReset ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x4458812B<br />
|-<br />
| 3.60 || 0x4458812B<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x18<br />
int _sceNpDrmCheckDrmReset(int unk0, int unk1, void *opt);<br />
</source><br />
<br />
=== _sceNpDrmRemoveActData ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x507D06A6<br />
|-<br />
| 3.60 || 0x507D06A6<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmRemoveActData(int unk0, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmGetRifName ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xB8C5DA7C<br />
|-<br />
| 3.60 || 0xB8C5DA7C<br />
|}<br />
<br />
<source lang="C">int _sceNpDrmGetRifName(char *name, int ignored, int unk2, int unk3);</source><br />
<br />
=== _sceNpDrmGetRifNameForInstall ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xD312424D<br />
|-<br />
| 3.60 || 0xD312424D<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
//rif_data is of size 0x200<br />
int _sceNpDrmGetRifNameForInstall(char *name, void *rif_data, int num);<br />
</source><br />
<br />
=== _sceNpDrmGetRifInfo ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xE8343660<br />
|-<br />
| 3.60 || 0xE8343660<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct rif_info //size is 0x70<br />
{<br />
char content_id[0x30];<br />
char version_number[0x04];<br />
char rif_lic_flags[0x04];<br />
char lic_type0[0x04]; //lic type related<br />
char lic_type1[0x04]; //lic type related<br />
char account_id[0x08];<br />
char rif_data_98[0x08];<br />
char lic_start_time[0x08];<br />
char lic_exp_time[0x08];<br />
char dec_rif_key[0x10]; //decrypted rif key<br />
}rif_info;<br />
<br />
typedef struct _sceNpDrmGetRifInfo_opt //size is 0x28<br />
{<br />
char* content_id;<br />
char* account_id;<br />
char* version_number;<br />
char* rif_lic_flags;<br />
char* lic_type0; //lic type related<br />
char* lic_type1; //lic type related<br />
char* lic_start_time;<br />
char* lic_exp_time;<br />
char* rif_data_98;<br />
}_sceNpDrmGetRifInfo_opt;<br />
<br />
//rif data is of size 0x200<br />
<br />
int _sceNpDrmGetRifInfo(void* rif_data, int rif_size, int num, _sceNpDrmGetRifInfo_opt* opt);<br />
<br />
</source><br />
<br />
=== _sceNpDrmGetFixedRifName ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xE935B0FC<br />
|-<br />
| 3.60 || 0xE935B0FC<br />
|}<br />
<br />
<source lang="C">int _sceNpDrmGetFixedRifName(char *name, int ignored, int unk2, int unk3);</source><br />
<br />
=== _sceNpDrmCheckActData ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xFEEBCD62<br />
|-<br />
| 3.60 || 0xFEEBCD62<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmCheckActData(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPresetRifProvisionalFlag ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x2523F57F<br />
|}<br />
<br />
<source lang="C"><br />
//rif data is of size 0x200<br />
int _sceNpDrmPresetRifProvisionalFlag(void* rif_data);<br />
</source><br />
<br />
== SceNpDrmForDriver ==<br />
<br />
=== sceNpDrmGetRifInfoForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDB406EAE<br />
|}<br />
<br />
<source lang="C"> <br />
//rif data is of size 0x200<br />
int sceNpDrmGetRifInfoForDriver(void* rif_data, int rif_size, int num, char* content_id, char* account_id, char* version_number, char* rif_lic_flags, char* lic_type0, char* lic_type1, char* lic_start_time, char* lic_exp_time, char* rif_data_98); <br />
</source><br />
<br />
=== sceNpDrmPackageSetGameExistForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x3BFD2850<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageSetGameExistForDriver(int value);</source><br />
<br />
=== sceNpDrmGetFixedRifNameForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x5D73448C<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
int sceNpDrmGetFixedRifNameForDriver(char *name, int ignored, int unk2, int unk3);<br />
</source><br />
<br />
=== sceNpDrmGetRifNameForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDF62F3B8<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
int sceNpDrmGetRifNameForDriver(char *name, int ignored, int unk2, int unk3);<br />
</source><br />
<br />
=== sceNpDrmGetRifNameForInstallForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x17573133<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
//rif data size is unknown but at least 0xF8<br />
int sceNpDrmGetRifNameForInstallForDriver(char *name, void *rif_data, int num);<br />
</source><br />
<br />
=== sceNpDrmPresetRifProvisionalFlagForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xC070FE89<br />
|}<br />
<br />
<source lang="C"><br />
//rif data size is unknown but at least 0xF8<br />
int sceNpDrmPresetRifProvisionalFlagForDriver(void* rif_data, int unk1);<br />
</source><br />
<br />
=== sceNpDrmCheckActDataForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x9265B350<br />
|}<br />
<br />
checks tm0:/npdrm/act.dat<br />
<br />
<source lang="C"><br />
//size of act data is 0x1040<br />
<br />
int sceNpDrmCheckActDataForDriver(int unk0, int unk1, int unk2, int unk3, int arg_0);<br />
</source><br />
<br />
=== sceNpDrmRemoveActDataForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x8B85A509<br />
|}<br />
<br />
checks tm0:/npdrm/act.dat<br />
<br />
<source lang="C">int sceNpDrmRemoveActDataForDriver(int unk);</source><br />
<br />
=== sceNpDrmUpdateAccountIdForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x116FC0D6<br />
|}<br />
<br />
<source lang="C">int sceNpDrmUpdateAccountIdForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmEbootSigGenMultiDiscForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x39A7A666<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenMultiDiscForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmEbootSigGenPs1ForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x6D9223E1<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenPs1ForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmGetLegacyDocKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4E321BDE<br />
|}<br />
<br />
<source lang="C"><br />
//rif data is of size 0x200<br />
//data1 is of size 0x90 - most likely decrypted with rif key from rif data using SceSblGcAuthMgr enc_dec 0x4c5de1aa<br />
int sceNpDrmGetLegacyDocKeyForDriver(void *rif_data, void *data1, int unk, void *dest);<br />
</source><br />
<br />
=== sceNpDrmEbootSigVerifyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x7A319692<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigVerifyForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmEbootSigGenPspForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x90B1A6D3<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenPspForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmEbootSigConvertForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA29B75F9<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigConvertForDriver(int unk0, int unk1, int unk2);</source><br />
<br />
=== sceNpDrmPspEbootVerifyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xB6CA3A2C<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPspEbootVerifyForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmPspEbootSigGenForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xEF387FC4<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPspEbootSigGenForDriver(int unk0, int unk1, int unk2);</source><br />
<br />
=== sceNpDrmIsLooseAccountBindForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFC84CA1A<br />
|}<br />
<br />
<source lang="C">int sceNpDrmIsLooseAccountBindForDriver();</source><br />
<br />
=== sceNpDrmUpdateDebugSettingsForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA91C7443<br />
|}<br />
<br />
checks /CONFIG/NP debug_upgradable and /CONFIG/NP2 debug_drm_loose_bind registry values<br />
<br />
<source lang="C">int sceNpDrmUpdateDebugSettingsForDriver();</source><br />
<br />
=== sceNpDrmGetRifPspKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDACB71F4<br />
|}<br />
<br />
<source lang="C"><br />
//rif_data is of size 0x200<br />
//dec_rif_key is of size 0x10<br />
int sceNpDrmGetRifPspKeyForDriver(void *rif_data, void *dec_rif_key, int unk2, int unk3, int arg_0);</source><br />
<br />
=== sceNpDrmGetRifVitaKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x723322B5<br />
|}<br />
<br />
use [[SceNpDrm#sceNpDrmGetRifInfoForDriver|sceNpDrmGetRifInfoForDriver]] to get required fields<br />
<br />
<source lang="C"><br />
int sceNpDrmGetRifVitaKeyForDriver(void *rif_data, void *dec_rif_key, char* lic_type0, char* lic_type1, char* lic_start_time, char* lic_exp_time, char* rif_lic_flags);<br />
</source><br />
<br />
=== set_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x742EBAF4<br />
|}<br />
<br />
Related to sceSblGcAuthMgrPcactActivation<br />
<br />
decrypts act_data with aes_dec_key and stores it to data segment<br />
<br />
verifies sha1 - ecdsa or sha256 - rca<br />
<br />
checks Loose Account Bind flag<br />
<br />
verifies OpenPsId<br />
<br />
creates tm0:/npdrm folder<br />
<br />
writes tm0:/npdrm/act.dat file<br />
<br />
repeats all verification steps<br />
<br />
decrypts Primary Key Table<br />
<br />
<source lang="C"><br />
//data is of size 0x1040 - this is most likely act.dat data because of size<br />
int set_act_data(void *act_data, const char *aes_dec_key);<br />
</source><br />
<br />
=== get_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xD91C3BCE<br />
|}<br />
<br />
Related to sceSblGcAuthMgrPcactGetChallenge<br />
<br />
reads 0x1038 bytes of tm0:/npdrm/act.dat data<br />
<br />
<source lang="C"><br />
//act_data is of size 0x1038<br />
int get_act_data(void* act_data);<br />
</source><br />
<br />
=== verify_rif ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFE7B17B6<br />
|}<br />
<br />
verify ECDSA - SHA1 pair or RSA - SHA256 pair<br />
<br />
<source lang="C"><br />
//rif_data max size is 0x200<br />
int verify_rif(void* rif_data, int rif_size);<br />
</source><br />
<br />
=== verify_rif_full ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFF63672D<br />
|}<br />
<br />
check OpenPsId<br />
<br />
check cmd56 handshake part<br />
<br />
perform steps to get decrypted rif key<br />
<br />
<source lang="C"><br />
//rif data size is unknown but at least 0xF8<br />
int verify_rif_full(void* rif_data);<br />
</source><br />
<br />
=== reset_act_dat ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x77926F5<br />
|}<br />
<br />
reads tm0:/npdrm/act.dat<br />
<br />
verifies sha1 - ecdsa or sha256 - rca<br />
<br />
checks Loose Account Bind flag<br />
<br />
verifies OpenPsId<br />
<br />
clears Secondary Table, RSA Signature, Unknown Sig, ECDSA Signature<br />
<br />
decrypts Primary Key Table<br />
<br />
<source lang="C"><br />
int reset_act_dat();<br />
</source><br />
<br />
== SceNpDrmPackage ==<br />
<br />
=== _sceNpDrmPackageTransform ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x567DCA1<br />
|-<br />
| 3.60 || 0x567DCA1<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x28<br />
int _sceNpDrmPackageTransform(int unk0, int unk1, void* opt, int unk3);<br />
</source><br />
<br />
=== _sceNpDrmPackageInstallFinished ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x6896EAF2<br />
|-<br />
| 3.60 || 0x6896EAF2<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmPackageInstallFinished(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageCheck ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xA1D885FA<br />
|-<br />
| 3.60 || 0xA1D885FA<br />
|}<br />
<br />
<source lang="C"><br />
int _sceNpDrmPackageCheck(const void *buffer1, SceSize size, void *buffer2, unsigned int identifier);<br />
</source><br />
<br />
=== sceNpDrmPackageIsGameExist ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xB9337914<br />
|-<br />
| 3.60 || 0xB9337914<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageIsGameExist();</source><br />
<br />
=== _sceNpDrmPackageInstallStarted ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xCEC18DA4<br />
|-<br />
| 3.60 || 0xCEC18DA4<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmPackageInstallStarted(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageDecrypt ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xD6F05ACC<br />
|-<br />
| 3.60 || 0xD6F05ACC<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct _sceNpDrmPackageDecrypt //size is 0x10<br />
{<br />
SceOff offset; //The offset in the encrypted data<br />
unsigned int identifier;<br />
uint32_t unk_C;<br />
} _sceNpDrmPackageDecrypt_opt;<br />
<br />
int _sceNpDrmPackageDecrypt(void * buffer, SceSize size, _sceNpDrmPackageDecrypt_opt * opt);<br />
</source><br />
<br />
=== sceNpDrmPackageInstallOngoing ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xED0471FE<br />
|-<br />
| 3.60 || 0xED0471FE<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageInstallOngoing(int unk0, int unk1);</source><br />
<br />
=== _sceNpDrmPackageUninstallFinished ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x23A28861<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmPackageUninstallFinished(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageUninstallStarted ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4901C3E6<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmPackageUninstallStarted(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== sceNpDrmPackageUninstallOngoing ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xF1FF6193<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageUninstallOngoing(int unk0, int unk1);</source><br />
<br />
=== unk_200D2DE4 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x200D2DE4<br />
|}<br />
<br />
<source lang="C">int unk_200D2DE4(int unk0, int unk1);</source><br />
<br />
=== unk_4665E75A ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4665E75A<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_4665E75A(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
=== unk_640C1724 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x640C1724<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int unk_640C1724(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
=== unk_97BB85BD ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x97BB85BD<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_97BB85BD(int unk0, int unk1, int unk2, void *opt)<br />
</source><br />
<br />
=== unk_A5E0F38C ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA5E0F38C<br />
|}<br />
<br />
<source lang="C">int unk_A5E0F38C(int unk0, int unk1);</source><br />
<br />
=== unk_C75A775B ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xC75A775B<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int unk_C75A775B(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
== ScePsmDrm ==<br />
<br />
=== get_rif_name ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x0D6470DA<br />
|}<br />
<br />
<source lang="C"><br />
//some data is of size 0x400 and contains rif data<br />
int get_rif_name(char *rif_name, void *some_data);<br />
</source><br />
<br />
=== _get_info ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xE31A6220<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct get_info_opt //size is 0x10<br />
{<br />
void* out2;<br />
void* out3;<br />
uint32_t unk_8;<br />
uint32_t unk_C;<br />
}get_info_opt<br />
<br />
int _get_info(void *some_data, void *out0, void *out1, get_info_opt *opt);<br />
</source><br />
<br />
=== scePsmDrmGetRifKey ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x207A2C53<br />
|}<br />
<br />
<source lang="C"><br />
<br />
/**<br />
* rif_data size 0x400<br />
* klicensee size 0x200<br />
**/<br />
int scePsmDrmGetRifKey(SceNpDrmLicense * rif_data , uint8_t *klicensee, uint32_t *flags, uint64_t *start_time, uint64_t *expiration_time);<br />
<br />
</source><br />
<br />
=== unk_E193CBB ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xE193CBB<br />
|}<br />
<br />
<source lang="C">int unk_E193CBB(int unk0);</source><br />
<br />
=== unk_3E881391 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x3E881391<br />
|}<br />
<br />
<source lang="C">int unk_3E881391(int unk0);</source><br />
<br />
=== unk_A89653B3 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA89653B3<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_A89653B3(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
== ScePsmDrmForDriver ==<br />
<br />
=== get_info_for_driver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x984F9017<br />
|}<br />
<br />
this function is named after sceNpDrmGetRifInfoForDriver since arguments are very similar<br />
<br />
<source lang="C"><br />
//some_data is of size 0x400 and should contain rca signature at offset 0x300<br />
//out0 is of size 0x30<br />
//out1 is of size 0x8<br />
//out2 is of size 0x8<br />
//out3 is of size 0x8<br />
int get_info_for_driver(void *some_data, void *out0, void *out1, void *out2, void *out3);<br />
</source><br />
<br />
=== get_info_2_for_driver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x8C8CFD01<br />
|}<br />
<br />
this function is named after sceNpDrmGetRifInfoForDriver since arguments are very similar<br />
<br />
<source lang="C"><br />
//data is of size 0x400<br />
//out0 is of size 0x200<br />
//out1 is of size 0x4<br />
//out2 is of size 0x8<br />
//out3 is of size 0x8<br />
int get_info_2_for_driver(void *data, void *out0, void *out1, void *out2, int out3);<br />
</source><br />
<br />
=== set_psm_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xCB73E9D3<br />
|}<br />
<br />
decrypts psm_act_data with aes_dec_key<br />
<br />
creates tm0:/psmdrm if nesessary<br />
<br />
writes tm0:/psmdrm/act.dat<br />
<br />
verifies sha256 - rca<br />
<br />
<source lang="C"><br />
//data is of size 0x400<br />
int set_psm_act_data(void *psm_act_data, const char *aes_dec_key);<br />
</source><br />
<br />
=== unk_4CD5375C ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4CD5375C<br />
|}<br />
<br />
<source lang="C">int unk_4CD5375C(int unk0);</source><br />
<br />
=== unk_791198CE ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x791198CE<br />
|}<br />
<br />
<source lang="C">int unk_791198CE();</source><br />
<br />
=== unk_B09003A7 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xB09003A7<br />
|}<br />
<br />
<source lang="C">int unk_B09003A7(int unk0, int unk1, int unk2, int unk3, int arg_0);</source><br />
<br />
== Package integrity checks ==<br />
=== Disable hash/signature verification ===<br />
To find the function responsible for package verification search for immediate 0x7F504B47 ('.PKG'). Inside it does a lot of stuff including determining the function that will do signature checks. Find the condition that looks like <code>if ( (v62 & 7) == 3 )</code>; below you will see the assignment <code>check_func = &off_81009CFC;</code>. To bypass signature checks you need to patch two functions located at this offset and offset+4, making them behave as "return 1" is enough. For reference, on 1.60 the functions are sub_81000310 and sub_81000AA4. sub_81000310 is the only function in this module that calls SceSblGcAuthMgrPkgForDriver_E459A9A8_imp.<br />
<br />
Note that on 1.60 this module sometimes is loaded at different addresses between reboots.<br />
<br />
=== Allow debug packages to be installed ===<br />
Find the function that calls SceSblAIMgrForDriver_D78B04A2; patch it to always return 1. On 1.60 it's at 0x81002d64.<br />
<br />
Search for immediate 0x80870003, there should be two matches. Replace both with "MOV Reg, #0". On 1.60 the locations are 0x810035fe and 0x81004856.<br />
<br />
== RIF ==<br />
The RIF files are used as the eboot.bin DRM. For each installed PKG and Game Card you will have an unique RIF file with proper information that will be used when you open the game to verify if you own the game(to PKG) and decrypt the eboot.bin. The RIF files may hold important information as PSN Account ID, the key used to decrypt one of the SELF encrypt layers [...]. <br />
<br />
PS Vita supports two different RIF file format. The first format (License Type 0) seems to be used by licenses with 0x98 bytes size and the second (License Type 1) seems to be used by RIF files with 0x200 bytes size. The difference between them is just the signature verification. License Type 0 only uses ECDSA Signature, the License Type 1 uses the ECDSA Signature verification and an extra RSA signature verification.<br />
<br />
{| class='wikitable'<br />
|-<br />
! Name !! Offset !! Size<br />
|-<br />
| Version || 0x0 || 0x2<br />
|-<br />
| Version Flag (0 or 1) || 0x2 || 0x2<br />
|-<br />
| License Type || 0x4 || 0x2<br />
|-<br />
| License Flags || 0x6 || 0x2<br />
|-<br />
| PSN Account ID || 0x8 || 0x8<br />
|- <br />
| Content ID || 0x10 || 0x30<br />
|- <br />
| Primary Key Table index || 0x40 || 0x10<br />
|- <br />
| RIF Key 1 || 0x50 || 0x10<br />
|- <br />
| License start time || 0x60 || 0x8<br />
|-<br />
| License expiration time || 0x68 || 0x8<br />
|- <br />
| ECDSA Signature || 0x70 || 0x28<br />
|- <br />
| Some Flag|| 0x98 || 0x8<br />
|- <br />
| RIF Key 2 || 0xA0 || 0x10<br />
|- <br />
| Unknown || 0xB0 || 0x10<br />
|- <br />
| [[SceSblSsMgr#sceKernelGetOpenPsIdForDriver|OpenPsId]] if bit 8 is set in License Flags || 0xC0 || 0x10<br />
|- <br />
| Unknown || 0xD0 || 0x10<br />
|- <br />
| [[SceSblGcAuthMgr#memcmp_5018_fast|CMD56 handshake part]] if bit A is set in License Flags || 0xE0 || 0x14<br />
|- <br />
| Some Flag related to debug_upgradable || 0xF4 || 0x4<br />
|- <br />
| Unknown || 0xF8 || 0x4<br />
|- <br />
| SKU flag|| 0xFC || 0x4<br />
|- <br />
| RSA Signature || 0x100 || 0x100<br />
|-<br />
|}<br />
<br />
== PSM-ACT ==<br />
PSM Activation file<br />
<br />
{| class='wikitable'<br />
|-<br />
! Name !! Offset !! Size !! Example !! Remark<br />
|-<br />
| Magic Number || 0x0 || 0x8 || PSM-ACT || <br />
|-<br />
| Unknown1 || 0x8 || 0x8 || 00 00 00 00 00 00 00 00 || <br />
|-<br />
| Account ID || 0x10 || 0x8 || 91 78 34 02 01 EF CD AB || PSN account ID (Reversed from ACT.DAT) <br />
|-<br />
| Unknown2 || 0x18 || 0x4 || 00 00 00 00 || Must be 0 <br />
|-<br />
| Unknown3 || 0x1C || 0x4 || 00 00 00 00 || Must be 0 <br />
|-<br />
| Activation start time || 0x20 || 0x8 || 00 00 01 4C 16 4D 83 A8 || <br />
|-<br />
| Activation expiration time || 0x28 || 0x8 || 00 00 04 2A D4 3D 3E 68 || <br />
|-<br />
| SHA256 from act.dat || 0x30 || 0x20 || || SHA 256 digest of get_act_data (0x39222A58) <br />
|-<br />
| Unknown4 || 0x50 || 0xB0 || || Zeros <br />
|-<br />
| Unknown5 || 0x100 || 0x200 || || KEY saved at 0x22C8 - Decrypted with 0x2288 <br />
|-<br />
| SHA256 digest || 0x300 || 0x100 || ||<br />
<br />
|}<br />
<br />
<br />
== PSM-RIF ==<br />
PSM RIF file<br />
<br />
{| class='wikitable'<br />
|-<br />
! Name !! Offset !! Size !! Example !! Remark<br />
|-<br />
| Magic Number || 0x0 || 0x8 || PSM-RIF || <br />
|-<br />
| Unknown1 || 0x8 || 0x4 || 00 00 00 01 || Maybe Version and Version Flag? <br />
|-<br />
| Unknown2 || 0xC || 0x4 || 00 00 00 00 || Maybe License Type and License Flags? <br />
|-<br />
| Account ID || 0x10 || 0x8 || 91 78 34 02 01 EF CD AB || PSN account ID (Reversed from ACT.DAT) <br />
|-<br />
| Unknown3 || 0x18 || 0x4 || 00 00 00 00 || Must be 0 <br />
|-<br />
| Unknown4 || 0x1C || 0x4 || 00 00 00 00 || Must be 0 <br />
|-<br />
| Activation start time || 0x20 || 0x8 || 00 00 01 4C 16 4D 83 A8 || <br />
|-<br />
| Activation expiration time || 0x28 || 0x8 || 7F FF FF FF FF FF FF FF || Max Value<br />
|-<br />
| SHA256 from act.dat || 0x30 || 0x20 || || SHA 256 digest of get_act_data (0x39222A58) <br />
|-<br />
| Content ID || 0x50 || 0x30 || EM0041-NPOA00013_00-0000000000000000 || <br />
|-<br />
| Unknown5 || 0x80 || 0x80 || || Zeros <br />
|-<br />
| Unknown6 || 0x100 || 0x200 || || Key saved at 0x1F40. First 0x200 bytes are decrypted with 0x22C8 and then only the first 0x20 bytes are again decrypted with 0x2288<br />
|-<br />
| SHA256 digest || 0x300 || 0x100 || ||<br />
<br />
|}<br />
<br />
[[Category:Modules]]<br />
[[Category:Kernel]]</div>
Frangarcj
http://wiki.henkaku.xyz/vita/index.php?title=SceNpDrm&diff=4654
SceNpDrm
2017-09-15T08:42:49Z
<p>Frangarcj: /* RIF */</p>
<hr />
<div>== Module ==<br />
<br />
=== Known NIDs ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! Name !! World !! Privilege !! NID<br />
|-<br />
| 1.69 || SceNpDrm || Non-secure || Kernel || 0xACCB4845<br />
|-<br />
| 3.60 || SceNpDrm || ? || Kernel || 0xE7E2CE05<br />
|}<br />
<br />
== Libraries ==<br />
<br />
=== Known NIDs ===<br />
<br />
{| class="wikitable"<br />
|-<br />
! Version !! Name !! World !! Visibility !! NID<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrm|SceNpDrm]] || Non-secure || User || 0xF2799B1B<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrm|SceNpDrm]] || ? || User || 0xF2799B1B<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrmForDriver|SceNpDrmForDriver]] || Non-secure || Kernel || 0xD84DC44A<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrmForDriver|SceNpDrmForDriver]] || ? || Kernel || 0xD84DC44A<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrmPackage|SceNpDrmPackage]] || Non-secure || User || 0x88514DB2<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrmPackage|SceNpDrmPackage]] || ? || User || 0x88514DB2<br />
|-<br />
| 3.60 || [[SceNpDrm#ScePsmDrm|ScePsmDrm]] || ? || User || 0x3F2B0888<br />
|-<br />
| 3.60 || [[SceNpDrm#ScePsmDrmForDriver|ScePsmDrmForDriver]] || ? || Kernel || 0x9F4924F2<br />
|}<br />
<br />
== Data segment layout ==<br />
<br />
{| class="wikitable"<br />
|-<br />
! Address !! Size !! Description<br />
|-<br />
| 0x0000 || 0x4 || SceNpDrm mutex SceUID<br />
|-<br />
| 0x0004 || 0x4 || ScePsmDrm mutex SceUID<br />
|-<br />
| 0x0008 || 0x8 || unknown<br />
|-<br />
| 0x0010 || 0xC0 || static keys decrypted with [[SceSblAuthMgr#sceSblAuthMgrGetEKc|sceSblAuthMgrGetEKc]] key 0. <br />
<br />
First 0x10 bytes are reencrypted with [[SceSblSsMgr#sceSblSsMgrGetConsoleId|CID]].<br />
<br />
First 0x10 bytes are aes_key used to decrypt 0x800 bytes of Primary Key Table from act.dat<br />
<br />
Second 0x10 bytes are aes_key used to decrypt Primary Key Table index from rif.<br />
|-<br />
| 0x00D0 || 0xCF8 || unknown<br />
|-<br />
| 0x0DC8 || 0x4 || Game Exist flag<br />
|-<br />
| 0x0DCC || 0x4 || Is DEX flag or Is Tool flag<br />
|-<br />
| 0x0DD0 || 0x30 || unknown<br />
|-<br />
| 0x0E00 || 0x1040 || tm0:/npdrm/act.dat data<br />
|-<br />
| 0x1E40 || 0x400 || tm0:/psmdrm/act.dat data<br />
|-<br />
| 0x2240 || 0x10 || [[SceSblSsMgr#sceKernelGetOpenPsIdForDriver|OpenPsId]]<br />
<br />
This key is compared against OpenPsId from act.dat<br />
<br />
This key is compared to data in rif file at offset 0xC0<br />
|-<br />
| 0x2250 || 0x4 || act data Is Valid flag<br />
|-<br />
| 0x2254 || 0x4 || unknown<br />
|-<br />
| 0x2258 || 0x8 || /CONFIG/NP/account_id reg key<br />
|-<br />
| 0x2260 || 0x4 || Loose Account Bind flag<br />
|-<br />
| 0x2264 || 0x4 || /CONFIG/NP/debug_upgradable reg key<br />
|-<br />
| 0x2268 || 0x20 || sha 256 digest of [[SceSblGcAuthMgr#get_act_data|get_act_data]]<br />
|-<br />
| 0x2288 || 0x20 || hmac sha 256 digest of [[SceSblGcAuthMgr#get_act_data|get_act_data]]<br />
|-<br />
| 0x22A8 || 0x8 || unknown<br />
|-<br />
| 0x22B0 || 0x8 || account_id<br />
|-<br />
| 0x22B8 || 0x8 || psm activation start date<br />
|-<br />
| 0x22C0 || 0x8 || psm activation end date<br />
|-<br />
| 0x22C8 || 0x20 || some key decrypted with 0x2288<br />
|-<br />
|}<br />
<br />
== Obtaining klicensee ==<br />
<br />
1. Get 0xC0 bytes from SceNpDrm code segment at offset 0x111D0. This is the list of static keys.<br />
<br />
2. Decrypt 0xC0 bytes of static keys using [[SceSblAuthMgr#sceSblAuthMgrGetEKc|sceSblAuthMgrGetEKc]] key 0.<br />
<br />
3. Get 0x10 bytes of CID with [[SceSblSsMgr#sceSblSsMgrGetConsoleIdForDriver| sceSblSsMgrGetConsoleIdForDriver]].<br />
<br />
4. Encrypt first 0x10 bytes of static keys with CID using AES (need to figure out which AES exactly).<br />
<br />
5. Read 0x800 bytes of Primary Key Table from act.dat<br />
<br />
6. Decrypt 0x800 bytes of Primary Key Table with reencrypted static key using AES (need to figure out which AES exactly).<br />
<br />
7. Get 0x97 / 0x200 bytes of rif data and select one of 5 scenarios for decrypting RIF Key based on license flags (need to figure out).<br />
<br />
=== Scenario 1 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take static keys 3, 4<br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 2 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take primary keys 1, 2<br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 3 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take cmd56 handshake keys with [[SceSblGcAuthMgr#get_5018_data|get_5018_data]] <br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 4 ===<br />
<br />
Take RIF Key 1<br />
<br />
Take cmd56 handshake keys with [[SceSblGcAuthMgr#get_5018_data|get_5018_data]] <br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Erase RIF Key 1 from rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 1 and obtain klicensee.<br />
<br />
=== Scenario 5 ===<br />
<br />
Decrypt Primary Table Key index from rif data with static key 2 using AES (need to figure out which AES exactly).<br />
<br />
Take primary key using decrypted index.<br />
<br />
Decrypt RIF key 1 with obtained primary key using AES (need to figure out which AES exactly).<br />
<br />
== Get rif name ==<br />
<br />
<source lang="C"><br />
uint8_t rif_name_keys[0x10] = {<br />
0x19, 0xDD, 0x4F, 0xB9, 0x89, 0x48, 0x2B, 0xD4,<br />
0xCB, 0x9E, 0xC9, 0xC7, 0x9A, 0x2E, 0xFB, 0xD0<br />
};<br />
<br />
int aes_encrypt(const void *buf, int size, uint8_t *keys) {<br />
AES_ctx ctx;<br />
AES_set_key(&ctx, rif_name_keys, 0x80);<br />
<br />
int i;<br />
for (i = 0; i < size; i += 0x10) {<br />
AES_encrypt(&ctx, buf+i, buf+i);<br />
}<br />
}<br />
<br />
typedef struct {<br />
uint64_t mode; // 0: bounded, 1: fixed<br />
uint64_t aid;<br />
} SceNpDrmRifName;<br />
<br />
int getRifName(char *name, int length, uint64_t aid, uint64_t mode) {<br />
SceNpDrmRifName rif_name;<br />
rif_name.mode = mode;<br />
rif_name.aid = aid;<br />
aes_encrypt(&rif_name, sizeof(SceNpDrmRifName), rif_name_keys);<br />
<br />
snprintf(name, length, "%016llx%016llx.rif", __builtin_bswap64(((uint64_t *)&rif_name)[0]), __builtin_bswap64(((uint64_t *)&rif_name)[1])); <br />
}<br />
</source><br />
<br />
== SceNpDrm ==<br />
<br />
=== _sceNpDrmCheckDrmReset ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x4458812B<br />
|-<br />
| 3.60 || 0x4458812B<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x18<br />
int _sceNpDrmCheckDrmReset(int unk0, int unk1, void *opt);<br />
</source><br />
<br />
=== _sceNpDrmRemoveActData ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x507D06A6<br />
|-<br />
| 3.60 || 0x507D06A6<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmRemoveActData(int unk0, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmGetRifName ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xB8C5DA7C<br />
|-<br />
| 3.60 || 0xB8C5DA7C<br />
|}<br />
<br />
<source lang="C">int _sceNpDrmGetRifName(char *name, int ignored, int unk2, int unk3);</source><br />
<br />
=== _sceNpDrmGetRifNameForInstall ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xD312424D<br />
|-<br />
| 3.60 || 0xD312424D<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
//rif_data is of size 0x200<br />
int _sceNpDrmGetRifNameForInstall(char *name, void *rif_data, int num);<br />
</source><br />
<br />
=== _sceNpDrmGetRifInfo ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xE8343660<br />
|-<br />
| 3.60 || 0xE8343660<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct rif_info //size is 0x70<br />
{<br />
char content_id[0x30];<br />
char version_number[0x04];<br />
char rif_lic_flags[0x04];<br />
char lic_type0[0x04]; //lic type related<br />
char lic_type1[0x04]; //lic type related<br />
char account_id[0x08];<br />
char rif_data_98[0x08];<br />
char lic_start_time[0x08];<br />
char lic_exp_time[0x08];<br />
char dec_rif_key[0x10]; //decrypted rif key<br />
}rif_info;<br />
<br />
typedef struct _sceNpDrmGetRifInfo_opt //size is 0x28<br />
{<br />
char* content_id;<br />
char* account_id;<br />
char* version_number;<br />
char* rif_lic_flags;<br />
char* lic_type0; //lic type related<br />
char* lic_type1; //lic type related<br />
char* lic_start_time;<br />
char* lic_exp_time;<br />
char* rif_data_98;<br />
}_sceNpDrmGetRifInfo_opt;<br />
<br />
//rif data is of size 0x200<br />
<br />
int _sceNpDrmGetRifInfo(void* rif_data, int rif_size, int num, _sceNpDrmGetRifInfo_opt* opt);<br />
<br />
</source><br />
<br />
=== _sceNpDrmGetFixedRifName ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xE935B0FC<br />
|-<br />
| 3.60 || 0xE935B0FC<br />
|}<br />
<br />
<source lang="C">int _sceNpDrmGetFixedRifName(char *name, int ignored, int unk2, int unk3);</source><br />
<br />
=== _sceNpDrmCheckActData ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xFEEBCD62<br />
|-<br />
| 3.60 || 0xFEEBCD62<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmCheckActData(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPresetRifProvisionalFlag ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x2523F57F<br />
|}<br />
<br />
<source lang="C"><br />
//rif data is of size 0x200<br />
int _sceNpDrmPresetRifProvisionalFlag(void* rif_data);<br />
</source><br />
<br />
== SceNpDrmForDriver ==<br />
<br />
=== sceNpDrmGetRifInfoForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDB406EAE<br />
|}<br />
<br />
<source lang="C"> <br />
//rif data is of size 0x200<br />
int sceNpDrmGetRifInfoForDriver(void* rif_data, int rif_size, int num, char* content_id, char* account_id, char* version_number, char* rif_lic_flags, char* lic_type0, char* lic_type1, char* lic_start_time, char* lic_exp_time, char* rif_data_98); <br />
</source><br />
<br />
=== sceNpDrmPackageSetGameExistForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x3BFD2850<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageSetGameExistForDriver(int value);</source><br />
<br />
=== sceNpDrmGetFixedRifNameForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x5D73448C<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
int sceNpDrmGetFixedRifNameForDriver(char *name, int ignored, int unk2, int unk3);<br />
</source><br />
<br />
=== sceNpDrmGetRifNameForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDF62F3B8<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
int sceNpDrmGetRifNameForDriver(char *name, int ignored, int unk2, int unk3);<br />
</source><br />
<br />
=== sceNpDrmGetRifNameForInstallForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x17573133<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
//rif data size is unknown but at least 0xF8<br />
int sceNpDrmGetRifNameForInstallForDriver(char *name, void *rif_data, int num);<br />
</source><br />
<br />
=== sceNpDrmPresetRifProvisionalFlagForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xC070FE89<br />
|}<br />
<br />
<source lang="C"><br />
//rif data size is unknown but at least 0xF8<br />
int sceNpDrmPresetRifProvisionalFlagForDriver(void* rif_data, int unk1);<br />
</source><br />
<br />
=== sceNpDrmCheckActDataForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x9265B350<br />
|}<br />
<br />
checks tm0:/npdrm/act.dat<br />
<br />
<source lang="C"><br />
//size of act data is 0x1040<br />
<br />
int sceNpDrmCheckActDataForDriver(int unk0, int unk1, int unk2, int unk3, int arg_0);<br />
</source><br />
<br />
=== sceNpDrmRemoveActDataForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x8B85A509<br />
|}<br />
<br />
checks tm0:/npdrm/act.dat<br />
<br />
<source lang="C">int sceNpDrmRemoveActDataForDriver(int unk);</source><br />
<br />
=== sceNpDrmUpdateAccountIdForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x116FC0D6<br />
|}<br />
<br />
<source lang="C">int sceNpDrmUpdateAccountIdForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmEbootSigGenMultiDiscForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x39A7A666<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenMultiDiscForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmEbootSigGenPs1ForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x6D9223E1<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenPs1ForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmGetLegacyDocKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4E321BDE<br />
|}<br />
<br />
<source lang="C"><br />
//rif data is of size 0x200<br />
//data1 is of size 0x90 - most likely decrypted with rif key from rif data using SceSblGcAuthMgr enc_dec 0x4c5de1aa<br />
int sceNpDrmGetLegacyDocKeyForDriver(void *rif_data, void *data1, int unk, void *dest);<br />
</source><br />
<br />
=== sceNpDrmEbootSigVerifyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x7A319692<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigVerifyForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmEbootSigGenPspForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x90B1A6D3<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenPspForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmEbootSigConvertForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA29B75F9<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigConvertForDriver(int unk0, int unk1, int unk2);</source><br />
<br />
=== sceNpDrmPspEbootVerifyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xB6CA3A2C<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPspEbootVerifyForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmPspEbootSigGenForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xEF387FC4<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPspEbootSigGenForDriver(int unk0, int unk1, int unk2);</source><br />
<br />
=== sceNpDrmIsLooseAccountBindForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFC84CA1A<br />
|}<br />
<br />
<source lang="C">int sceNpDrmIsLooseAccountBindForDriver();</source><br />
<br />
=== sceNpDrmUpdateDebugSettingsForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA91C7443<br />
|}<br />
<br />
checks /CONFIG/NP debug_upgradable and /CONFIG/NP2 debug_drm_loose_bind registry values<br />
<br />
<source lang="C">int sceNpDrmUpdateDebugSettingsForDriver();</source><br />
<br />
=== sceNpDrmGetRifPspKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDACB71F4<br />
|}<br />
<br />
<source lang="C"><br />
//rif_data is of size 0x200<br />
//dec_rif_key is of size 0x10<br />
int sceNpDrmGetRifPspKeyForDriver(void *rif_data, void *dec_rif_key, int unk2, int unk3, int arg_0);</source><br />
<br />
=== sceNpDrmGetRifVitaKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x723322B5<br />
|}<br />
<br />
use [[SceNpDrm#sceNpDrmGetRifInfoForDriver|sceNpDrmGetRifInfoForDriver]] to get required fields<br />
<br />
<source lang="C"><br />
int sceNpDrmGetRifVitaKeyForDriver(void *rif_data, void *dec_rif_key, char* lic_type0, char* lic_type1, char* lic_start_time, char* lic_exp_time, char* rif_lic_flags);<br />
</source><br />
<br />
=== set_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x742EBAF4<br />
|}<br />
<br />
Related to sceSblGcAuthMgrPcactActivation<br />
<br />
decrypts act_data with aes_dec_key and stores it to data segment<br />
<br />
verifies sha1 - ecdsa or sha256 - rca<br />
<br />
checks Loose Account Bind flag<br />
<br />
verifies OpenPsId<br />
<br />
creates tm0:/npdrm folder<br />
<br />
writes tm0:/npdrm/act.dat file<br />
<br />
repeats all verification steps<br />
<br />
decrypts Primary Key Table<br />
<br />
<source lang="C"><br />
//data is of size 0x1040 - this is most likely act.dat data because of size<br />
int set_act_data(void *act_data, const char *aes_dec_key);<br />
</source><br />
<br />
=== get_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xD91C3BCE<br />
|}<br />
<br />
Related to sceSblGcAuthMgrPcactGetChallenge<br />
<br />
reads 0x1038 bytes of tm0:/npdrm/act.dat data<br />
<br />
<source lang="C"><br />
//act_data is of size 0x1038<br />
int get_act_data(void* act_data);<br />
</source><br />
<br />
=== verify_rif ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFE7B17B6<br />
|}<br />
<br />
verify ECDSA - SHA1 pair or RSA - SHA256 pair<br />
<br />
<source lang="C"><br />
//rif_data max size is 0x200<br />
int verify_rif(void* rif_data, int rif_size);<br />
</source><br />
<br />
=== verify_rif_full ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFF63672D<br />
|}<br />
<br />
check OpenPsId<br />
<br />
check cmd56 handshake part<br />
<br />
perform steps to get decrypted rif key<br />
<br />
<source lang="C"><br />
//rif data size is unknown but at least 0xF8<br />
int verify_rif_full(void* rif_data);<br />
</source><br />
<br />
=== reset_act_dat ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x77926F5<br />
|}<br />
<br />
reads tm0:/npdrm/act.dat<br />
<br />
verifies sha1 - ecdsa or sha256 - rca<br />
<br />
checks Loose Account Bind flag<br />
<br />
verifies OpenPsId<br />
<br />
clears Secondary Table, RSA Signature, Unknown Sig, ECDSA Signature<br />
<br />
decrypts Primary Key Table<br />
<br />
<source lang="C"><br />
int reset_act_dat();<br />
</source><br />
<br />
== SceNpDrmPackage ==<br />
<br />
=== _sceNpDrmPackageTransform ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x567DCA1<br />
|-<br />
| 3.60 || 0x567DCA1<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x28<br />
int _sceNpDrmPackageTransform(int unk0, int unk1, void* opt, int unk3);<br />
</source><br />
<br />
=== _sceNpDrmPackageInstallFinished ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x6896EAF2<br />
|-<br />
| 3.60 || 0x6896EAF2<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmPackageInstallFinished(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageCheck ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xA1D885FA<br />
|-<br />
| 3.60 || 0xA1D885FA<br />
|}<br />
<br />
<source lang="C"><br />
int _sceNpDrmPackageCheck(const void *buffer1, SceSize size, void *buffer2, unsigned int identifier);<br />
</source><br />
<br />
=== sceNpDrmPackageIsGameExist ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xB9337914<br />
|-<br />
| 3.60 || 0xB9337914<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageIsGameExist();</source><br />
<br />
=== _sceNpDrmPackageInstallStarted ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xCEC18DA4<br />
|-<br />
| 3.60 || 0xCEC18DA4<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmPackageInstallStarted(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageDecrypt ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xD6F05ACC<br />
|-<br />
| 3.60 || 0xD6F05ACC<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct _sceNpDrmPackageDecrypt //size is 0x10<br />
{<br />
SceOff offset; //The offset in the encrypted data<br />
unsigned int identifier;<br />
uint32_t unk_C;<br />
} _sceNpDrmPackageDecrypt_opt;<br />
<br />
int _sceNpDrmPackageDecrypt(void * buffer, SceSize size, _sceNpDrmPackageDecrypt_opt * opt);<br />
</source><br />
<br />
=== sceNpDrmPackageInstallOngoing ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xED0471FE<br />
|-<br />
| 3.60 || 0xED0471FE<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageInstallOngoing(int unk0, int unk1);</source><br />
<br />
=== _sceNpDrmPackageUninstallFinished ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x23A28861<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmPackageUninstallFinished(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageUninstallStarted ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4901C3E6<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmPackageUninstallStarted(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== sceNpDrmPackageUninstallOngoing ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xF1FF6193<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageUninstallOngoing(int unk0, int unk1);</source><br />
<br />
=== unk_200D2DE4 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x200D2DE4<br />
|}<br />
<br />
<source lang="C">int unk_200D2DE4(int unk0, int unk1);</source><br />
<br />
=== unk_4665E75A ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4665E75A<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_4665E75A(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
=== unk_640C1724 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x640C1724<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int unk_640C1724(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
=== unk_97BB85BD ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x97BB85BD<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_97BB85BD(int unk0, int unk1, int unk2, void *opt)<br />
</source><br />
<br />
=== unk_A5E0F38C ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA5E0F38C<br />
|}<br />
<br />
<source lang="C">int unk_A5E0F38C(int unk0, int unk1);</source><br />
<br />
=== unk_C75A775B ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xC75A775B<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int unk_C75A775B(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
== ScePsmDrm ==<br />
<br />
=== get_rif_name ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x0D6470DA<br />
|}<br />
<br />
<source lang="C"><br />
//some data is of size 0x400 and contains rif data<br />
int get_rif_name(char *rif_name, void *some_data);<br />
</source><br />
<br />
=== _get_info ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xE31A6220<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct get_info_opt //size is 0x10<br />
{<br />
void* out2;<br />
void* out3;<br />
uint32_t unk_8;<br />
uint32_t unk_C;<br />
}get_info_opt<br />
<br />
int _get_info(void *some_data, void *out0, void *out1, get_info_opt *opt);<br />
</source><br />
<br />
=== _get_info_2 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x207A2C53<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct get_info2_opt //size is 0x10<br />
{<br />
void* out2;<br />
void* out3;<br />
uint32_t unk_8;<br />
uint32_t unk_C;<br />
}get_info2_opt<br />
<br />
int _get_info(void *some_data, void *out0, void *out1, get_info2_opt *opt);<br />
</source><br />
<br />
=== unk_E193CBB ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xE193CBB<br />
|}<br />
<br />
<source lang="C">int unk_E193CBB(int unk0);</source><br />
<br />
=== unk_3E881391 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x3E881391<br />
|}<br />
<br />
<source lang="C">int unk_3E881391(int unk0);</source><br />
<br />
=== unk_A89653B3 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA89653B3<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_A89653B3(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
== ScePsmDrmForDriver ==<br />
<br />
=== get_info_for_driver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x984F9017<br />
|}<br />
<br />
this function is named after sceNpDrmGetRifInfoForDriver since arguments are very similar<br />
<br />
<source lang="C"><br />
//some_data is of size 0x400 and should contain rca signature at offset 0x300<br />
//out0 is of size 0x30<br />
//out1 is of size 0x8<br />
//out2 is of size 0x8<br />
//out3 is of size 0x8<br />
int get_info_for_driver(void *some_data, void *out0, void *out1, void *out2, void *out3);<br />
</source><br />
<br />
=== get_info_2_for_driver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x8C8CFD01<br />
|}<br />
<br />
this function is named after sceNpDrmGetRifInfoForDriver since arguments are very similar<br />
<br />
<source lang="C"><br />
//data is of size 0x400<br />
//out0 is of size 0x200<br />
//out1 is of size 0x4<br />
//out2 is of size 0x8<br />
//out3 is of size 0x8<br />
int get_info_2_for_driver(void *data, void *out0, void *out1, void *out2, int out3);<br />
</source><br />
<br />
=== set_psm_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xCB73E9D3<br />
|}<br />
<br />
decrypts psm_act_data with aes_dec_key<br />
<br />
creates tm0:/psmdrm if nesessary<br />
<br />
writes tm0:/psmdrm/act.dat<br />
<br />
verifies sha256 - rca<br />
<br />
<source lang="C"><br />
//data is of size 0x400<br />
int set_psm_act_data(void *psm_act_data, const char *aes_dec_key);<br />
</source><br />
<br />
=== unk_4CD5375C ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4CD5375C<br />
|}<br />
<br />
<source lang="C">int unk_4CD5375C(int unk0);</source><br />
<br />
=== unk_791198CE ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x791198CE<br />
|}<br />
<br />
<source lang="C">int unk_791198CE();</source><br />
<br />
=== unk_B09003A7 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xB09003A7<br />
|}<br />
<br />
<source lang="C">int unk_B09003A7(int unk0, int unk1, int unk2, int unk3, int arg_0);</source><br />
<br />
== Package integrity checks ==<br />
=== Disable hash/signature verification ===<br />
To find the function responsible for package verification search for immediate 0x7F504B47 ('.PKG'). Inside it does a lot of stuff including determining the function that will do signature checks. Find the condition that looks like <code>if ( (v62 & 7) == 3 )</code>; below you will see the assignment <code>check_func = &off_81009CFC;</code>. To bypass signature checks you need to patch two functions located at this offset and offset+4, making them behave as "return 1" is enough. For reference, on 1.60 the functions are sub_81000310 and sub_81000AA4. sub_81000310 is the only function in this module that calls SceSblGcAuthMgrPkgForDriver_E459A9A8_imp.<br />
<br />
Note that on 1.60 this module sometimes is loaded at different addresses between reboots.<br />
<br />
=== Allow debug packages to be installed ===<br />
Find the function that calls SceSblAIMgrForDriver_D78B04A2; patch it to always return 1. On 1.60 it's at 0x81002d64.<br />
<br />
Search for immediate 0x80870003, there should be two matches. Replace both with "MOV Reg, #0". On 1.60 the locations are 0x810035fe and 0x81004856.<br />
<br />
== RIF ==<br />
The RIF files are used as the eboot.bin DRM. For each installed PKG and Game Card you will have an unique RIF file with proper information that will be used when you open the game to verify if you own the game(to PKG) and decrypt the eboot.bin. The RIF files may hold important information as PSN Account ID, the key used to decrypt one of the SELF encrypt layers [...]. <br />
<br />
PS Vita supports two different RIF file format. The first format (License Type 0) seems to be used by licenses with 0x98 bytes size and the second (License Type 1) seems to be used by RIF files with 0x200 bytes size. The difference between them is just the signature verification. License Type 0 only uses ECDSA Signature, the License Type 1 uses the ECDSA Signature verification and an extra RSA signature verification.<br />
<br />
{| class='wikitable'<br />
|-<br />
! Name !! Offset !! Size<br />
|-<br />
| Version || 0x0 || 0x2<br />
|-<br />
| Version Flag (0 or 1) || 0x2 || 0x2<br />
|-<br />
| License Type || 0x4 || 0x2<br />
|-<br />
| License Flags || 0x6 || 0x2<br />
|-<br />
| PSN Account ID || 0x8 || 0x8<br />
|- <br />
| Content ID || 0x10 || 0x30<br />
|- <br />
| Primary Key Table index || 0x40 || 0x10<br />
|- <br />
| RIF Key 1 || 0x50 || 0x10<br />
|- <br />
| License start time || 0x60 || 0x8<br />
|-<br />
| License expiration time || 0x68 || 0x8<br />
|- <br />
| ECDSA Signature || 0x70 || 0x28<br />
|- <br />
| Some Flag|| 0x98 || 0x8<br />
|- <br />
| RIF Key 2 || 0xA0 || 0x10<br />
|- <br />
| Unknown || 0xB0 || 0x10<br />
|- <br />
| [[SceSblSsMgr#sceKernelGetOpenPsIdForDriver|OpenPsId]] if bit 8 is set in License Flags || 0xC0 || 0x10<br />
|- <br />
| Unknown || 0xD0 || 0x10<br />
|- <br />
| [[SceSblGcAuthMgr#memcmp_5018_fast|CMD56 handshake part]] if bit A is set in License Flags || 0xE0 || 0x14<br />
|- <br />
| Some Flag related to debug_upgradable || 0xF4 || 0x4<br />
|- <br />
| Unknown || 0xF8 || 0x4<br />
|- <br />
| SKU flag|| 0xFC || 0x4<br />
|- <br />
| RSA Signature || 0x100 || 0x100<br />
|-<br />
|}<br />
<br />
== PSM-ACT ==<br />
PSM Activation file<br />
<br />
{| class='wikitable'<br />
|-<br />
! Name !! Offset !! Size !! Example !! Remark<br />
|-<br />
| Magic Number || 0x0 || 0x8 || PSM-ACT || <br />
|-<br />
| Unknown1 || 0x8 || 0x8 || 00 00 00 00 00 00 00 00 || <br />
|-<br />
| Account ID || 0x10 || 0x8 || 91 78 34 02 01 EF CD AB || PSN account ID (Reversed from ACT.DAT) <br />
|-<br />
| Unknown2 || 0x18 || 0x4 || 00 00 00 00 || Must be 0 <br />
|-<br />
| Unknown3 || 0x1C || 0x4 || 00 00 00 00 || Must be 0 <br />
|-<br />
| Activation start time || 0x20 || 0x8 || 00 00 01 4C 16 4D 83 A8 || <br />
|-<br />
| Activation expiration time || 0x28 || 0x8 || 00 00 04 2A D4 3D 3E 68 || <br />
|-<br />
| SHA256 from act.dat || 0x30 || 0x20 || || SHA 256 digest of get_act_data (0x39222A58) <br />
|-<br />
| Unknown4 || 0x50 || 0xB0 || || Zeros <br />
|-<br />
| Unknown5 || 0x100 || 0x200 || || KEY saved at 0x22C8 - Decrypted with 0x2288 <br />
|-<br />
| SHA256 digest || 0x300 || 0x100 || ||<br />
<br />
|}<br />
<br />
<br />
== PSM-RIF ==<br />
PSM RIF file<br />
<br />
{| class='wikitable'<br />
|-<br />
! Name !! Offset !! Size !! Example !! Remark<br />
|-<br />
| Magic Number || 0x0 || 0x8 || PSM-RIF || <br />
|-<br />
| Unknown1 || 0x8 || 0x4 || 00 00 00 01 || Maybe Version and Version Flag? <br />
|-<br />
| Unknown2 || 0xC || 0x4 || 00 00 00 00 || Maybe License Type and License Flags? <br />
|-<br />
| Account ID || 0x10 || 0x8 || 91 78 34 02 01 EF CD AB || PSN account ID (Reversed from ACT.DAT) <br />
|-<br />
| Unknown3 || 0x18 || 0x4 || 00 00 00 00 || Must be 0 <br />
|-<br />
| Unknown4 || 0x1C || 0x4 || 00 00 00 00 || Must be 0 <br />
|-<br />
| Activation start time || 0x20 || 0x8 || 00 00 01 4C 16 4D 83 A8 || <br />
|-<br />
| Activation expiration time || 0x28 || 0x8 || 7F FF FF FF FF FF FF FF || Max Value<br />
|-<br />
| SHA256 from act.dat || 0x30 || 0x20 || || SHA 256 digest of get_act_data (0x39222A58) <br />
|-<br />
| Content ID || 0x50 || 0x30 || EM0041-NPOA00013_00-0000000000000000 || <br />
|-<br />
| Unknown5 || 0x80 || 0x80 || || Zeros <br />
|-<br />
| Unknown6 || 0x100 || 0x200 || || Key saved at 0x1F40. First 0x200 bytes are decrypted with 0x22C8 and then only the first 0x20 bytes are again decrypted with 0x2288<br />
|-<br />
| SHA256 digest || 0x300 || 0x100 || ||<br />
<br />
|}<br />
<br />
[[Category:Modules]]<br />
[[Category:Kernel]]</div>
Frangarcj
http://wiki.henkaku.xyz/vita/index.php?title=SceNpDrm&diff=4653
SceNpDrm
2017-09-15T06:57:28Z
<p>Frangarcj: /* Data segment layout */</p>
<hr />
<div>== Module ==<br />
<br />
=== Known NIDs ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! Name !! World !! Privilege !! NID<br />
|-<br />
| 1.69 || SceNpDrm || Non-secure || Kernel || 0xACCB4845<br />
|-<br />
| 3.60 || SceNpDrm || ? || Kernel || 0xE7E2CE05<br />
|}<br />
<br />
== Libraries ==<br />
<br />
=== Known NIDs ===<br />
<br />
{| class="wikitable"<br />
|-<br />
! Version !! Name !! World !! Visibility !! NID<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrm|SceNpDrm]] || Non-secure || User || 0xF2799B1B<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrm|SceNpDrm]] || ? || User || 0xF2799B1B<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrmForDriver|SceNpDrmForDriver]] || Non-secure || Kernel || 0xD84DC44A<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrmForDriver|SceNpDrmForDriver]] || ? || Kernel || 0xD84DC44A<br />
|-<br />
| 1.69 || [[SceNpDrm#SceNpDrmPackage|SceNpDrmPackage]] || Non-secure || User || 0x88514DB2<br />
|-<br />
| 3.60 || [[SceNpDrm#SceNpDrmPackage|SceNpDrmPackage]] || ? || User || 0x88514DB2<br />
|-<br />
| 3.60 || [[SceNpDrm#ScePsmDrm|ScePsmDrm]] || ? || User || 0x3F2B0888<br />
|-<br />
| 3.60 || [[SceNpDrm#ScePsmDrmForDriver|ScePsmDrmForDriver]] || ? || Kernel || 0x9F4924F2<br />
|}<br />
<br />
== Data segment layout ==<br />
<br />
{| class="wikitable"<br />
|-<br />
! Address !! Size !! Description<br />
|-<br />
| 0x0000 || 0x4 || SceNpDrm mutex SceUID<br />
|-<br />
| 0x0004 || 0x4 || ScePsmDrm mutex SceUID<br />
|-<br />
| 0x0008 || 0x8 || unknown<br />
|-<br />
| 0x0010 || 0xC0 || static keys decrypted with [[SceSblAuthMgr#sceSblAuthMgrGetEKc|sceSblAuthMgrGetEKc]] key 0. <br />
<br />
First 0x10 bytes are reencrypted with [[SceSblSsMgr#sceSblSsMgrGetConsoleId|CID]].<br />
<br />
First 0x10 bytes are aes_key used to decrypt 0x800 bytes of Primary Key Table from act.dat<br />
<br />
Second 0x10 bytes are aes_key used to decrypt Primary Key Table index from rif.<br />
|-<br />
| 0x00D0 || 0xCF8 || unknown<br />
|-<br />
| 0x0DC8 || 0x4 || Game Exist flag<br />
|-<br />
| 0x0DCC || 0x4 || Is DEX flag or Is Tool flag<br />
|-<br />
| 0x0DD0 || 0x30 || unknown<br />
|-<br />
| 0x0E00 || 0x1040 || tm0:/npdrm/act.dat data<br />
|-<br />
| 0x1E40 || 0x400 || tm0:/psmdrm/act.dat data<br />
|-<br />
| 0x2240 || 0x10 || [[SceSblSsMgr#sceKernelGetOpenPsIdForDriver|OpenPsId]]<br />
<br />
This key is compared against OpenPsId from act.dat<br />
<br />
This key is compared to data in rif file at offset 0xC0<br />
|-<br />
| 0x2250 || 0x4 || act data Is Valid flag<br />
|-<br />
| 0x2254 || 0x4 || unknown<br />
|-<br />
| 0x2258 || 0x8 || /CONFIG/NP/account_id reg key<br />
|-<br />
| 0x2260 || 0x4 || Loose Account Bind flag<br />
|-<br />
| 0x2264 || 0x4 || /CONFIG/NP/debug_upgradable reg key<br />
|-<br />
| 0x2268 || 0x20 || sha 256 digest of [[SceSblGcAuthMgr#get_act_data|get_act_data]]<br />
|-<br />
| 0x2288 || 0x20 || hmac sha 256 digest of [[SceSblGcAuthMgr#get_act_data|get_act_data]]<br />
|-<br />
| 0x22A8 || 0x8 || unknown<br />
|-<br />
| 0x22B0 || 0x8 || account_id<br />
|-<br />
| 0x22B8 || 0x8 || psm activation start date<br />
|-<br />
| 0x22C0 || 0x8 || psm activation end date<br />
|-<br />
| 0x22C8 || 0x20 || some key decrypted with 0x2288<br />
|-<br />
|}<br />
<br />
== Obtaining klicensee ==<br />
<br />
1. Get 0xC0 bytes from SceNpDrm code segment at offset 0x111D0. This is the list of static keys.<br />
<br />
2. Decrypt 0xC0 bytes of static keys using [[SceSblAuthMgr#sceSblAuthMgrGetEKc|sceSblAuthMgrGetEKc]] key 0.<br />
<br />
3. Get 0x10 bytes of CID with [[SceSblSsMgr#sceSblSsMgrGetConsoleIdForDriver| sceSblSsMgrGetConsoleIdForDriver]].<br />
<br />
4. Encrypt first 0x10 bytes of static keys with CID using AES (need to figure out which AES exactly).<br />
<br />
5. Read 0x800 bytes of Primary Key Table from act.dat<br />
<br />
6. Decrypt 0x800 bytes of Primary Key Table with reencrypted static key using AES (need to figure out which AES exactly).<br />
<br />
7. Get 0x97 / 0x200 bytes of rif data and select one of 5 scenarios for decrypting RIF Key based on license flags (need to figure out).<br />
<br />
=== Scenario 1 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take static keys 3, 4<br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 2 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take primary keys 1, 2<br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 3 ===<br />
<br />
Take RIF Key 2<br />
<br />
Take cmd56 handshake keys with [[SceSblGcAuthMgr#get_5018_data|get_5018_data]] <br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 2 and obtain klicensee.<br />
<br />
=== Scenario 4 ===<br />
<br />
Take RIF Key 1<br />
<br />
Take cmd56 handshake keys with [[SceSblGcAuthMgr#get_5018_data|get_5018_data]] <br />
<br />
Take first 0x70 bytes of rif data<br />
<br />
Erase RIF Key 1 from rif data<br />
<br />
Use [[SceSblAuthMgr#sceSblAuthMgrDecBindData|sceSblAuthMgrDecBindData]] to decrypt RIF key 1 and obtain klicensee.<br />
<br />
=== Scenario 5 ===<br />
<br />
Decrypt Primary Table Key index from rif data with static key 2 using AES (need to figure out which AES exactly).<br />
<br />
Take primary key using decrypted index.<br />
<br />
Decrypt RIF key 1 with obtained primary key using AES (need to figure out which AES exactly).<br />
<br />
== Get rif name ==<br />
<br />
<source lang="C"><br />
uint8_t rif_name_keys[0x10] = {<br />
0x19, 0xDD, 0x4F, 0xB9, 0x89, 0x48, 0x2B, 0xD4,<br />
0xCB, 0x9E, 0xC9, 0xC7, 0x9A, 0x2E, 0xFB, 0xD0<br />
};<br />
<br />
int aes_encrypt(const void *buf, int size, uint8_t *keys) {<br />
AES_ctx ctx;<br />
AES_set_key(&ctx, rif_name_keys, 0x80);<br />
<br />
int i;<br />
for (i = 0; i < size; i += 0x10) {<br />
AES_encrypt(&ctx, buf+i, buf+i);<br />
}<br />
}<br />
<br />
typedef struct {<br />
uint64_t mode; // 0: bounded, 1: fixed<br />
uint64_t aid;<br />
} SceNpDrmRifName;<br />
<br />
int getRifName(char *name, int length, uint64_t aid, uint64_t mode) {<br />
SceNpDrmRifName rif_name;<br />
rif_name.mode = mode;<br />
rif_name.aid = aid;<br />
aes_encrypt(&rif_name, sizeof(SceNpDrmRifName), rif_name_keys);<br />
<br />
snprintf(name, length, "%016llx%016llx.rif", __builtin_bswap64(((uint64_t *)&rif_name)[0]), __builtin_bswap64(((uint64_t *)&rif_name)[1])); <br />
}<br />
</source><br />
<br />
== SceNpDrm ==<br />
<br />
=== _sceNpDrmCheckDrmReset ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x4458812B<br />
|-<br />
| 3.60 || 0x4458812B<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x18<br />
int _sceNpDrmCheckDrmReset(int unk0, int unk1, void *opt);<br />
</source><br />
<br />
=== _sceNpDrmRemoveActData ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x507D06A6<br />
|-<br />
| 3.60 || 0x507D06A6<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmRemoveActData(int unk0, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmGetRifName ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xB8C5DA7C<br />
|-<br />
| 3.60 || 0xB8C5DA7C<br />
|}<br />
<br />
<source lang="C">int _sceNpDrmGetRifName(char *name, int ignored, int unk2, int unk3);</source><br />
<br />
=== _sceNpDrmGetRifNameForInstall ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xD312424D<br />
|-<br />
| 3.60 || 0xD312424D<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
//rif_data is of size 0x200<br />
int _sceNpDrmGetRifNameForInstall(char *name, void *rif_data, int num);<br />
</source><br />
<br />
=== _sceNpDrmGetRifInfo ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xE8343660<br />
|-<br />
| 3.60 || 0xE8343660<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct rif_info //size is 0x70<br />
{<br />
char content_id[0x30];<br />
char version_number[0x04];<br />
char rif_lic_flags[0x04];<br />
char lic_type0[0x04]; //lic type related<br />
char lic_type1[0x04]; //lic type related<br />
char account_id[0x08];<br />
char rif_data_98[0x08];<br />
char lic_start_time[0x08];<br />
char lic_exp_time[0x08];<br />
char dec_rif_key[0x10]; //decrypted rif key<br />
}rif_info;<br />
<br />
typedef struct _sceNpDrmGetRifInfo_opt //size is 0x28<br />
{<br />
char* content_id;<br />
char* account_id;<br />
char* version_number;<br />
char* rif_lic_flags;<br />
char* lic_type0; //lic type related<br />
char* lic_type1; //lic type related<br />
char* lic_start_time;<br />
char* lic_exp_time;<br />
char* rif_data_98;<br />
}_sceNpDrmGetRifInfo_opt;<br />
<br />
//rif data is of size 0x200<br />
<br />
int _sceNpDrmGetRifInfo(void* rif_data, int rif_size, int num, _sceNpDrmGetRifInfo_opt* opt);<br />
<br />
</source><br />
<br />
=== _sceNpDrmGetFixedRifName ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xE935B0FC<br />
|-<br />
| 3.60 || 0xE935B0FC<br />
|}<br />
<br />
<source lang="C">int _sceNpDrmGetFixedRifName(char *name, int ignored, int unk2, int unk3);</source><br />
<br />
=== _sceNpDrmCheckActData ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xFEEBCD62<br />
|-<br />
| 3.60 || 0xFEEBCD62<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmCheckActData(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPresetRifProvisionalFlag ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x2523F57F<br />
|}<br />
<br />
<source lang="C"><br />
//rif data is of size 0x200<br />
int _sceNpDrmPresetRifProvisionalFlag(void* rif_data);<br />
</source><br />
<br />
== SceNpDrmForDriver ==<br />
<br />
=== sceNpDrmGetRifInfoForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDB406EAE<br />
|}<br />
<br />
<source lang="C"> <br />
//rif data is of size 0x200<br />
int sceNpDrmGetRifInfoForDriver(void* rif_data, int rif_size, int num, char* content_id, char* account_id, char* version_number, char* rif_lic_flags, char* lic_type0, char* lic_type1, char* lic_start_time, char* lic_exp_time, char* rif_data_98); <br />
</source><br />
<br />
=== sceNpDrmPackageSetGameExistForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x3BFD2850<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageSetGameExistForDriver(int value);</source><br />
<br />
=== sceNpDrmGetFixedRifNameForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x5D73448C<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
int sceNpDrmGetFixedRifNameForDriver(char *name, int ignored, int unk2, int unk3);<br />
</source><br />
<br />
=== sceNpDrmGetRifNameForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDF62F3B8<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
int sceNpDrmGetRifNameForDriver(char *name, int ignored, int unk2, int unk3);<br />
</source><br />
<br />
=== sceNpDrmGetRifNameForInstallForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x17573133<br />
|}<br />
<br />
<source lang="C"><br />
//name is of size 0x30<br />
//rif data size is unknown but at least 0xF8<br />
int sceNpDrmGetRifNameForInstallForDriver(char *name, void *rif_data, int num);<br />
</source><br />
<br />
=== sceNpDrmPresetRifProvisionalFlagForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xC070FE89<br />
|}<br />
<br />
<source lang="C"><br />
//rif data size is unknown but at least 0xF8<br />
int sceNpDrmPresetRifProvisionalFlagForDriver(void* rif_data, int unk1);<br />
</source><br />
<br />
=== sceNpDrmCheckActDataForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x9265B350<br />
|}<br />
<br />
checks tm0:/npdrm/act.dat<br />
<br />
<source lang="C"><br />
//size of act data is 0x1040<br />
<br />
int sceNpDrmCheckActDataForDriver(int unk0, int unk1, int unk2, int unk3, int arg_0);<br />
</source><br />
<br />
=== sceNpDrmRemoveActDataForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x8B85A509<br />
|}<br />
<br />
checks tm0:/npdrm/act.dat<br />
<br />
<source lang="C">int sceNpDrmRemoveActDataForDriver(int unk);</source><br />
<br />
=== sceNpDrmUpdateAccountIdForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x116FC0D6<br />
|}<br />
<br />
<source lang="C">int sceNpDrmUpdateAccountIdForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmEbootSigGenMultiDiscForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x39A7A666<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenMultiDiscForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmEbootSigGenPs1ForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x6D9223E1<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenPs1ForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmGetLegacyDocKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4E321BDE<br />
|}<br />
<br />
<source lang="C"><br />
//rif data is of size 0x200<br />
//data1 is of size 0x90 - most likely decrypted with rif key from rif data using SceSblGcAuthMgr enc_dec 0x4c5de1aa<br />
int sceNpDrmGetLegacyDocKeyForDriver(void *rif_data, void *data1, int unk, void *dest);<br />
</source><br />
<br />
=== sceNpDrmEbootSigVerifyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x7A319692<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigVerifyForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmEbootSigGenPspForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x90B1A6D3<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigGenPspForDriver(int unk0, int unk1, int unk2, int unk3);</source><br />
<br />
=== sceNpDrmEbootSigConvertForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA29B75F9<br />
|}<br />
<br />
<source lang="C">int sceNpDrmEbootSigConvertForDriver(int unk0, int unk1, int unk2);</source><br />
<br />
=== sceNpDrmPspEbootVerifyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xB6CA3A2C<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPspEbootVerifyForDriver(int unk0, int unk1);</source><br />
<br />
=== sceNpDrmPspEbootSigGenForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xEF387FC4<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPspEbootSigGenForDriver(int unk0, int unk1, int unk2);</source><br />
<br />
=== sceNpDrmIsLooseAccountBindForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFC84CA1A<br />
|}<br />
<br />
<source lang="C">int sceNpDrmIsLooseAccountBindForDriver();</source><br />
<br />
=== sceNpDrmUpdateDebugSettingsForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA91C7443<br />
|}<br />
<br />
checks /CONFIG/NP debug_upgradable and /CONFIG/NP2 debug_drm_loose_bind registry values<br />
<br />
<source lang="C">int sceNpDrmUpdateDebugSettingsForDriver();</source><br />
<br />
=== sceNpDrmGetRifPspKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xDACB71F4<br />
|}<br />
<br />
<source lang="C"><br />
//rif_data is of size 0x200<br />
//dec_rif_key is of size 0x10<br />
int sceNpDrmGetRifPspKeyForDriver(void *rif_data, void *dec_rif_key, int unk2, int unk3, int arg_0);</source><br />
<br />
=== sceNpDrmGetRifVitaKeyForDriver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x723322B5<br />
|}<br />
<br />
use [[SceNpDrm#sceNpDrmGetRifInfoForDriver|sceNpDrmGetRifInfoForDriver]] to get required fields<br />
<br />
<source lang="C"><br />
int sceNpDrmGetRifVitaKeyForDriver(void *rif_data, void *dec_rif_key, char* lic_type0, char* lic_type1, char* lic_start_time, char* lic_exp_time, char* rif_lic_flags);<br />
</source><br />
<br />
=== set_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x742EBAF4<br />
|}<br />
<br />
Related to sceSblGcAuthMgrPcactActivation<br />
<br />
decrypts act_data with aes_dec_key and stores it to data segment<br />
<br />
verifies sha1 - ecdsa or sha256 - rca<br />
<br />
checks Loose Account Bind flag<br />
<br />
verifies OpenPsId<br />
<br />
creates tm0:/npdrm folder<br />
<br />
writes tm0:/npdrm/act.dat file<br />
<br />
repeats all verification steps<br />
<br />
decrypts Primary Key Table<br />
<br />
<source lang="C"><br />
//data is of size 0x1040 - this is most likely act.dat data because of size<br />
int set_act_data(void *act_data, const char *aes_dec_key);<br />
</source><br />
<br />
=== get_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xD91C3BCE<br />
|}<br />
<br />
Related to sceSblGcAuthMgrPcactGetChallenge<br />
<br />
reads 0x1038 bytes of tm0:/npdrm/act.dat data<br />
<br />
<source lang="C"><br />
//act_data is of size 0x1038<br />
int get_act_data(void* act_data);<br />
</source><br />
<br />
=== verify_rif ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFE7B17B6<br />
|}<br />
<br />
verify ECDSA - SHA1 pair or RSA - SHA256 pair<br />
<br />
<source lang="C"><br />
//rif_data max size is 0x200<br />
int verify_rif(void* rif_data, int rif_size);<br />
</source><br />
<br />
=== verify_rif_full ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xFF63672D<br />
|}<br />
<br />
check OpenPsId<br />
<br />
check cmd56 handshake part<br />
<br />
perform steps to get decrypted rif key<br />
<br />
<source lang="C"><br />
//rif data size is unknown but at least 0xF8<br />
int verify_rif_full(void* rif_data);<br />
</source><br />
<br />
=== reset_act_dat ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x77926F5<br />
|}<br />
<br />
reads tm0:/npdrm/act.dat<br />
<br />
verifies sha1 - ecdsa or sha256 - rca<br />
<br />
checks Loose Account Bind flag<br />
<br />
verifies OpenPsId<br />
<br />
clears Secondary Table, RSA Signature, Unknown Sig, ECDSA Signature<br />
<br />
decrypts Primary Key Table<br />
<br />
<source lang="C"><br />
int reset_act_dat();<br />
</source><br />
<br />
== SceNpDrmPackage ==<br />
<br />
=== _sceNpDrmPackageTransform ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x567DCA1<br />
|-<br />
| 3.60 || 0x567DCA1<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x28<br />
int _sceNpDrmPackageTransform(int unk0, int unk1, void* opt, int unk3);<br />
</source><br />
<br />
=== _sceNpDrmPackageInstallFinished ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0x6896EAF2<br />
|-<br />
| 3.60 || 0x6896EAF2<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmPackageInstallFinished(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageCheck ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xA1D885FA<br />
|-<br />
| 3.60 || 0xA1D885FA<br />
|}<br />
<br />
<source lang="C"><br />
int _sceNpDrmPackageCheck(const void *buffer1, SceSize size, void *buffer2, unsigned int identifier);<br />
</source><br />
<br />
=== sceNpDrmPackageIsGameExist ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xB9337914<br />
|-<br />
| 3.60 || 0xB9337914<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageIsGameExist();</source><br />
<br />
=== _sceNpDrmPackageInstallStarted ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xCEC18DA4<br />
|-<br />
| 3.60 || 0xCEC18DA4<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmPackageInstallStarted(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageDecrypt ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xD6F05ACC<br />
|-<br />
| 3.60 || 0xD6F05ACC<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct _sceNpDrmPackageDecrypt //size is 0x10<br />
{<br />
SceOff offset; //The offset in the encrypted data<br />
unsigned int identifier;<br />
uint32_t unk_C;<br />
} _sceNpDrmPackageDecrypt_opt;<br />
<br />
int _sceNpDrmPackageDecrypt(void * buffer, SceSize size, _sceNpDrmPackageDecrypt_opt * opt);<br />
</source><br />
<br />
=== sceNpDrmPackageInstallOngoing ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 1.69 || 0xED0471FE<br />
|-<br />
| 3.60 || 0xED0471FE<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageInstallOngoing(int unk0, int unk1);</source><br />
<br />
=== _sceNpDrmPackageUninstallFinished ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x23A28861<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int _sceNpDrmPackageUninstallFinished(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== _sceNpDrmPackageUninstallStarted ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4901C3E6<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int _sceNpDrmPackageUninstallStarted(int unk0, int unk1, int unk2, void* opt);<br />
</source><br />
<br />
=== sceNpDrmPackageUninstallOngoing ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xF1FF6193<br />
|}<br />
<br />
<source lang="C">int sceNpDrmPackageUninstallOngoing(int unk0, int unk1);</source><br />
<br />
=== unk_200D2DE4 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x200D2DE4<br />
|}<br />
<br />
<source lang="C">int unk_200D2DE4(int unk0, int unk1);</source><br />
<br />
=== unk_4665E75A ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4665E75A<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_4665E75A(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
=== unk_640C1724 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x640C1724<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int unk_640C1724(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
=== unk_97BB85BD ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x97BB85BD<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_97BB85BD(int unk0, int unk1, int unk2, void *opt)<br />
</source><br />
<br />
=== unk_A5E0F38C ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA5E0F38C<br />
|}<br />
<br />
<source lang="C">int unk_A5E0F38C(int unk0, int unk1);</source><br />
<br />
=== unk_C75A775B ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xC75A775B<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x8<br />
int unk_C75A775B(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
== ScePsmDrm ==<br />
<br />
=== get_rif_name ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x0D6470DA<br />
|}<br />
<br />
<source lang="C"><br />
//some data is of size 0x400 and contains rif data<br />
int get_rif_name(char *rif_name, void *some_data);<br />
</source><br />
<br />
=== _get_info ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xE31A6220<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct get_info_opt //size is 0x10<br />
{<br />
void* out2;<br />
void* out3;<br />
uint32_t unk_8;<br />
uint32_t unk_C;<br />
}get_info_opt<br />
<br />
int _get_info(void *some_data, void *out0, void *out1, get_info_opt *opt);<br />
</source><br />
<br />
=== _get_info_2 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x207A2C53<br />
|}<br />
<br />
<source lang="C"><br />
typedef struct get_info2_opt //size is 0x10<br />
{<br />
void* out2;<br />
void* out3;<br />
uint32_t unk_8;<br />
uint32_t unk_C;<br />
}get_info2_opt<br />
<br />
int _get_info(void *some_data, void *out0, void *out1, get_info2_opt *opt);<br />
</source><br />
<br />
=== unk_E193CBB ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xE193CBB<br />
|}<br />
<br />
<source lang="C">int unk_E193CBB(int unk0);</source><br />
<br />
=== unk_3E881391 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x3E881391<br />
|}<br />
<br />
<source lang="C">int unk_3E881391(int unk0);</source><br />
<br />
=== unk_A89653B3 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xA89653B3<br />
|}<br />
<br />
<source lang="C"><br />
//opt is of size 0x10<br />
int unk_A89653B3(int unk0, int unk1, int unk2, void *opt);<br />
</source><br />
<br />
== ScePsmDrmForDriver ==<br />
<br />
=== get_info_for_driver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x984F9017<br />
|}<br />
<br />
this function is named after sceNpDrmGetRifInfoForDriver since arguments are very similar<br />
<br />
<source lang="C"><br />
//some_data is of size 0x400 and should contain rca signature at offset 0x300<br />
//out0 is of size 0x30<br />
//out1 is of size 0x8<br />
//out2 is of size 0x8<br />
//out3 is of size 0x8<br />
int get_info_for_driver(void *some_data, void *out0, void *out1, void *out2, void *out3);<br />
</source><br />
<br />
=== get_info_2_for_driver ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x8C8CFD01<br />
|}<br />
<br />
this function is named after sceNpDrmGetRifInfoForDriver since arguments are very similar<br />
<br />
<source lang="C"><br />
//data is of size 0x400<br />
//out0 is of size 0x200<br />
//out1 is of size 0x4<br />
//out2 is of size 0x8<br />
//out3 is of size 0x8<br />
int get_info_2_for_driver(void *data, void *out0, void *out1, void *out2, int out3);<br />
</source><br />
<br />
=== set_psm_act_data ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xCB73E9D3<br />
|}<br />
<br />
decrypts psm_act_data with aes_dec_key<br />
<br />
creates tm0:/psmdrm if nesessary<br />
<br />
writes tm0:/psmdrm/act.dat<br />
<br />
verifies sha256 - rca<br />
<br />
<source lang="C"><br />
//data is of size 0x400<br />
int set_psm_act_data(void *psm_act_data, const char *aes_dec_key);<br />
</source><br />
<br />
=== unk_4CD5375C ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x4CD5375C<br />
|}<br />
<br />
<source lang="C">int unk_4CD5375C(int unk0);</source><br />
<br />
=== unk_791198CE ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0x791198CE<br />
|}<br />
<br />
<source lang="C">int unk_791198CE();</source><br />
<br />
=== unk_B09003A7 ===<br />
{| class="wikitable"<br />
|-<br />
! Version !! NID<br />
|-<br />
| 3.60 || 0xB09003A7<br />
|}<br />
<br />
<source lang="C">int unk_B09003A7(int unk0, int unk1, int unk2, int unk3, int arg_0);</source><br />
<br />
== Package integrity checks ==<br />
=== Disable hash/signature verification ===<br />
To find the function responsible for package verification search for immediate 0x7F504B47 ('.PKG'). Inside it does a lot of stuff including determining the function that will do signature checks. Find the condition that looks like <code>if ( (v62 & 7) == 3 )</code>; below you will see the assignment <code>check_func = &off_81009CFC;</code>. To bypass signature checks you need to patch two functions located at this offset and offset+4, making them behave as "return 1" is enough. For reference, on 1.60 the functions are sub_81000310 and sub_81000AA4. sub_81000310 is the only function in this module that calls SceSblGcAuthMgrPkgForDriver_E459A9A8_imp.<br />
<br />
Note that on 1.60 this module sometimes is loaded at different addresses between reboots.<br />
<br />
=== Allow debug packages to be installed ===<br />
Find the function that calls SceSblAIMgrForDriver_D78B04A2; patch it to always return 1. On 1.60 it's at 0x81002d64.<br />
<br />
Search for immediate 0x80870003, there should be two matches. Replace both with "MOV Reg, #0". On 1.60 the locations are 0x810035fe and 0x81004856.<br />
<br />
== RIF ==<br />
The RIF files are used as the eboot.bin DRM. For each installed PKG and Game Card you will have an unique RIF file with proper information that will be used when you open the game to verify if you own the game(to PKG) and decrypt the eboot.bin. The RIF files may hold important information as PSN Account ID, the key used to decrypt one of the SELF encrypt layers [...]. <br />
<br />
PS Vita supports two different RIF file format. The first format (License Type 0) seems to be used by licenses with 0x98 bytes size and the second (License Type 1) seems to be used by RIF files with 0x200 bytes size. The difference between them is just the signature verification. License Type 0 only uses ECDSA Signature, the License Type 1 uses the ECDSA Signature verification and an extra RSA signature verification.<br />
<br />
{| class='wikitable'<br />
|-<br />
! Name !! Offset !! Size<br />
|-<br />
| Version || 0x0 || 0x2<br />
|-<br />
| Version Flag (0 or 1) || 0x2 || 0x2<br />
|-<br />
| License Type || 0x4 || 0x2<br />
|-<br />
| License Flags || 0x6 || 0x2<br />
|-<br />
| PSN Account ID || 0x8 || 0x8<br />
|- <br />
| Content ID || 0x10 || 0x30<br />
|- <br />
| Primary Key Table index || 0x40 || 0x10<br />
|- <br />
| RIF Key 1 || 0x50 || 0x10<br />
|- <br />
| License start time || 0x60 || 0x8<br />
|-<br />
| License expiration time || 0x68 || 0x8<br />
|- <br />
| ECDSA Signature || 0x70 || 0x28<br />
|- <br />
| Some Flag|| 0x98 || 0x8<br />
|- <br />
| RIF Key 2 || 0xA0 || 0x10<br />
|- <br />
| Unknown || 0xB0 || 0x10<br />
|- <br />
| [[SceSblSsMgr#sceKernelGetOpenPsIdForDriver|OpenPsId]] if bit 8 is set in License Flags || 0xC0 || 0x10<br />
|- <br />
| Unknown || 0xD0 || 0x10<br />
|- <br />
| [[SceSblGcAuthMgr#memcmp_5018_fast|CMD56 handshake part]] if bit A is set in License Flags || 0xE0 || 0x14<br />
|- <br />
| Some Flag related to debug_upgradable || 0xF4 || 0x4<br />
|- <br />
| Unknown || 0xF8 || 0x4<br />
|- <br />
| SKU flag|| 0xFC || 0x4<br />
|- <br />
| RSA Signature || 0x100 || 0x100<br />
|-<br />
|}<br />
<br />
<br />
[[Category:Modules]]<br />
[[Category:Kernel]]</div>
Frangarcj