Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29224
Скачиваний: 1689
Часть III. Файловая оболочка, вирус, резидент
124
Как мы знаем, видеобуфер имеет следующую структуру:
СИМВОЛ : АТРИБУТ СИМВОЛ : АТРИБУТ ...
Обратите внимание на приведенный выше пример. Вы видите, что в
ah
мы за-
гружаем атрибут, а в
al
— символ. Получается, что сперва заносится атрибут (т. к.
ah
— старшая (левая) половинка), а затем символ, что и доказывает расположение
данных в компьютере в обратном порядке. Получится, что при переносе
ax
в сег-
мент видеобуфера символ и атрибут поменяются местами!
Рассмотрим префикс
rep
, который часто используется вместе со строковыми
командами. Допустим, нам надо очистить экран. Это можно сделать с помощью
команды
stosw
, просто забив экран пробелами (листинг 12.8).
Листинг 12.8. Очистка экрана с помощью loop
...
mov ax,0B800h
mov es,ax
mov di,0 ;как обычно, с левого верхнего угла
mov cx,2000 ;80х25=2000 символов на экране
mov ax,0720h ;07 — атрибут, 20h — пробел
Next_sym: ;заносим посимвольно
stosw
loop Next_sym
;теперь экран чистый
...
Выглядит вроде и нормально, хотя этот пример имеет ряд недостатков:
1. Использование
loop
вместо префикса
rep
существенно замедляет работу про-
граммы.
2. Код программы больше, чем при использовании того же
rep
.
3. Необходимо заводить метку (в нашем случае —
Next_sym
).
Попробуем реализовать такой же алгоритм, но с использованием префикса
rep
(листинг 12.9).
Листинг 12.9. Очистка экрана с помощью rep
...
mov ax,0B800h
mov es,ax
mov di,0
mov cx,2000 ;cx — counter, счетчик
mov ax,0720h ;атрибуты/символ
rep stows ;выводим пробел столько раз, сколько указано в сх.
...
Глава 12. Повторная загрузка резидента
125
Все, экран чистый. В данном случае очистка экрана происходит мгновенно.
Этот процесс не заметен даже на компьютерах IBM PC/XT. После выполнения по-
следней команды —
rep stosw
—
сх
будет содержать 0.
В
Н И МА Н И Е
!
Оператор rep (от англ. repeat — повтор) неотделим от сх, как и loop от сх!
Подведем итог:
одна команда
stosw
записывает только два символа, находящихся в
ax
по адресу
es:di
;
команда
rep stosw
запишет два символа, находящихся в
ax
по адресу
es:di
столько раз, сколько находится в регистре
сх
;
строковые команды предпочтительней использовать в паре с
rep
, где это воз-
можно.
Все просто. При исследовании работы строковых команд желательно восполь-
зоваться отладчиком и следить за изменением регистров
сх
,
si
,
di
.
12.4. Использование xor и sub
для быстрого обнуления регистров
Рассмотрим одну маленькую хитрость, которую часто применяют программи-
сты на ассемблере: использование команд
xor
и
sub
для быстрого обнуления реги-
стров (рис. 12.9):
xor ax,ax ;равносильно mov ax,0
А можно и так (рис. 12.10):
sub ax,ax ;вычтем из ax ax
Рис. 12.9. Обнуление регистра с помощью команды xor
Часть III. Файловая оболочка, вирус, резидент
126
Рис. 12.10. Обнуление регистра с помощью команды sub
Эти команды (
xor ax,ax
/
sub ax,ax
) выполняются быстрее команд типа
mov
ax,0
. Поэтому не удивляйтесь, если где-то в наших примерах или в других про-
граммах встретите нечто подобное.
xor
— исключающее ИЛИ. Это логическая команда. Подобные инструкции мы
рассмотрим позже. Пока вам нужно уяснить, что такими операторами, как
xor
и
sub
, можно быстро и просто аннулировать регистры.
12.5. Задание для освоения информации
из данной главы
Досконально исследуйте программы resid12.asm и test12.asm в отладчике (лучше
в AFD): это позволит вам понять принцип работы резидентных программ и строко-
вых команд.
Глава 13
Поиск и считывание файлов:
вирус
Эта глава небольшая, но информативная. Из нее вы узнаете, как поместить ви-
рус временно в память, как передать ему управление, как найти очередной "файл-
жертву" и многое другое.
13.1. Теория
В данной главе рассмотрим следующее:
как вирус "прикрепляется" к файлу, не нарушая его работоспособности;
что должен сделать вирус в первую очередь;
как передать управление вирусу из чужой программы.
Первое, что хотелось бы отметить, — это то, что наш вирус будет заражать
только COM-файлы.
Как вы уже знаете, файлы типа COM загружаются в первый свободный сегмент,
и их код располагается по смещению
100h
. Следовательно, нам нужно будет сохра-
нить в теле нашего вируса первые три байта "файла-жертвы", записать вирус
в "хвост" файла и, вместо сохраненных трех байтов, установить команду
jmp
на
начало кода нашего вируса (т. е. передать ему первому управление).
После того как вирус отработает, следует восстановить сохраненные три байта
(записать их в памяти по адресу
100h
) и передать им управление. На практике все
будет понятно. Получается примерно так, как представлено в листингах 13.1 и 13.2.
Листинг 13.1. Программа до заражения (следите за адресами)
;код программы до заражения, расположенный по адресу 100h
[1234:0100h] mov ax,34
[1234:0103h] mov dx,15 ;здесь может быть все, что угодно...
[1234:0106h] add ax,bx
[1234:0108h] ...и т. д...
...
[1234:0500h] int 20h ;последний байт программы
Часть III. Файловая оболочка, вирус, резидент
128
[1234:0502h] ---
;далее идет уже память, не занятая под код или данные "файла-жертвы"...
...
Листинг 13.2. Программа после заражения
;"прыгаем" на начало нашего вируса (заменили байты здесь)
[1234:0100h] jmp 0502h
[1234:0103h] mov dx,15 ;а это байты "файла-жертвы"
[1234:0106h] add ax,bx
...
[1234:0500h] int 20h
[1234:0502h] --- ;а здесь уже начинается код нашего вируса.
... ;здесь тело вируса. Делаем, что хотим...
;=== После того, как вирус отработал ===
;Восстановим первые два байта "файла-жертвы"
[1234:0700h] mov word ptr cs:[0100h], First_bytes_1
;Восстановим третий байт "файла-жертвы"...
[1234:0705h] mov byte ptr cs:[0102h], First_bytes_2
;Теперь по адресу 100h первые два байта не jmp 502h, а mov ax,34
;(т. е. оригинальный код программы). Вспоминаем из прошлых глав о том,
;что в ассемблере можно менять код программы "на лету"...
;Все это меняется только в памяти, а не на диске!
;...перейдем по адресу 100h, т. е. передадим управление программе
[1234:0709h] jmp 0100h
...
Сравните два участка кода: незараженной программы и зараженной. Теоретиче-
ски вопросов возникнуть не должно...
13.2. Практика
Теперь приступим к практической части. Откройте файл virus13.asm. Первая
строка —
.286
— указывает ассемблеру, что будем использовать инструкции (ко-
манды, операторы) не только процессора 8086, но и 80286. То есть на компьютере
8086 наш вирус уже работать не будет! С первого же байта перейдем на метку
Init
(инициализации нашего вируса).