Frost Moon Project

Src/exe2vff.cpp-exe2vff Ver.1.00- - Frost Moon Project

Home > ソフトウェア > exe2vff > exe2vff100.zip > Src > exe2vff.cpp

//exe2vff Ver.1.00 by Y.Takanashi

#include<sys/stat.h>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cerrno>

#define max(a,b) ((a)>(b)?a:b)
#define BUFFER_SIZE 131072*12

int bm_search(const unsigned char* text,unsigned int text_length,const unsigned char* pattern,unsigned int pattern_length){
    unsigned int skip_table[256];
    unsigned int text_ptr,pattern_ptr;

    for(text_ptr=0;text_ptr<256;text_ptr++){
        skip_table[text_ptr]=pattern_length;
    }
    for(text_ptr=0;text_ptr<pattern_length-1;text_ptr++){
        skip_table[pattern[text_ptr]]=pattern_length-text_ptr-1;
    }

    text_ptr=pattern_length-1;

    while(text_ptr<text_length){
        pattern_ptr=pattern_length-1;
        while(text[text_ptr]==pattern[pattern_ptr]){
            if(pattern_ptr==0){
                return text_ptr;
            }
            
            text_ptr--;
            pattern_ptr--;
        }
        text_ptr=text_ptr+max(skip_table[text[text_ptr]],pattern_length-pattern_ptr);
    }
    return -1;
}

void msg(const char* file_name,const char* text){
    fprintf(stderr,"exe2vff: %s: %s\n",file_name,text);
    return;
}

int main(int argc,char** argv){
    fprintf(stderr,"exe2vff Ver.1.00 by Y.Takanashi\n");
    if(argc<2){
        fprintf(stderr,"usage:exe2vff <game.exe> [game.dat]\n");
        return -1;
    }

    char* exe_name=argv[1];
    char* dat_name=(argc<3)?(char*)"game.dat":argv[2];

    FILE* fpr;
    if((fpr=fopen(exe_name,"rb"))==NULL){
        msg(exe_name,strerror(errno));
        return -1;
    }

    FILE* fpw;
    if((fpw=fopen(dat_name,"ab"))==NULL){
        msg(dat_name,strerror(errno));
        return -1;
    }

    unsigned long exe_length;
    {
        struct stat st;
        fstat(fileno(fpr),&st);
        exe_length=st.st_size;
    }

    
    unsigned char* buffer=(unsigned char*)malloc(BUFFER_SIZE+2);
    if(buffer==NULL){
        msg(exe_name,strerror(errno));
        return -1;
    }
    memset(buffer,0,BUFFER_SIZE);
    const unsigned int cnt=fread(buffer,sizeof(unsigned char),BUFFER_SIZE,fpr);
    unsigned int pos=cnt;
    unsigned int vff_address;
    const unsigned char* const pattern=(const unsigned char*)"vff";

    msg(exe_name,"reading...");
    while(!feof(fpr)){
        fclose(fpr);
        if(fopen(exe_name,"rb")!=NULL){
            memset(buffer,0,BUFFER_SIZE);
            fseek(fpr,pos,SEEK_SET);
            fread(buffer,sizeof(unsigned char),BUFFER_SIZE,fpr);
            if((vff_address=bm_search(buffer,BUFFER_SIZE,pattern,sizeof(pattern)/sizeof(pattern[0])))!=-1)break;
            pos+=cnt;
        }else{
            msg(exe_name,strerror(errno));
            return -1;
        }
    }

    vff_address+=pos;
    {
        char address[24];
        sprintf(address,"begin address: 0x%x",vff_address);
        msg(exe_name,address);
    }

    pos=vff_address;
    msg(dat_name,"writing...");
    while(!feof(fpr)){
        fclose(fpr);
        if(fopen(exe_name,"rb")!=NULL){
            memset(buffer,0,BUFFER_SIZE);
            fseek(fpr,pos,SEEK_SET);
            fread(buffer,sizeof(unsigned char),BUFFER_SIZE,fpr);
            fwrite(buffer,sizeof(unsigned char),BUFFER_SIZE,fpw);
            pos+=cnt;
        }else{
            msg(exe_name,strerror(errno));
            return -1;
        }
    }

    msg(dat_name,"done");
    
    free(buffer);
    fclose(fpr);
    fclose(fpw);
    return 0;
}

Home > ソフトウェア > exe2vff > exe2vff100.zip > Src > exe2vff.cpp