home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* NOVIRUS.PAS *)
- (* Unit zur automatischen Selbstkontrolle des *)
- (* Programmcodes auf Integrität *)
- (* (c) 1991 Martin Wölker & TOOLBOX *)
- (* ------------------------------------------------------ *)
- UNIT NoVirus;
-
- INTERFACE
-
- USES Dos, Crt;
-
- CONST
- modul_name = 'anti_vir';
- Version = '1.1';
- date = '11-16-1990';
-
- VAR
- result : BOOLEAN;
- (* Die Variable result enthält das Ergbnis des Checks. *)
- (* TRUE es wurde keine Veränderung festgestellt *)
- (* FALSE das Programm wurde verändert *)
-
-
- FUNCTION Get_Prog_Name : STRING;
- PROCEDURE Advanced_Exec(Path : PathStr; ComLine : ComStr);
-
- IMPLEMENTATION
-
- CONST
- eof_length = 8;
- eof_marke : STRING [eof_length] = 'abcdefgh';
-
- TYPE
- counters = ARRAY [BYTE] OF BYTE;
-
- FUNCTION Get_Prog_Name : STRING;
- { ermittelt den Namen des laufenden Programms }
- { lauffähig mit MS-DOS ab Version 3.0 }
- VAR
- segm, i, j : WORD;
- BEGIN
- i := 0; j := 0; { Zähler initialisieren }
- { Am Offset $2c des PSP ist die Segmentadresse des }
- segm := MemW[PrefixSeg:$2c]; { Environment abgelegt }
- WHILE MemW[segm:i] <> 0 DO { das Environment }
- Inc(i); { schließt mit $0000 ab}
- Inc(i, 4); { 4 Bytes später folgt }
- WHILE Mem[segm:i] <> 0 DO BEGIN { der Programmname. }
- Inc(j); { Er ist komplett mit }
- Get_Prog_Name[j] := { Pfad abgelegt. }
- CHAR(Mem[segm:i]); { Das Ende ist wie in }
- Inc(i); { "C" mit $00 }
- END; { gekennzeichnet. }
- Get_Prog_Name[0] := CHAR(j); { Länge des Namens in j}
- END;
-
- PROCEDURE Advanced_Exec(Path : PathStr; ComLine : ComStr);
- { Dieses exec läuft immer, egal wie groß der Heap bei }
- { der Compilation des Programms eingestellt wurde, da }
- { unbenutzter Speicher mit dem MS-DOS-Funktionsaufruf }
- { $4A vorher freigegeben wird. }
- VAR
- temp : POINTER;
- anz : WORD;
- Regs : Registers;
- BEGIN
- anz := $FFFF-Ofs(FreePtr^)+10; { <-- Fragmentliste }
- GetMem(temp, anz); { auf dem Heap }
- Move(FreePtr^,temp^,anz); { sichern }
-
- Regs.ah := $4A;
- Regs.es := PrefixSeg;
- Regs.bx := Seg(HeapPtr^)+1-PrefixSeg;
- MsDos(Regs);
- Dos.SwapVectors;
- Dos.Exec(Path, ComLine);
- Dos.SwapVectors;
- Regs.ah := $4A;
- Regs.es := PrefixSeg;
- Regs.bx := $FFFF;
- MsDos(Regs);
- Move(temp^, FreePtr^, anz);
- FreeMem(temp, anz);
- END;
-
-
- FUNCTION Kontrolle_File : BOOLEAN;
- { Testet, ob es sich um ein File handelt, das bereits }
- { eine Kontrollstruktur hat. }
- { Dies wird am Schlüsseltext "eof_marke" erkannt. }
- VAR
- prog : FILE OF CHAR;
- zeichen : CHAR;
- position : BYTE;
- hilf : BOOLEAN;
- BEGIN
- Assign(prog, Get_Prog_Name);
- Reset(prog);
- Seek(prog, FileSize(prog)-eof_length);
- position := 1;
- REPEAT
- Read(prog, zeichen);
- hilf := (zeichen = eof_marke[position]);
- Inc(position);
- UNTIL NOT hilf OR (position > eof_length);
- Kontrolle_file := hilf;
- Close(prog);
- END;
-
- PROCEDURE get_check(VAR old_check_result : counters);
- { Öffnet die Datei, die das Programm enthält und liest }
- { die im Programm selbst gespeicherten Kontrolldaten. }
- VAR
- prog : FILE OF BYTE;
- position : BYTE;
- BEGIN
- Assign(prog, Get_Prog_Name);
- Reset(prog);
- Seek(prog, FileSize(prog)-SizeOf(counters)-eof_length);
- FOR position:= 0 TO 255 DO
- Read(prog, old_check_result[position]);
- Close(prog);
- END;
-
- PROCEDURE make_check(VAR check_result : counters);
- { Öffnet die Datei, die das Programm enthält und }
- { berechnet damit die Kontrollstruktur. }
- VAR
- daten : counters;
- prog : FILE OF CHAR;
- blockprog : FILE;
- i, anzahl : WORD;
- j : BYTE;
- BEGIN
- Assign(prog, Get_Prog_Name);
- Reset(prog);
- IF Kontrolle_file THEN
- anzahl := (FileSize(prog) - SizeOf(counters) -
- eof_length) DIV 256
- ELSE
- anzahl := FileSize(prog) DIV 256;
- Close(prog);
-
- FillChar(check_result, 256, 0);
- Assign(blockprog, Get_Prog_Name);
- Reset(blockprog);
- FOR i :=1 TO anzahl DO BEGIN
- BlockRead(blockprog, daten, 2);
- FOR j := 0 TO 255 DO
- Inc(check_result[daten[j]]);
- END;
- Close(blockprog);
-
- FOR j := 0 TO 255 DO
- IF check_result[j] = BYTE(^Z) THEN
- check_result[j] := 0;
- END;
-
- PROCEDURE Kontrolle_test;
- { Vergleicht die gespeicherten Kontrolldaten }
- { mit den aus dem Programm berechneten. }
- VAR
- alt,jetzt : counters;
- position : BYTE;
- BEGIN
- make_check(jetzt);
- get_check(alt);
- position := 0;
- REPEAT
- result := (alt[position] = jetzt[position]);
- Inc(position);
- UNTIL NOT result OR (position = 0);
- END;
-
- PROCEDURE Kontrolle_make;
- { Öffnet die Datei, die das Programm enthält und hängt }
- { die Kontrollsequenz, die mit der Routine check_file }
- { erzeugt wird, mittels command.com /c type }
- { "tempöräre Datei" >> an das Programm an. }
- VAR
- prog : FILE OF BYTE;
- check_array : counters;
- i : BYTE;
- BEGIN
- make_check(check_array);
- Assign(prog, 'temp.dat');
- Rewrite(prog);
- FOR i := 0 TO 255 DO
- Write(prog, check_array[i]);
- FOR i := 1 TO eof_length DO
- Write(prog, BYTE(eof_marke[i]));
- Close(prog);
- advanced_exec('\command.com ',
- '/C type temp.dat >> ' + Get_Prog_Name);
- { Pfad des Kommandoprozessors ggf. anpassen ! }
- Assign(prog, 'temp.dat');
- Erase(prog);
- result := TRUE;
- END;
-
- PROCEDURE anti_virus;
- BEGIN
- IF Kontrolle_file THEN Kontrolle_test
- ELSE Kontrolle_make;
- END;
-
-
- BEGIN
- anti_virus;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von NOVIRUS.PAS *)