home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 05 / tricks / novirus.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-01-09  |  6.4 KB  |  213 lines

  1. (* ------------------------------------------------------ *)
  2. (*                   NOVIRUS.PAS                          *)
  3. (*      Unit zur automatischen Selbstkontrolle des        *)
  4. (*    Programmcodes auf Integrität                        *)
  5. (*             (c) 1991 Martin Wölker & TOOLBOX           *)
  6. (* ------------------------------------------------------ *)
  7. UNIT NoVirus;
  8.  
  9. INTERFACE
  10.  
  11. USES Dos, Crt;
  12.  
  13. CONST
  14.   modul_name = 'anti_vir';
  15.   Version    = '1.1';
  16.   date       = '11-16-1990';
  17.  
  18. VAR
  19.   result : BOOLEAN;
  20.   (* Die Variable result enthält das Ergbnis des Checks.  *)
  21.   (*   TRUE    es wurde keine Veränderung festgestellt    *)
  22.   (*   FALSE   das Programm wurde verändert               *)
  23.  
  24.  
  25.   FUNCTION  Get_Prog_Name : STRING;
  26.   PROCEDURE Advanced_Exec(Path : PathStr; ComLine : ComStr);
  27.  
  28. IMPLEMENTATION
  29.  
  30. CONST
  31.   eof_length = 8;
  32.   eof_marke  : STRING [eof_length] = 'abcdefgh';
  33.  
  34. TYPE
  35.   counters  = ARRAY [BYTE] OF BYTE;
  36.  
  37.   FUNCTION Get_Prog_Name : STRING;
  38.     { ermittelt den Namen des laufenden Programms   }
  39.     { lauffähig mit MS-DOS ab Version 3.0           }
  40.   VAR
  41.     segm, i, j : WORD;
  42.   BEGIN
  43.     i := 0;  j := 0;               { Zähler initialisieren }
  44.         { Am Offset $2c des PSP ist die Segmentadresse des }
  45.     segm := MemW[PrefixSeg:$2c];    { Environment abgelegt }
  46.     WHILE MemW[segm:i] <> 0 DO      { das Environment      }
  47.       Inc(i);                       { schließt mit $0000 ab}
  48.     Inc(i, 4);                      { 4 Bytes später folgt }
  49.     WHILE Mem[segm:i] <> 0 DO BEGIN { der Programmname.    }
  50.       Inc(j);                       { Er ist komplett mit  }
  51.       Get_Prog_Name[j] :=           { Pfad abgelegt.       }
  52.          CHAR(Mem[segm:i]);         { Das Ende ist wie in  }
  53.       Inc(i);                       { "C" mit $00          }
  54.     END;                            { gekennzeichnet.      }
  55.     Get_Prog_Name[0] := CHAR(j);    { Länge des Namens in j}
  56.   END;
  57.  
  58.   PROCEDURE Advanced_Exec(Path : PathStr; ComLine : ComStr);
  59.     { Dieses exec läuft immer, egal wie groß der Heap bei  }
  60.     { der Compilation des Programms eingestellt wurde, da  }
  61.     { unbenutzter Speicher mit dem MS-DOS-Funktionsaufruf  }
  62.     { $4A vorher freigegeben wird.                         }
  63.   VAR
  64.     temp : POINTER;
  65.     anz  : WORD;
  66.     Regs : Registers;
  67.   BEGIN
  68.     anz := $FFFF-Ofs(FreePtr^)+10;   { <-- Fragmentliste   }
  69.     GetMem(temp, anz);               { auf dem Heap        }
  70.     Move(FreePtr^,temp^,anz);        { sichern             }
  71.  
  72.     Regs.ah := $4A;
  73.     Regs.es := PrefixSeg;
  74.     Regs.bx := Seg(HeapPtr^)+1-PrefixSeg;
  75.     MsDos(Regs);
  76.     Dos.SwapVectors;
  77.     Dos.Exec(Path, ComLine);
  78.     Dos.SwapVectors;
  79.     Regs.ah := $4A;
  80.     Regs.es := PrefixSeg;
  81.     Regs.bx := $FFFF;
  82.     MsDos(Regs);
  83.     Move(temp^, FreePtr^, anz);
  84.     FreeMem(temp, anz);
  85.   END;
  86.  
  87.  
  88.   FUNCTION Kontrolle_File : BOOLEAN;
  89.     { Testet, ob es sich um ein File handelt, das bereits  }
  90.     { eine Kontrollstruktur hat.                           }
  91.     { Dies wird am Schlüsseltext "eof_marke" erkannt.      }
  92.   VAR
  93.     prog     : FILE OF CHAR;
  94.     zeichen  : CHAR;
  95.     position : BYTE;
  96.     hilf     : BOOLEAN;
  97.   BEGIN
  98.     Assign(prog, Get_Prog_Name);
  99.     Reset(prog);
  100.     Seek(prog, FileSize(prog)-eof_length);
  101.     position := 1;
  102.     REPEAT
  103.       Read(prog, zeichen);
  104.       hilf := (zeichen = eof_marke[position]);
  105.       Inc(position);
  106.     UNTIL NOT hilf OR (position > eof_length);
  107.     Kontrolle_file := hilf;
  108.     Close(prog);
  109.   END;
  110.  
  111.   PROCEDURE get_check(VAR old_check_result : counters);
  112.     { Öffnet die Datei, die das Programm enthält und liest }
  113.     { die im Programm selbst gespeicherten Kontrolldaten.  }
  114.   VAR
  115.     prog     : FILE OF BYTE;
  116.     position : BYTE;
  117.   BEGIN
  118.     Assign(prog, Get_Prog_Name);
  119.     Reset(prog);
  120.     Seek(prog, FileSize(prog)-SizeOf(counters)-eof_length);
  121.     FOR position:= 0 TO 255 DO
  122.       Read(prog, old_check_result[position]);
  123.     Close(prog);
  124.   END;
  125.  
  126.   PROCEDURE make_check(VAR check_result : counters);
  127.     { Öffnet die Datei, die das Programm enthält und }
  128.     { berechnet damit die Kontrollstruktur.          }
  129.   VAR
  130.     daten     : counters;
  131.     prog      : FILE OF CHAR;
  132.     blockprog : FILE;
  133.     i, anzahl : WORD;
  134.     j         : BYTE;
  135.   BEGIN
  136.     Assign(prog, Get_Prog_Name);
  137.     Reset(prog);
  138.     IF Kontrolle_file THEN
  139.       anzahl := (FileSize(prog) - SizeOf(counters) -
  140.                                   eof_length) DIV 256
  141.     ELSE
  142.       anzahl := FileSize(prog) DIV 256;
  143.     Close(prog);
  144.  
  145.     FillChar(check_result, 256, 0);
  146.     Assign(blockprog, Get_Prog_Name);
  147.     Reset(blockprog);
  148.     FOR i :=1 TO anzahl DO  BEGIN
  149.       BlockRead(blockprog, daten, 2);
  150.       FOR j := 0 TO 255 DO
  151.         Inc(check_result[daten[j]]);
  152.     END;
  153.     Close(blockprog);
  154.  
  155.     FOR j := 0 TO 255 DO
  156.       IF check_result[j] = BYTE(^Z) THEN
  157.         check_result[j] := 0;
  158.   END;
  159.  
  160.   PROCEDURE Kontrolle_test;
  161.     { Vergleicht die gespeicherten Kontrolldaten }
  162.     { mit den aus dem Programm berechneten.      }
  163.   VAR
  164.     alt,jetzt : counters;
  165.     position  : BYTE;
  166.   BEGIN
  167.     make_check(jetzt);
  168.     get_check(alt);
  169.     position := 0;
  170.     REPEAT
  171.       result := (alt[position] = jetzt[position]);
  172.       Inc(position);
  173.     UNTIL NOT result OR (position = 0);
  174.   END;
  175.  
  176.   PROCEDURE Kontrolle_make;
  177.     { Öffnet die Datei, die das Programm enthält und hängt }
  178.     { die Kontrollsequenz, die mit der Routine check_file  }
  179.     { erzeugt wird, mittels command.com /c type            }
  180.     { "tempöräre Datei" >> an das Programm an.             }
  181.   VAR
  182.     prog        : FILE OF BYTE;
  183.     check_array : counters;
  184.     i           : BYTE;
  185.   BEGIN
  186.     make_check(check_array);
  187.     Assign(prog, 'temp.dat');
  188.     Rewrite(prog);
  189.     FOR i := 0 TO 255 DO
  190.       Write(prog, check_array[i]);
  191.     FOR i := 1 TO eof_length DO
  192.       Write(prog, BYTE(eof_marke[i]));
  193.     Close(prog);
  194.     advanced_exec('\command.com ',
  195.                   '/C type temp.dat >> ' + Get_Prog_Name);
  196.     { Pfad des Kommandoprozessors ggf. anpassen ! }
  197.     Assign(prog, 'temp.dat');
  198.     Erase(prog);
  199.     result := TRUE;
  200.   END;
  201.  
  202.   PROCEDURE anti_virus;
  203.   BEGIN
  204.     IF Kontrolle_file THEN Kontrolle_test
  205.                       ELSE Kontrolle_make;
  206.   END;
  207.  
  208.  
  209. BEGIN
  210.   anti_virus;
  211. END.
  212. (* ------------------------------------------------------ *)
  213. (*                 Ende von NOVIRUS.PAS                   *)