home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / trojanpr / check_os.arc / CHECK-OS.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1988-03-13  |  9.0 KB  |  274 lines

  1.  
  2. Program CheckOS;
  3.  
  4. { This program was written to be compiled with Turbo Pascal version 4.0.  It }
  5. { checks the Filesize, File Date/Time (last updated), and Checksum of        }
  6. { COMMAND.COM, AUTOEXEC.BAT, and CONFIG.SYS.  It was developed to verify     }
  7. { that no virus had installed itself in DOS.  It does not stay resident to   }
  8. { guard against Viruses, it just checks the specified drive once when the    }
  9. { program is invoked.  It also doesn't have terribly extensive error         }
  10. { checking so little things like the disk being too full to create the       }
  11. { Control file, or a Write protect error will cause a runtime error.  I      }
  12. { didn't feel it was necessary to fix these since I only use the program on  }
  13. { my hard disk.                                                              }
  14. {                                                                            }
  15. { No warranty is given with this software - use at your own risk.            }
  16. {                                                                            }
  17. { R.J. Bartlett  05 March 1988    GEnie address R.BARTLETT                   }
  18. {                                                                            }
  19. { Modified by Erik Ch. Ohrnberger GEnie address E.OHRNBERGER                 }
  20. {     Added support for ReadOnly files and the CONFIG.SYS SHELL= line.  For  }
  21. {     people who configured their system so that the COMMAND.COM file is not }
  22. {     in the root of the hard drive.                                         }
  23. {                                                                            }
  24.  
  25. {$R-,S-,I+,D+,T-,F-,V-,B-,N-,L+}
  26. {$M 8192,0,0}
  27.  
  28. Uses
  29.    DOS, CRT, StdDef, StdFunc, Debug;
  30.  
  31. Const
  32.     Checked_Files           = 5;
  33.  
  34. Type
  35.     Frec                     = Record
  36.        FPathname               : string79;  { max string for Assigns }
  37.        FSize                   : LongInt;
  38.        FTime                   : LongInt;
  39.        FChkSum                 : Word;
  40.                              End;
  41.  
  42.     Frec_Array               = Array [1..Checked_Files] Of Frec;
  43.  
  44. Var
  45.  
  46. {
  47.     The NewRec array contains the current file information.  The CtlRec array
  48.     contains the refrence information.  Both arrays hold the file information
  49.     in the following order:
  50.       Array element:  1     File: COMMAND.COM
  51.                       2           CONFIG.SYS   (if it exists)
  52.                       3           AUTOEXEC.BAT (if it exists)
  53.                       4           IBMDOS.COM   (or 'DOS' hidden system file)
  54.                       5           IBMBIO.COM   (or 'BIO' hidden system file)
  55.  
  56. }
  57.  
  58.     Buffer                   : Array [1..4096] Of Byte;
  59.     CtlRec                   : Frec_Array;
  60.     CtlFile                  : File of frec;
  61.     Drive                    : Char;
  62.     ErrFlag                  : Boolean;
  63.     I                        : Integer;
  64.     NewRec                   : Frec_Array;
  65.     Parm                     : String [80];
  66.  
  67.  
  68.  
  69. Function ChkSumBlock (Count     : Word;
  70.                       OldChkSum : Word) : Word;
  71.  
  72. Var
  73.     I                        : Word;
  74.     ChkSum                   : Word;
  75.  
  76. Begin
  77.     ChkSum := OldChksum;
  78.     For I := 1 To Count Do
  79.         ChkSum := ChkSum + (Buffer [I] XOR I);
  80.     ChkSumBlock := ChkSum;
  81. End;
  82.  
  83.  
  84. Procedure ChkFile (Var FArray : Frec_Array;
  85.                        Ndx    : Word);
  86.  
  87. Var
  88.     Attr_Word                : Word;
  89.     Cnt                      : Word;
  90.     F                        : File;
  91.  
  92. Begin
  93.     If (Length (FArray [Ndx]. FPathname) <> 0) Then
  94.     Begin
  95.         Assign (F, Drive + FArray [Ndx]. FPathname);
  96.         GetFAttr (F, Attr_Word);
  97.         SetFAttr (F, Archive);
  98.         {$I-} Reset (F, 1); {$I+}
  99.         If (IOResult <> 0) Then
  100.         Begin
  101.             Close (CtlFile);
  102.             Erase (CtlFile);
  103.             Error_Halt ('Could not find the: ' + Drive +
  104.                         FArray [Ndx]. FPathname  + ' file.');
  105.         End;
  106.         GetFTime (F, FArray [Ndx]. FTime);
  107.         FArray [Ndx]. FSize   := FileSize (F);
  108.         FArray [Ndx]. FChkSum := 0;
  109.         Repeat
  110.             BlockRead (F, Buffer, 4096, Cnt);
  111.             FArray [Ndx]. FChkSum := ChkSumBlock (Cnt, FArray [Ndx].FChkSum);
  112.         Until (Cnt < 1024);
  113.         Close (F);
  114.         SetFAttr (F, Attr_Word);
  115.     End;
  116. End; { Of Procedure ChkFile }
  117.  
  118.  
  119. Procedure WrtError (ErrMsg   : String;
  120.                     FNum     : Word;
  121.                     FilePath : AnyStr);
  122.  
  123. Begin
  124.     WriteLn (ErrMsg,' mismatch on file ', Drive, FilePath);
  125.     ErrFlag := True;
  126.  
  127. End;
  128.  
  129.  
  130. Procedure ValidateFiles;
  131.  
  132. Var
  133.     I                        : Integer;
  134.     Ch                       : Char;
  135.  
  136. Begin
  137.     ErrFlag := false;
  138.     For I := 1 To Checked_Files Do
  139.     Begin
  140.         If CtlRec [I]. FSize   <> NewRec [I]. FSize   Then
  141.             WrtError ('File size', I, CtlRec [I]. FPathname);
  142.         If CtlRec [I]. FTime   <> NewRec [I]. FTime   Then
  143.             WrtError ('Date/Time', I, CtlRec [I]. FPathname);
  144.         If CtlRec [I]. FChkSum <> NewRec [I]. FChkSum Then
  145.             WrtError ('Checksum ', I, CtlRec [I]. FPathname);
  146.     End;
  147.     If ErrFlag Then
  148.     Begin
  149.         WriteLn (                                                          CR, LF,
  150.         'Check-OS has determined that the file (or files) listed above',   CR, LF,
  151.         'have been changed since the last time Check-OS was run.',         CR, LF,
  152.         #7,
  153.         'Do you wish to update the Check-OS control file (\Check-OS.CTL)', CR, LF);
  154.         Write ('to reflect new values (Y or N)? ');
  155.         Ch := ReadKey;
  156.         WriteLn (Ch);
  157.         If UpCase (Ch) = 'Y' Then
  158.         Begin
  159.             ReWrite (CtlFile);
  160.             For I := 1 To Checked_Files Do
  161.                 Write (CtlFile, NewRec [I]);
  162.         End;
  163.     End
  164.     Else
  165.         WriteLn ('Check-OS found no errors');
  166. End;
  167.  
  168. Procedure CreateControlFile;
  169.  
  170. Var
  171.     Attr_Word                : Word;
  172.     Config                   : Text;
  173.     Config_Found             : Boolean;
  174.     Dir_Info                 : SearchRec;
  175.     I                        : Word;
  176.     J                        : Word;
  177.     Line                     : AnyStr;
  178.     Shell_Found              : Boolean;
  179.  
  180. Begin
  181. {
  182.     If the drive has a CONFIG.SYS file, and a 'SHELL=' line, find and log that
  183.     file path for the COMMAND.COM  .    If there is an AUTOEXEC.BAT file log
  184.     it.  If there is a CONFIG.SYS file, log that too.
  185. }
  186.     FillChar (CtlRec, SizeOf (CtlRec), Null);
  187.     Config_Found := False;
  188.     Assign (Config, Drive + ':\CONFIG.SYS');
  189.     {$I-} Reset (Config); {$I+}
  190.  
  191.     If (IOResult <> 0) Then                { Didn't find file, try readonly. }
  192.         Config_Found := False
  193.     Else
  194.         Config_Found := True;
  195.  
  196.     If Config_Found Then               { scan CONFIG.SYS for 'SHELL=' line }
  197.     Begin
  198.         Shell_Found := False;
  199.         CtlRec [2]. FPathname := ':\CONFIG.SYS';
  200.         While NOT EOF (Config) AND NOT Shell_Found Do
  201.         Begin
  202.             ReadLn (Config, Line);
  203.             I := Pos ('SHELL', UpCaseStr (Line));
  204.             If I <> 0 Then
  205.             Begin
  206.                 I := Pos ('=', Line);
  207.                 J := Pos ('.COM', Line);
  208.                 Line := RTrim (LTrim (SubStr (Line, I + 1, J + 4)));
  209.                 Shell_Found := True;
  210.             End;
  211.         End;
  212.         Close (Config);
  213.         CtlRec [1].fpathname := SubStr (Line, 2, Length (Line));
  214.     End
  215.     Else
  216.         CtlRec [1].fpathname := ':\COMMAND.COM';
  217.     CtlRec [3].fpathname := ':\AUTOEXEC.BAT';
  218.  
  219.     Attr_Word := Hidden OR SysFile;
  220.     I := 4;
  221.     FindFirst (Drive + ':\*.*', Attr_Word, Dir_Info);
  222.     While (DOSError = 0) AND (I <= Checked_Files) Do
  223.     Begin
  224.         If (Pos ('DOS', Dir_Info.Name) <> 0) OR
  225.            (Pos ('BIO', Dir_Info.Name) <> 0)    Then
  226.         Begin
  227.             CtlRec [I]. FPathname := ':\' + Dir_Info.Name;
  228.             Inc (I);
  229.         End;
  230.         FindNext (Dir_Info);
  231.     End;
  232.  
  233.     Assign  (CtlFile, Drive + ':\CHECK-OS.CTL');
  234.     ReWrite (CtlFile);
  235.     For I := 1 to Checked_Files Do
  236.     Begin
  237.         ChkFile (CtlRec, I);
  238.         Write   (CtlFile, CtlRec[I]);
  239.     End;
  240.     Writeln ('Control file created');
  241.  
  242. End;
  243.  
  244.  
  245.  
  246. Begin
  247.     DirectVideo := False; { make this program well behaved. }
  248.     Assign  (Output,'');  { allows redirection even though CRT unit is used }
  249.     ReWrite (Output);
  250.     WriteLn ('Check-OS       Version 1.0b    13 March 88', CR, LF);
  251.     If (ParamCount < 1) Then
  252.         WriteLn ('Usage: Check-OS <drive letter>')
  253.     Else
  254.     Begin
  255.         Parm  := Paramstr (1);
  256.         Drive := UpCase (Parm [1]);
  257.         Assign (CtlFile, Drive + ':\CHECK-OS.CTL');
  258.         {$I-} Reset (CtlFile); {$I+}
  259.         If (IOResult = 0) Then
  260.         Begin
  261.             For I := 1 to Checked_Files Do
  262.             Begin
  263.                 Read (CtlFile, CtlRec[I]);
  264.                 NewRec [I]. FPathname := CtlRec [I]. FPathname;
  265.                 ChkFile (NewRec, I);
  266.             End;
  267.             ValidateFiles;
  268.         End
  269.         Else
  270.             CreateControlFile;
  271.         Close (CtlFile);
  272.     End;
  273. End.
  274.