home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tags18.zip / VALIDCRC.C < prev    next >
C/C++ Source or Header  |  1991-10-05  |  5KB  |  164 lines

  1. /*
  2.  EPSHeader
  3.  
  4.    File: validcrc.c
  5.    Author: Kevin Dean
  6. */
  7. /*
  8.  EPSRevision History
  9.  
  10.    J. Kercheval  Sat, 10/05/1991  16:42:11  combine separate sources
  11. */
  12.  
  13. /*
  14. VALIDCRC.C
  15.  
  16. Kevin Dean
  17. Fairview Mall P.O. Box 55074
  18. 1800 Sheppard Avenue East
  19. Willowdale, Ontario
  20. CANADA    M2J 5B9
  21. CompuServe ID: 76336,3114
  22.  
  23. March 24, 1991
  24.  
  25.         This module validates the CRC of the program in which it is linked.
  26. The code was designed as an anti-virus algorithm.  The CRC is a very effective
  27. method of detecting viruses; any virus that attaches itself to the program
  28. changes the CRC of the program.  The response to an invalid CRC is entirely up
  29. to the programmer.
  30.  
  31.         This code is public domain.
  32. */
  33.  
  34.  
  35.  
  36. #include <dos.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40.  
  41. #include "viruscrc.h"
  42.  
  43. /*
  44.  * The _viruscrc variable is used by the anti-virus CRC check and is set to
  45.  * the default search string used by the CRCSET.EXE program.
  46.  */
  47. const union filecrc _viruscrc =
  48. {
  49.     'D', 'E', 'A', 'N', '_', 'C', 'R', 'C'
  50. };
  51.  
  52.  
  53. /* Macros to extract low and high bytes of a word. */
  54. #define lowb(x)  (*(unsigned char *)&(x))
  55. #define hib(x)   (*((unsigned char *)&(x) + 1))
  56.  
  57. /* Macros to extract low and high words of a dword. */
  58. #define loww(x)  (*(unsigned short *)&(x))
  59. #define hiw(x)   (*((unsigned short *)&(x) + 1))
  60.  
  61.  
  62. void *bufalloc(size_t * size, size_t minsize);
  63.  
  64.  
  65. #if defined(__TURBOC__)
  66.  
  67. #include <dir.h>
  68. #define findprog(progname, pn)  strcpy(pn, searchpath(progname))
  69. #define argv0  _argv[0]
  70.  
  71. #elif defined(_MSC_VER) || defined(_QC)
  72.  
  73. #define findprog(progname, pn)  _searchenv(progname, getenv("PATH"), pn)
  74. extern char **__argv;
  75.  
  76. #define argv0  __argv[0]
  77.  
  78. #endif
  79.  
  80.  
  81. /***/
  82. /* Allocate a buffer of flexible size. */
  83. void *bufalloc(size_t * size, size_t minsize)
  84. {
  85.     void *buffer = NULL;        /* Buffer allocated. */
  86.     size_t bufsize;             /* Size of buffer allocated. */
  87.  
  88.     /* Allocate as big a buffer as possible (at least minsize). */
  89.     for (bufsize = *size;
  90.          bufsize >= minsize && !(buffer = malloc(bufsize));
  91.          bufsize /= 2);
  92.  
  93.     /* Save buffer size. */
  94.     *size = bufsize;
  95.  
  96.     return (buffer);
  97. }
  98.  
  99.  
  100. /***/
  101. /* Calculate CRC of active program and compare it to CRC in _viruscrc. */
  102. int validatecrc(const char *progname)
  103. {
  104.     int retcode;                /* Function return code. */
  105.  
  106.     if (_viruscrc.x.polynomial != 0) {
  107.         unsigned char *buffer;  /* Buffer for program image. */
  108.         size_t bufsize;         /* Buffer size. */
  109.  
  110.         /* Allocate 8k buffer if possible, but get at least 512 bytes. */
  111.         bufsize = 8192;
  112.         buffer = bufalloc(&bufsize, 512);
  113.  
  114.         if (buffer) {
  115.             char pn[80];        /* Fully qualified program name. */
  116.             FILE *progfile;     /* Program file. */
  117.  
  118.             if (_osmajor < 3)
  119.                 /* Search PATH for program specified in progname. */
  120.                 findprog(progname, pn);
  121.             else
  122.                 /* Under DOS versions 3 and above, the program name is in
  123.                  * argv[0] (passed as argv0). */
  124.                 strcpy(pn, argv0);
  125.  
  126.             if ((progfile = fopen(pn, "rb")) != NULL) {
  127.                 crc32_t table[256];     /* CRC table. */
  128.                 register crc32_t *halfi;        /* Pointer to CRC of i / 2. */
  129.                 crc32_t crc;    /* Current CRC. */
  130.  
  131.                 register size_t i;      /* Byte counter. */
  132.                 unsigned char *bufptr;  /* Pointer to walk through buffer. */
  133.  
  134.                 /* Generate a CRC lookup table for faster calculation. */
  135.                 for (i = 0, halfi = table, table[0] = 0; i < 256; i += 2, halfi++)
  136.                     if (hib(hiw(*halfi)) & 0x80)
  137.                         table[i] = (table[i + 1] = *halfi << 1) ^ _viruscrc.x.polynomial;
  138.                     else
  139.                         table[i + 1] = (table[i] = *halfi << 1) ^ _viruscrc.x.polynomial;
  140.  
  141.                 crc = 0;
  142.                 while ((i = fread(buffer, 1, bufsize, progfile)) != 0)
  143.                     for (bufptr = buffer; i--; bufptr++)
  144.                         crc = (crc << 8) ^ table[hib(hiw(crc)) ^ *bufptr];
  145.  
  146.                 fclose(progfile);
  147.  
  148.                 retcode = crc == _viruscrc.x.crc ? CRC_VALID : CRC_INVALID;
  149.             }
  150.             else
  151.                 retcode = CRC_FILEERR;
  152.  
  153.             free(buffer);
  154.         }
  155.         else
  156.             retcode = CRC_NOMEM;
  157.     }
  158.     else
  159.         /* CRC polynomial must be something other than 0. */
  160.         retcode = CRC_ISZERO;
  161.  
  162.     return (retcode);
  163. }
  164.