Want more features on Pastebin? Sign Up, it's FREE!
Guest

ungpkg - PS3 - PSP - 2GB fix

By: a guest on Apr 9th, 2013  |  syntax: C  |  size: 5.60 KB  |  views: 560  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include <fcntl.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10.  
  11. #include "tools.h"
  12. #include "types.h"
  13. #include "common.h"
  14.  
  15. #ifdef WIN32
  16. #define MKDIR(x,y) mkdir(x)
  17. #else
  18. #define MKDIR(x,y) mkdir(x,y)
  19. #endif
  20.  
  21. typedef void (*decrypt_callback) (u8*, u64, u64, u8*);
  22.  
  23. static FILE *pkg;
  24. static u64 size;
  25. static u64 offset;
  26. static PKG_HEADER *header = NULL;
  27. static u8 key[0x10];
  28. static u8 pkg_type;
  29. static u8 psp_key[0x10];
  30.  
  31. static decrypt_callback decrypt;
  32.  
  33.  
  34. void decrypt_debug_block(u8 *data, u64 size, u64 register_offset, u8 *_key) {
  35.         u64 i;
  36.         u8 key[0x40];
  37.         u8 bfr[0x1c];
  38.  
  39.         memset(key, 0, sizeof key);
  40.         memcpy(key, header->digest, 8);
  41.         memcpy(key + 0x08, header->digest, 8);
  42.         memcpy(key + 0x10, header->digest + 0x08, 8);
  43.         memcpy(key + 0x18, header->digest + 0x08, 8);
  44.  
  45.         wbe64(key + 0x38, be64(key + 0x38) + register_offset);
  46.  
  47.         sha1(key, sizeof key, bfr);
  48.  
  49.         for(i=0; i<size;i++) {
  50.                 if(i != 0 && (i % 16) == 0) {
  51.                         wbe64(key + 0x38, be64(key + 0x38) + 1);
  52.                         sha1(key, sizeof key, bfr);
  53.                 }
  54.                 data[i] ^= bfr[i & 0xf];
  55.         }
  56. }
  57.  
  58. void decrypt_retail_block(u8 *data, u64 size, u64 register_offset, u8 *_key) {
  59.         u64 tmp;
  60.         u8 iv[0x10];
  61.  
  62.         memcpy(iv, header->k_licensee, 0x10);
  63.  
  64.         tmp = be64(iv + 8) + register_offset /*1*/;
  65.         wbe64(iv + 8, tmp);
  66.         if (tmp == 0)
  67.                 wbe64(iv, be64(iv) + register_offset /*1*/);
  68.  
  69.  
  70.                 aes128ctr(_key, iv, data, size ,data);
  71. }
  72.  
  73.  
  74. static void unpack_pkg(void) {
  75.        
  76.         PKG_FILE_HEADER *file;
  77.         u64 i;
  78.         u64 n_files;
  79.         u32 fname_len;
  80.         u64 file_offset;
  81.         u32 flags;
  82.         u32 fname_off;
  83.         u8 *data_block;
  84.         u8 *file_block;
  85.         char fname[255];
  86.  
  87.         n_files = be32( (u8*) &header->item_count);    
  88.         file = malloc(sizeof(PKG_FILE_HEADER));
  89.        
  90.        
  91.         for ( i = 0; i <  n_files; i++ ) {
  92.  
  93.                 fseek(pkg, offset + (i * 0x20), SEEK_SET);
  94.                 fread(file, 0x20, 1, pkg);
  95.  
  96.                                 if((pkg_type & 0x000000f) == 2)
  97.                                         decrypt((u8*)file , 0x20,  (offset + (i * 0x20) - offset) / 16, psp_key);
  98.                                 else
  99.                                         decrypt((u8*)file , 0x20,  (offset + (i * 0x20) - offset) / 16, key);  
  100.                      
  101.                 fname_off = be32((u8*)&file->filename_offset);
  102.                 fname_len = be32((u8*)&file->filename_size);
  103.                 file_offset = be64((u8*)&file->data_offset);
  104.                 size = be64((u8*)&file->data_size);
  105.                 flags = be32((u8*)&file->flags);
  106.                        
  107.                 fseek(pkg, fname_off + offset, SEEK_SET);                                                      
  108.                 file_block = malloc( fname_len );              
  109.                 fread( file_block, fname_len, 1, pkg );                        
  110.                                                                
  111.                                 if( (flags & 0xf0000000) == 0x90000000) {
  112.                                         decrypt(file_block, fname_len,  fname_off / 16, psp_key);
  113.                                 } else {
  114.                                         decrypt(file_block, fname_len,  fname_off / 16, key);
  115.                                 }
  116.  
  117.                 memset(fname, 0, sizeof fname);
  118.                 strncpy(fname,(const char*) file_block, fname_len);
  119.  
  120.                 fseek( pkg, file_offset + offset, SEEK_SET);                          
  121.                 data_block = malloc ( size );
  122.                 fread( data_block, size, 1, pkg);
  123.  
  124.                 if( (flags & 0xf0000000) == 0x90000000) {
  125.                                          decrypt(data_block, size, file_offset / 16, psp_key);
  126.                                 } else {
  127.                                          decrypt(data_block, size, file_offset / 16, key);
  128.                                 }
  129.                
  130.                 flags &= 0xff;
  131.                 if(flags == 4) {
  132.                         MKDIR(fname, 0777);
  133.                 } else if (flags == 1 || flags == 3 || flags == 2 || flags == 6) {
  134.                         memcpy_to_file( fname, data_block, size);
  135.                 } else {
  136.                         fail("unknown flags: %08x", flags);
  137.                 }
  138.         }
  139. }
  140.  
  141.  
  142. int main(int argc, char *argv[]) {
  143.         char *dir;
  144.  
  145.         if (argc != 2 && argc != 3)
  146.                 fail("usage: ungpkg filename.pkg [target]");
  147.  
  148.         pkg = fopen( (const char*) argv[1], "rb");
  149.        
  150.         header = malloc(sizeof(PKG_HEADER));
  151.         fread( header, sizeof(PKG_HEADER), 1, pkg);
  152.  
  153.         if (argc == 2) {
  154.                 dir = malloc(0x31);
  155.                 memset(dir, 0, 0x31);
  156.                 memset(dir, 0, 0x30);
  157.                 memcpy(dir, header->contentid, 0x30);
  158.         } else {
  159.                 dir = argv[2];
  160.         }
  161.  
  162.         offset = be64((u8*)&header->data_offset);
  163.         size = be64((u8*)&header->data_size);  
  164.         u32 type = be32((u8*)&header->pkg_type);
  165.        
  166.                 printf("%x\n", header->magic);
  167.                 return;
  168.            
  169.         if( type & 0x80000000 ) {
  170.                
  171.                 if ((type & 0x0000000F) != 1 && (type & 0x0000000F) != 2)
  172.                         fail("invalid pkg type: %x", type);
  173.        
  174.                                 pkg_type = type;
  175.            
  176.                 if (key_get_simple("gpkg-key", key, 0x10) < 0)
  177.                         fail("failed to load the package key.");
  178.  
  179.                                 if (key_get_simple("psp-gpkg-key", psp_key, 0x10) < 0)
  180.                         fail("failed to load the psp package key.");
  181.  
  182.                 decrypt = decrypt_retail_block;
  183.         } else {
  184.                 decrypt = decrypt_debug_block;
  185.         }
  186.  
  187.         MKDIR(dir, 0777);
  188.  
  189.         if (chdir(dir) != 0)
  190.                 fail("chdir(%s)", dir);
  191.        
  192.         unpack_pkg();
  193.         fclose(pkg);
  194.        
  195.         return 0;
  196. }
clone this paste RAW Paste Data