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

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

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

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

Добавлен: 16.02.2019

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

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

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

Глава 18. Высокоуровневая оптимизация программ 

199 

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

вана проверка нажатых клавиш (

MAIN_PROC

, main.asm). Также посмотрите процедуру 

Quit_prog

  в  этом  же  файле.  В  дальнейшем  мы  усовершенствуем  вывод  рамок  на 

экран с запросом "Да"/"Нет". Это диалоговое окно, как правило, аналогично общему. 

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

ский экран при нажатии комбинации клавиш <Ctrl>+<F5> (

MAIN_PROC

, main.asm). 

18.4. Резюме 

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

Far  Manager,  используя  программу  HELPASSM.  Наша  задача  теперь  заключается  
в том, чтобы показать вам "подводные камни", некоторые алгоритмы, которые не 
рассматривались  до  сих  пор,  общие  понятия  при  работе  с  расширенной  памятью  
и вывод десятичных чисел на экран. Этим мы и займемся в следующих главах. 

Как  видите,  мы  уже  написали  несколько  мощных  процедур  (например, 

Draw_frame

Print_string

), которыми вы можете пользоваться. Просто вставляйте 

их  в  собственные  программы  и  вызывайте!  Безусловно,  довольно  много  времени 
уходит на написание самих процедур. Зато как от этого выигрывает скорость рабо-
ты программы и ее размер! 

 


background image

 

 

 

Глава 19 

 

Создание резидентного шпиона 
 

19.1. Резидент 

В  данной  главе  приступаем  к  изучению  очередной  резидентной  программы. 

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

Итак,  после  загрузки  в  память  резидент  перехватывает  прерывание

  21h

. Затем 

отслеживает  некоторые  действия  программ  (функций,  которые  они  вызывают)  
и  записывает  информацию  в  свой  LOG-файл.  Список  отслеживаемых  функций 
прерывания 

21h

 приведен в табл. 19.1. 

Таблица 19.1. Отслеживаемые функции 

Номер функции в ax 

Описание функции 

ax = 4B00h 

Запуск файла на выполнение 

ah = 39h 

Создание каталога 

ah = 3Ah 

Удаление каталога 

ah = 3Bh 

Смена каталога 

ah = 3Ch 

Создание файла 

ax = 3D02h 

Открытие файла для чтения/записи 

ah = 41h 

Удаление файла 

 
По  стандартам  Microsoft  перед  вызовом  всех  этих  функций  прерывания 

21h

  

в регистры 

ds:dx

 должно быть загружено имя файла или каталога. Поэтому мы вы-

полняем  одни  и  те  же  действия,  если  какая-либо  функция  вызывается.  Примеры 
корректного вызова этих функций приведены в листингах 19.1 и 19.2. 

Листинг 19.1. Создание каталога 

mov ah,39h 

mov dx,offset Directory 

int 21h 


background image

Глава 19. Создание резидентного шпиона 

201 

Листинг 19.2. Удаление файла 

mov ah,41h 
mov dx,offset File 
int 21h 

Исключение  составляет  функция 

4B00h

.  Для  этой  функции,  помимо  указания 

смещения на файл в регистрах 

ds:dx

, необходимо еще дополнительно хорошо под-

готовиться. Запуск программ на выполнение мы будем рассматривать в последую-
щих главах, т. к. это довольно объемная тема и требует подробного рассмотрения. 

Теперь рассмотрим использование этих функций на примере получения атрибу-

тов файла. 

В  операционных  системах  MS-DOS  и  Windows  файл  может  иметь  следующие 

атрибуты (табл. 19.2). 

Таблица 19.2. Атрибуты файлов в MS-DOS 

Атрибут 

Описание 

000001b 

Только чтение 

000010b 

Спрятанный 

000100b 

Системный 

001000b 

Метка тома 

010000b 

Подкаталог 

100000b 

Архивный 

 
Существенное  отличие  в  атрибутах  файлов  в  Windows и MS-DOS заключается  

в том, что в Windows атрибуты более расширенные, в частности: сжатый, шифро-
ванный, индексируемый и т. п. 

Атрибуты файла могут комбинироваться, но не все. Например: 

  100001b

 — "только чтение" и "архивный"; 

  000110b

 — "системный" и "скрытый". 

Однако не следует указывать атрибуты, которые явно противоречат друг другу. 

Например, "подкаталог" и "метка тома" вместе. 

На рис. 19.1 приведен участок кода, который создает файл в текущем каталоге  

с помощью функции 

3Ch

. При этом смещение имени создаваемого файла находится 

в регистрах 

ds:dx

, а атрибуты — в 

cx

В  этом  примере  атрибуты  создаваемого  файла  будут  "архивный"  и  "скрытый".  

В двоичной системе это выглядит как 

100010b

, а в шестнадцатеричной — 

22h

Обратите  внимание,  что  существует  такой  атрибут,  как  "метка  тома".  Метка 

диска (тома) — это не что иное, как обычный файл с соответствующим атрибутом 
и имеющий нулевую длину. Аналогично и с "файлами", имеющими атрибут "под-
каталог". 


background image

 

Часть III. Файловая оболочка, вирус, резидент 

202 

 

Рис. 19.1. Создание файла 

Что именно делает наш резидент? 
Программы  типа  COM  начинаются со смещения 

100h

. От 

0

  до 

0FFh

  находится 

PSP  (Prefix  Segment  Program).  Некоторые  поля  PSP  вы  уже  знаете.  Например,  по 
смещению 0 находится команда 

int 20h

, а по смещению 

80h

 — DTA и изначально 

командная строка. 

Оставаясь  в  памяти,  резидент  сохраняет  с  собой  также  PSP  (т. е.  "лишние" 

100h байт). Получается, что 100h байт памяти постоянно зарезервировано. Вы уже, 
возможно,  заметили,  что  наши  предыдущие  резиденты  занимали  памяти  больше, 
чем их реальный размер на диске. Это-то как раз и связано с тем, что в памяти вме-
сте с кодом резидента остается PSP программы (плюс еще строка окружения, но об 
этом позже). 

Существует несколько способов избежать размещения лишних байтов в памяти: 

1.  Сделать  так,  чтобы  программа  в  памяти  начиналась  не  со  смещения 

100h

, а со 

смещения 

0

. Однако здесь возможны некоторые проблемы. Об этом позже. 

2.  Разместить  в  нашей  свободной  области  стек  на  то  время,  пока  работают  наши 

обработчики прерываний. 

3.  Сделать  в  области  PSP  буфер,  т. е.  задействовать  эту  память  для  временного 

хранения данных, которые не превышают 

100h

 байт. 

Мы будем использовать третий способ, хотя иногда удобнее пользоваться вто-

рым и даже комбинировать оба этих метода. Для какой цели нам нужен будет этот 
буфер, сейчас и рассмотрим. 

Как уже упоминалось, мы перехватываем указанные выше функции прерывания 

21h

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

шем LOG-файле (c:\report.txt). Теперь обратим внимание на то, что именно делает 
обработчик прерывания 

21h

 (листинг 19.3). 


background image

Глава 19. Создание резидентного шпиона 

203 

Листинг 19.3. Проверка вызова функций прерывания 21h 

... 

cmp ax,4B00h       ;Это запуск программы? 

je Start_f 

 

cmp ah,39h         ;Это создание каталога? 

je Create_dir 

 

... 

;Если что-то другое, то передадим управление оригинальному обработчику 

;прерывания 21h ... 

jmp short Go_21h 

 

Start_f: 

;Строка для записи в наш LOG-файл. 

mov si,offset Start_filemess 

call Move_string            ;Готовим строку и записываем ее в файл... 

 

jmp short Go_21h            ;Передадим управление прерыванию 21h... 

 
Create_dir:                 ;То же самое для остальных... 

mov si,offset Create_dirmess 

call Move_string 
 
jmp short Go_21h 

... 

В приведенном фрагменте кода нашего резидента мы вначале выясняем, запус-

кает ли какая-то программа на выполнение или нет. Затем проверяем другие функ-
ции, которые могут вызываться какой-либо программой. 

Допустим, некто пытается создать каталог при помощи функции 

39h

. Тогда мы 

передаем управление на метку 

Create_dir

 (создание каталога). Это видно из при-

веденного выше примера. Затем в 

si

 заносится адрес строки 

Create_dirmess

... 
Create_dirmess dw Create_dirmessl 
     db 'Создание каталога ---> ' 
Create_dirmessl equ $-Create_dirmess-2 
... 

Как видите, первые два байта адреса, который заносится в 

si

, содержат длину 

строки.  Обратите  внимание,  как  просто  мы  получаем  эту  длину:  переменную