Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Программирование

Добавлен: 16.02.2019

Просмотров: 29238

Скачиваний: 1689

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

Часть III. Файловая оболочка, вирус, резидент 

204 

Create_dirmessl

  программа-ассемблер  будет  использовать  исключительно  для 

своих целей, а значит, в код программы она не попадет. Рассмотрим это подробнее: 

Create_dirmessl equ $-Create_dirmess-2 

(текущее смещение) минус смещение 

Create_dirmess

 минус два (т. к. первые 

два  байта  и  будут  указывать  на  длину  строки).  Временная  переменная 

Create_dirmessl

  будет  равна  длине  строки.  Пожалуйста,  внимательно  изучите 

приведенные выше примеры. Очень важно понять этот принцип. 

Как  только  занесли  в 

si

  адрес  строки,  вызываем  процедуру 

Move_string

.  При 

этом в 

bx

 будет находиться сегмент строки, который передала некая программа. 

В  целом,  принцип  такой:  процедура 

Move_string

  заносит  по  смещению  0  сег-

мента, в котором находится наш резидент (т. е. в область PSP), соответствующую 
строку  (например,  "

Создание  каталога  --->

  "),  после  нее  заносится  имя  файла,  

а  именно  то,  что  находится  в  паре  регистров 

ds:dx

  на  входе  в  прерывание 

21h

.  

Это  может  быть  как  имя  файла,  так  и  полный  путь  к  нему.  Например, 

диск:\каталог\имя_файла

 —

 C:\My_dir\file.ext

. Вот именно это мы и записыва-

ем по смещению 0 сегмента, в котором находится наша программа. 

Допустим, какая-то программа пытается создать каталог c:\assm\directory, тогда 

в LOG-файл запишется приведенная ниже строка: 

Создание каталога ---> c:\assm\directory 

Резидент  достаточно  прост,  хотя  в  нем  существуют  команды, которые мы еще 

не рассматривали. В описаниях файла-приложения достаточно информации, чтобы 
разобраться  в  том,  что  именно  делает  та  или  иная функция или команда. Вы уже 
сами можете написать подобный резидент, опираясь на информацию из этой главы. 

19.2. Что нужно вам вынести из этой главы? 

Необходимо разобрать резидент и понять его работу. Вы должны проанализиро-

вать алгоритмы, если, конечно, хотите выучить ассемблер. Мы лишь приведем об-
щие понятия работы резидентной программы. 

Мы перехватываем прерывание 

21h

, помещая его адрес в прерывание 

03h

. Это 

значит, что наш резидент невозможно будет просмотреть под многими отладчика-
ми. Обратите внимание, как мы вызываем прерывание 

21h

 в нашем обработчике. 

В  принципе,  настоящий  резидент довольно прост. Вам достаточно разобраться  

с описанием в файле-приложении. 

Все то, что осталось за кадром, мы подробнее рассмотрим в последующих гла-

вах на других сходных примерах. 

 


background image

 

 

 

Глава 20 

 

Финальная версия вируса 

 

 
Теперь наш вирус полностью работоспособен. Будьте осторожны! Случайно за-

разив нужный файл, вам придется провести некоторое время, чтобы вылечить его 
вручную. Так что, будьте предельно внимательны! 

Несколько  слов  о  программе.  (Обязательно  прочитайте,  прежде  чем  запускать 

вирус!) 

 

Вирус  нерезидентный.  Это  значит,  что  заражать  он  будет  программы  только  
в случае, если запустить зараженный COM-файл. После того как вирус отрабо-
тал, он из памяти удаляется. 

 

Вирус не делает ничего, кроме как заражает файлы. 

 

Ни один антивирус не вылечит файл, зараженный нашим вирусом! Так что, не 
надейтесь ни на Dr. Web, ни на что-либо еще. 

 

Вирус заражает только COM-файлы в текущем каталоге. Что это значит? 
Допустим, в каталоге C:\assm есть следующие файлы: 

  test.com; 

  dn.com; 

  nc.exe. 

Причем test.com уже заражен нашим вирусом. Запуская test.com на выполнение, 
он  заражает  dn.com.  Запустив  затем  dn.com,  вирус  ничего  не  заразит,  т. к.  
в данном каталоге больше нет незараженных нашим вирусом COM-файлов. 
Но если у вас в переменной 

PATH

 (в autoexec.bat) стоит путь к каталогу c:\assm, 

то,  запустив  test.com  из  текущего  каталога,  скажем,  c:\nc,  наш  вирус  заразит 
первый встречный COM-файл в каталоге c:\nc. Будьте осторожны!!! 
Если все же произошла беда, и вы не знаете, как удалить вирус, заразивший весь 
компьютер, то см. главу 24, где приведен код антивируса. Хотя, если перед тем, 
как запускать virus20.com на выполнение, вы прочтете описания к нему и разбе-
ретесь во всем, то вам не составит труда восстановить зараженный файл. 

 

COM-файлы, расположенные в каталоге C:\Windows\Command, после заражения 
отказываются  работать  корректно.  С  чем  это  связано —  не  совсем  понятно. 
Причем  после  сжатия  файлов  программой  PKLITE,  командная  строка  по-
прежнему  определяется  неверно.  Скорее  всего,  эти  файлы  подсчитывают  кон-
трольную  сумму  или  еще  что-то...  Для  экспериментов  придется  искать  другие 
COM-файлы. 


background image

 

Часть III. Файловая оболочка, вирус, резидент 

206 

 

Как вы думаете, зачем мы изучали работу отладчика в главе 16? Дело в том, что 
если вы будете исследовать работу вируса в отладчике, то столкнетесь с одной 
проблемой. Записав вирус в файл с помощью отладчика, а затем, запустив файл 
на выполнение, вы с удивлением заметите, что этот зараженный файл работать 
не будет. Почему? Вспомните, что отладчик вставляет 

int  3

  (

0CCh

). При пере- 

записи  же  программой  самой  себя  под  управлением  отладчика,  программа  пе- 
резапишет  и 

int  3

,  вставленный  этим  отладчиком.  Поэтому  об  этом  забывать  

не следует. 
Еще такой момент: в  главе 24 мы напишем резидентный антивирус против на-

шего  вируса.  Однако  корректно лечить зараженные файлы он будет только в том 
случае, если вы не измените в нашем вирусе ни единого байта!  

20.1. Вирус 

20.1.1. Альтернативы retcall и jmp 

Вопрос:  можно  ли  вместо 

ret

  и 

call

  использовать 

jmp

,  а  вместо 

jmp

 — 

ret

Безусловно. Более того, в некоторых случаях просто невозможно обойтись без ис-
пользования нестандартных команд. 

В табл. 20.1 приведены альтернативы стандартным операторам ассемблера. 

Таблица 20.1. Альтернативы стандартным операторам 

Команда 

Альтернатива 

Описание 

ret  

pop ax 

jmp ax 

Вытащим из стека адрес возврата и пе-
рейдем на него 

call proced  move bx,offset lab_ret 

push bx 

jmp proced 

lab_ret: 

Занесем в стек адрес возврата и "прыг-
нем" на метку процедуры 

jmp label1 

push offset label1 

ret 

Занесем в стек адрес метки и сымитируем 
выход из процедуры 

 
Все это описывалось по той причине, что теперь переход на метку инициализа-

ции вируса (

Init

) осуществляется следующим образом: 

... 
push offset Init    ;3 байта 
ret                 ;1 байт 
... 

Дело  в  том,  что,  используя  нестандартный  метод,  нам  гораздо  удобнее  менять 

адрес метки 

Init

 в зараженных файлах. Читая дальше, вы поймете, почему именно 

так, а не иначе.  


background image

Глава 20. Финальная версия вируса 

207 

20.1.2. Заражение файла 

Заражение файла происходит с помощью процедуры 

Infect_file

. Опустим по-

иск  файлов,  будем  считать,  что  подходящий  файл  уже  найден.  Осталось  только 
проверить его длину (листинг 20.1).  

Листинг 20.1. Проверка размера заражаемого файла 

... 
mov ax,cs:[1Ch]     ;Получим второе слово длины заражаемого файла 
or ax,ax            ;Если оно не равно 0, то выходим... 
jnz Error_infect    ;... это значит, что размер файла больше 64 Кбайт 
mov bp,cs:[1Ah]     ;Получим младшее слово (т. е. размер файла) 
... 

Для чего нам нужно производить проверку размера файла перед его заражени-

ем, если известно, что COM-файлы не могут превышать 64 Кбайт? 

Дело в том, что операционная система определяет, какой тип файла запускается 

не по его расширению, а по первым двум байтам содержимого файла. Если это "

MZ

или "

ZM

", то файл EXE, иначе — COM. Это можно легко проверить, если посмот-

реть в текстовом редакторе на первые два символа файла. Ничто не мешает любому 
пользователю  переименовать  файл,  например,  test.exe  длиной  450 Кбайт  в  test.com. 
ОС все равно определит, что это EXE-файл, по первым двум байтам. 

Типичным  примером  может  служить  файл  command.com,  который  в  MS-DOS 

версии 7.0  занимает  95 Кбайт.  Расширение  COM  оставили  для  совместимости  
с программами, написанными в более старых версиях DOS. 

И что же получится, если мы попробуем заразить тот же command.com, который, 

по сути, является command.exe? 

Мы  просто  его  испортим.  То есть  он  перестанет  работать  вообще.  Вот,  собст-

венно, для этого и следует проверить размер файла, прежде чем заражать его. 

Обратите  внимание,  каким образом мы это делаем. После того как функция 

4Fh

 

или 

4Eh

 нашла файл, в DTA по смещению 

1Ah

 заносится его размер. Так как два бай-

та могут хранить число до 65 535, то для определения размера файла используются 
два  слова.  Первое  (смещение 

1Ah

) —  младшая  половинка,  второе  (смещение — 

1Ch

) — старшая. Вспоминаем, что данные в памяти хранятся в обратном порядке. 

Что мы еще не сделали в вирусе, так это не проверили первые два символа за-

ражаемого  файла  ("

MZ

"  или  "

ZM

").  Для  чего?  Может  случиться  так,  что  EXE-файл 

имеет длину менее 64 Кбайт, но расширение COM. В этом случае зараженный файл 
также  утратит  свою  работоспособность.  Реализовать  же  проверку  на  ассемблере 
труда не составит, поэтому в целях экономии места мы ее опустим. 

Следующие шаги: 

1.  Открываем найденный файл на чтение/запись (функция 

3D02h

 прерывания 

21h

). 

2.  Читаем его первые шесть байт в память (функция 

3Fh

 прерывания 

21h

). 

3.  Проверяем, заражен ли уже этот файл нашим вирусом или еще нет. 


background image

 

Часть III. Файловая оболочка, вирус, резидент 

208 

Рассмотрим  эти  шаги  подробнее.  В  нашем  примере  мы  используем  сигнатуру 

1122h

 для определения того, заражен ли найденный файл нашим вирусом или нет. 

Эта сигнатура должна быть расположена по смещению +4 от начала файла. Обра-
тите внимание, что мы проверяем 

cmp word ptr [bx+4],1122h 

а в файле сигнатура 

1122h

 будет располагаться наоборот: 

2211h

. Вот вам еще одно 

подтверждение того, что данные в компьютере хранятся в обратном порядке. 

А что, если в каком-то незараженном файле по смещению +4 от начала уже есть 

такие  байты?  Получается,  что  мы  посчитаем,  что  файл  уже  заражен?  Да,  это  так. 
Но  как  вы  думаете,  какова  вероятность  того,  что  эта  сигнатура  будет  находиться  
в произвольном файле по такому смещению? Возможно, даже еще и файла такого 
не существует в природе. 

Однако, при желании, программист может всегда увеличить сигнатуру до 10—

20 байт, чтобы быть уверенным в том, что найденный файл действительно уже за-
ражен нашим вирусом. 

Итак,  проверку  на  соответствие  файла  необходимым  требованиям  произвели. 

Теперь  устанавливаем  указатель файла на его конец. Будем дописывать в "хвост" 
"файла-жертвы" собственно код нашего вируса. 

Для  перемещения  указателя  открытого  файла  на  его  конец  следует  воспользо-

ваться функцией 

4202h

 прерывания 

21h

 (табл. 20.2).  

Таблица 20.2. Функция 

4202h

 

прерывания 

21h

:  

установка указателя на конец файла 

Вход 

Выход 

ax = 4202h 

bx 

= номер файла 

cx, dx 

= количество байтов, которые необходимо отсчитать от 

конца файла и установить на них указатель 

jc 

— ошибка 

 
Если  в  регистры 

cx

  и 

dx

  мы  загрузим  число  0,  то  указатель  будет  установлен 

сразу за последним байтом файла. Пока нас только это и интересует. 

Указатель служит для уведомления операционной системы, из какого места сле-

дует читать или в какое место следует писать байт (байты). Если указатель не пе-
реместить  на  конец  файла,  то,  записав  тело  вируса,  мы  затрем  файл,  начиная  со 
смещения 7. 

Запомните, что:  

 

при открытии файла указатель устанавливается на начало файла автоматически. 
Если указатель установлен на середину файла, то, после закрытия и повторного 
открытия файла, указатель снова установится на начало файла; 

 

при чтении файла указатель перемещается на количество прочитанных байтов. 
То есть если файл имеет длину 3000 байт, то, после прочтения 1500 байт, указа-
тель переместится на середину файла.