Skip to content

Commit

Permalink
np
Browse files Browse the repository at this point in the history
  • Loading branch information
euss committed Oct 12, 2011
1 parent 8e36cbd commit 0d4c515
Show file tree
Hide file tree
Showing 11 changed files with 390 additions and 26 deletions.
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ bin_PROGRAMS = sceverify \
eidsplitr \
spp

bin_SCRIPTS = pupexplode

if HAVE_LIBGMP
bin_PROGRAMS += scekrit
endif
Expand Down
35 changes: 35 additions & 0 deletions README_npdrm
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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>

22 changes: 8 additions & 14 deletions readself.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ static void parse_self(void)
static struct keylist *self_load_keys(void)
{
enum sce_key id;

switch (app_type) {
switch (app_type) {
case 1:
id = KEY_LV0;
break;
Expand All @@ -163,7 +163,7 @@ static struct keylist *self_load_keys(void)
id = KEY_LDR;
break;
case 8:
return NULL;
id = KEY_NPDRM;
break;
default:
fail("invalid type: %08x", app_type);
Expand All @@ -180,7 +180,8 @@ static void decrypt_header(void)
if (klist == NULL)
return;

decrypted = sce_decrypt_header(self, klist);
sce_remove_npdrm(self, klist);
decrypted = sce_decrypt_header(self, klist);
free(klist->keys);
free(klist);
}
Expand Down Expand Up @@ -217,13 +218,6 @@ static void show_self_header(void)
printf("\n");
}

static void print_hash(u8 *ptr, u32 len)
{
while(len--)
printf(" %02x", *ptr++);
}


static void show_ctrl(void)
{
u32 i, j;
Expand Down Expand Up @@ -365,14 +359,14 @@ static void show_meta(void)
printf("\n");

printf(" Sections\n");
printf(" Offset Length Key IV SHA1\n");
printf(" Offset Length Key IV SHA1 Type\n");
for (i = 0; i < meta_n_hdr; i++) {
tmp = self + meta_offset + 0x80 + 0x30*i;
offset = be64(tmp);
size = be64(tmp + 8);
printf(" %08x_%08x %08x_%08x %03d %03d %03d\n",
printf(" %08x_%08x %08x_%08x %03d %03d %03d %4d\n",
(u32)(offset >> 32), (u32)offset, (u32)(size >> 32), (u32)size,
be32(tmp + 0x24), be32(tmp + 0x28), be32(tmp + 0x1c));
be32(tmp + 0x24), be32(tmp + 0x28), be32(tmp + 0x1c), be32(tmp + 0x10));
}
printf("\n");

Expand Down
13 changes: 6 additions & 7 deletions readself2.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ static struct keylist *self_load_keys(void)
return NULL;
break;
case 8:
return NULL;
id = KEY_NPDRM;
break;
default:
fail("invalid type: %08x", app_type);
Expand All @@ -196,12 +196,6 @@ static const char *get_auth_type(void)
return "UnknownAuthIdType";
}

static void print_hash(u8 *ptr, u32 len)
{
while(len--)
printf(" %02x", *ptr++);
}

static void get_flags(u32 flags, char *ptr)
{
memset(ptr, '-', 3);
Expand Down Expand Up @@ -268,6 +262,7 @@ static void decrypt_header(void)
if (klist == NULL)
return;

sce_remove_npdrm(self, klist);
decrypted = sce_decrypt_header(self, klist);
free(klist->keys);
free(klist);
Expand Down Expand Up @@ -988,6 +983,10 @@ static void show_meta(void)
(u16)((meta_offset + 0x80 + 0x30*i) + 0x1c),
be32(tmp + 0x1c)
);
printf(" Type: %04x = %04x\n",
(u16)((meta_offset + 0x80 + 0x30*i) + 0x10),
be32(tmp + 0x10)
);
}
printf("\n");

Expand Down
78 changes: 76 additions & 2 deletions self.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
static struct keylist *load_keys(APP_INFO *app_info);
static int decrypt_metadata(uint8_t *metadata, uint32_t metadata_size,
struct keylist *klist);
static int remove_npdrm(SELF *self, CONTROL_INFO *control_info, uint8_t *metadata,
struct keylist *klist);
static void decrypt_npdrm(uint8_t *metadata, struct keylist *klist,
struct key *klicensee);




void
Expand Down Expand Up @@ -166,6 +172,9 @@ self_read_headers(FILE *in, SELF *self, APP_INFO *app_info, ELF *elf,
if (info[index].type == 1)
info[index].control_flags.control_flags =
swap64 (info[index].control_flags.control_flags);
if (info[index].type == 3)
info[index].npdrm.license_type =
swap32 (info[index].npdrm.license_type);

offset += info[index].size;
index++;
Expand Down Expand Up @@ -219,7 +228,7 @@ void
self_read_metadata (FILE *in, SELF *self, APP_INFO *app_info,
METADATA_INFO *metadata_info, METADATA_HEADER *metadata_header,
METADATA_SECTION_HEADER **section_headers, uint8_t **keys,
SIGNATURE_INFO *signature_info, SIGNATURE *signature)
SIGNATURE_INFO *signature_info, SIGNATURE *signature, CONTROL_INFO *control_info)
{
uint8_t *metadata = NULL;
uint32_t metadata_size = self->header_len - self->metadata_offset - 0x20;
Expand All @@ -240,6 +249,9 @@ self_read_metadata (FILE *in, SELF *self, APP_INFO *app_info,
if (klist == NULL)
ERROR(-5, "no key found");

if (remove_npdrm (self, control_info, metadata, klist) < 0)
ERROR (-5, "Error removing NPDRM");

if (decrypt_metadata (metadata, metadata_size, klist) < 0)
ERROR (-5, "Error decrypting metadata");
}
Expand Down Expand Up @@ -405,6 +417,9 @@ load_keys(APP_INFO *app_info)
case 6:
id = KEY_LDR;
break;
case 8:
id = KEY_NPDRM;
break;
default:
fprintf (stderr, "SELF type is invalid : 0x%08X\n", app_info->self_type);
exit (-4);
Expand All @@ -413,6 +428,66 @@ load_keys(APP_INFO *app_info)
return keys_get(id);
}

static int
remove_npdrm(SELF *self, CONTROL_INFO *control_info, uint8_t *metadata, struct keylist *klist)
{
CONTROL_INFO *info;
u32 license_type;
char content_id[0x31] = {'\0'};
struct rif *rif;
struct actdat *actdat;
u8 enc_const[0x10];
u8 dec_actdat[0x10];
struct key klicensee;
int i;
u64 off;

for (i = off = 0; off < self->controlinfo_size; i++) {
info = &control_info[i];
if (info->type == 3) {
license_type = info->npdrm.license_type;
switch (license_type) {
case 1:
// cant decrypt network stuff
return -1;
case 2:
memcpy(content_id, info->npdrm.content_id, 0x30);
rif = rif_get(content_id);
if (rif == NULL) {
return -1;
}
aes128(klist->rif->key, rif->padding, rif->padding);
aes128_enc(klist->idps->key, klist->npdrm_const->key, enc_const);
actdat = actdat_get();
if (actdat == NULL) {
return -1;
}
aes128(enc_const, &actdat->keyTable[swap32(rif->actDatIndex)*0x10], dec_actdat);
aes128(dec_actdat, rif->key, klicensee.key);
decrypt_npdrm(metadata, klist, &klicensee);
return 1;
case 3:
decrypt_npdrm(metadata, klist, klist->free_klicensee);
return 1;
}
}

off += info->size;
}
return 0;
}

static void
decrypt_npdrm(uint8_t *metadata, struct keylist *klist, struct key *klicensee)
{
struct key d_klic;

// iv is 0
memset(&d_klic, 0, sizeof(struct key));
aes128(klist->klic->key, klicensee->key, d_klic.key);

aes128cbc(d_klic.key, d_klic.iv, metadata, 0x40, metadata);
}

static int
decrypt_metadata(uint8_t *metadata, uint32_t metadata_size,
Expand All @@ -422,7 +497,6 @@ decrypt_metadata(uint8_t *metadata, uint32_t metadata_size,
METADATA_INFO metadata_info;
uint8_t zero[16] = {0};

memset (zero, 0, 16);
for (i = 0; i < klist->n; i++) {
aes256cbc(klist->keys[i].key, klist->keys[i].iv,
metadata, sizeof(METADATA_INFO), (uint8_t *) &metadata_info);
Expand Down
16 changes: 15 additions & 1 deletion self.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ typedef struct {
uint8_t digest2[20];
uint8_t padding[8];
} file_digest;

struct {
uint32_t unknown1;
uint32_t unknown2;
uint32_t magic;
uint32_t unknown3;
uint32_t license_type;
uint32_t type;
uint8_t content_id[0x30];
uint8_t hash[0x10];
uint8_t hash_iv[0x10];
uint8_t hash_xor[0x10];
uint8_t padding[0x10];
} npdrm;
};
} __attribute__((packed)) CONTROL_INFO;

Expand Down Expand Up @@ -186,7 +200,7 @@ void self_read_headers(FILE *in, SELF *self, APP_INFO *app_info, ELF *elf,
void self_read_metadata (FILE *in, SELF *self, APP_INFO *app_info,
METADATA_INFO *metadata_info, METADATA_HEADER *metadata_header,
METADATA_SECTION_HEADER **section_headers, uint8_t **keys,
SIGNATURE_INFO *signature_info, SIGNATURE *signature);
SIGNATURE_INFO *signature_info, SIGNATURE *signature, CONTROL_INFO *control_info);

int self_load_sections (FILE *in, SELF *self, ELF *elf, ELF_PHDR **phdr,
METADATA_HEADER *metadata_header, METADATA_SECTION_HEADER **section_headers,
Expand Down
Loading

0 comments on commit 0d4c515

Please sign in to comment.