отформатировать 4 дискеты на 4 стандартных формата: 360Кбайт,
720Кбайт, 1.2Мбайт и 1.44Мбайт. Затем при помощи программы
DiskEditor внимательно рассмотрим и постараемся запомнить
внешний вид boot-секторов этих дискет (0/0/1), хотя бы первые
байты (естественно, все это делается на чистой машине). Встав-
ляем не защищенные от записи дискеты по очереди в дисководы
"больной" машины и (обязательно) обращаемся к ним: пытаемся
прочитать каталог, записать, прочитать и удалить какие-либо
файлы. Наконец, на чистой машине при помощи DiskEditor
вновь просматриваем сектор 0/0/1. Если на какой-либо дискете
он изменился, при помощи того же DiskEditor снимаем образ
всей дискеты в файл. Вирус пойман. Можно упаковать файл ка-
ким-нибудь архиватором и послать его вирусологу. Некоторые
хитрые вирусы хранят свое тело на дополнительной, специально
отформатированной дорожке, так называемом инженерном ци-
линдре дискеты. В этом случае без пакета копирования ключевых
дискет типа fda, teledisk или copymaster не обойтись.

б) Выделение резидентного вируса. Как известно, резидентный ви-
рус постоянно находится в памяти ПЭВМ, выбирая жертву для
заражения. Наиболее часто в качестве жертв выступают запуска-
емые программы. Однако файлы программ могут заражаться при
открытии, копировании на дискету или с нее (вирус OneHalf), во
время поиска при помощи DOS-функций FindFirst или FindNext.
Необходимо подобрать подходящего претендента на "конт-
рольное" заражение - небольшую программу простой структуры,
приманку. Некоторые вирусы пытаются распознать приманку
и отказываются от ее заражения. Не подходят для таких целей
слишком короткие программы или такие, большая часть которых
состоит из повторяющихся байт (например, 90h - код команды
NOP). В качестве приманки с большим успехом можно использо-
вать программы test.com и test.exe. Вот их исходные тексты
на языке Assembler.

test.com

cseg segment

assume cs:cseg, ds:cseg, ss:cseg

org -lOOh
Start:

db 1249 dup (OFAh,90h,OFBh,OF8h)


1 60 Методы борьбы с вирусами

mov ah,4Ch

int 21h

cseg ends

End Start

test.exe

cseg segment

assume cs:cseg, ds:cseg
Start:

db 1000 dup (OFAh,90h,OFBh,OF8h)

mov ah,4Ch

int 21h

cseg ends

sseg segment stack

assume ss:sseg

db 118 dup (OFAh,90h,OFBh,OF8h)

sseg ends

End Start

Скопируем приманки на зараженную машину. Выполним над ними как
можно больше операций: запустим, скопируем в другое место винчесте-
ра и на дискету, переместим, просмотрим их в NC и DOS (командой
dir). При этом желательно несколько раз поменять системное время
и дату, потому что вирусы нередко активны не каждый день и не круг-
лые сутки. Чтобы исключить Stealth-эффект, загрузимся с чистой дис-
кеты и рассмотрим внимательно эти файлы. Как правило, достаточно
бывает проконтролировать размер файлов и просмотреть их код при
помощи F3 - наличие вируса определить несложно.

в) Выделение нерезидентного файла. Самый неприятный случай.
Помимо того, что вирус нередко привередничает, распознавая
приманку, и по-прежнему отказывается работать "без выходных
и отпусков", так еще и заражаемость программ сильно зависит от
их расположения на винчестере. Одни нерезидентные вирусы за-
ражают только в текущем каталоге, другие - только в подкатало-
гах 1-го уровня, третьи - в каталогах, указанных в строке path
системной среды (Vienna), четвертые - вообще во всех каталогах
винчестера. Поэтому воспользуемся программой типа it, чтобы
скопировать приманки во все каталоги диска (запускаем из кор-
невого каталога):

rt copy a:\test.* .


Точка "." в конце - символ текущего каталога. Потом их можно будет
удалить:

rt del test*

Теперь выбираем заведомо зараженную программу и запускаем ее N раз,
постоянно изменяя время и дату. Проконтролировать изменение длины
поможет та же программа rt:

rt dir test.* >test.txt

Получаем файл test.txt, содержащий список файлов test.* с указанием
их длины. Выбираем тот файл приманки, который изменил длину.
Вот вирус и пойман.

Как исследовать алгоритм работы вируса

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

1. Прежде чем перейти к рассмотрению этого вопроса, вспомним неко-
торые принципы функционирования MS DOS.

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

СОМ-программа представляет собой часть кода и данных, которая
начинается с исполняемой команды и занимает не более 64Кбайт.
Например, такую структуру имеет командный процессор
COMMAND.СОМ операционной системы MSDOS до версии 6.22
включительно.

Структура ЕХЕ-программы гораздо сложнее. В начале файла
ЕХЕ-программы располагается заголовок (см. приложение). Поля
ReloCS и ExelP определяют расположение точки входа в программу,
поля ExeSP и ReloSS - расположение стека, поля PartPag
и PageCnt - размер корневого сегмента программы. Размер некоторых

6-1436


программ, вычисленный по полям PartPag и PageCnt, может не со-
впадать с реальным размером файла. Такие программы называются
"сегментированными" или "содержащими внутренние оверлеи".
Опытные авторы вирусов избегают заражать такие программы. Пос-
ле заголовка может размещаться специальная таблица, точное место
расположения которой определяется полем TablOff, а размер - по-
лем ReloCnt. В этой таблице хранятся адреса тех слов в коде про-
граммы, которые модифицируются операционной системой во время
загрузки программы. Например, просматривая файл программы при
помощи утилиты HackerView, можно видеть команду call
0000:1234h. В процессе загрузки программы MS-DOS подставит вме-
сто нулей нужный сегментный адрес, и все будет работать коррект-
но. Кстати, если в поле TablOff указано число 40h или больше,
то, скорее всего, это программа в формате Windows. Подобный
формат имеет, например, командный процессор Windows 95
COMMAND.COM. Несмотря на свое расширение, он имеет в нача-
ле знаменитые символы "MZ" и длину 95Кбайт.

2. Приступаем к исследованию конкретного файлового вируса и разра-
ботке алгоритма его лечения. В качестве жертвы "показательного
вскрытия" возьмем широко известный в начале 90-х годов вирус
SVC-1740. Выбор определился следующими обстоятельствами:

- это очень простой вирус с четкой структурой;

- он не содержит деструктивных функций;

- не содержит грубых ошибок в алгоритме;

- он стандартно заражает СОМ- и ЕХЕ-программы.
Запустив SVC вирус на своей машине, можно наблюдать следую-
щие его проявления.

а) В MS-DOS успели заразиться файлы ARCVIEW.EXE,
HIEW.EXE и LEX.EXE. В результате HackerView, проверяющий
целостность своего кода, отказался работать, сообщив: "HIEW
bad, work is aborted".

6) Windows 3.11 и Windows 95 сначала запустились корректно, но
затем продемонстрировали разноцветные горизонтальные полосы
в видеорежиме 800х600х256 (вирус не заражал какие-либо драй-
вера, просто в момент старта Windows в памяти находился ви-
русный обработчик прерывания INT 21h).


Излечение пришло после использования антивирусов:

DrWeb с: /сир /а1
и
AidsTest с: /f /g /q

3. При помощи ранее описанных методов заразим две приманки:

TEST.COM и TEST.EXE. Увеличение их длины на 1740 байт мож-
но увидеть только на "чистой" машине (Stealth-эффект). Несколь-
ко слов об инструментарии. Вообще говоря, выбор дизассемблеров
весьма широк. В свое время была широко известна программа
DisDoc. По признанию Е. Касперского, он активно пользуется инте-
рактивным дизассемблером IDA. Быстро просмотреть код програм-
мы позволяет утилита HackerView. Также возможно использование
любого отладчика. В данном случае для изучения кода зараженных
приманок использовался дизассемблер Sourcer v5.04. Несмотря на
отсутствие некоторых полезных опций и ошибки при дизассембли-
ровании (достаточно редкие), пользоваться программой удобно -
упакованная PkLite, она занимает на дискете всего 48Кбайт.

Итак, запускаем дизассемблер командой sr test-сом. На экране появи-
лась темно-синяя лицевая страница. Нажав клавишу "а", можно пе-
рейти на страницу опций. Рекомендуется установить опцию "а" -
обязательно дизассемблировать фрагмент программы, располагаю-
щийся после команд jmp/ret/iret - это позволяет получить ассемб-
лерный код тех фрагментов программ, в которые нет явного перехо-
да (процедуры обработки прерываний, скрытые подпрограммы и так
далее). Нажав Enter, вернемся на первую страницу. Запустим процесс
дизассемблирования нажатием клавиши "g". В зависимости от про-
изводительности компьютера, процесс дизассемблирования длится от
нескольких секунд до нескольких минут. Для грубой оценки размера
листинга можно принять, что один килобайт кода соответствует деся-
ти-пятнадцати килобайтам текста. 6740 байт зараженной приманки
дают 96Кбайт текста+файл test.sdf. Этот очень интересный файл хра-
нит в текстовом виде как опции, использованные при дизассемблиро-
вании, так и параметры полученного текста (размещение фрагментов
кода и данных, место расположения символических имен и прочее).
Если изменить эти параметры, переименовать файл в test.def и пере-
дать его Sourcer в командной строке в качестве параметра, то дизас-
семблер будет работать в соответствии с новыми инструкциями. Ана-
логичную операцию проделаем для файла testexe.

б*


4. Займемся анализом полученного листинга. Поверхностно изучая за-
раженные приманки, видим:

- файлы увеличили свою длину на 1740 байт;

- в их конце явно видны посторонние коды;

- изменилось время создания файлов, точнее, изменилось количе-
ство секунд - оно стало равным 60;

- в начале файла test.coM появилась команда jmp;

- в заголовке файла test.exe изменились значения полей ReloCS,
ExelP, ExeSP, ReloSS, PartPag и PageCnt.

Итак.

а) В начале вирусного кода содержится последовательность команд
вида:

call sub_1
sub_1: pop si
sub si,3

Подобная последовательность символов характерна для очень мно-
гих вирусов. Команда call помещает в стек смещение следующей за
ней команды. Это значение извлекается вирусом при помощи ко-
манды pop si (в то время как обычно это делается командой ret)
и помещается в регистр si. Скорректировав эту величину на длину
команды call (3 байта), вирус получает возможность корректного
обращения к ячейкам памяти относительно кодового сегмента:

mov cs:Data[si], xxxx.

Не случайно DrWeb всегда реагирует на подобные команды в на-
чале программ, выдавая предупреждающее сообщение. Впрочем,
это не является обязательным признаком присутствия вируса. На-
пример, устаревшая пристыковочная защита от несанкционирован-
ного копирования (НСК) "Nota" также пользуется этим приемом.

б) Важным элементом алгоритма вируса является определение на-
личия собственного резидента в ОЗУ. Вызывая прерывание DOS
с "секретной" функцией 83h, вирус ждет реакции системы. "Здо-
ровая" система не среагирует на провокацию, а "больная" поме-
стит в регистр dx число 1990h (год создания вируса?), чем и из-
вестит о наличии вируса в памяти. Вот соответствующий
фрагмент вирусного обработчика прерывания INT 21h:


cmp ah,83h
je loc_9

loc_9:

mov dx,1990h
iret

Наличие такой проверки использует антивирус-фаг во время детекти-
рования вирусного кода в оперативной памяти. Также антивирус-бло-
кировщик может имитировать присутствие вируса в памяти, предот-
вращая его внедрение в программное обеспечение компьютера.

в) В случае отсутствия вирусного обработчика INT 21h в памяти,
вирус пытается установить его и остаться в памяти резидентно.
Алгоритм резидентной записи кода вируса в память основан
на прямой модификации заголовка блока памяти (МСВ). Под-
робное описание этого алгоритма и методов борьбы с вирусами,
использующими подобный метод инсталляции, можно найти
в одном из номеров журнала "Монитор" за 1993 г.

г) Установив свою резидентную копию в ОЗУ (или обнаружив на-
личие такой копии), вирус передает управление оригинальной
программе. Изучение этого момента чрезвычайно важно для ана-
лиза. В процессе заражения (данный фрагмент из листинга уда-
лен) вирус считывает (в data_15) 24 байта начала программы
и анализирует первые два байта из них. В зависимости от содер-
жимого первого слова ("MZ" или нет), вирус выполняет зараже-
ние жертвы либо по СОМ-, либо по ЕХЕ-алгоритму, дописывая
фрагмент памяти со своим кодом к ее концу. Естественно, счи-
танные 24 байта также дописываются в файл-жертву. Поэтому
для определения способа передачи управления оригинальному
коду программы вполне достаточно повторно сравнить сохранен-
ный фрагмент начала с признаком "MZ":

cmp cs:data_15[si],5A4Dh
je lt_Was_EXE

В случае если программа была заражена по СОМ-алгоритму, вирус
просто извлекает первые 3 байта из ячейки памяти по адресу
data_15, копирует их в старое начало оригинального кода (по адре-
су cs:100h) и передает туда управление. Адресу data_15 соответ-
ствует 80-ый (если считать от конца) байт зараженной программы.


В случае если программа была заражена по ЕХЕ-алгоритму, вирус
вычисляет старую точку входа по сохраненным в data_20 и data_21
значениям полей ReloCS и ExelP, восстанавливает расположение
стека по сохраненным в data_18 и data_19 значениям полей ReloSS
и ExeSP и передает управление на ReloCS+ES+10h:ExeIP (ES -
сегмент PSP; ES+lOh - сегмент начала программы; ES+ReloCS+
10h - полный сегмент точки входа). Расположение этих адресов
в зараженном файле (от конца файла):

data_20 - 60
data_21 - 58
data_18 - 66
data_19 - 64

Еще могут пригодиться сохраненные значения полей PartPag
и PageCnt (от конца файла):

data_16+1 - 78
data_16+3 - 76

Для излечения зараженного файла достаточно восстановить изме-
ненные значения ячеек, адреса которых только что вычислили,
и отсечь 1740 вирусных байт от конца файла.

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


Расшифровщик может быть совмещен с алгоритмами, противодей-
ствующими трассировке кода вируса с использованием отладчиков.
Ознакомиться с ними можно в специальной литературе, посвящен-
ной борьбе с НСК. Авторы вирусов, как правило, редко изобретают
что-то новое и используют широко известные методы.

Эвристические анализаторы кода

Эвристическим анализатором кода называется набор подпрограмм, ана-
лизирующих код исполняемых файлов, памяти или загрузочных секторов
для обнаружения в нем разных типов компьютерных вирусов. Рассмот-
рим универсальную схему такого кодоанализатора. Действуя в соответ-
ствии с этой схемой, кодоанализатор способен максимально эффективно
задействовать всю информацию, собранную для тестируемого объекта.

Основные термины:

Событие - это совокупность кода или вызов определенной функ-
ции операционной системы, направленные на преобразование сис-
темных данных, работу с файлами или часто используемые вирус-
ные конструкции.

Цепочка связных событий - это набор событий, которые должны
быть выявлены в порядке их следования.

Цепочка несвязных событий - это набор событий, которые должны
быть выявлены, но не обязательно в строгом порядке.
Действия - набор цепочек связных или несвязных событий, для ко-
торых выполнены все условия.

Эвристическая маска - набор действий, выявленных при проверке
файла.

Эвристическое число - порядковый номер первой из совпавших эв-
ристических масок.

События распознаются при помощи подпрограмм выявления событий,
в которых могут использоваться также таблицы с данными. Остальные
данные просто хранятся в массивах и не анализируются. Рассмотрим
функциональную схему эвристического анализатора (рис. 6.1.).

Эмулятор кода работает в режиме просмотра, то есть его основная зада-
ча - не эмулировать код, а выявлять в нем всевозможные события. Со-
бытия сохраняются в таблице событий по алгоритму:

if (Events[EventNumber]==0) Events[EventNumber]=++CountEvents;


где: Events - массив событий;

EventNumber - номер регистрируемого события;

CountEvents - порядковый номер зарегистрированного события.


Таким образом, в ячейку массива Events записывается порядковый но-
мер для выявленного события. CountEvents при инициализации равен 0.
После того, как эмулятор завершит свою работу, последовательно запус-
каются два преобразователя. Первый преобразователь заполняет массив


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

for(i=0;i<CountMaskEvrnrs;i++) {
if (MaskEvents[i][0]==0) {

for(j=2;j<MaskEvents[i][1 ];]++)
if(Events[MaskEvents[i][j]]==0) goto nextMask;

"

else
for(e=0,j=2;j<MaskEvents[i][1];j++) {

if(Events[MaskEvents[i][j]]==0 II Events[MaskEvents[i][j]]<e)

goto nextMask;

else e=Events[MaskEvents[i][j]];

}
Actions[i]=1;

nextMask:;

}

где: CountMaskEvents - число масок цепочек событий;

MaskEvents - двумерный массив цепочек связных и несвязных
событий;

Actions - массив действия.

Затем выполняется второй преобразователь, который выбирает дан-
ные из массива действия и цепочек эвристических масок и вычис-
ляет эвристическое число по следующему алгоритму:

for(i=0;i<CountMaskHeurist;i++) {
for(j=1;j<MaskHeurist[i][0];j++)

if(Actions[MaskHeurist[i][j]]==0) goto nextMaskI;

NumberHeurist=i+1;

break;

nextMaskI:

}

где: CountMaskHeurist - число эвристических масок;

MaskHeurist - двумерный массив с эвристическими масками;

NumberHeurist - эвристическое число.

Блокировщик вируса

Рассмотрим пример. В дисплейном классе ВУЗа эпидемия, часть машин
заражена неизвестным вирусом. До конца сессии - несколько дней,
выключение машин из учебного процесса смерти подобно (в первую


очередь для обслуживающих класс сотрудников). Ситуация усугубляет-
ся тем, что студенты постоянно переносят программы на дискетах с од-
ной машины на другую. Как ограничить распространение эпидемии,
пока вирус не уничтожен?

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

Разумеется, надо попытаться запустить блокировщик раньше всех ос-
тальных программ, например, в файле config.sys:

install c:\util\stopsvc.com

Но если вирус успел заразить command.com или стартует из загрузочно-
го сектора, то антивирус-блокировщик не поможет.

Листинг программы, блокирующей распространение вируса SVC-1740:

;; Резидентный блокировщик вируса SVC-1740
;; (с) К. Климентьев, Самара 1997
cseg segment

assume cs:cseg, ds:cseg, ss:cseg

org 100h

Переходим к инициализации программы
Start:

jmp Install

;0бработчик прерывания INT 21 h .
lnt21:

[Проверим номер функции, если 83h -
;то это запрос присутствия вируса

cmp ah, 83h

jnz Skip21

;0тветим, что вирус присутствует
mov dx, 1990h


;3апускаем оригинальный обработчик прерывания
Skip21:

db OEAh ;Код команды JMP
Ofs21 dw ?
Seg21 dw ?

Инициализируем программу
Install:

.Проверим, не инсталлирована ли уже эта программа. Если
инсталлирована, выведем сообщение об этом и выйдем из программы.
;Вторую копию программы инсталлировать не имеет смысла

mov ah,83h

int 21 h

cmp dx, 1990h

jz Already

.Считаем оригинальный вектор прерывания INT 21 h
mov ax,3521h
int 21h
mov Ofs21, bx
mov Seg21, es

.Установим наш вектор прерывания INT 21h
mov ax, 2521h
mov dx.offset lnt21
int 21h

[Выведем сообщение об успешной инсталляции программы в памяти
mov ah, 9

mov dx, offset OkMes
int 21h

.Выйдем из программы, оставив обработчик резидентным
mov dx, offset Install
int 27h

;Выведем сообщение о том, что вирус
;или наша программа уже в памяти
Already:

mov ah, 9

mov dx, offset BadMes


int 21 h
ret

.Сообщения программы

OkMes db "Yeah! STOPSVC installed now!",13,10

db "(c) KostyaSoft, Samara 1997$"
BadMes db 7, "Perhaps, virus is in memory already. Sorry $"
cseg ends

Пример антивируса

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

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

В качестве языка программирования выбран С. Приоритетным призна-
но использование таких библиотечных процедур, форматы которых
идентичны во многих системах программирования. Поэтому, например,
использовалась процедура _dos_findfirst(), а не findfirst(). Программа
была написана и отлаживалась в системе, программирования JPI
TopSpeed С v3.01, а также была проверена на Borland C++ v3.1. Кроме
того, контролировалось наличие, идентичность по функциям и форма-
там вызова использованных библиотечных функций в системах про-
граммирования Microsoft C++ v6.0 и Watcom C++ vlO.0. Но если что-
то и не совпадет, откорректировать программу любому программисту не
составит труда.

Основу программы составляет алгоритм обхода дерева каталогов и по-
иска в них файлов с расширениями "СОМ" и "ЕХЕ".

В тот момент, когда обнаружен очередной потенциально зараженный
файл, вызывается функция infectedQ с именем файла в качестве пара-
метра. Задачей этой функции является проверка указанного файла на
заражение и возврат соответствующего признака.


В случае положительного результата на заражение вызывается функция
cure(), которая и выполняет операцию исцеления зараженной программы.

Если требуется написать программу для лечения для какого-либо другого
вируса, достаточно просто изменить содержимое процедур cure() и infectedQ.

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

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

Разумеется, неправильно было бы использовать для детектирования
файла такие ненадежные признаки, как, например, 60 секунд во време-
ни создания файла. Во-первых, это может быть признаком случайного
изменения (например, при упаковке/распаковке некоторыми архивато-
рами). Во-вторых, слишком многие вирусы используют для самоопозна-
ния одинаковые признаки. Наконец, эти признаки могут принадлежать
совершенно здоровой программе (как в истории с антивирусом antitime
и сигнатурой MsDos).

Вообще говоря, сигнатура - это множество N пар <Pi,Bi>, i=l.N, где
Pi - расположение i-го байта, Bi - значение i-го байта. Но на практике
часто используют непрерывные сигнатуры, для которых важно опреде-
лить только место расположения первого байта и длину сигнатуры.

Какой должна быть длина сигнатуры? Вообще говоря, чем больше -
тем лучше, в идеале в сигнатуру должна входить вся неизменяемая
часть вируса, что гарантирует однозначность распознавания. Но это не-
вероятно увеличит объем антивируса (а известные программы лечат
тысячи вирусов) и замедлит процесс распознавания. Таким образом,
целесообразным следует считать количество от нескольких байт до не-
скольких десятков байт - не больше. Остановимся на цифре 6.

Итак, в качестве сигнатуры вируса SVC-1740 выберем 6 байт вируса,
которые размещены начиная с 1724-го байта, если считать от конца за-
раженного файла (с 16-го байта вируса). Вполне возможно, что эти
6 байт совпадают для всех вирусов семейства SVC. Но вероятность
того, что машина сразу заражена несколькими вирусами одного семей-
ства, крайне мала. А вот выбор в качестве сигнатуры шести первых байт
вируса был бы точно ошибочным, потому что, как уже говорилось
выше, подобное начало характерно для очень большого числа вирусов.


Итак, сигнатура OB4h 83h OCDh 21h 5Eh 56h длиной б байт расположена
начиная с 1724-го байта, если считать от конца зараженной программы.

Теперь рассмотрим вопрос лечения программы. Фрагменты заражен-
ной программы, которые необходимо восстановить для излечения, оп-
ределены ранее.

Напомним, что вирус SVC-1740, заражая программу, дописывается в ее
конец, сохраняя в своем теле первые 24 байта оригинальной программы.
Поэтому для излечения как ЕХЕ, так и СОМ-программ, вполне доста-
точно переписать сохраненные 24 байта в начало программы без учета
того, что большая их часть не была изменена, и отсечь 1740 вирусных
байт в конце зараженной программы.

Но с методической точки зрения, следуя стратегии заражения, необхо-
димо в СОМ-программе восстановить только первые три байта,
а в ЕХЕ-програмее - 6 ранее измененных слов заголовка.

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

Итак, для СОМ-файла считываем 3 байта, с 80-го по 78-й, если считать
от конца файла, и переписываем их в начало файла, для ЕХЕ-файла -
перемещаем 6 слов согласно таблице 6.1. и отсекаем последние
1740 байт.

Таблица 6.1. Таблица перемещений для ЕХЕ-файла

Источник, отсчет от
конца файла
Приемник, отсчет от
начала файла
78 2
76 4
66 14
64 16
60 20
58 22


Демонстрационный антивирус-фаг

для вируса SVC-1740.

"**"***************"**"**"*"*******"*"*"**^

#include <stdio.h>
^include <dos.h>


^include <dir.h>

^include <str.h>

^include <process.h>

^include <errno.h>

^include <bios.h>

^include <io.h>

#include <fcntl.h>

^define F_FOUND 0

#define PATH_LEN 128
^define DRIVE_LEN 4
ftdefine BLANK_LEN 80

#define BAD 1
^define GOOD 0

#define DBG
char

/* Строка имени текущего подкаталога */
path[PATH_LEN],

/* Строка имени начального места расположения */
old_path[PATH_LEN],

/* Строка имени требуемого устройства 7
drive[DRIVE_LEN],

/* Пустая строка */
blank[BLANK_LEN];

int

/* Количество отсканированных каталогов 7
n_dir,

/* Количество исследованных файлов 7
nJil,

/* Количество больных и исцеленных файлов 7
n_ill;


int

/* Длина имени файла */
I,

/* Временный индекс */

' 1

^include "antilib.c"

/* Рекурсивная процедура обхода дерева каталогов */
walk()

{
int found_d, found_f;

struct find_t buf;

/* Поиск каталогов */
found_d=_dos_findfirst("*.*",_A_SUBDIR ,&buf);

while (found_d =- F_FOUND)

{

if ((buf.name[0] != ".") && (buf.attrib & _A_SUBDIR ))

{
chdir(buf.name);

walk();

chdir("..");

}
found_d=_dos_findnext( &buf );

/* К этому моменту не отсканированных нижележащих каталогов
больше не осталось - сканируем файлы */

n_dir++;

getcwd( path, PATH_LEN );

/* Поиск файлов */
^иг^^оз.Лг^ЛгзЦ^.^^А.МОРМА!- ,&buf);

while (foundJ == F_FOUND)

{
1=strlen( buf.name );

if (((buf.name[l-3]=="C")&&
(buf.name[l-2]=="0")&&


(buf.name[l-1]=="M"))ll
((buf.name[l-3]=="E")&&
(buf.name[l-2]=="X")&&
(buf.name[l-1]=="E")))

(
n_fil++;

printf("%c%s",13,blank);

printf("%c%s\\%s ",13,path,buf.name);

/* Нашли новый файл - надо проверить, инфицирован ли он.
Если заражен, то лечим 7

if (infected(buf.name)==BAD) cure(buf.name);

}
found_f=_dos_findnext( &buf );

}
}

main( int argc, char *argv[] )

{
puts("ANTISVC - демонстрационный антивирус-фаг");

if (argc < 2)
{ р1Л8("Введите имя диска в качестве параметра"); exit(2); }

if(((toupper(argv[1][0]))>"Z")ll((toupper(argv[1][0]))<"A"))
{ puts("HeBepHO задано имя диска"); exit(3); }

drive[0]=argv[1][0]; drive[1 ]=":"; drive[3]="\0';

for (i=0;i<BLANK_LEN;i++) blank[i]=" ";blank[BI_ANK_LEN-1]="\0";

n_dir=0; n_fil=0;

getcwd(old_path, PATHJ-EN);

drive[2]="\0"; system(drive);

drive[2]=^\"; chdir(drive);

/* Запускаем рекурсивный обход дерева каталогов
для выбранного диска 7
walk();

old_path[2]="0"; system(old_path);

old_path[2]='\\"; chdir(old_path);


printf("\nKaTanoroB : %с1\пфайлов : %Ь\пОбнаружено больных
и излечено: %d", n_dir, n_fil, n_ill);

if (nJII) exit(1); else exit(O);

Файл "ANTILIB.C", включаемый в предыдущий:

Процедуры обнаружения и лечения

/* Сигнатура */
char sign[7]={ (char) OxB4,

(char) 0х83,

(char) OxCD,

(char) 0х21,

(char) Ox5E,

(char) 0х56,

"\0");

int infected( char *fn )

I
int f;

int r,q;

char buf[7]; /* Буфер под сигнатуру */

/* Открываем файл */
r=_dos_open( fn, 0_RDONLY, &f );

if (r) { printf(" - ошибка открытия!"); return GOOD; }

/* Читаем 6 байт */
lseek( f, -1724, SEEK_END );

r=_dos_read( f, buf, 6, &q ); buf[6]="\0";

if ((r)ll(q!=6)) {printf(" - ошибка чтения!"); _dos_close(f); return GOOD;

/* Закрываем файл */
_dos_close(f);

/* Сравниваем байты с сигнатурой 7
if (strcmp( buf, sign)==0)


( printf(" - был болен и..."); n_ill++; return BAD; } /* Болен !!! */

/* Годен к в/службе. П/пк мед. службы Орлов :-) */
return GOOD;

cure( char *fn )

i
int f;

int mz;

int r,q;

char buf[24]; /* Буфер под байты */

/* Открываем файл */
r=_dos_open( fn, 0_RDWR, &f );

if (r) { printf(" - ошибка открытия!"); return; }

/* Читаем первые два байта для определения типа программы */
r=_dos_read( f, &mz, 2, &q );

if ((r)ll(q!=2)) {printf(" - ошибка чтения!"); _dos_close(f); return; }

/* Читаем сохраненные вирусом 24 байта старого начала */
lseek( f, -80, SEEK_END );

r=_dos_read( f, buf, 24, &q );

if ((r)ll(q!=24)) (printf(" - ошибка чтения!"); _dos_close(f); return; }

/* Определяем тип программы 7
if ((mz==Ox4D5A)ll(mz==Ox5A4D))
{ /* Это ехе 7

/* Пишем правильные PartPag и PageCnt 7
lseek( f, 2, SEEK_SET );

r=_dos_write( f, &buf[2], 4, &q );

if ((r)ll(q!=4)) {printf(" - ошибка записи!"); _dos_close(f); return; }

/* Пишем правильные ReloSS и ExeSP 7
lseek( f, 14, SEEK_SET );

r=_dos_write( f, &buf[14], 4, &q );

if ((r)ll(q!=4)) {printf(" - ошибка записи!"); _dos_close(f); return; }


/* Пишем правильные ReloCS и ExelP */
lseek( f, 20, SEEK_SET );

r=_dos_write( f, &buf[20], 4, &q );

if ((r)ll(q!=4)) {printf(" - ошибка записи!"); _dos_close(f); return; }

)

else
( /* Это corn */

/* Восстанавливаем сохраненные З первые байта программы */
lseek( f, О, SEEK.SET);

r=_dos_write( f, &buf[0], 3, &q );

if ((r)ll(q!=3)) {printf(" - ошибка записи!"); _dos_close(f); return; }

/* Усекаем файл (переходим на начало вируса
и записываем 0 байт) */
lseek( f, -1740, SEEK_END);

r=_dos_write( f, buf, 0, &q);

/* Закрываем файл 7
_dos_close(f);

printf("Tenepb исцелен !\п");

return;

}

Дата добавления: 04.03.2002

База рефератов на портале KM.RU существует с 1999 года. Она пополнялась не только готовыми рефератами, докладами, курсовыми, но и авторскими публикациями, чтобы учащиеся могли использовать их и цитировать при самостоятельном написании работ.


Это популяризирует авторские исследования и научные изыскания, что и является целью работы истинного ученого или публициста. Таким образом, наша база - электронная библиотека, созданная в помощь студентам и школьникам.


Уважаемые авторы! Если Вы все же возражаете против размещения Вашей публикации или хотите внести коррективы, напишите нам на почту info@corp.km.ru, мы незамедлительно выполним Вашу просьбу или требование.


]]>
]]>
Сетевое издание KM.RU. Свидетельство о регистрации Эл № ФС 77 – 41842.
Мнения авторов опубликованных материалов могут не совпадать с позицией редакции.

Мультипортал KM.RU: актуальные новости, авторские материалы, блоги и комментарии, фото- и видеорепортажи, почта, энциклопедии, погода, доллар, евро, рефераты, телепрограмма, развлечения.

Карта сайта


Подписывайтесь на наш Telegram-канал и будьте в курсе последних событий.


Организации, запрещенные на территории Российской Федерации