Editing Talk:SELF - SPRX
Jump to navigation
Jump to search
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
[[Category:Software]] | |||
To be merged with [[SELF File Format and Decryption]] | |||
=== NPDRM Header === | |||
typedef struct | |||
{ | |||
u32 block_type; // this is 3(NPDRM) | |||
u32 block_size; // this is 0x90(sizeof(Self_NPDRM)) | |||
u32 unknown1; //So far always 0 | |||
u32 unknown2; //So far always 0 | |||
u32 magic; // 0x4E504400(NPD) | |||
u32 unknown3; // So far always 1 | |||
u32 license; // 1 Network License, 2 Local License, 3 Free | |||
u32 type; // 1 Executable, 21 Update for Disc Based Game | |||
u8 titleid[0x30]; | |||
u8 hash_unknown[0x10]; | |||
u8 hash1[0x10]; | |||
u8 hash2[0x10]; | |||
u8 padding[0x10]; | |||
} Self_NPDRM | |||
Located after the Self Control Info. | |||
---- | |||
=== App Info header: === | |||
Aligned to 0x10 bytes. | |||
{| class="wikitable" | |||
|- | |||
! field | |||
! offset | |||
! type | |||
! notes | |||
|- | |||
| authid | |||
| 0x00 | |||
| u64 | |||
|- | |||
|unknown | |||
|0x08 | |||
|u32 | |||
|- | |||
|app_type | |||
|0x0c | |||
|u32 | |||
| | |||
*1 -- level 0 | |||
*2 -- level 1 | |||
*3 -- level 2 | |||
*4 -- application | |||
*5 -- isolated SPU module | |||
*6 -- secure loader | |||
*8 -- NP-DRM application | |||
|- | |||
|app_version | |||
|0x10 | |||
|u64 | |||
|} | |||
=== Encrypted phdr offset entry === | |||
There is one of these entries for each phdr entry in the elf file so that the ps3 knows where to decrypt the data from. (because it might also be compressed.) | |||
{| class="wikitable" | |||
|- | |||
! field !! offset !! type !! notes | |||
|- | |||
| Encrypted Data Offset || 0x00 ||u64 || | |||
|- | |||
|Encrypted Data Size || 0x08 || u64 || | |||
|- | |||
|unknown || 0x10 || u32 || This has been 1 in all the examples I have seen. | |||
|- | |||
|unknown || 0x14 || u32 || Always 0, as far as I know. | |||
|- | |||
|unknown || 0x18 || u32 || Always 0, as far as I know. | |||
|- | |||
|unknown || 0x1c || u32 || This is 2 for loadable segment types, and 0 for other types. | |||
|- | |||
|} | |||
{| class="wikitable" | |||
|- | |||
! field !! offset !! type !! notes | |||
|- | |||
| Magic || 0x0 || u32 || Must be "SCE\0" | |||
|- | |||
| version || 0x4 || u32 || This must be 2 or the Self loader will abort | |||
|- | |||
| flags || 0x8 || u16|| | |||
*0: retail type 0 | |||
*1: retail | |||
*2: retail type 1 | |||
*0x8000: devkit | |||
*4: unknown, games that require 3.42. | |||
*7: unknown, all games that require 3.50 have that flag. | |||
0001: FW 1.00 (app version 1.0.0) | |||
... | |||
0001: FW 3.15 (app version 3.15.0) | |||
0001: FW 3.20 (app version 3.20.0) | |||
0001: FW 3.21 (app version 3.21.0) | |||
0001: FW 3.30 (app version 3.30.0) | |||
0004: FW 3.40 (app version 3.40.0) | |||
0004: FW 3.41 (app version 3.40.0) | |||
0004: FW 3.42 (app version 3.40.0) | |||
0007: FW 3.50 (app version 3.55.0) | |||
000a: FW 3.55 (app version 3.55.0) | |||
000d: FW 3.56 (app version 3.56.0) | |||
0010: FW 3.60 (app version 3.60.0) | |||
0010: FW 3.61 (app version 3.61.0) | |||
0013: FW 3.65 (app version 3.65.0) | |||
0013: FW 3.66 (app version 3.66.0) | |||
0016: FW 3.70 (app version 3.70.0) | |||
0016: FW 3.72 (app version 3.70.0) | |||
|- | |||
|- | |||
|} | |||
---- | |||
==NPDRM Self algorithm== | |||
THIS DOES NOT ALLOW TO OBTAIN 3.60+ keys, nor piracy as you require the rif, act.dat and IDPS | |||
On NPDRM self decryption all the security levels of the PS3 are involved: user space (vsh), kernel space(lv2), hypervisor( lv1) and isolated SPU (metldr + appldr) | |||
The process start on vsh.elf... | |||
===VSH=== | |||
Once the vsh detects that user is trying to start a self, it looks for the appinfo header type. If the type is 8, then the control digest element type 3 (NPD element) is located. From this NPD header the vsh gets the license type (free, local or network license). | |||
If a free content(type 3) is detected then a generic klicense will be use for further steps (go to LV2). That klicensee is already public (see geohot npdrm_omac_key_1). | |||
npdrm_omac_key1 : 72F990788F9CFF745725F08E4C128387 # ps3publictools/include/oddkeys.h | |||
npdrm_omac_key2 : 6BA52976EFDA16EF3C339FB2971E256B # ... | |||
npdrm_omac_key3 : 9B515FEACF75064981AA604D91A54E97 # ... | |||
However if a paid content is to be loaded the vsh loads the act.dat and the rif associated to the content (if local it will locate a file with the same titleid on NPD element, if remote it will download to vsh process memory) | |||
Then the signature is checked (last 0x28 bytes of both RIF and act.dat). The curves used are on vsh.self. It is a 3 element table, having the first curve nulled. The curve index for rif/act is 2. The curve values are negated as in the apploader and has the following structure | |||
struct curve { | |||
uint8_t p[0x14]; | |||
uint8_t a[0x14]; | |||
uint8_t b[0x14]; | |||
uint8_t N[0x14]; | |||
uint8_t Gx[0x14]; | |||
uint8_t Gy[0x14]; | |||
} | |||
If the curve checks then vsh will process the rif: | |||
struct rif { | |||
uint8_t unk1[0x10]; //version, license type and user number | |||
uint8_t titleid[0x30]; //Content ID | |||
uint8 padding[0xC]; //Padding for randomness | |||
uint32_t actDatIndex; //Key index on act.dat between 0x00 and 0x7F | |||
uint8 key[0x10]; //encrypted klicensee | |||
uint64_t unk2; //timestamp?? | |||
uint64_t unk3; //Always 0 | |||
uint8_t rs[0x28]; | |||
}; | |||
struct ACTDAT { | |||
uint8_t unk1[0x10]; //Version, User number | |||
uint8_t keyTable[0x800]; //Key Table | |||
...... | |||
uint8_t signature[0x28]; | |||
} | |||
Using the RIF_KEY it will obtain the actdatIndex: | |||
AES_KEY rifKey; | |||
uint8_t rif_key[0x10] = { 0xda, 0x7d, 0x4b, 0x5e, 0x49, 0x9a, 0x4f, 0x53, 0xb1, 0xc1, 0xa1, 0x4a, 0x74, 0x84, 0x44, 0x3b }; | |||
int result = AES_set_decrypt_key(rif_key, 0x80, &rifKey); | |||
AES_decrypt(&rif->padding, &rif->padding, &rifKey); | |||
And finally having the actDat key index the execution pass to LV2 syscall 471 | |||
===LV2=== | |||
Lv2 is accessed using syscall471 which haves the following syntax: | |||
int syscall_471(uint32_t type, char* titleID, void* klicensee, uint8_t* actdat, uint8_t* rif, int32_t licenseType, uint8_t* magicVersion); | |||
The function has different parameters depending if the content is debug, free or paid: | |||
FREE: syscall471(npd.type, &npd.titleID, freeklicensee, NULL, NULL, npd.license, &npd); | |||
PAID: syscall471(npd.type, &npd.titleID, NULL, &actdat.keyTable[rif.actDatIndex], &rif.key, npd.license, &npd); | |||
The lv2 keeps a memory table with contentID and the associated key. | |||
When it receives a free content (r5 is not null) then copies the titleID and the klicensee to the table. For a paid content the rif.key is converted to the klicensee using: | |||
AES_KEY IDPSKey, ConstKey, ActDatKey; | |||
uint8_t constactdat[0x10] = { 0x5e, 0x06, 0xe0, 0x4f, 0xd9, 0x4a, 0x71, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; | |||
uint8_t encrConst[0x10]; | |||
uint8_t decryptedActDat[0x10]; | |||
uint8_t klicensee[0x10]; | |||
int result = AES_set_encrypt_key(&IDPSVariation, 0x80, &IDPSKey); | |||
AES_encrypt(constactdat, &encrConst, &IDPSKey); | |||
result = AES_set_decrypt_key(&encrConst,0x80,&ConstKey); | |||
AES_decrypt(actDat,&decryptedActDat,&ConstKey); | |||
result = AES_set_decrypt_key(&decryptedActDat,0x80,&ActDatKey); | |||
AES_decrypt(rif,&klicensee,&ActDatKey); | |||
where CONSTACTDAT is a constant value on lv2, IDPSVaritaion appears to be IDPS (actually is the plain IDPS) (not checked but DRM_Manager_initialize (see graf_chokolo's "bible") to something with the same structure), actdat are the 0x10bytes selected by rif keyIndex, and rif is rif.key (bytes 0x50-0x5f). | |||
Once transformed it is stored on memory table... | |||
I haven't check further steps on vsh nor lv2 so perhaps there are further transformations on the paid case (NOT FOR THE FREE AS I HAVE DECRYPTED THOSE) so we are jumping directly to the appldr | |||
===AppLdr=== | |||
As you can see from graf_chokolo payloads a parameter is passed on spu_args.field60. That parameter is the previously stored klicensee. | |||
However this key must be transformed (again) even for the free case. The transformation is: | |||
uint8_t decryptedKLicensee[0x10] | |||
uint8_t KLicenseeDecryptKey[] = {0xf2, 0xfb, 0xca, 0x7a, 0x75, 0xb0, 0x4e, 0xdc, 0x13, 0x90, 0x63, 0x8c, 0xcd, 0xfd, 0xd1, 0xee}; | |||
AES_KEY KLicenseeKey | |||
int result = AES_set_decrypt_key(KLicenseeDecryptKey,0x80,&KLICENSEEKEY); | |||
AES_decrypt(klicensee,&decryptedKLicensee,&KLicenseeKey); | |||
EY is another key located inside the apploader and klicensee is the parameter. | |||
Then we can finally remove the NPDRM layer using: | |||
AES_KEY key; | |||
uint8_t iv[0x10]; | |||
memset(&iv[0],0,0x10); | |||
int result = AES_set_decrypt_key(&KLicenseeDecryptKey,0x80,&key); | |||
AES_cbc_encrypt(self + self->metaoffset + 0x20, self + self->metaoffset + 0x20,0x40,&key,&iv,0); | |||
Observe the above code in action at [http://pastie.org/2647887] | |||
Once that layer is removed we proceed as normal: | |||
*Decrypt using AESCBC256 with the NPDRM keys to obtain the metadata keys | |||
*Decrypt using AESCTR128 the data sha,hmac,iv keys | |||
*Decrypt the data. | |||
'''Source:''' http://www.ps3hax.net/showpost.php?p=259713&postcount=1 JuanNadie | |||
'''Footnote:''' KLicenseeDecryptKey is located in appldr twice, e.g. | |||
1.00: | |||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |||
000187C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
000187D0 F2 FB CA 7A 75 B0 4E DC 13 90 63 8C CD FD D1 EE òûÊzu°NÜ..cŒÍýÑî | |||
000187E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
000187F0 F2 FB CA 7A 75 B0 4E DC 13 90 63 8C CD FD D1 EE òûÊzu°NÜ..cŒÍýÑî | |||
3.15: | |||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |||
00018EB0 F2 FB CA 7A 75 B0 4E DC 13 90 63 8C CD FD D1 EE òûÊzu°NÜ..cŒÍýÑî | |||
00018EC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
00018ED0 F2 FB CA 7A 75 B0 4E DC 13 90 63 8C CD FD D1 EE òûÊzu°NÜ..cŒÍýÑî | |||
00018EE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
3.55: | |||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |||
00019730 F2 FB CA 7A 75 B0 4E DC 13 90 63 8C CD FD D1 EE òûÊzu°NÜ..cŒÍýÑî | |||
00019740 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
00019750 F2 FB CA 7A 75 B0 4E DC 13 90 63 8C CD FD D1 EE òûÊzu°NÜ..cŒÍýÑî | |||
00019760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
3.56: | |||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |||
0001F920 F2 FB CA 7A 75 B0 4E DC 13 90 63 8C CD FD D1 EE òûÊzu°NÜ..cŒÍýÑî | |||
0001F930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
0001F940 F2 FB CA 7A 75 B0 4E DC 13 90 63 8C CD FD D1 EE òûÊzu°NÜ..cŒÍýÑî | |||
0001F950 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
==== hex ==== | |||
appldr/npdrm 0.92-3.31: [http://www.multiupload.com/OAQY49VWLQ rev_0x01.rar (2.39 KB)] | |||
---- | |||
=== Part 2 === | |||
Thank to all of you. I hope someone is able to code a program using this info. | |||
First of all, I want to congratulate Euss of ps3devwiki on finding the klicensee decrypt key and provide a proof of concept of the AppLoder part of the algorithm. Check http://ps3devwiki.com/index.php?title=Talk:SELF_File_Format_and_Decryption | |||
Now you have the tools to decrypt all free executable content. | |||
Euss they key is not duplicated... there are two cases that lead to the same (similar to the keys, two cases so two repeated tables). | |||
Some of you asked what this algorithm is for. It has several use from backing up PSN games so they can be used with/without license (some countries allow backups, but NEVER sharing copyrighted material....) or use game updates on lower firmwares (some updates are NPDRM so they could not be decrypted and downgraded). I don't know if DUPLEX used this method or if they replaced the data with debug versions as some implied... | |||
Also, it can be use is to modify geohot's make_self_npdrm to use non static keys for encoding. I don't know if that would be enough to make a self runnable on 3.56+ firmware. However it is a step on the right direction (I think extra modifications are required). If someone knows which parts of the self is whitelisted it would be an interesting addition to the thread. Sony was publishing 3.55 after 3.56 went online so I really interested to see which part of the SELF was whitelisted. | |||
Others asked for the keys. I can not provide them nor functional code to avoid being sued... Graf and geohot were sued for providing the keys and/or functional code. | |||
==== RIF key ==== | |||
However, I can provide a tip on getting the RIF key.... once decrypted bytes 0x40 to 0x4F should be xx xx xx xx xx xx xx xx xx xx xx xx 00 00 00 aa where x is random and aa is a number between 0x00 and 0x7F. It is located on the VSH.elf (remember that PPC64 has 8 byte aligment). That is a plaintext attack + dictionary(vsh). You don't need the curves as you can not sign rif nor act.dat (You can only check that file is valid). And the vsh keys can be easily find... graf chokolo called IDPS as device_id_ptr.... and the CONST is very near on code execution... | |||
edit: | |||
===== RIF's act.dat index decryption key ===== | |||
actdatix_dec_key : DA7D4B5E499A4F53B1C1A14A7484443B | |||
Actually in vsh.self | |||
To <X>: That is a piracy related question. In addition you have published confidential info, which anyone who does RCE should avoid (I do not have the SDK). The answer is NO. Why?. See this code: | |||
<pre> | |||
ret = sceNpDrmVerifyUpgradeLicense("FAKE_CONTENT_TO_DETECT_CFW"); | |||
if(ret == 0){ | |||
banConsole(); | |||
print("CFW detected. Game will exit"); | |||
exit(-1); | |||
} | |||
ret = sceNpDrmVerifyUpgradeLicense("REAL_CONTENT"); | |||
if (ret == 0) { | |||
int fd = openEncryptedContent("REAL_CONTENT.edat",......,keyForFile,sizeof(KeyForFile)); | |||
if (fd > 0) { | |||
//Do things | |||
} | |||
} | |||
</pre> | |||
First part is an example of how a developers can easily catch that modification and stop execution making it dangerous (could get a ban!!!). You modification says that the console has access to a fake content, which only CFW will have. When patching code the modification should be done only to the case you want to fix. That modification should go on the executable not on npd libraries. That way we do not patch the first verify but we will patch the second... | |||
The second part is the real reason why it wont work... you REQUIRE the rif for opening the edat. The rif holds the klicensee for both SELF and EDAT. In fact I assume that the klicensee follows the same transformation upto the apploader. That key that you see on the command it is only used to check the HMAC on the NPD element (see geohot make_self_npdrm omac calculations) | |||
For executable the problem is similar as when trying to run another PPU executable the program will finish and ask the vsh to run the other process which will undergo the full decryption algorithm... again you need the rif. | |||
But.... what will happen if we decrypt the paid edat/SELF using the rif and then resign and encrypt as a free content before executing the code??? (Assuming we can sign edat) | |||
WE CAN SIGN EXECUTABLES UPTO 3.55 THANKS TO FAIL0VERFLOW'S EPIC FAIL..... I think people do not really understands what that means... | |||
'''Source:''' http://www.ps3hax.net/showpost.php?p=260574&postcount=8 | |||
---- | |||
=== Part 2 - responce === | |||
There is a reference for PSP's act.dat rif edat format posted here: http://www.emunewz.net/forum/archive/index.php/thread-8134.html | |||
there may be similarities between PS3 and PSP below: | |||
<pre>EDAT/SPRX format: | |||
[HEADER] | |||
0x00: 00 50 53 50 -> .PSP | |||
0x04: 45 44 41 54 -> EDAT | |||
0x08: 02 00 00 00 -> Content key format (0x2000000 fixed key from npdrm / 0x2000100 version key from act.dat) | |||
0x0C: 90 00 -> Header size | |||
0x0E: 01 01 -> Header format (01 01 = sprx; 00 01 = edat) | |||
0x10 - 0x40 -> Content ID | |||
0x40 -> Hash generated from Content ID | |||
0x50: 00 00 00 00 -> NULL | |||
0x54: 00 00 00 00 -> NULL | |||
0x58 - 0x70 -> Signature | |||
0x80 -> Hash generated from signature | |||
[HEADER] | |||
0x90: [Encrypted PRX (SPRX)] / [PGD (EDAT)] | |||
</pre> | |||
<pre> | |||
RIF format: | |||
0x00: 00 00 00 01 -> License version (shared with act.dat) | |||
0x04: 00 00 00 02 -> File version | |||
0x08 - 0x10 -> Account ID | |||
0x10 - 0x40 -> Content ID | |||
0x40 -> Hash generated from private key | |||
0x50 -> Hash generated from license key | |||
0x60: 00 00 01 1F -> License start time | |||
0x64: C5 16 7B D8 -> License expiration time | |||
0x68: 00 00 00 00 -> NULL | |||
0x6C: 00 00 00 00 -> NULL | |||
0x70 - 0x90 -> Signature | |||
</pre> | |||
<pre> | |||
ACT.DAT format: | |||
0x00: 00 00 00 01 -> License version (shared with .rif) | |||
0x04: 00 00 00 01 -> File version | |||
0x08 - 0x10 -> Account ID | |||
0x10 - 0x1010 -> Data hashes | |||
0x1010 - 0x1030 -> Signature[/CODE] | |||
</pre> | </pre> | ||
A MU link contains a sample act.dat and rif file for ps3 can be found if you search for "COD:BO First Strike DLC Activation blus30591" with google. | |||
I'm reading PSP forums, and it may possible to code an utility for cfw PS3 users, that decrypts their purchased content (A valid act.dat and rif required) if knowledge matures | |||
I see the reason that, some users lost their bought DLC because of someting not related with piracy, for example updating fw, hdd, etc. | |||
A PC utility could be written only if npdrm self contains a free license, etc... | |||
'''Source:''' http://www.ps3hax.net/showpost.php?p=260672&postcount=9 | |||
---- | ---- | ||
=== Part 3 === | |||
That link was very useful. The riff structure is very similar although the signature algorithm is different. | |||
I have some bad news. The IDPS has been confirmed as the plain IDPS with no variations (I expected it to be user ID). That means that some step is missing in the paid algorithm. For some time, people have been able to use DLC bought by other people by changing their user ID. That means that info could be extracted on any PS3, so a value coded by IDPS (which is different on EACH console) can not be part of the algorithm. I think that the value calculated by 471 is some kind of signature to validate act.dat. It will fail on different console which explains why the act.dat is deleted every time the machine boots. | |||
So I'm going to restudy the VSH looking for the missing part. We don't know the meaning of byte 0x810 to 0x1010 of act.dat. Previously I discarded that the act.dat contained an entry for each content as it has a fixed size but it is the only place to store keys. It is a slow process so please be patient. | |||
Meanwhile we can improved make_self_npdrm and decrypt updates (for disc games). | |||
By the way more info on keys: | |||
<pre> | <pre> | ||
VSH CURVE TABLE: | |||
Len: 360 | |||
SHA1: 870ce226c65325a64dae9362cf9d43665d13194b | |||
PUB_KEY: | |||
Len: 40 | |||
SHA1: 7b365a6a821fc03b1a9a764e5e695db3599ff7bc | |||
</pre> | </pre> | ||
'''edit:''' | |||
The contents of the above: | |||
<pre> u8 vsh_pub_key[] = { | |||
0x62, 0x27, 0xb0, 0x0a, 0x02, 0x85, 0x6f, 0xb0, 0x41, 0x08, 0x87, 0x67, | |||
0x19, 0xe0, 0xa0, 0x18, 0x32, 0x91, 0xee, 0xb9, 0x6e, 0x73, 0x6a, 0xbf, | |||
0x81, 0xf7, 0x0e, 0xe9, 0x16, 0x1b, 0x0d, 0xde, 0xb0, 0x26, 0x76, 0x1a, | |||
0xff, 0x7b, 0xc8, 0x5b, | |||
}; | |||
</pre> | |||
<pre> u8 vsh_curves[] = { | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x03, 0x9a, 0x2e, 0xb7, 0x73, 0xfc, 0xa6, 0x1d, 0xcb, | |||
0x52, 0x36, 0xa4, 0x2c, 0x6f, 0x7f, 0xeb, 0x42, 0x6e, 0x5a, 0xda, 0x06, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x4a, 0x39, | |||
0xe8, 0x0d, 0x6f, 0x15, 0x1e, 0x24, 0x52, 0x70, 0xdd, 0xa6, 0x53, 0x11, | |||
0xea, 0xb7, 0x63, 0x4f, 0x69, 0x57, 0x7d, 0x0f, 0x51, 0xe3, 0x06, 0x02, | |||
0x71, 0x1a, 0x07, 0x05, 0x9f, 0xbc, 0xa7, 0xba, 0x92, 0xf5, 0xe3, 0x4d, | |||
0x6f, 0x72, 0x16, 0xf0, 0xd8, 0x28, 0xa3, 0x7d, 0x41, 0x3e, 0xf7, 0x3f, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x03, 0x59, 0x74, 0x12, 0x3c, 0xcb, 0xe7, 0xfd, 0x63, | |||
0xe2, 0xc3, 0x1c, 0xc4, 0x65, 0xcd, 0xe0, 0x33, 0x44, 0x61, 0xf0, 0xf4, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4a, 0x51, | |||
0xc3, 0xad, 0xc1, 0x9c, 0x6b, 0xb0, 0xde, 0xd8, 0xed, 0x71, 0x3b, 0xda, | |||
0x9b, 0x78, 0x02, 0x70, 0x20, 0x9b, 0x1d, 0xbc, 0x84, 0x3f, 0x5e, 0x09, | |||
0x2a, 0x50, 0x21, 0xd3, 0xa6, 0xa7, 0xaa, 0x81, 0x4e, 0x24, 0xff, 0xed, | |||
0x9f, 0xbd, 0xaa, 0xdb, 0x24, 0x3c, 0x86, 0x2a, 0x53, 0xa0, 0xb5, 0x20, | |||
}; | |||
</pre> | |||
'''edit:''' [http://www.multiupload.com/A19Q0HV7OW vsh-pub-curves.rar (367 Bytes)] | |||
I apologize for providing an incomplete solutions and I hope that me or someone else completes the info. | |||
'''Source:''' http://www.ps3hax.net/showpost.php?p=261043&postcount=10 | |||
---- | |||
=== Part 3 - responses === | |||
I'm not sure about that... It sounds weird. People had the opportunity to use DLC from others with account sharing. I log psn with your account and the psn generates a new act and rif for me (based on my IDPS??) | |||
So maybe your work isn't incomplete. | |||
And also, if syscall471 is used to verify act.dat, what's the purpose to call that also for free content? | |||
'''Source:''' http://www.ps3hax.net/showpost.php?p=261065&postcount=11 | |||
---- | |||
Don't doubt yourself, JuanNadie! The algorithm you posted is correct. It is indeed the plain IDPS. Using your posted algorithm I was able to completely remove the NPDRM layer on an encrypted, paid SELF to get the decrypted metadata keys. I suspect the game sharing people download games while logged in to a friend's PS3. When they download the game to their friend's PS3, the NPDRM layer is added using their friend's IDPS. | |||
'''Source:''' http://www.ps3hax.net/showpost.php?p=261140&postcount=13 | |||
---- | |||
I can confirm it, the algo is correct | |||
'''Source:''' http://www.ps3hax.net/showpost.php?p=261294&postcount=15 | |||
=== Part 4 === | |||
Did it really work? Wowww... I never tested that last step as i don't have an act.dat for my current PS3 (the other has YLOD). I released the info so somenone else could test it. I modified the first message to credit you for testing | |||
Then we have the NDPDRM algorithm solved and a new mystery (why changing userID at xregistry.sys allows using other's act.dat and rif). | |||
If someone has access to two consoles with act.dat he should check if values from 0x10 to 0x810 decrypts to the same. If the decrypted tables are equal them we can improve the algorithm to avoid using the IDPS, so anyone that lost their act.dat but have their rif could recover their games. | |||
IDPS for 3.55 kmeaws is located at 0x80000000003C2EF0. You will also need a program for getting it (two LV2 peeks). | |||
AppLoader keys are at 0x32510 (program memory address for 3.56 appLdr not file offset).There are 16 keys. Then there is another unknown key and then NPDRM keys at 0x32B70. Again 16 entries (some of them nulled). Then a copy of NPDRM keys at 0x33170. The revision value on self header is use as index for these table (the fail0verflow code tested all the values until it found zero padding). scekrit could be modified to get the private keys | |||
And now we wait until someone has guts to release a working code. | |||
'''Source:''' http://www.ps3hax.net/showpost.php?p=261963&postcount=21 | |||
===NPDRM ps3tools=== | |||
====v1==== | |||
http://www.multiupload.com/O72W5QERWN | |||
<!--// http://www.ps3hax.net/showpost.php?p=262715&postcount=27 //--> | |||
====v2==== | |||
unself2 and readself2 working. see questions about section type 3 in the readme | |||
http://www.multiupload.com/YWFWFJM7PX | |||
readme: | |||
Based off of gitbrew's 215d8903bc86539ca1da53519e2ac10eeafc4c27 | |||
ps3tools. .git folder not included to protect senstive info about the author. | |||
Sorry about the fucked up tabs, TAB = 4 SPACES 4 LYFE!!! | |||
Add the files in the npdrm_keystuff folder to your ps3 keys folder. Create a | |||
file with your console's 16 byte IDPS in the 'idps' file in your ps3 keys | |||
folder (e.g. ~/.ps3/idps). | |||
Copy your PS3's exdata folder containing your act.dat and rif files to your | |||
ps3 keys dir (e.g. ~/.ps3/exdata/act.dat). Compile and have fun with your | |||
LEGALLY purchased NPDRM games! | |||
Also works on free games without exdata/idps. | |||
Apologies for any existing bugs in unself. Adding these changes to | |||
unself2 is left as an exercise for the reader. | |||
v2 info: | |||
Added npdrm magic to unself2 and readself2 | |||
unself2 doesn't like the metadata section with type 3 in my game. | |||
This section looks to be some kind of linking information. Here is a snippet: | |||
crt0:p190002crt1:p190002libaudio_stub:p190002libaudio_stub:p190002 | |||
I haven't yet looked around to see if this is type of section is documented anywhere. | |||
Thanks: | |||
*fail0verflow for the orginal tools | |||
*JuanNadie for figuring out NPDRM | |||
*euss for his endless hours of work on the wiki | |||
<drama> | |||
Why didn't you beat me to the punch, Team PS360? I didn't need to reverse a | |||
single instruction! It isn't that hard... | |||
</drama> | |||
<!--// http://www.ps3hax.net/showpost.php?p=262809&postcount=31 //--> | |||
====v2 Newsitem==== | |||
http://www.ps3hax.net/2011/10/compile-your-legally-purchased-npdrm-games/ | |||
====Reaction==== | |||
I checked my notes on Metadata Section Header. Value on unk2 indicates the type of data: | |||
*1: the section header itself | |||
*2: program data. program index indicates which program section. | |||
*3: section data. program index indicates which section. | |||
I have checked several game updates and Sony removes some of the section info (I have seen the section header removed). That data is not needed on loading game (just program header, elf header and of course the program data). The ¿lv2? creates a memory image from only the data at segment Information. It never knows the contents of the metadata section headers. | |||
For backing up a game I think is not necessary to decrypt the data just the Self header and then modify the license type to 3 (free) reencode the NPD element resign the header with the priv and reencrypt the Self header. | |||
I don't have info on EDATA.... yet. On EDATA the index for act.dat uses the same key what I don't know if it uses the same table | |||
http://www.ps3hax.net/showpost.php?p=262858&postcount=34 |