home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / utility / virus / peneciln / peniciln.c next >
C/C++ Source or Header  |  1988-03-26  |  14KB  |  230 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /* Module:     peniciln.c                                                   */
  4. /*                                                                          */
  5. /* Function:   Remove any possible virus programs from boot sector          */
  6. /*                                                                          */
  7. /* Programmer: George R. Woodside                                           */
  8. /*                                                                          */
  9. /* Date:       March 27, 1988                                               */
  10. /*                                                                          */
  11. /****************************************************************************/
  12.  
  13. /****************************************************************************/
  14. /* INCLUDE FILES                                                            */
  15. /****************************************************************************/
  16.  
  17. #include <stdio.h>
  18. #include <osbind.h>
  19.  
  20. #define  SECSIZE          512           /* floppy sector size               */
  21.  
  22. int  msflag = 0;                        /* not doing MS-DOS boot sector     */
  23. int  kflag = 0;                         /* keyboard loop flag               */
  24.  
  25. unsigned  char  ibuf[SECSIZE];          /* input boot sector buffer         */
  26. unsigned  char  obuf[SECSIZE];          /* output boot sector buffer        */
  27. unsigned  char  mbuf[SECSIZE] =         /* MS-DOS boot sector buffer        */
  28. {
  29.   0xEB, 0x34, 0x90, 0x49, 0x42, 0x4D, 0x20, 0x20, 0x33, 0x2E, 0x32, 0x00, 0x02,
  30.   0x02, 0x01, 0x00, 0x02, 0x70, 0x00, 0xA0, 0x05, 0xF9, 0x03, 0x00, 0x09, 0x00,
  31.   0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  32.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
  33.   0x01, 0x00, 0xFA, 0x33, 0xC0, 0x8E, 0xD0, 0xBC, 0x00, 0x7C, 0x16, 0x07, 0xBB,
  34.   0x78, 0x00, 0x36, 0xC5, 0x37, 0x1E, 0x56, 0x16, 0x53, 0xBF, 0x2B, 0x7C, 0xB9,
  35.   0x0B, 0x00, 0xFC, 0xAC, 0x26, 0x80, 0x3D, 0x00, 0x74, 0x03, 0x26, 0x8A, 0x05,
  36.   0xAA, 0x8A, 0xC4, 0xE2, 0xF1, 0x06, 0x1F, 0x89, 0x47, 0x02, 0xC7, 0x07, 0x2B,
  37.   0x7C, 0xFB, 0xCD, 0x13, 0x72, 0x67, 0xA0, 0x10, 0x7C, 0x98, 0xF7, 0x26, 0x16,
  38.   0x7C, 0x03, 0x06, 0x1C, 0x7C, 0x03, 0x06, 0x0E, 0x7C, 0xA3, 0x3F, 0x7C, 0xA3,
  39.   0x37, 0x7C, 0xB8, 0x20, 0x00, 0xF7, 0x26, 0x11, 0x7C, 0x8B, 0x1E, 0x0B, 0x7C,
  40.   0x03, 0xC3, 0x48, 0xF7, 0xF3, 0x01, 0x06, 0x37, 0x7C, 0xBB, 0x00, 0x05, 0xA1,
  41.   0x3F, 0x7C, 0xE8, 0x96, 0x00, 0xB8, 0x01, 0x02, 0xE8, 0xAA, 0x00, 0x72, 0x19,
  42.   0x8B, 0xFB, 0xB9, 0x0B, 0x00, 0xBE, 0xCD, 0x7D, 0xF3, 0xA6, 0x75, 0x0D, 0x8D,
  43.   0x7F, 0x20, 0xBE, 0xD8, 0x7D, 0xB9, 0x0B, 0x00, 0xF3, 0xA6, 0x74, 0x18, 0xBE,
  44.   0x6E, 0x7D, 0xE8, 0x61, 0x00, 0x32, 0xE4, 0xCD, 0x16, 0x5E, 0x1F, 0x8F, 0x04,
  45.   0x8F, 0x44, 0x02, 0xCD, 0x19, 0xBE, 0xB7, 0x7D, 0xEB, 0xEB, 0xA1, 0x1C, 0x05,
  46.   0x33, 0xD2, 0xF7, 0x36, 0x0B, 0x7C, 0xFE, 0xC0, 0xA2, 0x3C, 0x7C, 0xA1, 0x37,
  47.   0x7C, 0xA3, 0x3D, 0x7C, 0xBB, 0x00, 0x07, 0xA1, 0x37, 0x7C, 0xE8, 0x40, 0x00,
  48.   0xA1, 0x18, 0x7C, 0x2A, 0x06, 0x3B, 0x7C, 0x40, 0x50, 0xE8, 0x4E, 0x00, 0x58,
  49.   0x72, 0xCF, 0x28, 0x06, 0x3C, 0x7C, 0x76, 0x0C, 0x01, 0x06, 0x37, 0x7C, 0xF7,
  50.   0x26, 0x0B, 0x7C, 0x03, 0xD8, 0xEB, 0xD9, 0x8A, 0x2E, 0x15, 0x7C, 0x8A, 0x16,
  51.   0xFD, 0x7D, 0x8B, 0x1E, 0x3D, 0x7C, 0xEA, 0x00, 0x00, 0x70, 0x00, 0xAC, 0x0A,
  52.   0xC0, 0x74, 0x22, 0xB4, 0x0E, 0xBB, 0x07, 0x00, 0xCD, 0x10, 0xEB, 0xF2, 0x33,
  53.   0xD2, 0xF7, 0x36, 0x18, 0x7C, 0xFE, 0xC2, 0x88, 0x16, 0x3B, 0x7C, 0x33, 0xD2,
  54.   0xF7, 0x36, 0x1A, 0x7C, 0x88, 0x16, 0x2A, 0x7C, 0xA3, 0x39, 0x7C, 0xC3, 0xB4,
  55.   0x02, 0x8B, 0x16, 0x39, 0x7C, 0xB1, 0x06, 0xD2, 0xE6, 0x0A, 0x36, 0x3B, 0x7C,
  56.   0x8B, 0xCA, 0x86, 0xE9, 0x8A, 0x16, 0xFD, 0x7D, 0x8A, 0x36, 0x2A, 0x7C, 0xCD,
  57.   0x13, 0xC3, 0x0D, 0x0A, 0x4E, 0x6F, 0x6E, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65,
  58.   0x6D, 0x20, 0x64, 0x69, 0x73, 0x6B, 0x20, 0x6F, 0x72, 0x20, 0x64, 0x69, 0x73,
  59.   0x6B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x0D, 0x0A, 0x52, 0x65, 0x70, 0x6C,
  60.   0x61, 0x63, 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6B,
  61.   0x65, 0x20, 0x61, 0x6E, 0x79, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x77, 0x68, 0x65,
  62.   0x6E, 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x44,
  63.   0x69, 0x73, 0x6B, 0x20, 0x42, 0x6F, 0x6F, 0x74, 0x20, 0x66, 0x61, 0x69, 0x6C,
  64.   0x75, 0x72, 0x65, 0x0D, 0x0A, 0x00, 0x49, 0x42, 0x4D, 0x42, 0x49, 0x4F, 0x20,
  65.   0x20, 0x43, 0x4F, 0x4D, 0x49, 0x42, 0x4D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x43,
  66.   0x4F, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  68.   0x00, 0x00, 0x00, 0x55, 0xAA
  69. };                                      /* end MS-DOS boot sector buffer    */
  70.  
  71. /****************************************************************************/
  72. /* Check the command line for the drive to disinfect                        */
  73. /****************************************************************************/
  74. main(argc,argv)
  75. int    argc;                            /* argument count                   */
  76. char  *argv[];                          /* argument pointers                */
  77. {
  78.   register  int    arg;                 /* current argument                 */
  79.   register  int    i;                   /* byte counter                     */
  80.   register  char  *bptr;                /* buffer pointer                   */
  81.   register  char  *drive;               /* drive to clean up                */
  82.  
  83.   if(argc < 2)                          /* if no arguments                  */
  84.     {
  85.       printf("Usage: peniciln [-km] drive {drive}\n"); /* simple usage      */
  86.       printf("                 -k   Keyboard mode\n"); /* option k          */
  87.       printf("                 -m   MS-DOS boot sector\n"); /* option m     */
  88.       exit(0);                          /* exit without error               */
  89.     }                                   /* end no arguments                 */
  90.  
  91.   bptr = obuf;                          /* point to normal output buffer    */
  92.   for(i = 0; i < SECSIZE; i++)          /* full buffer size                 */
  93.     *bptr++ = 0x00;                     /* clear the output buffer          */
  94.  
  95.   for(arg = 1; arg < argc; arg++)       /* for each request                 */
  96.     {
  97.       drive = argv[arg];                /* get the pointer                  */
  98.       if(*drive == '-')                 /* if a leading dash                */
  99.         drive++;                        /* skip it                          */
  100.  
  101.       switch(*drive)                    /* check the input                  */
  102.         {
  103.           case 'a':                     /* drive a                          */
  104.           case 'A':
  105.             clean_boot(0);              /* clean up drive a                 */
  106.             break;
  107.  
  108.           case 'b':                     /* drive b                          */
  109.           case 'B':
  110.             clean_boot(1);              /* clean up drive b                 */
  111.             break;
  112.  
  113.           case 'k':                     /* keyboard loop mode               */
  114.           case 'K':
  115.             kflag = 1;                  /* set keyboard loop mode           */
  116.             break;
  117.  
  118.           case 'm':                     /* set MS-DOS flag                  */
  119.           case 'M':
  120.             msflag = 1;                 /* set MS-DOS boot sector           */
  121.             break;
  122.  
  123.           default:
  124.             printf("peniciln: invalid request %c\n",*drive); /* report error */
  125.             break;
  126.         }                               /* end switch                       */
  127.     }                                   /* end for                          */
  128.  
  129.   if(kflag)                             /* if entering keyboard mode        */
  130.     {
  131.       printf("Press 'a' or 'b' to clean disk in that drive,\n"); /* prompt  */
  132.       printf("or any other key to exit.\n"); /* and explain exit            */
  133.     }                                   /* end keyboard prompt              */
  134.  
  135.   while(kflag)                          /* as long as in keyboard mode      */
  136.     {
  137.       switch ((int)Crawcin())           /* read a key                       */
  138.         {
  139.           case 'a':                     /* drive a                          */
  140.           case 'A':
  141.             clean_boot(0);              /* clean up drive a                 */
  142.             break;
  143.  
  144.           case 'b':                     /* drive b                          */
  145.           case 'B':
  146.             clean_boot(1);              /* clean up drive b                 */
  147.             break;
  148.  
  149.           default:
  150.             kflag = 0;                  /* exit keyboard loop mode          */
  151.             break;
  152.  
  153.         }                               /* end keyboard switch              */
  154.     }                                   /* end keyboard mode                */
  155.  
  156.   return(0);                            /* exit without error               */
  157. }                                       /* end main                         */
  158.  
  159. /****************************************************************************/
  160. /* Clean up the boot sector data                                            */
  161. /****************************************************************************/
  162. clean_boot(dno)
  163. int    dno;                             /* drive number                     */
  164. {
  165.   register  long   reply;               /* I/O reply                        */
  166.   register  int    csum;                /* checksum value                   */
  167.   register  char  *fptr;                /* copy from here                   */
  168.   register  char  *tptr;                /* copy to here                     */
  169.   register  char  *eptr;                /* stop copy here                   */
  170.  
  171.   Getbpb(dno);                          /* clear media change               */
  172.   reply = Rwabs(0,ibuf,1,0,dno);        /* try the read                     */
  173.  
  174.   if(reply)                             /* if a read error                  */
  175.     {
  176.       printf("peniciln: read error %ld\n",reply); /* display error code     */
  177.       return;                           /* punt                             */
  178.     }                                   /* end bad read                     */
  179.  
  180.   if(msflag)                            /* if writing MS-DOS boot           */
  181.     {
  182.       fptr = ibuf + 11L;                /* start at bytes per sector        */
  183.       tptr = mbuf + 11L;                /* to MS-DOS prototype              */
  184.     }                                   /* end MS-DOS boot                  */
  185.   else                                  /* normal boot sector               */
  186.     {
  187.       fptr = ibuf + 8L;                 /* start at serial number           */
  188.       tptr = obuf + 8L;                 /* to empty buffer                  */
  189.     }                                   /* end clean boot sector            */
  190.  
  191.   eptr = ibuf + 30L;                    /* stop here                        */
  192.  
  193.   while(fptr != eptr)                   /* up to the last byte we need      */
  194.     *tptr++ = *fptr++;                  /* copy the configuration data      */
  195.  
  196.   if(msflag)                            /* if writing MS-DOS boot           */
  197.     reply = Rwabs(1,mbuf,1,0,dno);      /* write it                         */
  198.   else                                  /* a clean boot sector              */
  199.     {
  200.       csum = chksum(obuf);              /* get buffer checksum              */
  201.       csum = csum ^ 0xffff;             /* get 1's complement               */
  202.       obuf[510] = (char)(csum >> 8);    /* set high byte                    */
  203.       obuf[511] = (char)(csum & 0xff);  /* set low byte                     */
  204.       reply = Rwabs(1,obuf,1,0,dno);    /* write it                         */
  205.     }                                   /* end non-MS-DOS boot sector       */
  206.  
  207.   if(reply)                             /* if a read error                  */
  208.     {
  209.       printf("peniciln: write error %ld  ",reply); /* display error code    */
  210.       if(reply == -13L)                 /* may be write protected           */
  211.         printf("(Write Protected)");    /* yep, it was                      */
  212.       printf("\n");                     /* insure we print                  */
  213.     }                                   /* end bad write                    */
  214. }                                       /* end clean boot                   */
  215.  
  216. /****************************************************************************/
  217. /* Compute checksum of a buffer                                             */
  218. /****************************************************************************/
  219. chksum(bptr)
  220. register  int  *bptr;                   /* buffer address                   */
  221. {
  222.   register  int  sum   = 0;             /* accumulated checksum             */
  223.   register  int  count = (512 / sizeof(int)) - 1; /* ints in buffer less 1  */
  224.  
  225.   while(count--)                        /* for full buffer                  */
  226.     sum += *bptr++;                     /* add up the data                  */
  227.  
  228.   return(sum);                          /* give back checksum               */
  229. }                                       /* end checksum buffer              */
  230.