Advertisement
patrickvogt

PSX-EXEFIXUP

May 3rd, 2013
524
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.08 KB | None | 0 0
  1. /*
  2.  * exefixup.c v0.02 Andrew Kieschnick <andrewk@mail.utexas.edu>
  3.  *
  4.  * displays PS-X EXE header information
  5.  * offers to fix incorrect t_size
  6.  * offers to pad to 2048-byte boundary for cd-rom use
  7.  *
  8.  * THIS SOURCE WAS MODIFIED (SLIGHTLY) TO WORK UNDER DOS
  9.  * IF YOU USE UNIX, GET THE THE UNMODIFIED SOURCE
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  *
  25.  */
  26. /* CHANGES by Patrick Vogt (2012-12-16):                
  27.  * -Modified to be compatible with the latest gcc
  28.  * -Added an outfilename for the fixed/padded file
  29.  * -Remove question to always fix/pad
  30.  * -commented a bit
  31.  */
  32.  
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <ctype.h>
  36. #include <stdlib.h>
  37.  
  38. /* converts four chars into one int */
  39. unsigned int char2int(unsigned char *foo)
  40. {
  41.   return foo[3]*16777216 + foo[2]*65536 + foo[1]*256 + foo[0];
  42. }
  43.  
  44. /* converts one given int into four chars */
  45. void int2char(unsigned int foo, unsigned char *bar)
  46. {
  47.   bar[3]=foo>>24;
  48.   bar[2]=foo>>16;
  49.   bar[1]=foo>>8;
  50.   bar[0]=foo;
  51. }
  52.  
  53. /* prints the usage of the exefixup tool */
  54. void usage(void)
  55. {
  56.   (void) printf("Usage: exefixup <infilename> <outfilename>\n\n");
  57.   (void) printf("\t<infilename>\ta PS-X EXE file\n\n");
  58.   (void) printf("\t<outfilename>\ta PS-X EXE file\n\n");
  59.   (void) printf("\tdisplays EXE header\n");
  60.   (void) printf("\toffers to correct a wrong t_size\n");
  61.   (void) printf("\toffers to pad to 2048-byte boundary\n\n");
  62.  
  63.   exit(0);
  64. }
  65.  
  66. int main(int argc, char *argv[])
  67. {
  68.   FILE *exe;
  69.   FILE *out;
  70.   unsigned char data[8];
  71.   char infilename[256];
  72.   char outfilename[256];
  73.   int i;
  74.   unsigned int header_data[12];
  75.   unsigned int size;
  76.   unsigned int padsize;
  77.  
  78.   /* usage correct? */
  79.   if(argc!=3)
  80.   {
  81.     usage();
  82.   }
  83.  
  84.   (void) strncpy(infilename, argv[1], 256);
  85.   (void) strncpy(outfilename, argv[2], 256);
  86.  
  87.   /* open psx file */
  88.   exe=fopen(infilename, "rb");
  89.  
  90.   (void) printf("\n\n");
  91.  
  92.   if(NULL==exe)
  93.   {
  94.     /* could not open file */
  95.     (void) printf("ERROR: Can't open %s\n",infilename);
  96.     exit(-1);
  97.   }
  98.  
  99.   for(i=0; i<8; i=i+1)
  100.   {
  101.     (void) fscanf(exe, "%c", &data[i]);
  102.   }
  103.   data[8]='\0';
  104.  
  105.   /* valid psx exe file? */
  106.   if(0!=strncmp((const char *)data, "PS-X EXE", 8))
  107.   {
  108.     /* not a valid psx file! */
  109.     (void) printf("ERROR: Not a PS-X EXE file\n");
  110.     exit(-1);
  111.   }
  112.  
  113.   /* read header */
  114.   for(i=0; i<12; i=i+1)
  115.   {
  116.     (void) fscanf(exe, "%c", &data[0]);
  117.     (void) fscanf(exe, "%c", &data[1]);
  118.     (void) fscanf(exe, "%c", &data[2]);
  119.     (void) fscanf(exe, "%c", &data[3]);
  120.     header_data[i]=char2int(data);
  121.   }
  122.  
  123.   /* print header */
  124.   (void) printf("id\tPS-X EXE\n");
  125.   (void) printf("text\t0x%.8x\n", header_data[0]);
  126.   (void) printf("data\t0x%.8x\n", header_data[1]);
  127.   (void) printf("pc0\t0x%.8x\n", header_data[2]);
  128.   (void) printf("gp0\t0x%.8x\n", header_data[3]);
  129.   (void) printf("t_addr\t0x%.8x\n", header_data[4]);
  130.   (void) printf("t_size\t0x%.8x\n", header_data[5]);
  131.   (void) printf("d_addr\t0x%.8x\n", header_data[6]);
  132.   (void) printf("d_size\t0x%.8x\n", header_data[7]);
  133.   (void) printf("b_addr\t0x%.8x\n", header_data[8]);
  134.   (void) printf("b_size\t0x%.8x\n", header_data[9]);
  135.   (void) printf("s_addr\t0x%.8x\n", header_data[10]);
  136.   (void) printf("s_size\t0x%.8x\n\n", header_data[11]);
  137.  
  138.   /* go to the end of the psx exe file */
  139.   (void) fseek(exe, 0, SEEK_END);
  140.  
  141.   size=ftell(exe)-2048;
  142.  
  143.   /* check if filesoze is a multiple of 2048 */
  144.   padsize=2048-(size%2048);
  145.   if(padsize!=2048)
  146.   {
  147.     /* filesize is not a multiple of 2048 */
  148.     (void) printf("WARNING: EXE size is not a multiple of 2048! I'll fix that for you.\n");
  149.    
  150.     out = fopen(outfilename, "wb");
  151.    
  152.     header_data[5]=size+padsize;
  153.  
  154.     (void) fprintf(out, "PS-X EXE");
  155.    
  156.     for(i=0; i<12; i=i+1)
  157.     {
  158.       int2char(header_data[i], data);
  159.       (void) fprintf(out, "%c%c%c%c", data[0], data[1], data[2], data[3]);
  160.     }
  161.  
  162.     (void) fseek(exe, 56, SEEK_SET);
  163.  
  164.     for(i=0; i<size+1992; i=i+1)
  165.     {
  166.       (void) fscanf(exe, "%c", &data[0]);
  167.       (void) fprintf(out, "%c", data[0]);
  168.     }
  169.    
  170.     /* fill the rest of the file with zeros */
  171.     for(i=0; i<padsize; i++)
  172.     {
  173.       (void) fprintf(out, "%c", 0);
  174.     }
  175.    
  176.     size=header_data[5];
  177.     (void) fclose(out);
  178.   }
  179.  
  180.   /* is size in header correct? */
  181.   if(size!=header_data[5])
  182.   {
  183.     (void) printf("WARNING: EXE header t_size does not match filesize-2048\n");
  184.     (void) printf("EXE header:\t 0x%.8x bytes\n", header_data[5]);
  185.     (void) printf("filesize-2048:\t 0x%.8x bytes\n", size);
  186.  
  187.     out = fopen(outfilename, "wb");
  188.  
  189.     (void) fprintf(out, "PS-X EXE");
  190.    
  191.     /*write header till size */
  192.     for(i=0; i<5; i=i+1)
  193.     {
  194.       int2char(header_data[i], data);
  195.       (void) fprintf(out, "%c%c%c%c", data[0], data[1], data[2], data[3]);
  196.     }
  197.  
  198.     /* write correct size */
  199.     int2char(size, data);
  200.     (void) fprintf(out, "%c%c%c%c", data[0], data[1], data[2], data[3]);
  201.    
  202.     /* write header after size */
  203.     for(i=6; i<12; i=i+1)
  204.     {
  205.       int2char(header_data[i], data);
  206.       (void) fprintf(out, "%c%c%c%c", data[0], data[1], data[2], data[3]);
  207.     }
  208.  
  209.     /* jump to real data */
  210.     (void) fseek(exe, 56, SEEK_SET);
  211.  
  212.     /* copy the rest of the file */
  213.     for(i=0; i<size+1992; i=i+1)
  214.     {
  215.       (void) fscanf(exe, "%c", &data[0]);
  216.       (void) fprintf(out, "%c", data[0]);
  217.     }
  218.    
  219.     (void) fclose(out);
  220.  
  221.   }
  222.  
  223.   (void) fclose(exe);
  224.  
  225.   return EXIT_SUCCESS;
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement