/* Program: FINDBUG.C Author : Kim Moser Date : 2/13/89 System : IBM PC / Borland Turbo-C 2.0 Descrip: Finds the "Dungeon" virus on either the boot sector or all files Usage : FINDBUG [drive:] [options] OPTIONS ------- b Searches in boot sector for "Dungeon" f Searches all files (including this one!) for code that virus appends to files. e Searches only .COM and .EXE files (including this one!) for code that virus appends to files. 'drive' defaults to current drive if omitted */ #include #include /* getdisk() */ #include #include /* isalpha(), toupper() */ #include /* fatinfo */ #include /* strcmp() */ #include /* setmode() */ #include /* O_BINARY */ #include #include /* getch() */ char DISK, OLDDISK; char OLDDIR[255]; /* Current directory */ char *VIRUS; long int VIRUSLEN; char VIRUSNAME[255]; /* Will be set to 'd:\[path\]FINDBUG.VIR' */ char *SHORTNAME = "FINDBUG.VIR"; long int TOTALFILES=0; /* How many total files searched */ int JUSTEXE=0; /* Whether to search just EXE files */ char *BUF; #define MAXNAMES 1000 typedef char *ptr; ptr NAMES[MAXNAMES]; /* Array of MAXNAMES pointers to strings */ long int NAMESNDX = 0; /* Index into NAMES; always points to next free */ #define EXTENDED 255 int keyhit(void) { int ch; if ((ch=getch()) == NULL) /* Assumes that extended key code is next char returned, and that getch() will NOT wait for a key [i.e. key will be available immediately]. */ return (getch()+EXTENDED); else return ch; } void usage(void) /* Shows usage and exits */ { printf( "Usage: FINDBUG [drive:] [options]\n" ); printf( "OPTIONS\n" ); printf( " b Searches boot sector\n" ); printf( " f Searches all files\n" ); printf( " e Searches just .COM and .EXE files.\n\n" ); printf( "If no options are specified, both the 'b' and 'f options are assumed.\n" ); printf( "If drive is not specified, drive defaults to currently logged drive.\n" ); exit(1); } void readvirus(void) /* Set VIRUSLEN, allocate VIRUS, read virus into it, allocate BUF */ { FILE *fp; if ( (fp=fopen(VIRUSNAME,"r")) == NULL) { printf( "Unable to open virus data file '%s' for reading.\n", VIRUSNAME ); exit(1); } setmode(fileno(fp), O_BINARY); /* Get file length */ if ( (VIRUSLEN=filelength(fileno(fp)))==-1 ) { printf( "Unable to get file length of virus data file '%s'.\n", VIRUSNAME ); fclose(fp); exit(1); } VIRUS = (char *) calloc(1,(unsigned int)VIRUSLEN); if ( fread(VIRUS,1,VIRUSLEN,fp) != VIRUSLEN ) { printf( "Unable to read %ld bytes from virus data file.\n" ); fclose(fp); exit(1); } fclose(fp); printf( "Virus is %ld bytes long.\n", VIRUSLEN ); if ( (BUF=(char*)calloc(VIRUSLEN,1)) == NULL ) { printf( "Unable to allocate room for buffer.\n" ); exit(1); } } void doboot(void) /* Searches boot sector of drive 'DISK' for 'Dungeon' */ { struct fatinfo f; char *b; char text[] = "Dungeon"; int i, j, infected=0; printf( "Reading boot sector:\n" ); getfat(DISK+1,&f); /* Add 1 because getfat() expects 1=A, etc */ printf( "Reading boot sector of drive %c (%d bytes)\n", DISK+'A', f.fi_bysec ); b = (char *) calloc(1,(unsigned int)f.fi_bysec); if (absread(DISK, 1, 0, b)) { printf( "Unable to read boot sector!\n\a" ); exit(1); } /* Search image of boot sector for 'Dungeon': */ for (i=0; (i=VIRUSLEN) { TOTALFILES++; /* File long enough to contain virus, so check it: */ fseek(fp,len-VIRUSLEN,SEEK_SET); if ( fread(BUF,1,VIRUSLEN,fp) != VIRUSLEN ) { printf( "Unable to read %ld bytes from file %s.\n", VIRUSLEN, name ); exit(1); } /* Compare offset 138..1550: */ /* Search main body .................... or look for "MsDos" */ if ( (!memcmp(VIRUS+138,BUF+138,1410)||!memcmp(VIRUS+0x10,BUF+0x10,5)) && (strcmp(name,SHORTNAME)) ) { /* Get full path of infected file: */ addname( searchpath(name) ); } } else printf( " (too short)" ); printf( "\n" ); fclose(fp); } void dofiles(void) /* Search all files for virus code */ { int local=0; struct ffblk info; static int level=0; /* Global level */ int i; level++; while ((local++==0 ? !findfirst("*.*",&info,(~0)-FA_LABEL) : !findnext(&info))) { if (info.ff_attrib & FA_DIREC) { /* It's a directory */ if (strcmp(info.ff_name,".") && strcmp(info.ff_name,"..")) { /* Ignore "." and ".." directories */ for (i=0; i