Advertisement
Guest User

ps4pupextractor v1 by xerpi

a guest
Oct 29th, 2013
416
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.02 KB | None | 0 0
  1. // Copyright (c) 2013   xerpi
  2.  
  3. /*
  4.    Fast and simple PS4 PUP extractor
  5.    Thanks to SKFU for the PUP information analysis
  6.    Version 1, may have lots of bugs (coded fast)
  7.    I'm not even sure this will work on Big Endian machines...
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <stdint.h>
  13. #include <string.h>
  14.  
  15. #define PS4_PUP_MAGIC             0x32424C53 //Little endian
  16. #define PS4_PUP_HEADER_SIZE       512
  17. #define PS4_PUP_HEADER_INFO_SIZE  32 //Until PUP entries
  18. #define PS4_PUP_ENTRY_SIZE        48 //PUP entry size
  19.  
  20. struct ps4pup_pup_info {
  21.     uint32_t offset;
  22.     uint32_t content_size;
  23.     uint64_t reserved;
  24.     uint8_t  filename[32];
  25. } __attribute__((packed));
  26.  
  27. struct ps4pup_header {
  28.     uint32_t magic;
  29.     uint64_t version;
  30.     uint32_t file_count;
  31.     uint32_t block_count;
  32.     uint8_t  reserved1[12];
  33.     struct ps4pup_pup_info *pups;
  34.     uint8_t  reserved2[288];
  35. } __attribute__((packed));
  36.  
  37.  
  38. int  ps4pup_read_header(FILE *fd, struct ps4pup_header *header);
  39. void ps4pup_free_header(struct ps4pup_header *header);
  40. int  ps4pup_extract(FILE *fd, struct ps4pup_header *header);
  41. void ps4pup_print_header(const struct ps4pup_header *header);
  42.  
  43. void print_usage(void);
  44.  
  45. int main (int argc, char *argv[])
  46. {
  47.     if (argc < 2) {
  48.         print_usage();
  49.         goto exit_error;
  50.     }
  51.    
  52.     FILE *fd;
  53.     if ((fd = fopen(argv[1], "rb")) == NULL ) {
  54.         printf ("Could not open %s\n", argv[1]);
  55.         goto exit_close;
  56.     }
  57.    
  58.     struct ps4pup_header h;
  59.    
  60.     if (!ps4pup_read_header(fd, &h)) {
  61.         printf("Error reading PUP file\n");
  62.         goto exit_close;
  63.     }
  64.    
  65.     ps4pup_print_header(&h);
  66.    
  67.     printf("\nExtracting PUP files...\n");
  68.    
  69.     if (!ps4pup_extract(fd, &h)) {
  70.         printf("Error extracting PUP files\n");
  71.         ps4pup_free_header(&h);
  72.         goto exit_close;
  73.     }
  74.    
  75.     printf("Done!\n");
  76.    
  77.    
  78.     ps4pup_free_header(&h);
  79.     return 1;
  80.    
  81.    
  82. exit_close:
  83.     fclose(fd);
  84. exit_error:
  85.     return EXIT_FAILURE;
  86. }
  87.  
  88. int ps4pup_read_header(FILE *fd, struct ps4pup_header *header)
  89. {
  90.     if (fd == NULL || header == NULL) {
  91.         return 0;
  92.     }
  93.    
  94.     fseek(fd, 0, SEEK_SET);
  95.     fread((void*)header, 1, PS4_PUP_HEADER_INFO_SIZE, fd);
  96.    
  97.     if (header->magic != PS4_PUP_MAGIC) {
  98.         printf("This is not a PUP file!\n");
  99.         return 0;
  100.     }
  101.    
  102.     header->pups = malloc (header->file_count * sizeof(struct ps4pup_pup_info));
  103.    
  104.     int i;
  105.     for (i = 0; i < header->file_count; ++i) {
  106.         fread((void*)&header->pups[i], 1, PS4_PUP_ENTRY_SIZE, fd);
  107.     }
  108.    
  109.     return 1;
  110. }
  111.  
  112.  
  113. void ps4pup_free_header(struct ps4pup_header *header)
  114. {  
  115.     if (header) {
  116.         if (header->pups) {
  117.             free(header->pups);
  118.         }
  119.     }
  120. }
  121.  
  122. int ps4pup_extract(FILE *fd, struct ps4pup_header *header)
  123. {
  124.     if (fd == NULL || header == NULL) {
  125.         return 0;
  126.     }
  127.    
  128.     FILE *pup_out;
  129.     uint8_t copy_buffer[512];
  130.    
  131.     int i;
  132.     for (i = 0; i < header->file_count; ++i) {
  133.         fseek(fd, PS4_PUP_HEADER_SIZE + header->pups[i].offset, SEEK_SET);
  134.         pup_out = fopen(header->pups[i].filename, "wb");
  135.         int copy_size = header->pups[i].content_size;
  136.        
  137.         while (copy_size > 0) {
  138.             if (copy_size > 512) {
  139.                 fread(copy_buffer, 1, 512, fd);
  140.                 fwrite(copy_buffer, 1, 512, pup_out);
  141.                 copy_size -= 512;
  142.             } else {
  143.                 fread(copy_buffer, 1, copy_size, fd);
  144.                 fwrite(copy_buffer, 1, copy_size, pup_out);
  145.                 copy_size = 0; 
  146.             }
  147.         }
  148.         fflush(pup_out);
  149.         fclose(pup_out);
  150.     }  
  151.    
  152.    
  153.     return 1;  
  154. }
  155.  
  156. void ps4pup_print_header(const struct ps4pup_header *header)
  157. {
  158.     char magic_string[5];
  159.     strncpy(magic_string, (char*)(uintptr_t)(&header->magic), 4);
  160.     magic_string[4] = '\0';
  161.     printf("Magic:      0x%X  %s\n", header->magic, magic_string);
  162.     printf("Version:    %lu\n", header->version);
  163.     printf("File count: %i\n", header->file_count);
  164.    
  165.     int i;
  166.     for (i = 0; i < header->file_count; ++i) {
  167.         printf("PUP %i:\n", i+1);
  168.         printf("  Offset:   0x%X\n", header->pups[i].offset);
  169.         printf("  Size:     %i\n", header->pups[i].content_size);
  170.         printf("  Filename: %s\n", header->pups[i].filename);
  171.        
  172.     }
  173. }
  174.  
  175. void print_usage(void)
  176. {  
  177.     printf("Usage:\nps4pupextractor <PS4UPDATE.PUP>\n");
  178.     printf("It will extract the PUPs as: PS4UPDATEX.PUP being X the PUP number\n");
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement