V G A n t i
___________
Создателю
вируса
"AIDC"
посвящается.
Причиной, побудившей меня написать VGAnti, послужило то,
что в Курском политехническом ( где я учусь ) появился новый
вирус. Кто и когда его занес в институт - остается только га-
дать, хотя я не исключаю, что он написан одним из наиболее
грамотных наших студентов ( а большинство студентов КПИ на это
не способна по причине отсуствия элементарных знаний Ассембле-
ра и работы MSDOS). С чего содрали этот вирус мне судить не
приходится, но некоторое философское начало в структуре
присуствует.
Короче распространился он быстро, и кто-то из студентов
завез вирус на работу к моему другу Польшинскому Юре. И в один
прекрасный день на дисплее при запуске какой-то программы
высветилось "AIDS" и машина зависла. Хватились туда-сюда :
большинство программ заражено. Что возможно восстановили из
архивов, но кое-что ценное хранилось на жестком диске в одном
экземпляре. Это и стало основной причиной моих усилий.
Конечно не мне тягаться с Лозинским и другими ассами, но
на данный момент ни AIDSTEST, ни SOS , ни SCAN не ловят
"AIDS", так что, как говорится, не от хорошей жизни я коря-
чился.
Теперь несколько слов о вирусе. Не для создателей фагов
( они с вирусом, думаю, и без моих советов разберуться ) а
просто для любопытных.
Вирус "AIDS"
____________
Вирус имеет длину 552 байта, и именно на это количество
байт удлинняется зараженная программа. При запуске зара-
женной программы вирус проверяет себя на наличие в памя-
ти, и если его там еще нет - инициализируется. При этом
он пересылает себя в старшие адреса памяти и "отрезает"
у ДОС 1К ОЗУ. Перехватывается 21H прерывание ДОС функция
3EH. Заражение происходит только при закрытии файла. За-
ражаются только EXE файлы, если младшие два байта длинны
больше 2800H. После каждого 8-го заражения файл пога-
нится : в начало записывается кусок вируса, выдающий ду-
рацкую заставку. В том что вирус советского происхожде-
ния у меня нет сомнений, причем писал его человек, абсо-
лютно не сведующий в медицине, так как "AIDS" написано
как "AIDC". При каждом заражении вирус случайным образом
кодирует часть своего тела. Записывается всегда в конец
файла. Косвенным признаком наличия вируса служат буквы
"шв" в окрестности 500 байт от конца файла. Год написа-
ния вируса - 1990, т.к. именно эта цифра проставляется в
контрольной сумме зараженного файла и служит признаком
заражения. Но кроме зтой маленькой слабости в вирусе не
содержится никакой саморекламы.
Надеюсь, мой маленький вклад в дело борьбы с заразой не
пропадет и мой VGAnti поможет кому-нибудь сохранить свои прог-
раммы.
Валера Гражданкин.
1991 год.
_____________________________________________________________________
Адрес для отзывов и замечаний:
305018 г.Курск-18 пр.Кула-
кова д.7 кв.5
P.S.
1.VGAnti может дать сбой если атрибут проверяемого фай-
ла "Read only". Я это конечно исправлю, но сейчас
некогда. Извиняюсь.
2.AIDSTEST 157 и SOS обезвреживают этот вирус,
но не вакцинируют файл.
22.11.91 г.
{> Cut here. FileName= VGANTI.PAS }
{************************************}
{* Turbo Pascal 4.0 - 6.0 *}
{* Свободно для использования *}
{* и модификации *}
{*----------------------------------*}
{* Автор: Гражданкин Валерий *}
{* г.Курск *}
{* VGSoft Inc. *}
{************************************}
{*=======================================================*}
{* P.S. Неудачен алгоритм построения дерева каталога : *}
{* может не хватить памяти *}
{*=======================================================*}
program VGAnti;
uses Dos, CRT {, AidsTst };
const
Len=10;
AidsDat:array[0..len-1] of byte=
($FA, $80, $FC, $3E, $75, $3, $E8, $5, $0, $EA );
type
ByteArr = array [0..65534] of byte;
PPath = ^PathRec;
PathRec = record
Path : PathStr;
Next : PPath;
end;
var Vec1o, Vec1s, Vec2o, Vec2s:word;
I: integer;
Buf, Buf1: ^ByteArr;
Result, AIP : word;
AOfs, VirOfs, VirLoc : longint;
Vakcin : boolean;
VS : string[20];
FPath : PathStr;
Sr:SearchRec;
DiskName : String[2];
F:file;
Trees, PTree1 : PPath;
Procedure NextToSpis(Var PS: PPath; LPath: PathStr; Var Sr: SearchRec);
var P1 :PPath;
begin
While DosError=0 do
begin
New(P1);
P1^.Next:=PS;
PS:=P1;
PS^.Path:=DiskName+LPath+'\'+Sr.Name;
FindNext(Sr);
end;
end;
procedure MakeTree( Var PTree: PPath);
label 10, 20, 30;
type
PDKats = ^DKats;
DKats = record
Name : String[14];
Path : PathStr;
Level : word;
Pred : PDKats;
Right : PDKats;
Left : PDKats;
end;
var
Sr, KSr : SearchRec;
SP, LPath : PathStr;
TekKat : PDKats;
WorkKat, OldLeft, OldPred : PDKats;
P1, P2 : PPath;
CurLevel:word;
CurPath :PathStr;
IsOne :Boolean;
begin
While PTree<>nil do
begin
P1:=PTree;
PTree:=PTree^.Next;
Dispose(P1);
end;
FindFirst(DiskName+'\*.EXE', Archive, Sr);
NextToSpis(PTree,'', Sr);
SP:='';
CurLevel:=1;
CurPath :='\';
New(TekKat);
TekKat^.Pred:=nil;
TekKat^.Left:=nil;
TekKat^.Right:=nil;
TekKat^.Level:=0;
TekKat^.Name:='';
TekKat^.Path:='\';
FindFirst(DiskName+'\*.*', Directory, KSr);
OldLeft:=TekKat;
OldPred:=nil;
IsOne:=false;
10:
IsOne:=false;
while DosError=0 do
begin
if (KSr.Name<>'.') and (KSr.Name<>'..')
and (KSr.Attr=Directory) then
begin
IsOne:=true;
New(WorkKat);
WorkKat^.Pred:=OldPred;
WorkKat^.Left:=OldLeft;
WorkKat^.Right:=nil;
WorkKat^.Name:=KSr.Name;
WorkKat^.Level:=CurLevel;
if CurPath='\' then WorkKat^.Path:=CurPath+KSr.Name
else WorkKat^.Path:=CurPath+'\'+KSr.Name;
TekKat:=WorkKat;
OldLeft:=TekKat;
OldPred:=nil;
{ Writeln(DiskName+TekKat^.Path);}
FindFirst(DiskName+TekKat^.Path+'\*.EXE', Archive, Sr);
NextToSpis(PTree,TekKat^.Path, Sr);
end;
FindNext(KSr);
end;
If IsOne then
begin
20:
CurPath:=TekKat^.Path;
FindFirst(DiskName+CurPath+'\*.*', Directory, KSr);
if DosError=0 then
begin
OldLeft:=nil;
OldPred:=TekKat;
goto 10;
end;
end;
30:
if TekKat^.Left<>nil then
begin
TekKat:=TekKat^.Left;
if TekKat^.Right<>nil then Dispose(TekKat^.Right);
Goto 20;
end;
if TekKat^.Pred<>nil then
begin
TekKat:=TekKat^.Pred;
if TekKat^.Right<>nil then Dispose(TekKat^.Right);
Goto 30;
end;
end;
begin
writeln;
writeln('VGAnti версия 1.0, автор В.Гражданкин.');
writeln('(C) VGSoft, май, 1991 г.');
writeln;
writeln('Средство против вируса "AIDS"');
writeln;
{ AidsControl(129,21,14);}
Vakcin :=false;
Vec1o:=MemW[0:$A];
Vec1s:=MemW[0:$C];
Vec2o:=MemW[0:$84];
Vec2s:=MemW[0:$86];
I:=0;
While (I<len) and (Mem[Vec2s:Vec2o+I]=AidsDat[I]) do inc(I);
if I>=Len then
begin
Writeln('Вирус "AIDS" в памяти Вашей машины !!!');
MemW[0:$84]:=MemW[Vec2s:Vec2o+Len];
MemW[0:$86]:=MemW[Vec2s:Vec2o+Len+2];
writeln('Деятельность вируса блокирована .');
inc(MemW[0:$413]);
writeln('Вирус из памяти удален.');
writeln;
end;
if paramcount<1 then
begin
writeln('Это моя первая антивирусная программа, так что не',
' обижайтесь,');
writeln('если она что-нибудь не так исправит. Пока VGAnti находит ');
writeln('только "AIDS" и излечивает от него. Файлы, испорченные',
' вирусом,');
writeln('после запуска выдают на экран заставку и машина зависает.');
writeln('Такие файлы легко обнаружить самому, они исправлению не',
' подлежат');
writeln('и их надо уничтожить. ');
writeln;
writeln('Формат запуска : VGAnti Диск /V');
writeln('Например : VGAnti C: /V');
writeln('Флажок /V указывает на вакцинирование файлов (если',
' возможно)');
writeln('от повторного заражения "AIDS"');
exit;
end;
DiskName:=ParamStr(1);
DiskName[2]:=':';
DiskName[1]:=UpCase(DiskName[1]);
if paramcount>1 then
begin
VS:=ParamStr(2);
if (VS='/v') or (VS='/V') then Vakcin:=true;
end;
TRees:=nil;
MakeTree(Trees);
GetMem(Buf, $1A);
GetMem(Buf1, 10000);
while Trees<>nil do
begin
Assign(F, Trees^.Path);
{$I-}
reset(F,1);
{$I+}
if IOResult<>0 then
begin
writeln('Ошибка ввода-вывода : ненормальное завершение .');
exit;
end;
GotoXY(1, WhereY);
ClrEol;
write(Trees^.Path);
BlockRead(F, Buf^, $1A, Result);
if (Buf^[$13]=$19) and(Buf^[$12]=$90) then
begin
write(' - заражен "AIDS"');
AOfs:=(Buf^[8]+Buf^[9]*256)*16;
AIP:=Buf^[$14]+Buf^[$15]*256;
VirOfs:=(Buf^[$16]+Buf^[$17]*256);
VirLoc:=AOfs+AIP+VirOfs*16;
Seek(F, VirLoc);
BlockRead(F, Buf1^, 1000, Result);
Buf^[$14]:=Buf1^[10];
Buf^[$15]:=Buf1^[11];
Buf^[$16]:=Buf1^[3];
Buf^[$17]:=Buf1^[4];
VirOfs:=VirLoc-$FF;
AIP:=(VirOfs-AOfs) mod 512;
Buf^[2]:=Lo(AIP);
Buf^[3]:=Hi(AIP);
AIP:=trunc(VirOfs/512);
if AIP*512<VirOfs then inc(AIP);
Buf^[4]:=Lo(AIP);
Buf^[5]:=Hi(AIP);
If Vakcin then
Buf^[$12]:=1 else Buf^[$12]:=0;
Buf^[$13]:=0;
Seek( F, 0);
BlockWrite(F, Buf^, $1A, Result);
Seek(F, VirLoc-$FF);
Truncate(F);
write(' : вылечен');
if Buf^[$12] = 1 then writeln(' и вакцинирован')
else writeln;
end;
close(F);
PTree1:=Trees;
Trees:=Trees^.Next;
Dispose(PTree1);
end;
FreeMem(Buf, $1A);
FreeMem(Buf1, 10000);
gotoXy(1,WhereY);
ClrEol;
writeln('Работа закончена .');
end.
|