home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.pascal
- Path: sparky!uunet!spool.mu.edu!uwm.edu!ux1.cso.uiuc.edu!news.cso.uiuc.edu!s.psych.uiuc.edu!amead
- From: amead@s.psych.uiuc.edu (Alan Mead)
- Subject: Does this work (was My PD editor strikes back)
- Message-ID: <BzHr6x.CBs@news.cso.uiuc.edu>
- Sender: usenet@news.cso.uiuc.edu (Net Noise owner)
- Organization: UIUC Department of Psychology
- Date: Sat, 19 Dec 1992 05:28:08 GMT
- Lines: 283
-
- A short while ago someone posted about the strange behavior of an
- editor to having its object code fiddled with. I think we all agreed
- that the code monitored its own CRC and self-destructed when it found
- that it had been modified.
-
- Here is a unit that proports to give your code the same level of
- protection. I also included code that modifies itself so as to
- retain arbitrary valiable values ACROSS runs.
-
- In trying to integrate the two bits of code, I fail to see where the
- virus protection code is excluding its CRC from later CRC checks???
-
- -alan mead
-
- program modifier;
- type
- str7 = string[7];
- modtype = record
- TAG : str7; { TAG is FIRST field!! }
- Val : byte;
- UserData : array[1..100] of byte;
- end;
-
- const
- modify : modtype = (TAG:'ILL-INI'; Val:0; UserData:( 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0 ));
-
- var
- c : longint;
- f : file;
- s : str7;
- i : integer;
- j : byte;
-
- begin
-
- writeln('Tag field is now : ',Modify.TAG);
- writeln('Value field is now: ',Modify.Val);
- Modify.Val := Modify.Val + 1;
- writeln('Next time, it will be: ',Modify.Val);
- repeat
- writeln( 'Set any memory location (0 or 1-100)? ' );
- readln( i );
- if ( i>0 ) AND ( i<=100 ) then
- begin
- writeln( 'Location ',i,' currently equals ',
- Modify.UserData[i],', new value?' );
- readln( j );
- Modify.UserData[i] := j;
- end;
- until i = 0;
-
- assign(f,ParamStr(0)); { open file currently running (will only work under }
- reset(f,1); { DOS 3+; set buffer size to 1 }
-
- c := filesize(f); { set c to current file size (because data is }
- c := c - SizeOf(s); { probably at end of file); subtract off size of s }
- s := '';
-
- {- loop towards front of file looking until match or file starts -}
- While (c > 0) and (s <> Modify.TAG) do
- begin
- Seek(f,c);
- Blockread(f,s,SizeOf(s));
- Dec(c);
- end;
-
- {- seek to the offset of the found string write new record -}
- if c > 0 then
- begin
- Seek(f,c+1);
- BlockWrite(f,Modify,SizeOf(Modify));
- end;
-
- close(f);
-
- end.
-
-
- unit VirCheck;
- interface
- uses dos;
-
- { ==================================================================
-
- Unit: VirCheck v1.0
- Author: Igal Brener
- Solid State Institute and
- Physics Department
- Technion, Haifa
- Israel
- e-mail.: ssrecib@technion.bitnet
- ssrecib@techunix.bitnet
- July, 1990.
- ==================================================================
- The subroutine CheckVirus is based on the program "AUTOINST.PAS" posted
- to usenet news, group comp.lang.pascal by David Dubois. For details,
- see his documentation. After compilation, on the first run of your
- program, this subroutine will calculate the checksum of the EXE file
- (passed as a parameter to the subroutine),
- and store it again on disk (on the same EXE file). Next time you will
- run your program, the subroutine will compare the new checksum with the
- one stored, and if there is a discrepancy, you will get a notice.
- The checksum calculation is done excluding the variable InstallBlock
- which retains the checksum, the flag used for detecting which run
- you are doing, and the last date your file was checked.
- In order to make this routine work with big EXE files,
- I have decided to read the EXE file from disk in records of length
- RecSize, a constant you can change in the subroutine FindChecksum.
- I've chosen records of ~10K, since I'm always short of heap space.
- There is no check to see weather the EXE file exists, but this can
- be easily added.
-
- Any comments or problems, use my e-mail address.
-
- Igal Brener.
-
-
- ==================================================================}
- procedure CheckVirus(FileName:string);
-
- type
- InstallBlockType = record
- already : integer;
- checksum : longint;
- date_Year, date_Month, date_Day: Word;
- end;
- Instptr= array[1..12] of byte;
-
-
-
- const
- InstallBlock : InstallBlockType
-
- = ( already : 0;
- checksum : 0;
- date_Year: 0;
- date_Month: 0;
- date_Day: 0);
-
- implementation
- procedure CheckVirus(FileName:string);
-
- var
- c : Longint;
- pInst : ^Instptr;
- i : integer;
- y,m,d,dow: Word;
-
- {*****************************************************************************}
- procedure ReInstall;
-
- var
- ExeFile : file;
- HeaderSize: word;
-
- begin
- assign ( ExeFile, FileName );
- reset ( ExeFile, 1 );
-
- seek ( ExeFile, 8 );
- blockread ( ExeFile, HeaderSize, sizeof ( HeaderSize ) );
-
- seek ( ExeFile, 16 * ( longint ( seg ( InstallBlock ) )
- - PrefixSeg
- + HeaderSize )
- + ofs ( InstallBlock )
- - 256 );
-
- blockwrite ( ExeFile, InstallBlock, sizeof ( InstallBlock ) );
-
- close ( ExeFile );
- end;
-
- {****************************************************************************}
- procedure Findchecksum ( var Checksum: Longint);
-
- const
- RecSize=10000;
-
- type
- barr = array[1..RecSize] of byte;
-
- var
- ExeFile : file;
- t : word;
- b : byte;
- fpointer, pSize, bytesleft, i: Longint;
- DirInfo: SearchRec;
- p : ^barr;
-
- begin
- assign ( ExeFile, FileName );
- reset ( ExeFile, 1 );
- checksum := 0;
- fpointer := 0;
-
- FindFirst(Filename, Archive, DirInfo);
- bytesleft := DirInfo.Size;
-
- { If available heap space is less than RecSize, we don't execute
- this routine}
- if MemAvail>RecSize then
- begin
- while bytesleft>0 do
- begin
- {Here we read RecSize bytes at a time from the EXE file}
- if RecSize<bytesleft then pSize :=RecSize
- else pSize := bytesleft;
-
- GetMem ( p, pSize);
- seek ( ExeFile, fpointer );
- blockread ( ExeFile, p^, pSize );
- i := 1;
- while i <= pSize do
- begin
- checksum := checksum + p^[i];
- inc(i);
- end;
-
- FreeMem ( p, pSize);
- bytesleft := bytesleft - pSize;
- fpointer := fpointer + pSize;
- end;
-
- close ( ExeFile );
- end;
- end;
-
- {****************************************************************************}
-
- begin {of CheckVirus}
-
- GetDate(y,m,d,dow);
-
- with InstallBlock do
- begin
- if already=1 then writeln('** Last date your file was verified: ',
- date_Month:2, '/', date_Day:2, '/', date_Year:4);
- Writeln('** Please wait, checking EXE file ... **');
- findchecksum( c );
-
- if already=1 then
- begin
- pInst := @InstallBlock;
- i := 1;
- While i<=Sizeof(InstallBlock) do
- begin
- c := c - pInst^[i];
- inc(i);
- end;
- if c<>checksum then
- begin
- writeln('** Your EXE file has been changed: possible virus!!');
- Writeln(chr(7), 'Press return ');
- Readln;
- end;
- end
- else
- begin
- checksum := c;
- already := 1;
- end;
-
- date_Year := y;
- date_Month:= m;
- date_Day := d;
- { update .EXE file only if checksum is ok, or if this is the first time
- it is run }
- if c=checksum then ReInstall;
- end;
- end;
-
- end.
-
-