home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / L.ZIP / LITBLA.LZH / FINDINT.PAS < prev    next >
Pascal/Delphi Source File  |  1991-04-01  |  5KB  |  122 lines

  1. {The program find_intruder determines which files are infected by the INTRUDER
  2.  virus on a specified disk drive. It works by looking for the same ID code as
  3.  the virus does when determining whether a file has already been infected. That
  4.  code is located at the initial code segment, offset 0, in the EXE file. This
  5.  must be located in the disk file and read, and compared with the value
  6.  contained in INTRUDER}
  7.  
  8.  
  9. program find_intruder;     {Compile with Turbo Pascal 4.0 or higher}
  10.  
  11. uses dos;
  12.  
  13. const
  14.   id_check         :word=$C8AA;         {Intruder ID code word to look for}
  15.  
  16. type
  17.   header_type      =record              {EXE file header structure}
  18.     signature      :word;
  19.     lp_size        :word;
  20.     pg_count       :word;
  21.     rel_tbl_entries:word;
  22.     hdr_paragraphs :word;
  23.     minalloc       :word;
  24.     maxalloc       :word;
  25.     init_ss        :word;
  26.     init_sp        :word;
  27.     chksum         :word;
  28.     init_ip        :word;
  29.     init_cs        :word;
  30.     rel_tbl_ofs    :word;
  31.     overlay        :word;
  32.     end;
  33.  
  34. var
  35.   check_file       :file;               {File being checked}
  36.   header           :header_type;        {Exe header data area for file being checked}
  37.   id_byte          :word;               {Init CS:0000 value from the file being checked}
  38.   srchpath         :string;             {Used to store the current path being searched}
  39.  
  40.  
  41. {The following routine checks one file for infection by opening it, reading
  42.  the EXE header, calculating the location of Initial CS:0000, and reading 2
  43.  bytes from there. Then it compares those bytes with id_check. If they're the
  44.  same, then the file is infected. If the signature is not correct, then the
  45.  program will also display that, so you can find out if you have any non-EXE
  46.  files with the extent .EXE with it.}
  47.  
  48. procedure check_one_file(fname:string);
  49. begin
  50.   assign(check_file,fname);             {Set up the file with this path\name}
  51. {$I-}                                   {I/O checking handled explicitly here}
  52.   reset(check_file,1);                  {Open the file}
  53.   if IOResult<>0 then                   {If an error, just report it to the console}
  54.     begin
  55.       writeln('IO error on the file ',fname);
  56.       exit;
  57.     end;
  58.   BlockRead(check_file,header,sizeof(header));                  {Read the EXE header}
  59.   if IOResult<>0 then
  60.     begin
  61.       writeln('IO error on the file ',fname);
  62.       exit;
  63.     end;
  64.   if header.signature<>ord('Z')*256+ord('M') then
  65.     begin
  66.       writeln(fname,' is not an EXE program file!');
  67.       exit;
  68.     end;
  69.   Seek(check_file,16*(header.hdr_paragraphs+header.init_cs));   {Go seek Init CS:0000}
  70.   if IOResult<>0 then                                           {Don't forget to take into account the size}
  71.     begin                                                       {of header in calculating this!}
  72.       writeln('IO error on the file ',fname);
  73.       exit;
  74.     end;
  75.   BlockRead(check_file,id_byte,2);                              {Read 2 bytes at Init CS:0000}
  76.   if IOResult<>0 then
  77.     begin
  78.       writeln('IO error on the file ',fname);
  79.       exit;
  80.     end;
  81.   close(check_file);                                            {and close the file}
  82.   if IOResult<>0 then
  83.     begin
  84.       writeln('IO error on the file ',fname);
  85.       exit;
  86.     end;
  87. {$I+}
  88.   if id_byte=id_check then writeln(fname,' is infected.')       {if id_byte read from file = id_check, it's infected}
  89. end;
  90.  
  91.  
  92. {The following routine checks all files in the specified path, or any of its
  93.  subdirectories for infection. It will check a whole disk if the initial path
  94.  is '\'. Note that it is recursive, and if directories are nested too deep,
  95.  a stack overflow error will occur.}
  96.  
  97. procedure check_all_files(path:string);
  98. var
  99.   ExeFile          :SearchRec;
  100.   DirEntry         :SearchRec;
  101. begin
  102.   FindFirst(path+'\*.*',Directory,DirEntry);
  103.   while DosError=0 do
  104.     begin
  105.       if (DirEntry.Attr and Directory <> 0)
  106.         and (DirEntry.Name[1]<>'.') then check_all_files(path+'\'+DirEntry.Name);
  107.       FindNext(DirEntry);
  108.     end;
  109.   FindFirst(path+'\*.EXE',AnyFile,ExeFile);
  110.   while DosError=0 do
  111.     begin
  112.       check_one_file(path+'\'+ExeFile.Name);
  113.       FindNext(ExeFile);
  114.     end;
  115. end;
  116.  
  117. begin {main}
  118.   if ParamCount=1 then srchpath:=ParamStr(1)            {if a drive (e.g. 'D:') is specified on command line, use it}
  119.   else srchpath:='';                                    {otherwise take default drive}
  120.   check_all_files(srchpath);                            {and check all files on that drive}
  121. end.
  122.