#include #include #include #define TRUE 1 #define FALSE 0 #define BLOCKS 20 struct avirus { char code[8]; int bytes; unsigned long lowcrc; int crcs[BLOCKS]; } antivir = { "CAPRIO\xDF\0" }; main (int argc, char *argv[]) { int crc; char fname[25]; char *buff, *buffp; /* Pointers to data buffer */ int j1, j2 = 0, j3; int found = FALSE; /* TRUE if patch code found */ int bsize; /* Size of CRC block */ int rsize; /* Amount of data read into buffer */ int sector = 0, offset; /* Position of patch code */ long fl; /* File length */ FILE *fn; /* Open executable file for reading and writing */ if (argc == 2) strcpy(fname, argv[1]); else { printf("Filename: "); gets(fname); } if ((fn = fopen(fname, "rb+")) == NULL) { printf("File not found\n" ); exit(1); } /* Query user for size of CRC block */ fl = filelength(fileno(fn)); do { printf ("\nFile size is %ld, max blocks is %d\n", fl, BLOCKS); printf ("Lower limit on bytes per block is %d\n", fl/BLOCKS+1); printf ("\nEnter number of bytes per block: "); scanf ("%d", &bsize); } while ((bsize < fl/BLOCKS+1) || (bsize > fl)); /* Find the string that precedes the patch area */ buff = calloc(1024, sizeof(char)); rsize = fread(buff, sizeof(char), 512, fn); while (!eof(fileno(fn)) && !found) { sector++; rsize = fread(&buff[512], sizeof(char), 512, fn); for (offset=0; offset < 512; offset++) if (strncmp(&buff[offset], antivir.code, strlen(antivir.code)) == 0) { found = TRUE; break; } memcpy(buff, &buff[512], 512); } /* Search the last sector read if patch area not yet found */ if (!found) { sector++; for (offset=0; offset < rsize - strlen(antivir.code); offset++) if (strncmp(&buff[offset+512], antivir.code, strlen(antivir.code)) == 0) { found = TRUE; break; } } if (found) printf("Inserting antivirus data...\n\n"); else { printf("\nPatch area not found in file\n"); printf("No antivirus data inserted\n"); exit(1); } /* Calculate CRC values and write them into the executable */ free(buff); buff = calloc(bsize, sizeof(char)); rewind(fn); do { rsize = fread (buff, sizeof(char), bsize, fn); buffp = buff; crc = 0; for (j1 = 0; j1 < rsize; j1++) crc = crc_update (crc, *(buffp++)); crc = crc_finish(crc); antivir.crcs[j2++] = crc; printf ("CRC for block %d was %04x\n", j2, crc); } while (rsize == bsize); antivir.bytes = bsize; antivir.lowcrc = (sector-1) * 512 + offset; fseek (fn, antivir.lowcrc, SEEK_SET); fwrite(&antivir, sizeof(struct avirus), 1, fn); fclose(fn); } crc_update(int crcval, char crc_char) { long tmp; int j1; tmp = ((long)crcval << 8) + crc_char; for (j1 = 0; j1 < 8; j1++) { tmp = tmp << 1; if(tmp & 0x01000000) tmp = tmp ^ 0x01800500; } return((tmp & 0x00ffff00) >> 8); } crc_finish(int crc) { return(crc_update(crc_update(crc,'\0'), '\0')); }