Steampunk sewers

Patching NVDI for the FireBee

FireBee0. Start up your FireBee into FireTOS
1. Install NVDI as usual
2. Remove cops.acc and reinstall XControl for the firebee. (if needed)
3. Rename all NVDI*.SYS Files to NVDI*.SYX (to be sure, it is also possible to keep NVDI8, NVDIH...)
4. Run this patch program:
NVDI Patch ( Coldfire version )
NVDI Patch ( m68k version )

Here is the source for the patch program:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <dirent.h>

char * basepath = "C:\\";
struct pattern_patch 
{
   char * file;
   int maxmatch;
   long maxpos;
   char * pattern; 
   char * replacement;
   int pattern_len;  
};

struct pattern_patch files_to_patch[] = 
{
 {
  "AUTO/NVDI.PRG", 1, 24000, "\xA0\x00", "\xA9\x20", 2
 },
 {
  "GEMSYS/*.NOD", -1, -1, "\x48\xE7\xE0\xE0\xA0\x00", "\x48\xE7\xE0\xE0\xA9\x20", 6 
 }
};

#define NPATCHES (sizeof(files_to_patch)/sizeof(struct pattern_patch))

char * data;

char * readfile(char * path, unsigned long * size )
{
   FILE    *f;
   int     fs, read;
   void    *data; 
   f = fopen( path, "r+b");
   if(!f)
     return((char*)NULL);
   fseek(f, 0, SEEK_END);
   fs = ftell(f);
   *size = fs;
   fseek(f, 0, SEEK_SET);
   data = malloc( fs );
   if( !data )
     return( (char*)NULL );
   read = fread( data, 1, fs, f );
   fclose( f );
   if( read != fs )
     {
	if(data != NULL)
	  free(data);
	return( (char*)NULL );
     }
   return( data );
}

int lmemfind( const char* ptr1, unsigned long len1, const char* ptr2, unsigned long len2 )
{
   register int i, j;
   int size = len1 - len2;  // size stops the loop before accessing wrong mem
   if( len1 < len2 )
        return -2;
   for( i = 0; i <= size; i++ )   // run through the buf, i is the offset
     {
        short equal = 1;
	for( j = 0; j < len2; j++ )// run through the signature
	  {
	     if( ptr1[i + j] != ptr2[j] ) // 
	       {
		  equal = 0;     // found char not contained in signature.
		  break;             // step to the next signature disposition
	       }
	  }
	if( equal > 0 )
	  return i;
     }
   return -1;                     // nothing was found :(
}

void pattern_patch_file(char * path, struct pattern_patch * patch )
{
   int i;
   int count = 0;
   int c;
   unsigned long size;
   FILE * f;
   long pos;
   
   printf("Patching %s\n", path);
   data = readfile( path, &size );
   if( data == NULL )
     {
	printf("patch failed\n");
	return;
     }
   
   printf("Scanning %lu bytes (of %lu) for pattern 0x", (patch->maxpos > -1 ) ? patch->maxpos : size, size );
   for( i = 0; ipattern_len; i++) 
     {
	printf("%02X", (unsigned char)patch->pattern[i]);
     }
   printf("...\n");
   
   f = fopen(path, "r+b");
   if( !f ) 
     {
	printf("Could not open file for writing\n");
	return;
     }
   
   fseek( f, 0, SEEK_SET );
   pos = 0;
   count = 0;
   while( count < patch->maxmatch || patch->maxmatch < 0 )
     { 
	pos = lmemfind( data+pos, size-pos, patch->pattern, patch->pattern_len );
	if( pos > -1 && pos <= (( patch->maxpos > -1 ) ? patch->maxpos : size-patch->pattern_len) ) 
	  {
	     count++;
	     printf("Found match at %d, patch (y/n)?", pos );
	     c = getchar();
	     if(c == 'y' || c == 'Y')
	       {
		  printf( "Writing 0x" );
		  for( i=0; ipattern_len; i++)
		    {
		       printf("%02X", (unsigned char)patch->replacement[i] );
		    }
		  printf(" at %d\n", pos );
		  fseek( f, pos, SEEK_SET );
		  fwrite( patch->replacement, patch->pattern_len, 1, f );
	       }
	     while ( c != '\n' )
	       c = getchar();
	     pos++;
	  } 
	else 
	  {	
	     break;  
	  }	
     }
   if(count == 0)
     {
	printf("No matching pattern found!\n");
     }
   
   fclose( f );
   free(data);
   printf("-----------------\n\n");
}


int main(int argc, char **argv)
{
   struct dirent * ent;
   DIR * dir;
   char filemask[1024];
   char mask[1024];
   char * sep;
   int i=0;
   int c;
   if( argc > 1 )
     basepath = argv[1];
   
   printf("NVDI 5 patcher\n");
   printf("--------------\n");
   printf("This will patch NVDI for the fireBEE!\n");
   printf("The patch was reverse engineered by: Didier Mequignon!\n");
   printf("Usage: %s [%s]\n", argv[0], "Basedir (C:\\)");
   printf("Continue? (y/n) ");
   c = getchar();
   if( c != 'y' )
     return(0);
   while ( c != '\n' )
     c = getchar();
   printf("---\n\n");
   
   printf("Applying %d patch types in: %s\n", NPATCHES, basepath);
   for( i = 0; i<NPATCHES; i++) 
     {
	memset( &filemask, 0, 1024);
	sprintf( (char*)&filemask, "%s%s", basepath, files_to_patch[i].file );
	if( strchr( (char*)&filemask, '*') != NULL )
	  {
	     basepath = malloc(1024);
	     strcpy( basepath, (char*)&filemask );
	     sep = strchr( basepath, '*');
	     strcpy((char*)&mask, sep );
	     *sep = 0;
	     dir = opendir(basepath);
	     if(dir)
	       {
		  while( (ent = readdir(dir)) != NULL )
		    {
		       // printf("matching folder: %s\n", ent->d_name );
		       if( fnmatch( (char*)&mask, ent->d_name, 0X10 ) == 0 )
			 { 
			    sprintf((char*)&filemask, "%s%s", basepath, ent->d_name);
			    pattern_patch_file( (char*)&filemask, &files_to_patch[i] );
			 }  
		    }
		  closedir( dir );
	       }  
	     else 
	       {
		  printf("Could not open dir: %s\n", basepath);
	       }
	     
	     free( basepath );
	  }
	else 
	  {
	     pattern_patch_file( (char*)&filemask, &files_to_patch[i] );
	  }
     }   
   printf("Done.\n");
   getchar();
   return( 0 );
}
Patching NVDI for the FireBee | 0 Kommentar(e) | Neuen Account anlegen
Die folgenden Kommentare geben Meinungen von Lesern wieder und entsprechen nicht notwendigerweise der Meinung der Betreiber dieser Site. Die Betreiber behalten sich die Löschung von Kommentaren vor.