Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29263
Скачиваний: 1690
Глава 27. Удаление резидента из памяти
269
То есть удалять резиденты следует в соответствии с их загрузкой, в порядке ра-
боты стека. Мы абсолютно никак не сможем "вырезать" резидентную программу
из середины.
В заключение остается добавить, что удалить чужой резидент возможно только
в том случае, если мы знаем, по какому адресу в цепочке прерывания
21h
он даль-
ше передает управление.
Например, Volcov Commander удаляет резиденты, начиная с загруженных в по-
следнюю очередь. Причем могут быть удалены только те резидентные программы,
которые были загружены после загрузки самого Volcov Commander. Как уже упо-
миналось, это происходит согласно принципу работы стека. Резидентные програм-
мы загружаются в память в следующем порядке:
push ax (первый загруженный резидент)
push bx (второй резидент)
push cx (третий резидент)
Выгрузка резидентных программ из памяти происходит в таком порядке:
pop cx (третий резидент)
pop bx (второй резидент)
pop ax (первый резидент)
Удаление резидентных программ в Volcov Commander возможно в случае, когда
он сохраняет в своих внутренних переменных адреса последующих обработчиков
того или иного прерывания в цепочке. Иными словами, перед загрузкой любой
программы Volcov Commander сохраняет в специально отведенной области памяти
текущую таблицу векторов прерываний. Если после выполнения запущенной про-
граммы таблица векторов изменилась, то это значит, что загруженная программа
была резидентной и перехватила одно или несколько прерываний. Volcov Com-
mander также запоминает измененную таблицу векторов и в случае необходимости
удаления резидента восстанавливает предыдущую сохраненную таблицу, освобож-
дает отведенную загруженному резиденту память, что приводит к корректному
удалению резидентной программы.
27.2. Практика
Как экспериментировать с прилагаемыми к данной главе файлами?
Загружаем test27.com, который выведет на экран 50 символов "A". Убедитесь,
что это так.
1. Запустите Resid27.com без параметров в командной строке (рис. 27.1).
2. Запустите снова test27.com.
3. Запустите Resid27.com с параметром
/u
(т. е.
resid27.com /u
).
4. Запустите снова test27.com.
5. Запустите Resid27.com.
6. Запустите Resid27_.com.
7. Запустите Resid27.com с параметром /u (т. е. resid27.com /u) (рис. 27.2).
Часть III. Файловая оболочка, вирус, резидент
270
Рис. 27.1. Результат работы резидента
Рис. 27.2. Невозможность удаления резидента из памяти
Подробные описания, как обычно, находятся в файлах-приложениях. Увлека-
тельного вам исследования!
Глава 28
Алгоритм считывания
имен файлов в память
Итак, теперь оболочка работает без сбоев, т. е. мы можем читать корневой каталог,
заходить в подкаталоги и возвращаться обратно в корневой. Работают также клавиши
<PageUp>, <PageDown>, <Home>, <End>, <Insert> (отметка файлов), <Ctrl>+<F3>.
28.1. Новый алгоритм считывания файлов
в память
Алгоритм считывания файлов и вывод их на экран полностью изменился.
В данном разделе мы рассмотрим его подробно. Считывание каталога происходит
следующим образом (листинг 28.1).
Листинг 28.1. Подготовка сегментных регистров
...
(01) mov fs,Seg_offset ;fs — сегмент смещений файлов
(02) xor di,di
(03) mov Current_offset,di
;Получаем смещение файла в банке данных смещений
(04) mov fs:[di],di
(05) mov bp,2 ;Следующий файл будет помещаться по адресу 2
...
Обратите внимание на новый сегментный регистр
fs
(01), который начал ис-
пользоваться в процессоре 286. Ничего особенного в нем нет. Поэтому считайте
его дополнительным сегментным регистром типа
es
.
Чтобы разместить файлы в памяти, отведем память под смещения для файлов
(листинг 28.2 и рис. 28.1).
Листинг 28.2. Отводим память под смещения для файлов
...
;Здесь будут смещения для файлов. Отводим 4000 байт для ссылок.
(01) mov ah,48h
Часть III. Файловая оболочка, вирус, резидент
272
(02) mov bx,250 ;250 * 16 = 4000 байт = 2000 ссылок на файлы
(03) int 21h
(04) mov Seg_offset,ax ;Сохраним сегмент
;Отводим память для хранения файлов:
;Здесь будут сами файлы. Для имен файлов отводим 64 Кбайт
(05) mov ah,48h
(06) mov bx,4096 ;4096 * 16 = 65536 байт
(07) int 21h
(08) mov Seg_files,ax ;Сохраним сегмент
...
Рис. 28.1. Выделяем память для указателей и названий файлов
Предположим, в каталоге, файлы которого наша оболочка считывает в память,
есть два файла: main.asm и other.asm. Таким образом, файлы в памяти будут раз-
мещены так, как показано в табл. 28.1.
В табл. 28.1 вы видите два сегмента, которые мы отвели:
Seg_offset
(04) и
Seg_files
(08). В первом сегменте будут сохраняться смещения на файлы, которые
находятся во втором сегменте. Сигналом окончания файлов служит число
0FFFFh
вместо очередного смещения в первом сегменте.
Таблица 28.1. Размещение файлов в памяти оболочки
Сегмент
Файл
main.asm
other.asm
Конец файлов
Seg_offset
0000h
0009h
0FFFFh
Seg_files
main.asm+ASCIZ
other.asm+ASCIZ
Глава 28. Алгоритм считывания имен файлов в память
273
28.2. Процедура вывода имен файлов на экран
Получаем число (2 байта), расположенное в сегменте
Seg_offset
по смещению
0000h
. В первом случае это будет
0000h
. Затем читаем и выводим файл, который
расположен по полученному смещению из сегмента
Seg_offset
(рис. 28.2).
Увеличиваем указатель смещения в первом сегменте на 2 (т. е. перейдем на сле-
дующий файл). Получаем число
0009h
. По этому смещению находится в памяти
следующий файл (other.asm). Его и выводим.
Увеличиваем указатель на 2. Получаем очередное смещение. Это
0FFFFh
? Зна-
чит, предыдущий файл был последним. Все! Вывод закончен (рис. 28.3).
Рис. 28.2. Подготовка к выводу файлов на экран
Рис. 28.3. Вывод файлов закончен