Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29234
Скачиваний: 1689
Глава 17. Заражение файлов вирусом
179
получаем смещение для возврата. К этому смещению и прибавляем размер "файла-
жертвы", который находится в
ax
. Теперь в стеке у нас смещение и сегмент метки
Lab_jmp
(точнее, первого оператора, который находится после нее). На основе вы-
шеизложенного постарайтесь разобраться, что делает строка (5).
Вопрос: а как нам вернуться назад, в сегмент "файла-жертвы"? Ответ на этот
вопрос можно найти в прилагаемом файле для практического изучения.
Рис. 17.4. Пока еще в начальном сегменте
Рис. 17.5. Уже в новом сегменте кода
Часть III. Файловая оболочка, вирус, резидент
180
17.2.1. Первые байты "файла-жертвы"
Обратите также внимание, что мы создаем массив байтов "файла-жертвы", ко-
торые нужно восстанавливать после того, как вирус отработал:
First_bytes db 90h, 90h, 90h, 90h, 0CDh, 20h
Это — знакомые машинные коды:
90h
—
nop
;
0CDh
—
int
;
20h
—
20h
.
Из этого получаем программу:
nop
nop
nop
nop
int 20h
В данный массив будем заносить первые 6 байт "программы-жертвы", вместо
которых запишем
jmp
на начало нашего вируса. Более того, эти байты будут запи-
саны вместе с телом нашего вируса на диск, после "файла-жертвы". Они нужны для
того, чтобы впоследствии, когда вирус отработает, восстановить их в памяти по
адресу
100h
и "прыгнуть" на него. Программа даже и не заподозрит, что кто-то пе-
ред тем, как она получила управление, уже что-то делал.
Изначально мы заполняем массив командами
nop
, а после них —
int 20h
. Это
нужно для того, чтобы при первом запуске вируса корректно завершиться.
Первый запуск вируса — это когда мы только-только его сассемблировали (по-
лучили COM-файл) и запустили полученную программу (в нашем случае — это
будет virus17.com). Она отработает: если найдет подходящий файл, то заразит его,
восстановит первые 6 байт и передаст управление на метку
100h
, полагая, что вос-
становила байты "файла-жертвы" и передала ему управление. Но на деле она
просто закончит работу. А если мы не восстановим эти байты, но перейдем на мет-
ку
100h
, тогда вирус будет работать бесконечно. Если же мы заразили какой-то
файл и сохранили в переменной
First_bytes
первые байты зараженного файла, то
мы просто передадим ей управление (рис. 17.6 и 17.7).
Если вы заглянули в файл-приложение, то заметили там не строку
First_bytes db 90h, 90h, 90h, 90h, 0CDh, 20h
а
First_bytes db 4 dup (90h), 0CDh, 20h
Директива
dup
(от англ. duplicate) дублирует число, которое находится в скоб-
ках столько раз, сколько указывает стоящая перед ней цифра. Сравните приведен-
ные выше две строки. Однако следует иметь в виду, что этот массив занимает па-
мять на диске. Проще говоря, он увеличивает нашу программу на 6 байт.
Пример:
Array db 1500 dup ('1')
создаст массив
Array
размером 1500 байт, заполнив его по умолчанию цифрой 1,
но увеличит программу на указанное количество байтов. Заполнение массива "еди-
Глава 17. Заражение файлов вирусом
181
ницей", а также любым другим символом, указанным в круглых скобках после
dup
,
происходит на стадии ассемблирования.
Рис. 17.6. Подготовка к переходу на адрес 100h
Рис. 17.7. Вот что в конце работы вируса находится по стартовому адресу 100h
17.2.2. Передача управления "файлу-жертве"
Обратите также внимание, как мы переходим на адрес
100h
(передаем управле-
ние "файлу-жертве" после того, как вирус отработал) (листинг 17.6).
Часть III. Файловая оболочка, вирус, резидент
182
Листинг 17.6. Переход на адрес 100h
...
mov ax,100h
jmp ax ;безусловный переход по адресу, указанному в ax
...
С вирусом пока достаточно. В главе 18 мы рассмотрим ошибку, которая была
сознательно допущена в настоящей главе, с тем, чтобы вы сами попробовали ее
обнаружить, а также продолжим писать оболочку.
Глава 18
Высокоуровневая
оптимизация программ
18.1. Пример высокоуровневой
оптимизации
Алгоритм перевода колонки/строки в линейный адрес для вывода символов ме-
тодом прямого отображения в видеобуфер, приведенный в процедуре
Get_linear
файла display.asm главы 14, можно немного оптимизировать следующим образом
(листинги 18.1 и 18.2).
Листинг 18.1. Неоптимизированный вариант (14 строк)
;Из файла display.asm, процедура Get_linear, глава 17
...
push ax ;сохраним все используемые регистры
push bx
push dx
shl dl,1 ;математика: умножаем dl на 2 (dl=dl*2)
mov al,dh ;в al — ряд,
mov bl,160 ;который нужно умножить на 160
mul bl ;умножаем: al(ряд)*160; результат — в ax
mov di,ax ;результат умножения в di
xor dh,dh ;аннулируем dh
add di,dx ;теперь в di линейный адрес в видеобуфере
pop dx ;восстанавливаем регистры...
pop bx
pop ax
ret
...