Changes

Jump to navigation Jump to search
6,041 bytes added ,  23:24, 26 February 2007
no edit summary
Line 221: Line 221:  
}
 
}
 
  </nowiki>
 
  </nowiki>
 +
 +
 +
=C Code=
 +
This is C code translation of the Perl script above.  It may contain bugs, it was only tested on one game save file.  If you find any errors, please edit the code with the fixes.  Thanks, Advant.
 +
 +
#ifdef WIN32
 +
#define _CRT_SECURE_NO_DEPRECATE
 +
#endif
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <string.h>
 +
 +
unsigned long readLongChk(char * name, unsigned long chk);
 +
void readBlock(char * title, unsigned long len, char * filename);
 +
void readByteChk(char * name, unsigned char chk);
 +
unsigned long findEndOfHeader();
 +
 +
unsigned long readLong(char * name);
 +
unsigned long address = 0;
 +
FILE * fp = NULL;
 +
char read_String[256] = {0};
 +
 +
int main(int argc, char * argv[])
 +
{
 +
  char filename[256] = {0}; 
 +
  char title[256] = {0};
 +
  unsigned long filesize = 0;
 +
  unsigned long files = 0;
 +
  unsigned long i = 0;
 +
  if(argc < 2)
 +
  {
 +
    printf("Usage: wii-parse filename.bin\n");
 +
    return 0;
 +
  }
 +
  fp = fopen(argv[1], "r+b");
 +
 
 +
  if(fp == NULL)
 +
  { printf("Error:  Unable to open %s\n", argv[1]); return -1;}
 +
 
 +
  findEndOfHeader();
 +
  readLong("WiiID:");
 +
  files = readLong("Number of files");
 +
  readLong("FileDataLen");
 +
  readLongChk("Magic",0x00000000);
 +
  readLongChk("Magic",0x00000000);
 +
  readLong("PostHeadLen");
 +
  readBlock("Zeros",64,0);
 +
  readLongChk("Magic",0x00010000);
 +
  readLong("PrgID");
 +
  readLong("MacAdd");
 +
  readLongChk("Magic",0xF5550000); 
 +
  sprintf(filename,"%s.hash1\0",argv[1],i+1);
 +
  readBlock("Hash1",16,filename); 
 +
  for(i = 0; i < files; i++)
 +
  {
 +
    sprintf(title,"Magic%d",i);
 +
    readLong(title,0x03ADF17E);
 +
    sprintf(title,"Filesize%d",i);
 +
    filesize = readLong(title);
 +
    sprintf(title,"Magic%d",i);
 +
    readByteChk(title,0x34);
 +
    readByteChk(title,0x00);
 +
    readByteChk(title,0x01);
 +
    sprintf(title,"Filename%d",i);
 +
    readString(title);
 +
    sprintf(filename,"%s.f%dsfille\0",argv[1],i+1);
 +
    readBlock("StrFiller",117-strlen(read_String)-1,filename);
 +
    sprintf(filename,"%s.f%ddata\0",argv[1],i+1);
 +
    readBlock("Filedata",filesize,filename);
 +
    sprintf(filename,"%s.f%ddfill\0",argv[1],i+1);
 +
    readBlock("DataFiller",filesize % 64,filename);
 +
  }
 +
  sprintf(filename,"%s.hash2\0",argv[1]);
 +
  readBlock("Hash2",60,filename); 
 +
 
 +
  readLongChk("Magic",0x00000000);
 +
  readLongChk("Magic",0x00010002);
 +
 
 +
  sprintf(filename,"%s.hash3\0",argv[1]);
 +
  readBlock("Hash3",60,filename);
 +
 +
  readBlock("Zeros",64,0);
 +
  readString("RootCA");
 +
  readBlock("Zeros",64-strlen(read_String)-1,0);
 +
  readLongChk("Magic",0x00000002);
 +
  readString("NG");
 +
  readBlock("Zeros",64-strlen(read_String)-1,0);
 +
 +
  sprintf(filename,"%s.hash4\0",argv[1]);
 +
  readBlock("Hash4",64,filename);
 +
 
 +
  readBlock("Zeros",60,0);
 +
  readLongChk("Magic",0x00010002);
 +
 
 +
  sprintf(filename,"%s.hash5\0",argv[1]);
 +
  readBlock("Hash5",60,filename);
 +
 +
  readBlock("Zeros",64,0); 
 +
  readString("RootCA-MS-NG");
 +
  readBlock("Zeros",64-strlen(read_String) - 1,0);
 +
  readLongChk("Magic",0x00000002);
 +
  readString("AP");
 +
  readBlock("Zeros",64-strlen(read_String) - 1,0);
 +
  readLongChk("Magic",0x00000000);
 +
 +
  sprintf(filename,"%s.hash6\0",argv[1]);
 +
  readBlock("Hash6",60,filename);
 +
 +
}
 +
 +
unsigned int readString(char *title)
 +
{
 +
    char data[80] = {0};
 +
    unsigned int bytes_read = 0;
 +
    bytes_read = fread(&data,80,sizeof(unsigned char), fp);
 +
    strcpy(read_String,data);
 +
    printf("0x%.8x | String %s ends after %uL bytes \"%s\"\n", address,title, strlen(read_String),read_String);
 +
    fseek(fp,address+strlen(read_String)+1,SEEK_SET);
 +
    address += strlen(read_String)+1;
 +
 +
}
 +
unsigned long findEndOfHeader()
 +
{
 +
    unsigned char buffer[64] = {0};
 +
    unsigned long location = 0;
 +
    int bytes_read = -1;
 +
    unsigned char chk_buffer[16] = {0x00,0x00,0x00,0x70,0x42,0x6B,0x00,0x01};
 +
  do
 +
  {
 +
    if(bytes_read == 0)
 +
    { printf("Error:  Unable to locate end of header!\n"); exit(0);}
 +
    bytes_read = fread(buffer,sizeof(unsigned char),64,fp);
 +
    location += 64;
 +
  }
 +
  while(memcmp(buffer,chk_buffer,8) != 0);
 +
  location -= 64;
 +
  printf("Header offset: 0x%.8x\n", location);
 +
  fseek(fp,location + 8, SEEK_SET);
 +
  address = location + 8;
 +
 +
}
 +
 +
void readByteChk(char * name, unsigned char chk)
 +
{
 +
    unsigned char data[1] = {0}; 
 +
    fread(&data,1,sizeof(unsigned char), fp);
 +
    if(data[0] != chk)
 +
    { printf("0x%.8x |  %s 0x%.2x (%uL)...Check failed!\n",address, name,data[0],data[0]);}
 +
    else{printf("0x%.8x |  %s 0x%.2x (%uL)...Check passed!\n",address, name,data[0],data[0]);}
 +
    address += 1;
 +
 +
}
 +
void readBlock(char * title, unsigned long len, char * filename)
 +
{
 +
    FILE * fp2 = 0;
 +
    unsigned char * data = calloc(len,sizeof(unsigned char));
 +
    unsigned long bytes_read = 0;
 +
    bytes_read = fread(data,len,sizeof(unsigned char), fp);
 +
    printf("0x%.8x | Block  %s ends after %uL bytes\n", address,title,len);
 +
    address += len;
 +
    if(filename > 0)
 +
    {
 +
        fp2 = fopen(filename,"w+b");
 +
        fwrite(data,sizeof(unsigned char),len*bytes_read,fp2);
 +
        fclose(fp2);
 +
    }
 +
}
 +
unsigned long readLongChk(char * name, unsigned long chk)
 +
{
 +
    unsigned long dataL = 0;
 +
    unsigned char data[4] = {0}; 
 +
    fread(&data,4,sizeof(unsigned char), fp);
 +
    dataL += data[0];
 +
    dataL = dataL << 8;
 +
    dataL += data[1];
 +
    dataL = dataL << 8;
 +
    dataL += data[2];
 +
    dataL = dataL << 8;
 +
    dataL += data[3];
 +
    if(dataL != chk)
 +
    {printf("0x%.8x |  %s 0x%.8x != 0x%.8x...Check failed!\n",address, name,dataL,chk); }
 +
    else{printf("0x%.8x |  %s 0x%.8x (%uL)...Check passed!\n",address, name,dataL,dataL);}
 +
    address += 4;
 +
 +
    return dataL;
 +
}
 +
 +
unsigned long readLong(char * name)
 +
{
 +
    unsigned long dataL = 0;
 +
    unsigned char data[4] = {0};
 +
    fread(&data,4,sizeof(unsigned char), fp);
 +
    dataL += data[0];
 +
    dataL = dataL << 8;
 +
    dataL += data[1];
 +
    dataL = dataL << 8;
 +
    dataL += data[2];
 +
    dataL = dataL << 8;
 +
    dataL += data[3];
 +
    printf("0x%.8x |  %s 0x%.8x (%uL)\n", address,name,dataL,dataL);
 +
    address += 4;
 +
   
 +
    return dataL;
 +
}
0

edits

Navigation menu