home *** CD-ROM | disk | FTP | other *** search
- /* Remove the Form virus from floppy diskettes */
- /* P. Jarvis. 10/05/1991 */
-
- /* This program should only be used to remove */
- /* the Form virus from floppy disks. The SYS */
- /* command should work with hard disks, but */
- /* make a backup before trying! */
-
- /* Disinfection method: */
- /* */
- /* 1) Read boot sector and check for virus */
- /* 2) Locate copy of original boot sector */
- /* 3) Clear bad cluster flag from FAT */
- /* 4) Copy original boot sector back */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <dos.h>
-
- void main(int, char **);
- void exit(int);
- void patch(unsigned char *fat, int s, int t, int h);
-
- int bytes_sector;
- int sectors_track;
- int sectors_cluster;
- int sectors_fat;
- int tracks_side;
- int directory_size;
- int heads;
- int reserved;
-
- void main(int argc, char *argv[])
- {
- int drive; /* Drive code (0 - 3) */
- static unsigned char boot[512];
- static unsigned char orig[512];
- unsigned char *fat;
- union REGS regs;
- struct SREGS sregs;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s drive\n", argv[0]);
- exit(1);
- }
-
- drive = toupper(argv[1][0]) - 'A'; /* Get drive number */
- if ((drive < 0) || (drive > 3)) {
- fprintf(stderr, "Drive must be in range A - D\n");
- exit(2);
- }
-
- regs.h.ah = 0x00; /* Reset disk */
- regs.h.dl = (unsigned char) drive;
- int86(0x13, ®s, ®s);
-
- regs.h.ah = 0x08; /* Now status it */
- regs.h.dl = (unsigned char) drive;
- int86x(0x13, ®s, ®s, &sregs);
- if (regs.x.cflag) {
- fprintf(stderr, "Unable to status disk\n");
- exit(3);
- }
-
- /* Read boot sector */
-
- regs.h.al = (unsigned char) drive;
- regs.x.bx = (unsigned int) boot;
- regs.x.cx = 1;
- regs.x.dx = 0;
- int86(0x25, ®s, ®s);
- if (regs.x.cflag) {
- fprintf(stderr, "Failed to read boot sector\n");
- exit(4);
- }
-
- /* Check if disk is infected already */
-
- if ((boot[0x3F] != 0x01) || (boot[0x40] != 0xFE)) {
- fprintf(stderr, "This disk does not have the Form virus\n");
- exit(0);
- }
-
- /* Get parameters */
-
- heads = boot[0x1B] * 256 + boot[0x1A];
- bytes_sector = boot[0x0C] * 256 + boot[0x0b];
- sectors_track = boot[0x19] * 256 + boot[0x18];
- sectors_cluster = (int) boot[0x0D];
- sectors_fat = boot[0x17] * 256 + boot[0x16];
- tracks_side = (boot[0x14] * 256 + boot[0x13]) / sectors_track / heads;
- reserved = boot[0x0f] * 256 + boot[0x0E] + boot[0x10] *
- (boot[0x17] * 256 + boot[0x16]);
- directory_size = boot[0x12] * 256 + boot[0x11];
-
- /* Allocate space for FAT */
-
- fat = (unsigned char *) malloc(bytes_sector * sectors_fat);
- if (fat == NULL) {
- fprintf(stderr, "Unable to assign space for FAT\n");
- exit(6);
- }
-
- /* Now read the FAT */
-
- regs.h.al = (unsigned char) drive;
- regs.x.bx = (unsigned int) fat;
- regs.x.cx = sectors_fat;
- regs.x.dx = 1;
- int86(0x25, ®s, ®s);
- if (regs.x.cflag) {
- fprintf(stderr, "Failed to read FAT\n");
- exit(4);
- }
-
- patch(fat, boot[0x49], boot[0x4C], boot[0x4A]);
- patch(fat, boot[0x4D], boot[0x50], boot[0x4E]);
-
- /* Now re-write the FAT */
-
- regs.h.al = (unsigned char) drive;
- regs.x.bx = (unsigned int) fat;
- regs.x.cx = sectors_fat;
- regs.x.dx = 1;
- int86(0x26, ®s, ®s);
- if (regs.x.cflag) {
- fprintf(stderr, "Failed to re-write FAT sector\n");
- exit(4);
- }
-
- /* Now try to read original boot sector */
-
- regs.x.ax = 0x0201;
- regs.x.bx = (unsigned int) orig;
- regs.x.cx = boot[0x4A] * 256 + boot[0x49];
- regs.x.dx = boot[0x4C] * 256 + boot[0x4B];
- regs.h.dl = (unsigned char) drive;
- int86(0x13, ®s, ®s);
- if (regs.x.cflag) {
- fprintf(stderr, "Unable to read original boot sector\n");
- exit(5);
- }
-
- /* Now write the original boot sector */
-
- regs.h.al = (unsigned char) drive;
- regs.x.bx = (unsigned int) orig;
- regs.x.cx = 1;
- regs.x.dx = 0;
- int86(0x26, ®s, ®s);
- if (regs.x.cflag) {
- fprintf(stderr, "Failed to re-write boot sector\n");
- exit(4);
- }
-
- printf("The Form virus has been removed.\n");
- exit(0);
- }
-
-
- void patch(unsigned char *fat, int s, int t, int h)
- {
- int sector;
- int cluster;
- int offset;
- sector = s -1 +
- t * sectors_track +
- h * sectors_track * heads;
- cluster = (sector - reserved - (directory_size * 32 + bytes_sector -1) /
- bytes_sector) / sectors_cluster + 2;
- offset = cluster * 3 / 2;
- if (cluster & 1) {
- fat[offset] &= 0x0F;
- fat[offset+1] = 0;
- }
- else {
- fat[offset] = 0;
- fat[offset+1] &= 0xF0;
- }
- }
-
-
-