xerpi

PUP extractor v1.0

Apr 28th, 2012
332
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* by xerpi (18-1-2013)*/
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. #ifndef byte
  7.     #define byte unsigned char
  8. #endif
  9.  
  10. typedef unsigned long long u64;
  11.  
  12. typedef struct{
  13.     u64 entry_ID;
  14.     u64 data_offset;
  15.     u64 data_length;
  16.     u64 unknown;
  17. }File_table;
  18.  
  19. typedef struct{
  20.     u64 file_index;
  21.     byte *file_hash;
  22.     byte *unknown;
  23. }Hash_table;
  24.  
  25. typedef struct{
  26.     u64 magic;
  27.     u64 package_version;
  28.     u64 image_version;
  29.     u64 file_count;
  30.     u64 header_length;
  31.     u64 package_length;
  32.     byte *unknown;
  33.     File_table *file_table;
  34.     Hash_table *hash_table;
  35.     byte *header_hash;
  36. }PUP_header;
  37.  
  38.  
  39. void pup_free_pup_header(PUP_header *pup_header);
  40. int pup_read_header(PUP_header *pup_header, FILE *pup_file);
  41. void pup_extract(PUP_header *pup_header, FILE *pup_file);
  42. void pup_print_header(PUP_header *pup_header);
  43. char *ID_to_filename(u64 entry_ID);
  44.  
  45. int main(int argc, char **argv){
  46.     if( argc < 2)  {
  47.         printf("\nUsage: pupreader <file>\n");
  48.         return -1;
  49.     }
  50.     //Open the PUP file
  51.         FILE* pup_file = fopen(argv[1], "rb");
  52.     //Check if file is OK
  53.         if(pup_file == NULL){
  54.             printf("Could not open the file.");
  55.             return -1;
  56.         }
  57.     //Create the struct
  58.         PUP_header pup_header;
  59.     //Read the pup
  60.         printf("\nReading the header of: %s", argv[1]);
  61.         pup_read_header(&pup_header, pup_file);
  62.     //Print
  63.        pup_print_header(&pup_header);
  64.      //Extract files
  65.         printf("\n-> Extracting files...");
  66.         pup_extract(&pup_header, pup_file);
  67.         printf("\n\nEverything extracted!!! Press any key to exit.");
  68.  
  69.     fclose(pup_file);
  70.     pup_free_pup_header(&pup_header);
  71.     getchar();
  72.     return 0;
  73. }
  74.  
  75. void pup_free_pup_header(PUP_header *pup_header)
  76. {
  77.     free(pup_header->file_table);
  78.     free(pup_header->hash_table);
  79.     free(pup_header->unknown);
  80.     free(pup_header->header_hash);
  81.     int i;
  82.     for(i = 0; i < pup_header->file_count; i++)
  83.     {
  84.         free(pup_header->hash_table[i].file_hash);
  85.         free(pup_header->hash_table[i].unknown);
  86.     }
  87. }
  88.  
  89. int pup_read_header(PUP_header *pup_header, FILE *pup_file){
  90.     int i, size;
  91.     size = 0;
  92.     //Cursor at the beginning of the file
  93.         fseek(pup_file, 0, SEEK_SET);
  94.     //Allocate ememory for unknown
  95.         pup_header->unknown     = (char *)malloc(sizeof(char) * 0x50);
  96.     //Start reading the header
  97.         size += fread( &(pup_header->magic),           1, 0x8, pup_file ); //Read magic
  98.         size += fread( &(pup_header->package_version), 1, 0x8, pup_file ); //Read Package Version
  99.         size += fread( &(pup_header->image_version),   1, 0x8, pup_file ); //Read Image Version
  100.         size += fread( &(pup_header->file_count),      1, 0x8, pup_file ); //Read File Count
  101.         size += fread( &(pup_header->header_length),   1, 0x8, pup_file ); //Read Header Length
  102.         size += fread( &(pup_header->package_length),  1, 0x8, pup_file ); //Read Package Length
  103.         size += fread( (pup_header->unknown),          1, 0x50, pup_file ); //Read ¿UNKNOWN?
  104.     //Allocate memory for the header
  105.         pup_header->file_table = (File_table *)malloc(sizeof(File_table) * 0x20 * pup_header->file_count);
  106.         pup_header->hash_table = (Hash_table *)malloc(sizeof(Hash_table) * 0x40 * pup_header->file_count);
  107.     //Read File Table
  108.         for(i = 0; i < pup_header->file_count; i++){
  109.             size += fread( &(pup_header->file_table[i].entry_ID),    1, 0x8, pup_file );
  110.             size += fread( &(pup_header->file_table[i].data_offset), 1, 0x8, pup_file );
  111.             size += fread( &(pup_header->file_table[i].data_length), 1, 0x8, pup_file );
  112.             size += fread( &(pup_header->file_table[i].unknown),     1, 0x8, pup_file );
  113.         }
  114.     //Read Hash Table
  115.         for(i = 0; i < pup_header->file_count; i++){
  116.             size += fread( &(pup_header->hash_table[i].file_index),  1, 0x8, pup_file ); //Read Entry_ID
  117.             //Allocate memory for file_hash and unknown¿?
  118.                 pup_header->hash_table[i].file_hash  = (char *)malloc(sizeof(char) * 0x20);
  119.                 pup_header->hash_table[i].unknown    = (char *)malloc(sizeof(char) * 0x18);
  120.                 size += fread(  (pup_header->hash_table[i].file_hash),   1, 0x20, pup_file ); //Read File Hash
  121.                 size += fread(  (pup_header->hash_table[i].unknown),     1, 0x18, pup_file ); //Read ¿UNKNOWN?
  122.         }
  123.     //Allocate memory for header_hash
  124.         pup_header->header_hash = (char *)malloc(sizeof(char) * 0x20);
  125.     //Header hash
  126.         size += fread( (pup_header->header_hash),     1, 0x20, pup_file ); //Read Header Hash
  127.  
  128.     return size;
  129. }
  130.  
  131. void pup_print_header(PUP_header *pup_header){
  132.     int i;
  133.     printf("\n\n");
  134.     printf("-> Magic 0x%llX\n", pup_header->magic); //Magic
  135.     printf("-> Package version 0x%llX\n", pup_header->package_version); //Package Version
  136.     printf("-> Image version 0x%llX\n", pup_header->image_version); //Image Version
  137.     printf("-> File count 0x%llX\n", pup_header->file_count); //File Count
  138.     printf("-> Header length 0x%llX\n", pup_header->header_length); //Header Length
  139.     printf("-> Package length 0x%llX\n", pup_header->package_length); //Package Length
  140.     printf("-> Unknown 0x%llX\n", *(u64 *)pup_header->unknown); //Unknown
  141.     printf("-> Header hash 0x%llX\n", *(u64 *)pup_header->unknown); //Header hash
  142.     //File Table and hash table
  143.         for(i = 0; i < pup_header->file_count; i++){
  144.             printf("\n-> File %i", i+1);
  145.                 printf("\n----> File table\n");
  146.                     printf("-------> Entry ID 0x%llX\n", pup_header->file_table[i].entry_ID);
  147.                     printf("-------> Data offset 0x%llX\n", pup_header->file_table[i].data_offset);
  148.                     printf("-------> Data length 0x%llX\n", pup_header->file_table[i].data_length);
  149.                     printf("-------> Unknown 0x%llX\n", pup_header->file_table[i].unknown);
  150.                 printf("----> Hash table\n");
  151.                     printf("-------> File index 0x%llX\n", pup_header->hash_table[i].file_index);
  152.                     printf("-------> File hash 0x%llX\n", *(u64 *)pup_header->hash_table[i].file_hash);
  153.                     printf("-------> Unknown 0x%llX\n", *(u64 *)pup_header->hash_table[i].unknown);
  154.         }
  155.     return;
  156. }
  157.  
  158. char *ID_to_filename(u64 entry_ID){
  159.     switch(entry_ID){
  160.         case 0x100:
  161.             return "version.txt";
  162.         case 0x101:
  163.             return "license.xml";
  164.         case 0x200:
  165.             return "psp2swu.self";
  166.         case 0x204:
  167.             return "exec_file.self";
  168.         case 0x301:
  169.             return "package_data01.pkg";
  170.         case 0x302:
  171.             return "package_data02.pkg";
  172.         case 0x303:
  173.             return "package_data03.pkg";
  174.         case 0x304:
  175.             return "package_data04.pkg";
  176.         case 0x305:
  177.             return "package_data05.pkg";
  178.         case 0x306:
  179.             return "package_data06.pkg";
  180.         case 0x307:
  181.             return "package_data07.pkg";
  182.         case 0x308:
  183.             return "package_data08.pkg";
  184.         case 0x309:
  185.             return "package_data09.pkg";
  186.         case 0x30a:
  187.             return "package_data10.pkg";
  188.         case 0x30b:
  189.             return "package_data11.pkg";
  190.         case 0x30c:
  191.             return "package_data12.pkg";
  192.         case 0x30d:
  193.             return "package_data13.pkg";
  194.         case 0x30e:
  195.             return "package_data14.pkg";
  196.         case 0x30f:
  197.             return "package_data15.pkg";
  198.         case 0x400:
  199.             return "package_scewm.wm";
  200.         case 0x401:
  201.             return "package_sceas.as";
  202.         default:
  203.             break;
  204.     }
  205.     return NULL;
  206. }
  207.  
  208. void pup_extract(PUP_header *pup_header, FILE *pup_file){
  209.     int i, j;
  210.     char *output_name;
  211.     byte buffer[512];
  212.     unsigned int data_read;
  213.     FILE *output;
  214.     for(i = 0; i < pup_header->file_count; i++){
  215.         output_name = ID_to_filename(pup_header->file_table[i].entry_ID);
  216.         if(output_name != NULL){
  217.             //Creating file...
  218.                 printf("\n\n----> Extracting file: %s", output_name);
  219.             //Set the cursor
  220.                 fseek(pup_file, pup_header->file_table[i].data_offset, SEEK_SET);
  221.             //Create output file
  222.                 output = fopen(output_name, "wb");
  223.             //Check if file is OK
  224.                 if(output == NULL){
  225.                     printf("\n-------> Could not extract the file.", output_name);
  226.                     continue;
  227.                 }
  228.             //Write
  229.                 for(j = 0; j < pup_header->file_table[i].data_length; j++){
  230.                     data_read = fread(buffer, 1, 512, pup_file);
  231.                     fwrite(buffer, 1, data_read, output);
  232.                 }
  233.             //Close
  234.                 fflush(output);
  235.                 fclose(output);
  236.             //File was successfully created
  237.                 printf("\n-------> File successfully extracted!");
  238.         }
  239.     }
  240.     return;
  241. }
RAW Paste Data