Reisyukaku

US/UM AC container unpacker

Nov 15th, 2017
523
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.09 KB | None | 0 0
  1. /*
  2. *   UnpackAC.c
  3. *       by Reisyukaku
  4. *
  5. *   Unpacks files from AC/AS container (quick and dirty).
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdint.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <malloc.h>
  13.  
  14. #if defined(_WIN32)
  15.     #include <direct.h>
  16. #else
  17.     #include <sys/stat.h>
  18. #endif
  19.    
  20. typedef uint8_t u8;
  21. typedef uint16_t u16;
  22. typedef uint32_t u32;
  23.  
  24. typedef struct{
  25.     u32 startAddr;
  26. } Entry;
  27.  
  28. typedef struct{
  29.     u16 magic;
  30.     u16 entryCnt;
  31. } Header;
  32.  
  33. void makeDir(const char* name) {
  34.    #if defined(_WIN32)
  35.         _mkdir(name);
  36.     #else
  37.         mkdir(name, 777);
  38.    #endif
  39. }
  40.  
  41. char *magicToExt(u32 magic){
  42.     if(magic == 0x4D43) return ".cm";
  43.     return ".bin";
  44. }
  45.    
  46. int main(int argc, char **argv){
  47.     u32 currPos = 0;
  48.     char currFolder[8];
  49.     char fullPath[0x20];
  50.     u8 *fileBuffer;
  51.    
  52.     if(argc != 2){
  53.         printf("Usage: %s <AS Package>\n", argv[0]);
  54.         return -1;
  55.     }
  56.    
  57.     //Open
  58.     FILE *fpIn, *fpOut;
  59.     fpIn = fopen(argv[1], "rb");
  60.     if(!fpIn){printf("File not found!\n"); return -1;}
  61.    
  62.     //Read AC header
  63.     Header acHead;
  64.     fread(&acHead, sizeof(Header), 1, fpIn);
  65.     Entry entries[acHead.entryCnt];
  66.     fread(&entries, sizeof(Entry) * (acHead.entryCnt+1), 1, fpIn);
  67.     if(acHead.magic != 0x4341 && acHead.magic != 0x5341){printf("Not and AC or AS container!\n"); goto final;}
  68.    
  69.     printf("Entries: %d\n\n", acHead.entryCnt);
  70.  
  71.     u32 i; for(i = 0; i < acHead.entryCnt; i++){
  72.         currPos = entries[i].startAddr;
  73.         fseek(fpIn, currPos, SEEK_SET);
  74.         printf("Start: %08X\n\n", currPos);
  75.        
  76.         //Read CP headers
  77.         Header cp;
  78.         fread(&cp, sizeof(Header), 1, fpIn);
  79.         Entry cpEntries[cp.entryCnt];
  80.         fread(cpEntries, sizeof(Entry) * (cp.entryCnt+1), 1, fpIn);
  81.         if(cp.magic != 0x5043 && cp.magic != 0x4D53){printf("Not CP or SM header!\n"); goto final;}
  82.         snprintf(currFolder, 8, "%08X", currPos);
  83.         makeDir(currFolder);
  84.        
  85.         printf("\tEntries: %d\n\n", cp.entryCnt);
  86.         u32 j; for(j = 0; j < cp.entryCnt; j++){
  87.             currPos = entries[i].startAddr + cpEntries[j].startAddr;
  88.             u32 endPos = entries[i].startAddr + cpEntries[j+1].startAddr;
  89.             fseek(fpIn, currPos, SEEK_SET);
  90.             printf("\tStart: %08X\n", currPos);
  91.  
  92.             //Obtain info about file
  93.             size_t size = endPos - currPos;
  94.             fileBuffer = malloc(size);
  95.             u32 fileMagic = 0;
  96.             fread(&fileMagic, 2, 1, fpIn);
  97.             fseek(fpIn, currPos, SEEK_SET);
  98.             memset(fullPath, 0, 22);
  99.             snprintf(fullPath, 0x20, "%s/%08X%s", currFolder, cpEntries[j].startAddr, magicToExt(fileMagic));
  100.             printf("\tSize: %08X\n\tPath: %s\n\n", size, fullPath);
  101.            
  102.             //Write out file
  103.             fpOut = fopen(fullPath, "wb");
  104.             fread(fileBuffer, size, 1, fpIn);
  105.             fwrite(fileBuffer, size, 1, fpOut);
  106.             fclose(fpOut);
  107.             free(fileBuffer);
  108.         }
  109.     }
  110.    
  111.     final:;
  112.     fclose(fpIn);
  113.    
  114.     return 0;
  115. }
Add Comment
Please, Sign In to add comment