Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Программирование

Добавлен: 16.02.2019

Просмотров: 29231

Скачиваний: 1689

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

Часть 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. Резюме 

Итак, ваша задача сейчас — не разобрать программу полностью, а понять прин-

цип  работы  прерываний,  причем  на  довольно-таки сложном примере. Но если вы 
досконально разберетесь с материалом данной главы, то в дальнейшем вам будет 
очень просто постигать новое. 

 


background image

 

 

 

Глава 16 

 

Принципы работы отладчиков 

 

 
В этой главе мы рассмотрим принципы работы отладчиков на примере AFD Pro. 

Данная  тема  вынесена  в  отдельную  главу,  т. к.  это  действительно  важно.  И  вот  
почему: 

 

отладчик  для  программиста —  это  основной  и  очень  важный  инструмент,  т. к. 
тестирование написанных на ассемблере программ осуществляется только с его 
помощью.  Без  отладчика  найти  ошибку  в  программе  очень  и  очень  проблема-
тично; 

 

при необходимости исследовать чужую программу помощь профессионального 
программиста  со  знанием  ассемблера  просто  необходима.  Иного  пути,  кроме 
как дизассемблировать программу или запустить ее под отладчиком, просто не 
существует. 
Чтобы продолжить изучение ассемблера, вам необходимо вооружиться отлад-

чиком  AFD  Pro.  Если  до  настоящего  момента  вы  его  не  установили,  то  мы  на-
стоятельно  рекомендуем  это  сделать  сейчас.  Скачать  программу  можно  с  сайта 
http://www.Kalashnikoff.ru

16.1. Как работает отладчик 

Вы  задумывались  над тем, как отладчик выполняет программу? Можно ли его 

обмануть?  Естественно,  уважаемые  читатели!  Обмануть  отладчик  на  ассемблере 
очень просто. Мы с вами уже знаем два способа: 

 

перенести стек в тело программы; 

 

прочитать программу заново с диска и записать в память по месту ее загрузки. 
Однако второй способ мы до сих пор подробно не рассмотрели. Поэтому сдела-

ем это прямо сейчас. 

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

память? Давайте разберемся сперва с работой самого отладчика.  

16.1.1. Прерывание 03h 

Вы  уже  знаете,  что  существует  ряд  аппаратных  прерываний,  выполняющих  те 

или иные функции при возникновении некоторых ситуаций. Например: 

 

при нажатии комбинации клавиш <Shift>+<Print Screen> вызывается прерывание 

05h


background image

 

Часть 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 


background image

Глава 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  (отладчик-то  перехватывает  это  прерывание  непосредственно  после  


background image

 

Часть 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

).