Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29218
Скачиваний: 1689
Часть III. Файловая оболочка, вирус, резидент
104
10.4.1. Новые операторы и функции прерываний
Рассмотрим новые прерывания и операторы, используемые в обработчике
(табл. 10.1—10.3).
Таблица 10.1. Функция
35h
прерывания
21h
: получить адрес (вектор) прерывания
Вход
Выход
ah = 35h
es
= сегментный адрес вектора прерывания
bx
= его смещение
Таблица 10.2. Функция
25h
прерывания
21h
: установить вектор прерывания
Вход
Выход
ah =25h
ds
= сегмент нашего обработчика
dx
= его смещение
Ничего
Таблица 10.3. Прерывание
27h
: оставить программу резидентной в памяти
Вход
Выход
ds:dx
= последний байт, оставляемый в памяти
Ничего (выход в DOS)
10.5. Работа с флагами процессора
Познакомимся с двумя новыми операторами (табл. 10.4 и 10.5).
Таблица 10.4. Оператор
pushf
Команда
Перевод
Назначение
Процессор
pushf
Push flags
— втолкнуть флаги
Сохранить флаги
8086
Таблица 10.5. Оператор
popf
Команда
Перевод
Назначение
Процессор
popf
Pop flags
— вытолкнуть флаги
Восстановить флаги
8086
Рассмотрим еще раз работу флагов процессора на конкретном примере:
...
(01) cmp ax,23
(02) je Ok_ax
...
Здесь, после выполнения строки (01), установится либо сбросится флаг нуля.
В строке (02) проверяем этот самый флаг. Если он установлен, значит, команда
Глава 10. Введение в вирусологию. Обработчик прерываний
105
сравнения верна (т. е.
ax = 23
). Если же не установлен, то
ax
не равен 23. Рассмот-
рим, как это отображается в отладчиках AFD и Code View (особенно обращайте
внимание на то, как в этих отладчиках отображается флаг нуля и прочие флаги)
(рис. 10.4 и 10.5).
Рис. 10.4. AFD: Флаг нуля ZF (Zero Flag) сброшен
Рис. 10.5. Code View: Флаг нуля ZR (ZeRo) установлен
Теперь обратите внимание на самое начало процедуры
Int_21h_proc
листин-
га 10.4. Мы видим следующие команды:
...
cmp ah,9
je Ok_09
...
Часть III. Файловая оболочка, вирус, резидент
106
В результате выполнения команды сравнения будет изменен флаг нуля. Однако
нет необходимости сохранять флаги в стеке в нашем обработчике. Дело в том, что
при вызове любого прерывания (будь то программный или аппаратный вызов)
в стеке сохраняются не только регистры
cs:ip
, но и флаги. Таким образом, после
выполнения команды
iret
процессор восстановит указанные выше регистры
и флаги.
Тем не менее, все остальные регистры должны быть сохранены, если процедура
обработки их изменяет. Иначе это может привести к довольно-таки серьезным из-
менениям в ходе работы программы, вызвавшей прерывание
21h
. Для этого, собст-
венно, мы и сохраняем в стеке регистры
ds
и
dx
. Обратите внимание на то, что
в обработчике прерывания (в нашем случае —
Int_21h_proc
) необходимо сохра-
нять все используемые регистры, кроме
cs:ip
и регистра флагов.
Теперь рассмотрим следующую строку:
;Переменная для хранения оригинального адреса обработчика 21h
Int_21h_vect dd ?
Данная переменная может хранить двойное слово (Define Double word — опре-
делить двойное слово — четыре байта). Вспоминаем, что один 16-разрядный ре-
гистр занимает 2 байта (одно слово) (
dx
,
ax
,
es
,
ss
и т. д., но не
ah
,
dl
,
bh
, ... — это
8-разрядные регистры, которые занимают 1 байт). Если мы хотим загрузить в пе-
ременную
Int_21h_vect
слово (2 байта), то нам необходимо указать это следую-
щим образом:
mov word ptr Int_21h_vect,ax
Если же мы хотим загрузить 1 байт, то запишем так:
mov byte ptr Int_21h_vect,ah
Вспоминаем, что "word" по-английски — это "слово", а byte — "байт".
10.5.1. Как проверить работу программы?
В данном случае нам понадобится отладчик, который способен заходить
"внутрь" прерывания
21h
. Например, AFD, TD, SoftIce и пр., но не CodeView. Если
у вас нет AFD, то его можно загрузить с сайта http://www.Kalashnikoff.ru. Затем
создайте простейшую программу, которая будет выводить на экран некоторую
строку путем вызова функции
09h
прерывания
21h
. Например, так, как это показа-
но в листинге 10.5 (\010\test10.asm).
Листинг 10.5. Программа для проверки работы прерываний
CSEG segment
assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
org 100h
Begin:
mov ah,9
mov dx,offset String
Глава 10. Введение в вирусологию. Обработчик прерываний
107
int 21h
int 20h
String db 'My string.$'
CSEG ends
end Begin
Запустите вначале программу из листинга 10.4. После того как она завершит
свою работу, запустите программу из листинга 10.5. Обратите внимание, что про-
исходит. Затем запустите программу из листинга 10.5 в отладчике. Смело заходите
"внутрь" прерывания
21h
и обратите внимание на код. На рис. 10.6 отображено со-
стояние программы test10.com, которая только что выполнила команду
int 21h
.
Рис. 10.6. Программа test10.com выполнила команду int 21h
Обратите внимание на текущую команду (выделенную светлым фоном) и сле-
дующие за ней. Это как раз и будет процедура обработки
21h
-го прерывания
Int_21h_proc
из программы данной главы prog10.com, которая и заменяет пару ре-
гистров
ds:dx
. На рис. 10.7 приведен фрагмент кода, заменяющий адрес выводи-
мой строки на экран.
На рис. 10.6 и 10.7 четко видно, что процедура
int_21h_proc
выполняет сле-
дующие действия:
сохраняет изменяемые регистры;
заменяет
ds:dx
, которые теперь содержат смещение строки "Моя строка!";
вызывает оригинальный обработчик прерывания
21h
, которое и выведет строку;
восстанавливает сохраненные регистры;
Часть III. Файловая оболочка, вирус, резидент
108
Рис. 10.7. Подмена выводимой строки
выходит из обработчика прерывания, при этом оператор
iret
передаст управле-
ние на test10.com, сразу после команды
int 21h
.
Вот таким образом и будут фильтроваться вызовы прерывания
21h
всех про-
грамм. Именно так, с помощью резидентных программ, и можно контролировать
почти все процессы, происходящие в компьютере.
* * *
В главе 11 начнем писать оболочку типа Norton Commander.