wget http://ftp.netbsd.org/pub/pkgsrc/distfiles/applyppf3_src.zip
unzip applyppf3_src.zip
sudo apt install gcc
gcc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -o applyppf applyppf3_linux.c
# Si vous l'avez installé dans le système via un paquet
applyppf a dir-game/game.bin dir-patch/patch.ppf
# Si vous êtes dans le dossier de la compilation
./applyppf a dir-game/game.bin dir-patch/patch.ppf
/*
 *     ApplyPPF3.c (Linux Version)
 *     written by Icarus/Paradox
 *
 *     Big Endian support by Hu Kares.
 *
 *     Applies PPF1.0, PPF2.0 & PPF3.0 Patches (including PPF3.0 Undo support)
 *     Feel free to use this source in and for your own
 *     programms.
 *
 *     To compile enter:
 *     gcc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE applyppf3_linux.c
 * 
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(__APPLE__) || defined (MACOSX)
//////////////////////////////////////////////////////////////////////
// fseeko is already 64 bit for Darwin/MacOS X!
// fseeko64 undefined for Darwin/MacOS X!
#define   fseeko64      fseeko
//////////////////////////////////////////////////////////////////////
// ftellko is already 64 bit for Darwin/MacOS X!
// ftello64 undefined for Darwin/MacOS X!
#define   ftello64      ftello
//////////////////////////////////////////////////////////////////////
// "off_t" is already 64 bit for Darwin/MacOS X!
// "__off64_t" undefined for Darwin/MacOS X!
typedef   off_t         __off64_t;
#endif /* __APPLE__ || MACOSX */
//////////////////////////////////////////////////////////////////////
// Macros for little to big Endian conversion.
#ifdef __BIG_ENDIAN__
#define Endian16_Swap(value)   (value = (((((unsigned short) value) << 8) & 0xFF00)  | \
                                          ((((unsigned short) value) >> 8) & 0x00FF)))
#define Endian32_Swap(value)    (value = (((((unsigned long) value) << 24) & 0xFF000000)  | \
                                          ((((unsigned long) value) <<  8) & 0x00FF0000)  | \
                                          ((((unsigned long) value) >>  8) & 0x0000FF00)  | \
                                          ((((unsigned long) value) >> 24) & 0x000000FF)))
#define Endian64_Swap(value)   (value = (((((unsigned long long) value) << 56) & 0xFF00000000000000ULL)  | \
                                          ((((unsigned long long) value) << 40) & 0x00FF000000000000ULL)  | \
                                          ((((unsigned long long) value) << 24) & 0x0000FF0000000000ULL)  | \
                                          ((((unsigned long long) value) <<  8) & 0x000000FF00000000ULL)  | \
                                          ((((unsigned long long) value) >>  8) & 0x00000000FF000000ULL)  | \
                                          ((((unsigned long long) value) >> 24) & 0x0000000000FF0000ULL)  | \
                                          ((((unsigned long long) value) >> 40) & 0x000000000000FF00ULL)  | \
                                          ((((unsigned long long) value) >> 56) & 0x00000000000000FFULL)))
#else
#define   Endian16_Swap(value)
#define   Endian32_Swap(value)
#define   Endian64_Swap(value)
#endif /* __BIG_ENDIAN__ */
//////////////////////////////////////////////////////////////////////
// Used global variables.
FILE *ppf, *bin;
char binblock[1024], ppfblock[1024];
unsigned char ppfmem[512];
#define APPLY 1
#define UNDO 2
//////////////////////////////////////////////////////////////////////
// Used prototypes.
int   PPFVersion(FILE *ppf);
int   OpenFiles(char* file1, char* file2);
int   ShowFileId(FILE *ppf, int ppfver);
void   ApplyPPF1Patch(FILE *ppf, FILE *bin);
void   ApplyPPF2Patch(FILE *ppf, FILE *bin);
void   ApplyPPF3Patch(FILE *ppf, FILE *bin, char mode);
int main(int argc, char **argv){
   int x;
   printf("ApplyPPF v3.0 by =Icarus/Paradox= %s\n", __DATE__);
#ifdef __BIG_ENDIAN__
        printf("Big Endian support by =Hu Kares=\n\n");         // <Hu Kares> sum credz
#endif /* __BIG_ENDIAN__ */        
   if(argc!=4){
      printf("Usage: ApplyPPF <command> <binfile> <patchfile>\n");
      printf("<Commands>\n");
      printf("  a : apply PPF1/2/3 patch\n");
      printf("  u : undo patch (PPF3 only)\n");
      printf("\nExample: ApplyPPF.exe a game.bin patch.ppf\n");
      return(0);
   }
   switch(*argv[1]){
         case 'a'   :   if(OpenFiles(argv[2], argv[3])) return(0);
                     x=PPFVersion(ppf);
                     if(x){
                        if(x==1){ ApplyPPF1Patch(ppf, bin); break; }
                        if(x==2){ ApplyPPF2Patch(ppf, bin); break; }
                        if(x==3){ ApplyPPF3Patch(ppf, bin, APPLY); break; }
                     } else{ break; }
                     break;
         case 'u'   :   if(OpenFiles(argv[2], argv[3])) return(0);
                     x=PPFVersion(ppf);
                     if(x){
                        if(x!=3){
                           printf("Undo function is supported by PPF3.0 only\n");
                        } else {
                           ApplyPPF3Patch(ppf, bin, UNDO);
                        }
                     } else{ break; }
                     break;
         default      :
                     printf("Error: unknown command: \"%s\"\n",argv[1]);
                     return(0);
                     break;
   }
   fclose(bin);
   fclose(ppf);
   return(0);
}
//////////////////////////////////////////////////////////////////////
// Applies a PPF1.0 patch.
void ApplyPPF1Patch(FILE *ppf, FILE *bin){
   char desc[50];
   int pos;
   unsigned int count, seekpos;
   unsigned char anz;
   fseeko64(ppf, 6,SEEK_SET);  /* Read Desc.line */
   fread(&desc, 1, 50, ppf); desc[50]=0;
   printf("Patchfile is a PPF1.0 patch. Patch Information:\n");
   printf("Description : %s\n",desc);
   printf("File_id.diz : no\n");
   printf("Patching... "); fflush(stdout);
   fseeko64(ppf, 0, SEEK_END);
   count=ftell(ppf);
   count-=56;
   seekpos=56;
   printf("Patching ... ");
   do{
      printf("reading...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
      fseeko64(ppf, seekpos, SEEK_SET);
      fread(&pos, 1, 4, ppf);
                Endian32_Swap (pos);         // <Hu Kares> little to big endian
      fread(&anz, 1, 1, ppf);
      fread(&ppfmem, 1, anz, ppf);
      fseeko64(bin, pos, SEEK_SET);
      printf("writing...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
      fwrite(&ppfmem, 1, anz, bin);
      seekpos=seekpos+5+anz;
      count=count-5-anz;
   } while(count!=0);
   printf("successful.\n");
}
//////////////////////////////////////////////////////////////////////
// Applies a PPF2.0 patch.
void ApplyPPF2Patch(FILE *ppf, FILE *bin){
      char desc[50], in;
      unsigned int binlen, obinlen, count, seekpos;
      int idlen, pos;
      unsigned char anz;
      fseeko64(ppf, 6,SEEK_SET);
      fread(&desc, 1, 50, ppf); desc[50]=0;
      printf("Patchfile is a PPF2.0 patch. Patch Information:\n");
      printf("Description : %s\n",desc);
      printf("File_id.diz : ");
      idlen=ShowFileId(ppf, 2);
      if(!idlen) printf("not available\n");
      fseeko64(ppf, 56, SEEK_SET);
      fread(&obinlen, 1, 4, ppf);
                Endian32_Swap (obinlen);      // <Hu Kares> little to big endian
        fseeko64(bin, 0, SEEK_END);
        binlen=ftell(bin);
        if(obinlen!=binlen){
         printf("The size of the bin file isn't correct, continue ? (y/n): "); fflush(stdout);
         in=getc(stdin);
         if(in!='y'&&in!='Y'){
            printf("Aborted...\n");
            return;
         }
      }
      fflush(stdin);
      fseeko64(ppf, 60, SEEK_SET);
      fread(&ppfblock, 1, 1024, ppf);
      fseeko64(bin, 0x9320, SEEK_SET);
      fread(&binblock, 1, 1024, bin);
      in=memcmp(ppfblock, binblock, 1024);
      if(in!=0){
         printf("Binblock/Patchvalidation failed. continue ? (y/n): "); fflush(stdout);
#if defined(__APPLE__) || defined (MACOSX)
                        if(obinlen!=binlen) {      // <Hu Kares> required, since fflush doesn't flush '\n'!
                            in=getc(stdin);
                        }
#endif /* __APPLE__ || MACOSX */
         in=getc(stdin);
         if(in!='y'&&in!='Y'){
            printf("Aborted...\n");
            return;
         }
      }
      printf("Patching... "); fflush(stdout);
      fseeko64(ppf, 0, SEEK_END);
      count=ftell(ppf);
      seekpos=1084;
      count-=1084;
      if(idlen) count-=idlen+38;
        do{
         printf("reading...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
         fseeko64(ppf, seekpos, SEEK_SET);
         fread(&pos, 1, 4, ppf);
                        Endian32_Swap (pos);      // <Hu Kares> little to big endian
         fread(&anz, 1, 1, ppf);
         fread(&ppfmem, 1, anz, ppf);
         fseeko64(bin, pos, SEEK_SET);
         printf("writing...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
         fwrite(&ppfmem, 1, anz, bin);
         seekpos=seekpos+5+anz;
         count=count-5-anz;
        } while(count!=0);
      printf("successful.\n");
}
//////////////////////////////////////////////////////////////////////
// Applies a PPF3.0 patch.
void ApplyPPF3Patch(FILE *ppf, FILE *bin, char mode){
   char desc[50], imagetype=0, in;
        unsigned char   undo=0, blockcheck=0;
   int idlen;
   __off64_t offset, count;         // <Hu Kares> count has to be 64 bit!
   unsigned int seekpos;
   unsigned char anz=0;
   fseeko64(ppf, 6,SEEK_SET);  /* Read Desc.line */
   fread(&desc, 1, 50, ppf); desc[50]=0;
   printf("Patchfile is a PPF3.0 patch. Patch Information:\n");
   printf("Description : %s\n",desc);
   printf("File_id.diz : ");
   idlen=ShowFileId(ppf, 3);
   if(!idlen) printf("not available\n");
   fseeko64(ppf, 56, SEEK_SET);
   fread(&imagetype, 1, 1, ppf);
   fseeko64(ppf, 57, SEEK_SET);
   fread(&blockcheck, 1, 1, ppf);
   fseeko64(ppf, 58, SEEK_SET);
   fread(&undo, 1, 1, ppf);
   if(mode==UNDO){
      if(!undo){
         printf("Error: no undo data available\n");
         return;
      }
   }
   if(blockcheck){
      fflush(stdin);
      fseeko64(ppf, 60, SEEK_SET);
      fread(&ppfblock, 1, 1024, ppf);
      if(imagetype){
         fseeko64(bin, 0x80A0, SEEK_SET);
      } else {
         fseeko64(bin, 0x9320, SEEK_SET);
      }
      fread(&binblock, 1, 1024, bin);
      in=memcmp(ppfblock, binblock, 1024);
      if(in!=0){
         printf("Binblock/Patchvalidation failed. continue ? (y/n): "); fflush(stdout);
         in=getc(stdin);
         if(in!='y'&&in!='Y'){
            printf("Aborted...\n");
            return;
         }
      }
   }
   fseeko64(ppf, 0, SEEK_END);
   count=ftello64(ppf);            // <Hu Kares> 64 bit!
   fseeko64(ppf, 0, SEEK_SET);
   
   if(blockcheck){
      seekpos=1084;
      count-=1084;
   } else {
      seekpos=60;
      count-=60;
   }
   if(idlen) count-=(idlen+18+16+2);
   
   printf("Patching ... ");
   fseeko64(ppf, seekpos, SEEK_SET);
   do{
      printf("reading...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
      fread(&offset, 1, 8, ppf);
                Endian64_Swap(offset);         // <Hu Kares> little to big endian
      fread(&anz, 1, 1, ppf);
      if(mode==APPLY){
         fread(&ppfmem, 1, anz, ppf);
         if(undo) fseeko64(ppf, anz, SEEK_CUR);
      }
                else {
                    if(mode==UNDO){
                            fseeko64(ppf, anz, SEEK_CUR);
                            fread(&ppfmem, 1, anz, ppf);
                    }
                }
    
      printf("writing...\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);      
      fseeko64(bin, offset, SEEK_SET);
      fwrite(&ppfmem, 1, anz, bin);
      count-=(anz+9);
      if(undo) count-=anz;
   } while(count!=0);
      printf("successful.\n");
}
//////////////////////////////////////////////////////////////////////
// Shows File_Id.diz of a PPF2.0 / PPF3.0 patch.
// Input: 2 = PPF2.0
// Input: 3 = PPF3.0
// Return 0 = Error/no fileid.
// Return>0 = Length of fileid.
int ShowFileId(FILE *ppf, int ppfver){
   char buffer2[3073];
   unsigned int idmagic;
   int lenidx=0, idlen=0, orglen=0;
   if(ppfver==2){
      lenidx=4;
   } else {
      lenidx=2;
   }
   fseeko64(ppf,-(lenidx+4),SEEK_END);
   fread(&idmagic, 1, 4, ppf);
        Endian32_Swap (idmagic);         // <Hu Kares> little to big endian
   if(idmagic!='ZID.'){
      return(0);
   } else {
      fseeko64(ppf,-lenidx,SEEK_END);
      fread(&idlen, 1, lenidx, ppf);
                Endian32_Swap (idlen);         // <Hu Kares> little to big endian
                orglen = idlen;
                if (idlen > 3072) {         // <Hu Kares> to be secure: avoid segmentation fault!
                    idlen = 3072;
                }
      fseeko64(ppf,-(lenidx+16+idlen),SEEK_END);
      fread(&buffer2, 1, idlen, ppf);
      buffer2[idlen]=0;
      printf("available\n%s\n",buffer2);
   }
   return(orglen);
}
//////////////////////////////////////////////////////////////////////
// Check what PPF version we have.
// Return: 0 - File is no PPF.
// Return: 1 - File is a PPF1.0
// Return: 2 - File is a PPF2.0
// Return: 3 - File is a PPF3.0
int PPFVersion(FILE *ppf){
   unsigned int magic;
   fseeko64(ppf,0,SEEK_SET);
   fread(&magic, 1, 4, ppf);
        Endian32_Swap (magic);            // <Hu Kares> little to big endian
   switch(magic){
         case '1FPP'      :   return(1);
         case '2FPP'      :   return(2);
         case '3FPP'      :   return(3);
         default         :   printf("Error: patchfile is no ppf patch\n"); break;
   }
   return(0);
}
//////////////////////////////////////////////////////////////////////
// Open all needed files.
// Return: 0 - Successful
// Return: 1 - Failed.
int OpenFiles(char* file1, char* file2){
   bin=fopen(file1, "rb+");
   if(!bin){
      printf("Error: cannot open file '%s' ",file1);
      return(1);
   }
   ppf=fopen(file2,  "rb");
   if(!ppf){
      printf("Error: cannot open file '%s' ",file2);
      fclose(bin);
      return(1);
   }
   return(0);
}


Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité