home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / crc / crcset / validcrc.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-07-13  |  4.1 KB  |  215 lines

  1. {$I-}
  2. {
  3. VALIDCRC.PAS
  4.  
  5. Kevin Dean
  6. Fairview Mall P.O. Box 55074
  7. 1800 Sheppard Avenue East
  8. Willowdale, Ontario
  9. CANADA    M2J 5B9
  10. CompuServe ID: 76336,3114
  11.  
  12. March 24, 1991
  13.  
  14.     This module validates the CRC of the program in which it is linked.
  15. The code was designed as an anti-virus algorithm.  The CRC is a very effective
  16. method of detecting viruses; any virus that attaches itself to the program
  17. changes the CRC of the program.  The response to an invalid CRC is entirely up
  18. to the programmer.
  19.  
  20.     This code is public domain.
  21. }
  22.  
  23.  
  24. unit ValidCRC;
  25.  
  26.  
  27. interface
  28.  
  29.  
  30. uses
  31.   DOS, AllocBuf;
  32.  
  33.  
  34. type
  35.   crc32_t =
  36.     longint;
  37.  
  38.   FileCRC =
  39.     record
  40.     case boolean of
  41.       false:
  42.     (
  43.     SearchStr : array [1 .. 8] of char;    { String to search for. }
  44.     );
  45.  
  46.       true:
  47.     (
  48.     Polynomial : crc32_t;            { Polynomial for this file. }
  49.     CRC : crc32_t;                { Calculated CRC for this file. }
  50.     )
  51.     end;
  52.  
  53.  
  54. const
  55.   crcValid =    { CRC is valid. }
  56.     0;
  57.   crcInvalid =    { CRC is invalid. }
  58.     1;
  59.   crcIsZero =    { CRC polynomial has been reset to zero. }
  60.     2;
  61.   crcNoMem =    { No memory for data buffer. }
  62.     3;
  63.   crcFileErr =    { Program file not found. }
  64.     4;
  65.  
  66.  
  67. function ValidateCRC(ProgName : string) : integer;
  68. function IsValidCRC(ProgName : string) : boolean;
  69.  
  70.  
  71. implementation
  72.  
  73.  
  74. const _VirusCRC : FileCRC =
  75.   (
  76.   SearchStr : ('D', 'E', 'A', 'N', '_', 'C', 'R', 'C')
  77.   );
  78.  
  79.  
  80. type
  81.   dwordrec =
  82.     record
  83.     Lo, Hi : word
  84.     end;
  85.  
  86.   BytePtr =
  87.     ^byte;
  88.  
  89.  
  90. {***}
  91. { Extract the low word of a dword. }
  92. function LowW(dword : longint) : word;
  93.  
  94. begin
  95. LowW := (dwordrec(dword)).Lo
  96. end;
  97.  
  98.  
  99. {***}
  100. { Extract the high word of a dword. }
  101. function HiW(dword : longint) : word;
  102.  
  103. begin
  104. HiW := (dwordrec(dword)).Hi
  105. end;
  106.  
  107.  
  108. {***}
  109. { Calculate CRC of active program and compare it to CRC in _VirusCRC. }
  110. function ValidateCRC(ProgName : string) : integer;
  111.  
  112. var
  113.   Buffer : BytePtr;            { Buffer for file's data. }
  114.   BufSize : word;            { Buffer size. }
  115.  
  116.   PN : string[79];            { Program name. }
  117.   ProgFile : file;            { Program file. }
  118.  
  119.   Table : array [0 .. 255] of crc32_t;    { CRC table. }
  120.   HalfI : ^crc32_t;            { Pointer to CRC of I div 2. }
  121.   CRC : crc32_t;            { Current CRC. }
  122.  
  123.   I : word;                { Byte counter. }
  124.   BufPtr : BytePtr;            { Pointer to Buffer. }
  125.  
  126. begin
  127. if _VirusCRC.Polynomial <> 0 then
  128.   begin
  129.   { Allocate 8k buffer if possible, but get at least 512 bytes. }
  130.   BufSize := 8192;
  131.   Buffer := BufAlloc(BufSize, 512);
  132.  
  133.   if Buffer <> nil then
  134.     begin
  135.     if Lo(DosVersion) < 3 then
  136.       { Search PATH for program file. }
  137.       PN := FSearch(ProgName, GetEnv('PATH'))
  138.     else
  139.       { Under DOS versions 3 and above, the program name is in ParamStr(0). }
  140.       PN := ParamStr(0);
  141.  
  142.     Assign(ProgFile, PN);
  143.     Reset(ProgFile, 1);
  144.  
  145.     if IOResult = 0 then
  146.       begin
  147.       { Generate a CRC lookup table for faster calculation. }
  148.       HalfI := @Table[0];
  149.       Table[0] := 0;
  150.       I := 0;
  151.       while I < 256 do
  152.     begin
  153.     if Hi(HiW(HalfI^)) and $80 = $80 then
  154.       begin
  155.       Table[I + 1] := HalfI^ shl 1;
  156.       Table[I] := Table[I + 1] xor _VirusCRC.Polynomial
  157.       end
  158.     else
  159.       begin
  160.       Table[I] := HalfI^ shl 1;
  161.       Table[I + 1] := Table[I] xor _VirusCRC.Polynomial
  162.       end;
  163.  
  164.     Inc(I, 2);
  165.     Inc(longint(HalfI), sizeof(crc32_t))
  166.     end;
  167.  
  168.       CRC := 0;
  169.       BlockRead(ProgFile, Buffer^, BufSize, I);
  170.       while I <> 0 do
  171.     begin
  172.     BufPtr := Buffer;
  173.     while I <> 0 do
  174.       begin
  175.       CRC := (CRC shl 8) xor Table[Hi(HiW(CRC)) xor BufPtr^];
  176.  
  177.       Dec(I);
  178.       Inc(longint(BufPtr))
  179.       end;
  180.  
  181.     BlockRead(ProgFile, Buffer^, BufSize, I)
  182.     end;
  183.  
  184.       Close(ProgFile);
  185.  
  186.       if CRC = _VirusCRC.CRC then
  187.     ValidateCRC := crcValid
  188.       else
  189.     ValidateCRC := crcInvalid
  190.       end
  191.     else
  192.       ValidateCRC := crcFileErr;
  193.  
  194.     FreeMem(Buffer, BufSize)
  195.     end
  196.   else
  197.     ValidateCRC := crcNoMem
  198.   end
  199. else
  200.   { CRC polynomial must be something other than 0. }
  201.   ValidateCRC := crcIsZero
  202. end;
  203.  
  204.  
  205. {***}
  206. { Defined for compatibility with earlier releases of CRCSET. }
  207. function IsValidCRC(ProgName : string) : boolean;
  208.  
  209. begin
  210. IsValidCRC := ValidateCRC(Progname) = crcValid
  211. end;
  212.  
  213.  
  214. end.
  215.