Go Back  
Reply
 
Thread Tools
Old 10-08-2011   #11
jester
Member
null
 
Join Date: Dec 2008
Posts: 30
Likes: 0
Liked 8 Times in 6 Posts
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
Originally Posted by JuanNadie View Post
For some time, people have been able to use DLC bought by other people by changing their user ID
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?
jester is offline   Reply With Quote
Likes: (1)
Old 10-08-2011   #12
H3avyRa1n
Senior Member
 
H3avyRa1n's Avatar
 
Join Date: Aug 2011
Posts: 1,268
Likes: 178
Liked 838 Times in 391 Posts
Mentioned: 59 Post(s)
Tagged: 0 Thread(s)
this is a really interesting read. thanks for sharing.
H3avyRa1n is offline   Reply With Quote
Old 10-08-2011   #13
mallory
Homebrew Developer
 
Join Date: Oct 2011
Posts: 9
Likes: 0
Liked 33 Times in 6 Posts
Mentioned: 6 Post(s)
Tagged: 0 Thread(s)
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.
mallory is offline   Reply With Quote
Likes: (1)
Old 10-08-2011   #14
mckenziesdaddy
Member
 
Join Date: Sep 2011
Location: York,PA USA
Posts: 509
Likes: 11
Liked 92 Times in 60 Posts
Mentioned: 32 Post(s)
Tagged: 0 Thread(s)
This is good news for me. I lost all of my content with that dumb QA setting. Yes I tried it before I should have and yes it is my fault,But it will still be nice to get my stuff back.
mckenziesdaddy is offline   Reply With Quote
Old 10-08-2011   #15
jester
Member
null
 
Join Date: Dec 2008
Posts: 30
Likes: 0
Liked 8 Times in 6 Posts
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
I can confirm it, the algo is correct
jester is offline   Reply With Quote
Likes: (1)
Old 10-08-2011   #16
badhabit
 
Join Date: Jul 2011
Posts: 79
Likes: 94
Liked 81 Times in 35 Posts
Mentioned: 7 Post(s)
Tagged: 0 Thread(s)
Great work JuanNadie !!
Thanks for sharing ...
badhabit is offline   Reply With Quote
Old 10-08-2011   #17
imaverybigboi
Apprentice
 
Join Date: Sep 2011
Posts: 13
Likes: 0
Liked 5 Times in 2 Posts
Mentioned: 0 Post(s)
Tagged: 0 Thread(s)
so how long untill someone codes a app to use this huh
imaverybigboi is offline   Reply With Quote
Old 10-09-2011   #18
RikuKH3
Member
null
 
Join Date: Sep 2010
Posts: 49
Likes: 1
Liked 36 Times in 15 Posts
Mentioned: 10 Post(s)
Tagged: 0 Thread(s)
Here's sources of unself_gnpdrm (tool for decrypting NPDRM'ed SELFs generated with Geohot's make_self_npdrm static key):

Code:
// Copyright 2010       Sven Peter <svenpeter@gmail.com>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt

#include "tools.h"
#include "types.h"

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

#define	MAX_SECTIONS	255

static u8 *self = NULL;
static u8 *elf = NULL;
static FILE *out = NULL;

static u64 info_offset;
static u32 key_ver;
static u64 phdr_offset;
static u64 shdr_offset;
static u64 sec_offset;
static u64 ver_offset;
static u64 version;
static u64 elf_offset;
static u64 meta_offset;
static u64 header_len;
static u64 filesize;
static u32 arch64;
static u32 n_sections;
static u64 ctrl_offset;
static u64 ctrl_size;
static u64 unknown2;

static u64 authid;
static u32 vendorid;
static u32 app_type;
static u64 unknown3;

static u64 elf_ident;
static u64 elf_ident2;

static struct elf_hdr ehdr;

static struct {
	u32 offset;
	u32 size;
	u32 compressed;
	u32 size_uncompressed;
	u32 elf_offset;
} self_sections[MAX_SECTIONS];

static void read_header(void)
{
	key_ver =    be16(self + 0x08);
	meta_offset = be32(self + 0x0c);
	header_len =  be64(self + 0x10);
	filesize =    be64(self + 0x18);
	info_offset = be64(self + 0x28);
	elf_offset =  be64(self + 0x30);
	phdr_offset = be64(self + 0x38) - elf_offset;
	shdr_offset = be64(self + 0x40) - elf_offset;
	sec_offset =  be64(self + 0x48);
	ver_offset =  be64(self + 0x50);
	ctrl_offset = be64(self + 0x58);
	ctrl_size =   be64(self + 0x60);
	unknown2 =    be64(self + 0x68);

	authid =      be64(self + info_offset + 0x00);
	vendorid =    be32(self + info_offset + 0x08);
	app_type =    be32(self + info_offset + 0x0c);
	version =	  be64(self + info_offset + 0x10);
	unknown3 =    be64(self + info_offset + 0x18);

  elf_ident =   be64(self + elf_offset + 0x00);
  elf_ident2 =  be64(self + elf_offset + 0x08);
	elf = self + elf_offset;
	arch64 = elf_read_hdr(elf, &ehdr);
}

struct self_sec {
	u32 idx;
	u64 offset;
	u64 size;
	u32 compressed;
	u32 encrypted;
	u64 next;
};



static void read_section(u32 i, struct self_sec *sec)
{
	u8 *ptr;

	ptr = self + sec_offset + i*0x20;

	sec->idx = i;
	sec->offset     = be64(ptr + 0x00);
	sec->size       = be64(ptr + 0x08);
	sec->compressed = be32(ptr + 0x10) == 2 ? 1 : 0;
	sec->encrypted  = be32(ptr + 0x1c);
	sec->next       = be64(ptr + 0x20);
}

static int qsort_compare(const void *a, const void *b)
{
	const struct self_sec *sa, *sb;
	sa = a;
	sb = b;

	if (sa->offset > sb->offset)
		return 1;
	else if(sa->offset < sb->offset)
		return -1;
	else
		return 0;
}

static void read_sections(void)
{
	struct self_sec s[MAX_SECTIONS];
	struct elf_phdr p;
	u32 i;
	u32 j;
	u32 n_secs;
	u32 self_offset, elf_offset;

	memset(s, 0, sizeof s);
	for (i = 0, j = 0; i < ehdr.e_phnum; i++) {
		read_section(i, &s[j]);
		if (s[j].compressed)
			j++;
	}

	n_secs = j;
	qsort(s, n_secs, sizeof(*s), qsort_compare);

	elf_offset = 0;
	self_offset = header_len;
	j = 0;
	i = 0;
	while (elf_offset < filesize) {
		if (i == n_secs) {
			self_sections[j].offset = self_offset;
			self_sections[j].size = filesize - elf_offset;
			self_sections[j].compressed = 0;
			self_sections[j].size_uncompressed = filesize - elf_offset;
			self_sections[j].elf_offset = elf_offset;
			elf_offset = filesize;
		} else if (self_offset == s[i].offset) {
			self_sections[j].offset = self_offset;
			self_sections[j].size = s[i].size;
			self_sections[j].compressed = 1;
			elf_read_phdr(arch64, elf + phdr_offset +
					(ehdr.e_phentsize * s[i].idx), &p);
			self_sections[j].size_uncompressed = p.p_filesz;
			self_sections[j].elf_offset = p.p_off;

			elf_offset = p.p_off + p.p_filesz;
			self_offset = s[i].next;
			i++;
		} else {
			elf_read_phdr(arch64, elf + phdr_offset +
					(ehdr.e_phentsize * s[i].idx), &p);
			self_sections[j].offset = self_offset;
			self_sections[j].size = p.p_off - elf_offset;
			self_sections[j].compressed = 0;
			self_sections[j].size_uncompressed = self_sections[j].size;
			self_sections[j].elf_offset = elf_offset;

			elf_offset += self_sections[j].size;
			self_offset += s[i].offset - self_offset;
		}
		j++;
	}

	n_sections = j;
}

static void write_elf(void)
{
	u32 i;
	u8 *bfr;
	u32 size;
	u32 offset = 0;

	for (i = 0; i < n_sections; i++) {
		fseek(out, self_sections[i].elf_offset, SEEK_SET);
		offset = self_sections[i].elf_offset;
		if (self_sections[i].compressed) {
			size = self_sections[i].size_uncompressed;

			bfr = malloc(size);
			if (bfr == NULL)
				fail("failed to allocate %d bytes", size);

			offset += size;

			printf("compressed self_sections[i].offset 0x%x self_sections[i].size 0x%x\n",
				self_sections[i].offset,self_sections[i].size);


			decompress(self + self_sections[i].offset,
			           self_sections[i].size,
				   bfr, size);
			fwrite(bfr, size, 1, out);
			free(bfr);
		} else {
			bfr = self + self_sections[i].offset;
			size = self_sections[i].size;
			offset += size;

			fwrite(bfr, size, 1, out);
		}
	}
}

static void remove_shnames(u64 shdr_offset, u16 n_shdr, u64 shstrtab_offset, u32 strtab_size)
{
	u16 i;
	u32 size;
	struct elf_shdr s;

	if (arch64)
		size = 0x40;
	else
		size = 0x28;

	for (i = 0; i < n_shdr; i++) {
		elf_read_shdr(arch64, elf + shdr_offset + i * size, &s);

		s.sh_name = 0;
		if (s.sh_type == 3) {
			s.sh_offset = shstrtab_offset;
			s.sh_size = strtab_size;
		}

		elf_write_shdr(arch64, elf + shdr_offset + i * size, &s);
	}
}

static void check_elf(void)
{
	u8 bfr[0x48];
	u64 elf_offset;
	u64 phdr_offset;
	u64 shdr_offset;
	u64 phdr_offset_new;
	u64 shdr_offset_new;
	u64 shstrtab_offset;
	u16 n_phdr;
	u16 n_shdr;
	const char shstrtab[] = ".unknown\0\0";
	const char elf_magic[4] = {0x7f, 'E', 'L', 'F'};

	fseek(out, 0, SEEK_SET);
	fread(bfr, 4, 1, out);

	if (memcmp(bfr, elf_magic, sizeof elf_magic) == 0)
		return;

	elf_offset =  be64(self + 0x30);
	phdr_offset = be64(self + 0x38) - elf_offset;
	shdr_offset = be64(self + 0x40) - elf_offset;

	if (arch64) {
		fseek(out, 0x48, SEEK_SET);
		phdr_offset_new = 0x48;

		fseek(out, 0, SEEK_END);
		shdr_offset_new = ftell(out);

		n_phdr = be16(elf + 0x38);
		n_shdr = be16(elf + 0x3c);
		shstrtab_offset = shdr_offset_new + n_shdr * 0x40;

		remove_shnames(shdr_offset, n_shdr, shstrtab_offset, sizeof shstrtab);

		fseek(out, phdr_offset_new, SEEK_SET);
		fwrite(elf + phdr_offset, 0x38, n_phdr, out);

		fseek(out, shdr_offset_new, SEEK_SET);
		fwrite(elf + shdr_offset, 0x40, n_shdr, out);

		wbe64(elf + 0x20, phdr_offset_new);
		wbe64(elf + 0x28, shdr_offset_new);

		fseek(out, SEEK_SET, 0);
		fwrite(elf, 0x48, 1, out);

		fseek(out, shstrtab_offset, SEEK_SET);
		fwrite(shstrtab, sizeof shstrtab, 1, out);
	} else {
		fseek(out, 0x34, SEEK_SET);
		phdr_offset_new = 0x34;
		fseek(out, 0, SEEK_END);
		shdr_offset_new = ftell(out);

		n_phdr = be16(elf + 0x2c);
		n_shdr = be16(elf + 0x30);
		shstrtab_offset = shdr_offset_new + n_shdr * 0x40;

		remove_shnames(shdr_offset, n_shdr, shstrtab_offset, sizeof shstrtab);

		fseek(out, phdr_offset_new, SEEK_SET);
		fwrite(elf + phdr_offset, 0x20, n_phdr, out);

		fseek(out, shdr_offset_new, SEEK_SET);
		fwrite(elf + shdr_offset, 0x28, n_shdr, out);

		wbe32(elf + 0x1c, phdr_offset_new);
		wbe32(elf + 0x20, shdr_offset_new);

		fseek(out, SEEK_SET, 0);
		fwrite(elf, 0x34, 1, out);

		fseek(out, shstrtab_offset, SEEK_SET);
		fwrite(shstrtab, sizeof shstrtab, 1, out);
	}
}

static void sce_decrypt_header_gnpdrm(u8 *ptr)
{
	u32 meta_offset;
	u32 meta_len;
	u64 header_len;


	meta_offset = be32(ptr + 0x0c);
	header_len  = be64(ptr + 0x10);

	u8 npdrm_key[] = {
		0x87,0xC7,0x4F,0xFE,0x66,0x93,0x0B,0xAA,0xA1,0x6F,0x86,0x40,0x91,0xC5,0x66,0xFB};
	u8 npdrm_iv[] = {
		0x08,0x28,0xB5,0x8F,0xAC,0xF9,0xDE,0xC8,0xD7,0x0D,0xFE,0xF0,0xF3,0x76,0x63,0xAE};

	aes128ctr(npdrm_key, npdrm_iv, ptr + meta_offset + 0x60, 0x20, ptr + meta_offset + 0x60);

	meta_len = header_len - meta_offset;

	aes128ctr(npdrm_key, npdrm_iv, ptr + meta_offset + 0x80, meta_len - 0x80, ptr + meta_offset + 0x80);

}


static void self_decrypt(void)
{
	if (sce_decrypt_data(self) < 0)
		fail("self_decrypt_data failed");
}

int main(int argc, char *argv[])
{
	if (argc != 3)
		fail("usage: unself in.self out.elf");

	self = mmap_file(argv[1]);

	if (be32(self) != 0x53434500)
		fail("not a SELF");

	read_header();
	read_sections();

	sce_decrypt_header_gnpdrm(self);
    self_decrypt();

	out = fopen(argv[2], "wb+");

	write_elf();
	check_elf();

	fclose(out);

	return 0;
}
RikuKH3 is offline   Reply With Quote
Old 10-09-2011   #19
Pirate
 
Pirate's Avatar
 
Join Date: Feb 2007
Posts: 6,930
Likes: 370
Liked 7,987 Times in 1,233 Posts
Mentioned: 568 Post(s)
Tagged: 0 Thread(s)
Moved to PS3 | Technical Development and Coding Area
__________________


Please do not PM me with help/questions (I will not reply). Use this for your questions.
PS3 Hacks
Pirate is offline   Reply With Quote
Old 10-09-2011   #20
Nichibotsu
Member
 
Nichibotsu's Avatar
 
Join Date: Dec 2010
Posts: 333
Likes: 6
Liked 44 Times in 24 Posts
Mentioned: 11 Post(s)
Tagged: 0 Thread(s)
Originally Posted by imaverybigboi View Post
so how long untill someone codes a app to use this huh
as long as it takes, mate : )
Nichibotsu is offline   Reply With Quote
Reply

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



PS3Hax.net is Copyright © 2010-2013.
Use of this site is governed by our Terms of Use and Privacy Policy. All Trademarks and images are owned by their respected owners.
Posts and links are subject to each author on this forum and are no way affiliated with the operations and/or opinions of ps3hax.net
All times are GMT -5. The time now is 04:20 AM.