static void unpack_content(const char *name) { u8 *tmp; u8 *decompressed; u64 offset; u64 size; u64 size_real; tmp = pkg + meta_offset + 0x80 + 0x30 * 2; offset = be64(tmp); size = be64(tmp + 8); size_real = dec_size - 0x80; if (be32(tmp + 0x2c) == 0x2) { decompressed = malloc(size_real); memset(decompressed, 0xaa, size_real); decompress(pkg + offset, size, decompressed, size_real); memcpy_to_file(name, decompressed, size_real); } else { memcpy_to_file(name, pkg + offset, size); } }
void Unpup(const char* folder){ u32 i; char folder_2[200]; if(read_only!=1){ DIR *dip; i=0; do{ sprintf(folder_2,"%s_%u",folder,i++); }while((dip = opendir(folder_2)) != NULL); closedir(dip); MKDIR(folder_2, 0777); chdir(folder_2); } const char *file_name; if(read_only!=0) printf("Read Only Mode!\n"); printf("Reading...\n"); u64 HDR = be64(pup); if(HDR!=PSV_HDR) fail("\nERROR! Not a PlayStation Vita Update File (%08x%08x)",HDR>>32,HDR); u32 pkg_version = le32(pup+0x08); u32 img_version = le32(pup+0x10); file_count = le32(pup+0x18); u32 hdr_lenght = le32(pup+0x20); u32 pkg_lenght = le32(pup+0x28); dmsg("HDR 0x%08x%08x\n",HDR>>32,HDR); dmsg("PKG VERSION 0x%08x\n",pkg_version); dmsg("IMG VERSION 0x%08x\n",img_version); printf("N of Files %u\n",file_count); dmsg("HDR Lenght 0x%08x\n",hdr_lenght); dmsg("PKG Lenght 0x%08x\n",pkg_lenght); dmsg("Table Lenght 0x%08x\n",0x80+(0x20*file_count)); u32 entry,offset,size; for(i=0;i<file_count;i+=0x1){ entry = le32(pup+0x80+0x20*i); offset = le32(pup+0x80+0x20*i+0x08); size = le32(pup+0x80+0x20*i+0x10); file_name = id2name(entry, t_names, NULL); if(file_name==NULL){ dmsg("unknown entry id: 0x%08x | Offset: 0x%08x\n",entry,offset); snprintf(unknown_name,256,"unknown_data_0x%x_%02d.data",entry,unknown_type++); file_name = unknown_name; } printf("Found: %30s | size: %10u Bytes\n",file_name,size); if(read_only!=1) memcpy_to_file(file_name, pup + offset, size); } if(read_only!=1){ dmsg("Writing security_1.."); Write("security_1",0x30,0x50); } printf("Done!\n"); }
static void unpack_file(u32 i) { u8 *ptr; u8 name[33]; u64 offset; u64 size; ptr = pkg + 0x10 + 0x30 * i; offset = be64(ptr + 0x00); size = be64(ptr + 0x08); memset(name, 0, sizeof name); strncpy((char *)name, (char *)(ptr + 0x10), 0x20); printf("unpacking %s...\n", name); memcpy_to_file((char *)name, pkg + offset, size); }
static void unpack_info(u32 i) { u8 *tmp; u64 offset; u64 size; char path[256]; tmp = pkg + meta_offset + 0x80 + 0x30 * i; snprintf(path, sizeof path, "info%d", i); offset = be64(tmp); size = be64(tmp + 8); if (size != 0x40) fail("weird info size: %08x", size); memcpy_to_file(path, pkg + offset, size); }
static void do_toc(u8 *ptr) { u32 n_entries; u32 i; u8 *p; u8 *tmp; u64 size; char name[0x20]; n_entries = be32(ptr + 0x04); p = ptr + 0x10; for(i = 0; i < n_entries; i++) { memcpy(name, p + 16, 0x20); tmp = ptr + be64(p); size = be64(p + 0x08); memcpy_to_file(name, tmp, size); p += 0x30; } }
static void unpack_pkg(void) { u64 i; u64 n_files; u32 fname_len; u32 fname_off; u64 file_offset; u32 flags; char fname[256]; u8 *tmp; n_files = be32(pkg + 0x14); for (i = 0; i < n_files; i++) { tmp = pkg + offset + i*0x20; fname_off = be32(tmp) + offset; fname_len = be32(tmp + 0x04); file_offset = be64(tmp + 0x08) + offset; size = be64(tmp + 0x10); flags = be32(tmp + 0x18); if (fname_len >= sizeof fname) fail("filename too long: %s", pkg + fname_off); memset(fname, 0, sizeof fname); strncpy(fname, (char *)(pkg + fname_off), fname_len); flags &= 0xff; if (flags == 4) MKDIR(fname, 0777); else if (flags == 1 || flags == 3) memcpy_to_file(fname, pkg + file_offset, size); else fail("unknown flags: %08x", flags); } }