Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29231
Скачиваний: 1689
Часть III. Файловая оболочка, вирус, резидент
164
jnz Go_1Ch
...
Вот она, эта "таинственная" переменная
Num_status
. Как видите, процедура
Int_1Ch_proc
проверяет, равна ли она нулю или нет. И если не равна, то переходит
на метку
Go_1Ch
. А там:
...
Go_1Ch:
jmp dword ptr cs:[Int_1Ch_vect]
...
Просто передача на оригинальный обработчик
1Ch
. Если переменная
Num_status
равна единице, то наш обработчик моментально передаст управление на старый
вектор, т. е. символы на экране заменяться не будут. Теперь вспомним про преры-
вание
09h
, которое меняло переменную
Num_status
при нажатии клавиши <F12>.
Причем меняло командой
xor
. А что именно делает
xor
— мы рассматривали ранее
в этой главе...
15.7. Резюме
Итак, ваша задача сейчас — не разобрать программу полностью, а понять прин-
цип работы прерываний, причем на довольно-таки сложном примере. Но если вы
досконально разберетесь с материалом данной главы, то в дальнейшем вам будет
очень просто постигать новое.
Глава 16
Принципы работы отладчиков
В этой главе мы рассмотрим принципы работы отладчиков на примере AFD Pro.
Данная тема вынесена в отдельную главу, т. к. это действительно важно. И вот
почему:
отладчик для программиста — это основной и очень важный инструмент, т. к.
тестирование написанных на ассемблере программ осуществляется только с его
помощью. Без отладчика найти ошибку в программе очень и очень проблема-
тично;
при необходимости исследовать чужую программу помощь профессионального
программиста со знанием ассемблера просто необходима. Иного пути, кроме
как дизассемблировать программу или запустить ее под отладчиком, просто не
существует.
Чтобы продолжить изучение ассемблера, вам необходимо вооружиться отлад-
чиком AFD Pro. Если до настоящего момента вы его не установили, то мы на-
стоятельно рекомендуем это сделать сейчас. Скачать программу можно с сайта
http://www.Kalashnikoff.ru.
16.1. Как работает отладчик
Вы задумывались над тем, как отладчик выполняет программу? Можно ли его
обмануть? Естественно, уважаемые читатели! Обмануть отладчик на ассемблере
очень просто. Мы с вами уже знаем два способа:
перенести стек в тело программы;
прочитать программу заново с диска и записать в память по месту ее загрузки.
Однако второй способ мы до сих пор подробно не рассмотрели. Поэтому сдела-
ем это прямо сейчас.
Почему же отладчик работал неверно, если программа перечитывала саму себя в
память? Давайте разберемся сперва с работой самого отладчика.
16.1.1. Прерывание 03h
Вы уже знаете, что существует ряд аппаратных прерываний, выполняющих те
или иные функции при возникновении некоторых ситуаций. Например:
при нажатии комбинации клавиш <Shift>+<Print Screen> вызывается прерывание
05h
;
Часть III. Файловая оболочка, вирус, резидент
166
при нажатии или отпускании любой клавиши вызывается прерывание
09h
;
прерывание же
1Ch
вообще вызывается автоматически примерно 18,2 раза в се-
кунду.
Все эти прерывания и их обработку мы подробно рассмотрели в главе 15.
Вообще номера прерываний от
00
до
1Fh
"обслуживаются" BIOS (ПЗУ). Все ос-
тальные доступны программисту или операционной системе (программные преры-
вания). Например, MS-DOS использует номера от
20h
до
2Fh
(
int 20h
— выход из
программы;
int 21h
— комплекс процедур и т. д.).
Как понять фразу "обслуживаются ПЗУ"? Это значит, что обработчики этих
прерываний находятся в области ПЗУ — постоянном запоминающем устройстве,
в то время как обработчики
20h
—
0FFh
находятся в ОЗУ — оперативном запоми-
нающем устройстве (т. е. в той области памяти, которая теряется при выключе-
нии/перезагрузке компьютера). Естественно, мы можем перехватить как прерыва-
ния ПЗУ (от
00
до
1Fh
), так и все остальные, что мы уже делали.
Чем же примечательно прерывание
03h
?
Во-первых, оно используется для отладки программ, в частности, для работы
AFD и CodeView.
Во-вторых, машинный код этой команды занимает всего один байт —
0CCh
, чего
не скажешь о вызове других прерываний. Например,
int 20h
—
0CDh 20h
, т. е.
два байта.
В-третьих, обработчик прерывания
03h
изначально содержит всего одну инст-
рукцию:
iret
, т. е. при вызове данного прерывания происходит моментальный
возврат. Можете, кстати, это проверить, принудительно вызвав данное прерыва-
ние в любом месте вашей программы. Ничего не произойдет.
П
Р И МЕ Ч А Н И Е
Чтобы принудительно вызвать прерывание 03h, нужно записать в любом месте нашей
программы int 3.
В процессе отладки программы отладчик перехватывает прерывание
03h
. Проще
говоря, устанавливает вектор (адрес) данного прерывания на некую свою процеду-
ру. Выполняя одну команду (когда пользователь нажимает клавишу <F1> или
<F2>), отладчик просто сохраняет следующий за текущей командой байт и вместо
него вписывает
0CCh
, т. е.
int 3
. Естественно, что на экран отладчик выводит из-
мененную инструкцию в ее нормальном, первозданном виде, а не
int 3
. Рассмот-
рим это на примере. Возьмем такую простейшую программу, которая выводит один
символ "Q" на экран в текущую позицию курсора (листинг 16.1).
Листинг 16.1. Вывод символа в текущую позицию курсора
cseg segment
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
org 100h
Begin:
mov ah,2
Глава 16. Принципы работы отладчиков
167
mov dl,'Q'
int 21h
ret
cseg ends
end Begin
В табл. 16.1 показана эта программа в том виде, как ее отображает отладчик.
Таблица 16.1. Шаг первый: программа только что загрузилась
Смещение
Инструкция ассемблера
Машинный код
Что на экране
0100h
Mov ah,2
0B402h
MOV AH,02
0102h
Mov dl,'Q'
0B251h
MOV DL,51
0104h
Int 21h
0CD21h
INT 21
0106h
ret
0C3h
RET
П
Р И МЕ Ч А Н И Е
Курсивным начертанием выделены текущие команды, т. е. команды, которые выпол-
нятся после нажатия клавиши <F1>/<F2> в AFD.
В колонке Смещение указано, по какому смещению находится в памяти коман-
да. В колонке Инструкция ассемблера — реальные ассемблерные команды, рас-
положенные по соответствующему смещению. Реальные ассемблерные коман-
ды — команды, которые на самом деле находятся в памяти по соответствующему
смещению (читайте дальше — будет понятно). В колонке Машинный код — ма-
шинный код команды в шестнадцатеричной системе из колонки Инструкция ас-
семблера. Колонка Что на экране отражает то, что отладчик показывает нам на
экране, а также оригинальный код команд.
П
Р И МЕ Ч А Н И Е
Посмотреть машинные коды соответствующих команд ассемблера можно в любом
отладчике, а лучше — в Hacker's View.
Итак, запускаем нашу программу под отладчиком AFD. Команда
mov ah,2
рас-
положится по адресу
100h
, а
mov dl,'Q'
—
102h
(см. табл. 16.1). Естественно, что
отладчик сразу не даст программе работать, а просто загрузит ее в память и выве-
дет на экран инструкции ассемблера.
Допустим, пользователь нажимает клавишу <F2>. AFD запоминает 1 байт по
адресу
102h
(первый байт следующей за
mov ah,2
команды; в нашем случае —
0B2h
), записывает на его место
0CCh
, т. е. команду
int 3
, и выполняет инструкцию
mov ah,2
. После этого процессор выполнит не команду
mov dl,'Q'
, а
int 3
— вы-
зовет прерывание
03h
, адрес которого указывает на определенную процедуру обра-
ботки AFD (отладчик-то перехватывает это прерывание непосредственно после
Часть III. Файловая оболочка, вирус, резидент
168
загрузки!). Когда пользователь первый раз нажимает клавишу <F1>, получается
следующее (табл. 16.2).
Таблица 16.2. Нажали клавишу <F2> первый раз
Смещение
Инструкция ассемблера Машинный код
Что на экране
0100h
mov ah,2
0B402h
MOV AH,02
0B402h
0102h
int 3
0CCh
MOV DL,51
0B251h
0103h
push cx
51h
—
—
0104h
int 21h
0CD21h
INT 21
0CD21h
0106h
ret
0C3h
RET
0C3h
Что делает процедура обработки прерывания
03h
отладчика?
Допустим, текущая команда находится по адресу
0102h
(см. табл. 16.2). Пользо-
ватель нажимает <F1>/<F2>. Прерывание
03h
делает следующее:
1. Сохраняет все изменяемые отладчиком регистры в памяти.
2. Восстанавливает сохраненный байт (
0B2h
) по адресу
102h
.
3. Высчитывает количество байтов следующей команды (
mov dl,'Q'
= 2 байта =
=
0B251h
).
4. Получив адрес следующей за
mov dl,'Q'
команды (у нас —
104h
), заносит по
этому адресу число
0CCh
(т. е.
int 3
), предварительно сохранив затертый байт
(у нас —
0CDh
) в своей переменной.
5. Выполняется инструкция
mov dl,'Q'
, а за ней же сразу
int 3
, которая и пере-
даст управление отладчику (процедуре обработки прерывания
03h
).
6. Процедура обработки
03h
изменяет кое-что на экране.
7. Выполняет некоторые другие действия (все зависит от конкретного отладчика).
8. И ждет от пользователя дальнейших указаний.
Когда пользователь второй раз нажмет клавишу <F2>, получится следующее
(табл. 16.3).
Таблица 16.3. Пользователь нажал клавишу <F2> второй раз
Смещение
Инструкция ассемблера Машинный код
Что на экране
0100h
mov ah,2
0B402h
MOV AH,02
0B402h
0102h
mov dl,'Q'
0B251h
MOV DL,51
0B251h
0104h
int 3
0CCh
INT 21
0CD21h
0105h
and bx,ax
21C3h
RET
0C3h
0107h
"мусор"
"мусор"
"мусор"
"мусор"
Обратите внимание, какой машинный код находится по адресу
0105h
—
21C3h
.
Перед ним, по адресу
0104h
, находится код
0CCh
(
int 3
).