SceNpDrm: Difference between revisions

From Vita Development Wiki
Jump to navigation Jump to search
Line 492: Line 492:
| 3.60 || 0x77926F5
| 3.60 || 0x77926F5
|}
|}
reads tm0:/npdrm/act.dat
verifies sha1 - ecdsa or sha256 - rca
checks Loose Account Bind flag
verifies OpenPsId
clears Secondary Table, RSA Signature, Unknown Sig, ECDSA Signature
decrypts Primary Key Table
<source lang="C">
int set_act_dat();
</source>


== SceNpDrmPackage ==
== SceNpDrmPackage ==

Revision as of 21:38, 15 June 2017

Module

Known NIDs

Version Name World Privilege NID
1.69 SceNpDrm Non-secure Kernel 0xACCB4845
3.60 SceNpDrm ? Kernel 0xE7E2CE05

Libraries

Known NIDs

Version Name World Visibility NID
1.69 SceNpDrm Non-secure User 0xF2799B1B
3.60 SceNpDrm ? User 0xF2799B1B
1.69 SceNpDrmForDriver Non-secure Kernel 0xD84DC44A
3.60 SceNpDrmForDriver ? Kernel 0xD84DC44A
1.69 SceNpDrmPackage Non-secure User 0x88514DB2
3.60 SceNpDrmPackage ? User 0x88514DB2
3.60 ScePsmDrm ? User 0x3F2B0888
3.60 ScePsmDrmForDriver ? Kernel 0x9F4924F2

Data segment layout

Address Size Description
0x0000 0x4 SceNpDrm mutex SceUID
0x0004 0x4 ScePsmDrm mutex SceUID
0x0008 0x8 unknown
0x0010 0xC0 constant data decrypted with sceSblAuthMgrGetEKc key 0.

First 0x10 bytes are reencrypted with aes key from get_aes_key.

First 0x10 bytes are aes_key used to decrypt 0x800 bytes of Primary Key Table from act.dat

Second 0x10 bytes are aes_key used to decrypt Primary Key Table index from rif.

0x00D0 0xCF8 unknown
0x0DC8 0x4 Game Exist flag
0x0DCC 0x34 unknown
0x0E00 0x1040 tm0:/npdrm/act.dat data
0x1E40 0x400 tm0:/psmdrm/act.dat data
0x2240 0x10 some key that should be equal to 0x10 of rif from offset 0xC0

This key is compared against OpenPsId from act.dat

0x2250 0x10 unknown
0x2260 0x4 Loose Account Bind flag
0x2264 0x84 unknown

SceNpDrm

_sceNpDrmCheckDrmReset

Version NID
1.69 0x4458812B
3.60 0x4458812B

_sceNpDrmRemoveActData

Version NID
1.69 0x507D06A6
3.60 0x507D06A6

_sceNpDrmGetRifName

Version NID
1.69 0xB8C5DA7C
3.60 0xB8C5DA7C

_sceNpDrmGetRifNameForInstall

Version NID
1.69 0xD312424D
3.60 0xD312424D

_sceNpDrmGetRifInfo

Version NID
1.69 0xE8343660
3.60 0xE8343660
typedef struct _sceNpDrmGetRifInfo_opt //size is 0x28
{
  char* unk_0; // buffer of size 0x30
  char* unk_4; // buffer of size 0x8
  char* unk_8; // buffer of size 0x4
  char* unk_C; // buffer of size 0x4 
  char* unk_10; // buffer of size 0x4
  char* unk_14; // buffer of size 0x4
  char* unk_18; // buffer of size 0x8
  char* unk_1C; // buffer of size 0x8
  char* unk_20; // buffer of size 0x8
}_sceNpDrmGetRifInfo_opt;

//rif data is of size 0x200

int _sceNpDrmGetRifInfo(void* rif_data, int rif_size, int num, _sceNpDrmGetRifInfo_opt* opt);

_sceNpDrmGetFixedRifName

Version NID
1.69 0xE935B0FC
3.60 0xE935B0FC

_sceNpDrmCheckActData

Version NID
1.69 0xFEEBCD62
3.60 0xFEEBCD62

_sceNpDrmPresetRifProvisionalFlag

Version NID
3.60 0x2523F57F

SceNpDrmForDriver

sceNpDrmGetRifInfoForDriver

Version NID
3.60 0xDB406EAE
 
//rif data is of size 0x200
//out0 buffer is of size 0x30
//out1 buffer is of size 0x8
//out2 buffer is of size 0x4
//out3 buffer is of size 0x4 
//out4 buffer is of size 0x4
//out5 buffer is of size 0x4
//out6 buffer is of size 0x8
//out7 buffer is of size 0x8
//out8 buffer is of size 0x8

int sceNpDrmGetRifInfoForDriver(void* rif_data, int rif_size, int num, void* out0, void* out1, void* out2, void* out3, void* out4, void* out5, void* out6, void* out7, void* out8);

sceNpDrmPackageSetGameExistForDriver

Version NID
3.60 0x3BFD2850
int sceNpDrmPackageSetGameExistForDriver(int value);

sceNpDrmGetFixedRifNameForDriver

Version NID
3.60 0x5D73448C
//name is of size 0x30
int sceNpDrmGetFixedRifNameForDriver(char* name);

sceNpDrmGetRifNameForDriver

Version NID
3.60 0xDF62F3B8
//name is of size 0x30
int sceNpDrmGetRifNameForDriver(char *name, int unk1, int unk2, int unk3);

sceNpDrmGetRifNameForInstallForDriver

Version NID
3.60 0x17573133
//name is of size 0x30
//rif data size is unknown but at least 0xF8
int sceNpDrmGetRifNameForInstallForDriver(char *name, void *rif_data, int num);

sceNpDrmPresetRifProvisionalFlagForDriver

Version NID
3.60 0xC070FE89
//rif data size is unknown but at least 0xF8
int sceNpDrmPresetRifProvisionalFlagForDriver(void* rif_data, int unk1);

sceNpDrmCheckActDataForDriver

Version NID
3.60 0x9265B350

checks tm0:/npdrm/act.dat

//size of act data is 0x1040

int sceNpDrmCheckActDataForDriver(int unk0, int unk1, int unk2, int unk3, int arg_0);

sceNpDrmRemoveActDataForDriver

Version NID
3.60 0x8B85A509

checks tm0:/npdrm/act.dat

int sceNpDrmRemoveActDataForDriver(int unk);

sceNpDrmUpdateAccountIdForDriver

Version NID
3.60 0x116FC0D6
int sceNpDrmUpdateAccountIdForDriver(int unk0, int unk1);

sceNpDrmEbootSigGenMultiDiscForDriver

Version NID
3.60 0x39A7A666
int sceNpDrmEbootSigGenMultiDiscForDriver(int unk0, int unk1, int unk2, int unk3);

sceNpDrmEbootSigGenPs1ForDriver

Version NID
3.60 0x6D9223E1
int sceNpDrmEbootSigGenPs1ForDriver(int unk0, int unk1, int unk2, int unk3);

sceNpDrmGetLegacyDocKeyForDriver

Version NID
3.60 0x4E321BDE
//rif data is of size 0x200
//data1 is of size 0x90 - most likely decrypted with rif key from rif data using SceSblGcAuthMgr enc_dec 0x4c5de1aa
int sceNpDrmGetLegacyDocKeyForDriver(void *rif_data, void *data1, int unk, void *dest);

sceNpDrmEbootSigVerifyForDriver

Version NID
3.60 0x7A319692
int sceNpDrmEbootSigVerifyForDriver(int unk0, int unk1);

sceNpDrmEbootSigGenPspForDriver

Version NID
3.60 0x90B1A6D3
int sceNpDrmEbootSigGenPspForDriver(int unk0, int unk1, int unk2, int unk3);

sceNpDrmEbootSigConvertForDriver

Version NID
3.60 0xA29B75F9
int sceNpDrmEbootSigConvertForDriver(int unk0, int unk1, int unk2);

sceNpDrmPspEbootVerifyForDriver

Version NID
3.60 0xB6CA3A2C
int sceNpDrmPspEbootVerifyForDriver(int unk0, int unk1);

sceNpDrmPspEbootSigGenForDriver

Version NID
3.60 0xEF387FC4
int sceNpDrmPspEbootSigGenForDriver(int unk0, int unk1, int unk2);

sceNpDrmIsLooseAccountBindForDriver

Version NID
3.60 0xFC84CA1A
int sceNpDrmIsLooseAccountBindForDriver();

sceNpDrmUpdateDebugSettingsForDriver

Version NID
3.60 0xA91C7443

checks /CONFIG/NP debug_upgradable and /CONFIG/NP2 debug_drm_loose_bind registry values

int sceNpDrmUpdateDebugSettingsForDriver();

sceNpDrmGetRifPspKeyForDriver

Version NID
3.60 0xDACB71F4

I guess this one was originally derived from the code of SceCompat

sceNpDrmGetRifVitaKeyForDriver

Version NID
3.60 0x723322B5

I guess this one was originally derived from the code of SceAppMgr

unk_742EBAF4

Version NID
3.60 0x742EBAF4

Related to sceSblGcAuthMgrPcactActivation

//data is of size 0x1040 - this is most likely act.dat data because of size
int unk_742EBAF4(void *act_data, const char *aes_dec_key);

get_act_data

Version NID
3.60 0xD91C3BCE

Related to sceSblGcAuthMgrPcactGetChallenge

reads 0x1038 bytes of tm0:/npdrm/act.dat data

//act_data is of size 0x1038
int get_act_data(void* act_data);

verify_rif

Version NID
3.60 0xFE7B17B6

verify ECDSA - SHA1 pair or RSA - SHA256 pair

//rif_data max size is 0x200
int verify_rif(void* rif_data, int rif_size);

unk_FF63672D

Version NID
3.60 0xFF63672D
//rif data size is unknown but at least 0xF8
int unk_FF63672D(void* rif_data);

set_act_dat

Version NID
3.60 0x77926F5

reads tm0:/npdrm/act.dat

verifies sha1 - ecdsa or sha256 - rca

checks Loose Account Bind flag

verifies OpenPsId

clears Secondary Table, RSA Signature, Unknown Sig, ECDSA Signature

decrypts Primary Key Table

int set_act_dat();

SceNpDrmPackage

_sceNpDrmPackageTransform

Version NID
1.69 0x567DCA1
3.60 0x567DCA1
//opt is of size 0x28
int _sceNpDrmPackageTransform(int unk0, int unk1, void* opt, int unk3);

_sceNpDrmPackageInstallFinished

Version NID
1.69 0x6896EAF2
3.60 0x6896EAF2
//opt is of size 0x8
int _sceNpDrmPackageInstallFinished(int unk0, int unk1, int unk2, void* opt);

_sceNpDrmPackageCheck

Version NID
1.69 0xA1D885FA
3.60 0xA1D885FA
int _sceNpDrmPackageCheck(const void *buffer, SceSize size, int zero, unsigned int identifier);

sceNpDrmPackageIsGameExist

Version NID
1.69 0xB9337914
3.60 0xB9337914
int sceNpDrmPackageIsGameExist();

_sceNpDrmPackageInstallStarted

Version NID
1.69 0xCEC18DA4
3.60 0xCEC18DA4
//opt is of size 0x10
int _sceNpDrmPackageInstallStarted(int unk0, int unk1, int unk2, void* opt);

_sceNpDrmPackageDecrypt

Version NID
1.69 0xD6F05ACC
3.60 0xD6F05ACC
typedef struct _sceNpDrmPackageDecrypt {
	/** The offset in the encrypted data */
	SceOff offset;

	/**
	 * The identifier specified for _sceNpDrmPackageCheck but NOT ORed
	 * with (1 << 8)
	 */
	unsigned int identifier;
} _sceNpDrmPackageDecrypt_opt;

int _sceNpDrmPackageDecrypt(void * buffer, SceSize size, _sceNpDrmPackageDecrypt_opt * opt);

sceNpDrmPackageInstallOngoing

Version NID
1.69 0xED0471FE
3.60 0xED0471FE
int sceNpDrmPackageInstallOngoing(int unk0, int unk1);

_sceNpDrmPackageUninstallFinished

Version NID
3.60 0x23A28861
//opt is of size 0x8
int _sceNpDrmPackageUninstallFinished(int unk0, int unk1, int unk2, void* opt);

_sceNpDrmPackageUninstallStarted

Version NID
3.60 0x4901C3E6
//opt is of size 0x10
int _sceNpDrmPackageUninstallStarted(int unk0, int unk1, int unk2, void* opt);

sceNpDrmPackageUninstallOngoing

Version NID
3.60 0xF1FF6193
int sceNpDrmPackageUninstallOngoing(int unk0, int unk1);

ScePsmDrm

get_rif_name

Version NID
3.60 0x0D6470DA
//some data is of size 0x400
int get_rif_name(char *rif_name, void *some_data);

_get_info

Version NID
3.60 0xE31A6220
typedef struct get_info_opt //size is 0x10
{
 void* out2;
 void* out3;
 uint32_t unk_8;
 uint32_t unk_C;
}get_info_opt

int _get_info(void *some_data, void *out0, void *out1, get_info_opt *opt);

_get_info_2

Version NID
3.60 0x207A2C53
typedef struct get_info2_opt //size is 0x10
{
 void* out2;
 void* out3;
 uint32_t unk_8;
 uint32_t unk_C;
}get_info2_opt

int _get_info(void *some_data, void *out0, void *out1, get_info2_opt *opt);

ScePsmDrmForDriver

get_info_for_driver

Version NID
3.60 0x984F9017

this function is named after sceNpDrmGetRifInfoForDriver since arguments are very similar

//some_data is of size 0x400 and should contain rca signature at offset 0x300
//out0 is of size 0x30
//out1 is of size 0x8
//out2 is of size 0x8
//out3 is of size 0x8
int get_info_for_driver(void *some_data, void *out0, void *out1, void *out2, void *out3);

unk_CB73E9D3

Version NID
3.60 0xCB73E9D3
//data is of size 0x400
int unk_CB73E9D3(void *data, const char *aes_dec_key);

get_info_2_for_driver

Version NID
3.60 0x8C8CFD01

this function is named after sceNpDrmGetRifInfoForDriver since arguments are very similar

//data is of size 0x400
//out0 is of size 0x200
//out1 is of size 0x4
//out2 is of size 0x8
//out3 is of size 0x8
int get_info_2_for_driver(void *data, void *out0, void *out1, void *out2, int out3);

Package integrity checks

Disable hash/signature verification

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 if ( (v62 & 7) == 3 ); below you will see the assignment check_func = &off_81009CFC;. 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.

Note that on 1.60 this module sometimes is loaded at different addresses between reboots.

Allow debug packages to be installed

Find the function that calls SceSblAIMgrForDriver_D78B04A2; patch it to always return 1. On 1.60 it's at 0x81002d64.

Search for immediate 0x80870003, there should be two matches. Replace both with "MOV Reg, #0". On 1.60 the locations are 0x810035fe and 0x81004856.

RIF

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 [...].

PS Vita supports two different RIF file format. The first format (License Type 0) seems to be used by licenses with 0x97 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.

Name Offset Size
Version 0x0 0x4
License Type 0x4 0x4
PSN Account ID 0x8 0x8
Content ID 0x10 0x30
Primary Key Table index 0x40 0x10
RIF Key 0x50 0x10
License start time 0x60 0x8
License expiration time 0x68 0x8
ECDSA Signature 0x70 0x28
Unknown 0x98 0x28
Unknown 0xC0 0x10
Unknown 0xD0 0x10
CMD56 handshake part 0xE0 0x14
Unknown 0xF4 0x0C
RSA Signature 0x100 0x100