forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[HELP] Error Extracting 360.PSAR

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
raing3



Joined: 09 Nov 2008
Posts: 12

PostPosted: Tue Dec 09, 2008 10:13 am    Post subject: [HELP] Error Extracting 360.PSAR Reply with quote

I am currently having trouble extracting the full contents of the 3.60 PSAR created by the 360 dumper included with Time Machine. I am using a modified version of the 5.00 3000 PSAR dumper. The application stops extracting once it gets to the point where it needs to buffer more data and displays the error 'PSAR decode error at 0x008A7826'.

I have tried using just the plain PSAR file and the PSAR packed into an updater EBOOT and this hasn't fixed the issue all official updater EBOOTs appear to extract alright. I have also tried extracting the PSAR with the original 5.00 3000 PSAR dumper and it correctly dumped the files and I have not modified libpsardumper or pspdecrypt. I have also left the PSAR buffer size at 9400000 which is the same as the original PSAR decrypter but I have tried a number of different buffer sizes, although I cannot read the whole file at once due to a lack of available RAM so I cannot increase the buffer to the full PSAR size. Lastly I have also tried disabling that particular check and using a 'less' modified version of the PSAR dumper which decrypts all the files with no success.

Assume the paramaters passed are DumpPSAR(MODE_ENCRYPT, "ms0:/360.PSAR", "ms0:/TM/360M33", "3.60", NULL);

Code:
void DumpPSAR(int extractmode, char *filepath, char *outdir, char *requiredver, char *requiredfiles[])
{
   char message[256];
   int s, res;
   u8 pbp_header[0x28];
   SceUID fd;
   int error = 0;
   int psar_pos = 0, psar_offs;
   int table_mode;

   if (sceKernelDevkitVersion() < 0x02070110){
      vlfGuiMessageDialog("PSAR Extraction requires a 2.71 or higher kernel. If you are in a Custom Firmware please re-execute this application on a higher kernel.", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
   }

   sceKernelVolatileMemLock(0, (void *)&g_dataOut2, &s);

   SetStatus(0, 0, 240, 120, VLF_ALIGNMENT_CENTER, "Loading PSAR...");

   if (ReadFile(filepath, 0, pbp_header, sizeof(pbp_header)) != sizeof(pbp_header)){
      sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog(strcat("Unable to read ", strdup(filepath)), VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
   }

   if(memcmp(pbp_header, "PSAR", 4) == 0){psar_offs = 0;}
   else{psar_offs = *(u32 *)&pbp_header[0x24];}

   fd = sceIoOpen(filepath, PSP_O_RDONLY, 0);
   
   int cbFile = sceIoLseek32(fd, 0, PSP_SEEK_END) - psar_offs;
   sceIoLseek32(fd, psar_offs, PSP_SEEK_SET);

   SetStatus(0, 1, 240, 160, VLF_ALIGNMENT_CENTER, "Buffering PSAR data...");
   if (sceIoRead(fd, g_dataPSAR, PSAR_BUFFER_SIZE) <= 0){
      sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("Error reading file", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
   }

   if (memcmp(g_dataPSAR, "PSAR", 4) != 0){
      sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("Invalid PSAR file", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;   
   }
   
   res = pspPSARInit(g_dataPSAR, g_dataOut, g_dataOut2);
   if (res < 0){
      sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("pspPSARInit failed", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
   }

   char *ver = GetVersion((char *)g_dataOut+0x10);
   if(requiredver != NULL){
      if(strcmp(ver, requiredver) != 0){
         sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("Wrong EBOOT.PBP version", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
      }
   }

   if (memcmp(ver, "3.8", 3) == 0 || memcmp(ver, "3.9", 3) == 0){table_mode = 1;}
   else if (memcmp(ver, "4.0", 3) == 0){table_mode = 2;}
   else if (memcmp(ver, "5.0", 3) == 0){table_mode = 3;}
   else{table_mode = 0;}

   SetStatus(0, 0, 240, 120, VLF_ALIGNMENT_CENTER, "Table Mode: %d", table_mode);

   while (1){
      char name[128];
      int cbExpanded;
      int pos;
      int signcheck;
      int i = 0,  filerequired = 1;

      int res = pspPSARGetNextFile(g_dataPSAR, cbFile, g_dataOut, g_dataOut2, name, &cbExpanded, &pos, &signcheck);

      if (res < 0){
         if (error){
            sprintf(message, "PSAR decode error at 0x%08X", pos);
            sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog(message, VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
         }

         int dpos = pos-psar_pos;
         psar_pos = pos;
         
         error = 1;
         memmove(g_dataPSAR, g_dataPSAR+dpos, PSAR_BUFFER_SIZE-dpos);

         SetStatus(0, 1, 240, 160, VLF_ALIGNMENT_CENTER, "Buffering PSAR data...");
         if (sceIoRead(fd, g_dataPSAR+(PSAR_BUFFER_SIZE-dpos), dpos) <= 0){
            sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("Unable to read file", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
         }

         pspPSARSetBufferPosition(psar_pos);

         continue;
      }
      else if (res == 0){ /* no more files */
         break;
      }

      if (is5Dnum(name)){
         if (strcmp(name, "00001") != 0 && strcmp(name, "00002") != 0 && strcmp(name, "00003") != 0){
            int found = 0;
            
            if (_1gtable_size > 0){found = FindTablePath(_1g_table, _1gtable_size, name, name);}

            if (!found && _2gtable_size > 0){found = FindTablePath(_2g_table, _2gtable_size, name, name);}
            if (!found && _3gtable_size > 0){found = FindTablePath(_3g_table, _3gtable_size, name, name);}
            if (!found){
               SetStatus(0, 0, 240, 120, VLF_ALIGNMENT_CENTER, "Warning: cannot find path of %s", name);
               error = 0;
               continue;
            }
         }
      }
      else if (!strncmp(name, "com:", 4) && comtable_size > 0){
         if (!FindTablePath(com_table, comtable_size, name+4, name)){
            SetStatus(0, 0, 240, 120, VLF_ALIGNMENT_CENTER, "Warning: cannot find path of %s", name);
            error = 0;
            continue;
         }
      }

      else if (!strncmp(name, "01g:", 4) && _1gtable_size > 0){
         if (!FindTablePath(_1g_table, _1gtable_size, name+4, name)){
            sprintf(message, "Cannot find path of %s", name);
            sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog(message, VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
         }
      }

      else if (!strncmp(name, "02g:", 4) && _2gtable_size > 0){
         if (!FindTablePath(_2g_table, _2gtable_size, name+4, name)){
            sprintf(message, "Cannot find path of %s", name);
            sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog(message, VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
         }
      }

      if(requiredfiles == NULL){filerequired = 1;}
      else{
         filerequired = 0;
         i = 0;
         while(i != -1){
            if(strcmp(name, requiredfiles[i]) == 0){filerequired = 1;i = -2;}
            i++;
            if(strcmp(requiredfiles[i], "0") == 0){i = -1;}
         }
      }
      if(filerequired == 1){SetStatus(0, 0, 240, 120, VLF_ALIGNMENT_CENTER, "%s", name);}

      char* szFileBase = strrchr(name, '/');
      
      if (szFileBase != NULL)
         szFileBase++;  // after slash
      else
         szFileBase = "err.err";

      if (cbExpanded > 0){
         char szDataPath[128];
         
         if (!strncmp(name, "flash0:/", 8)){sprintf(szDataPath, "%s/%s", outdir, name+8);}
         else if (!strncmp(name, "flash1:/", 8)){sprintf(szDataPath, "%s/%s", outdir, name+8);}
         else if (!strcmp(name, "com:00000")){
            comtable_size = pspDecryptTable(g_dataOut2, g_dataOut, cbExpanded, table_mode);
                     
            if (comtable_size <= 0){
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("Cannot decrypt common table", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
            }

            if (comtable_size > sizeof(com_table)){
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("COM table buffer is too small", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
            }

            memcpy(com_table, g_dataOut2, comtable_size);
            continue;
         }   
         else if (!strcmp(name, "01g:00000") || !strcmp(name, "00001")){
            _1gtable_size = pspDecryptTable(g_dataOut2, g_dataOut, cbExpanded, table_mode);
                     
            if (_1gtable_size <= 0){
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("Cannot decrypt 1g table", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
            }

            if (_1gtable_size > sizeof(_1g_table)){
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("1g table buffer is too small", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
            }

            memcpy(_1g_table, g_dataOut2, _1gtable_size);
            continue;
         }   
         else if (!strcmp(name, "02g:00000") || !strcmp(name, "00002")){
            _2gtable_size = pspDecryptTable(g_dataOut2, g_dataOut, cbExpanded, table_mode);
                     
            if (_2gtable_size <= 0){
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("Cannot decrypt 2g table", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
            }

            if (_2gtable_size > sizeof(_2g_table)){
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("2g table buffer is too small", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
            }

            memcpy(_2g_table, g_dataOut2, _2gtable_size);
            continue;
         }
         else if (!strcmp(name, "00003")){
            _3gtable_size = pspDecryptTable(g_dataOut2, g_dataOut, cbExpanded, table_mode);
                     
            if (_3gtable_size <= 0){
               // We don't have yet the keys for table of 3000, they are only in mesg_led03g.prx
               SetStatus(0, 0, 240, 120, VLF_ALIGNMENT_CENTER, "Cannot decrypt 3g table");
               error = 0;
               continue;
            }

            if (_3gtable_size > sizeof(_3g_table)){
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("3g table buffer is too small", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
            }

            memcpy(_3g_table, g_dataOut2, _3gtable_size);
            continue;
         }
         else{continue;}

         if (signcheck && extractmode == MODE_ENCRYPT_SIGCHECK && (strcmp(name, "flash0:/kd/loadexec.prx") != 0) && (strcmp(name, "flash0:/kd/loadexec_01g.prx") != 0) && (strcmp(name, "flash0:/kd/loadexec_02g.prx") != 0)){
            pspSignCheck(g_dataOut2);
         }

         if ((extractmode != MODE_DECRYPT) || (memcmp(g_dataOut2, "~PSP", 4) != 0)){            
            if (WriteFile(szDataPath, g_dataOut2, cbExpanded) != cbExpanded){
               sprintf(message, "Cannot write %s", szDataPath);
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog(message, VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
               break;
            }
         }

         if ((memcmp(g_dataOut2, "~PSP", 4) == 0) &&   (extractmode == MODE_DECRYPT)){
            int cbDecrypted = pspDecryptPRX(g_dataOut2, g_dataOut, cbExpanded);

            // output goes back to main buffer
            // trashed 'g_dataOut2'
            if (cbDecrypted > 0){
               u8* pbToSave = g_dataOut;
               int cbToSave = cbDecrypted;
                           
               if ((g_dataOut[0] == 0x1F && g_dataOut[1] == 0x8B) || memcmp(g_dataOut, "2RLZ", 4) == 0 || memcmp(g_dataOut, "KL4E", 4) == 0){
                  int cbExp = pspDecompress(g_dataOut, g_dataOut2, sizeof(g_dataOut));
                  
                  if (cbExp > 0){
                     pbToSave = g_dataOut2;
                     cbToSave = cbExp;
                  }
                  else{
                     SetStatus(0, 0, 240, 120, VLF_ALIGNMENT_CENTER, "Decompress error 0x%08X\n\nFile will be written compressed", cbExp);
                  }
               }
                 
               if (WriteFile(szDataPath, pbToSave, cbToSave) != cbToSave){
                  sprintf(message, "Cannot write %s", szDataPath);
                  sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog(message, VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
               }
            }
            else
            {
               sceKernelVolatileMemUnlock(0);vlfGuiMessageDialog("Unable to decrypt file", VLF_MD_TYPE_ERROR|VLF_MD_BUTTONS_NONE);OnBackToMainMenu(0);return;
            }
         }
      }

      error = 0;
      scePowerTick(0);   
   }

   sceIoClose(fd);

    scePowerTick(0);   
   SetStatus(1, 0, 240, 120, VLF_ALIGNMENT_CENTER, "PSAR file has been extracted to %s", outdir);

    return 0;
}


I am also having an issue when I extract the 4.01 PSAR the 'dmacman.prx' module is being created but by the time the whole PSAR is extracted the file has been deleted. I think what is causing this issue is that the directories are created just before the file is created because this is not an issue when I create the folders manually at the start of the PSAR extraction. I have not tested any other updater EBOOTs but the only file which is deleted is 'dmacman.prx' and I know this file is being created.

Code:
int WriteFile(char *file, void *buf, int size)
{
   SceUID fd;   
   int i;
   int pathlen = 0;
   char filepath[128];

   for(i=1; i<(strlen(file)); i++){
      if(strncmp(file+i-1, "/", 1) == 0){
         pathlen=i-1;
         strncpy(filepath, file, pathlen);
         filepath[pathlen] = 0;

         sceIoMkdir(filepath, 0777);
      }
   }
   

   fd = sceIoOpen(file, PSP_O_WRONLY|PSP_O_CREAT|PSP_O_TRUNC, 0777);
   if(fd < 0){return fd;}

   int written = sceIoWrite(fd, buf, size);

   sceIoClose(fd);
   return written;
}


The full project can be downloaded from http://ifile.it/o2aztsy. Keep in mind that I'm still trying to fix other issues and a number of features do not work also their are a number of other minor issues with the PSAR extraction which I have encountered which are caused if I do PSAR extraction multiple times without restarting and if I do not call sceKernelVolatileMemUnlock(0); the VLF messages and other stuff doesn't work. Any help in fixing the issues would be greatly appreciated I've spent so many hours trying to figure out what is wrong and I'm sure some of you pros will be able to find out what the problem is in a couple of minutes.
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group