скачать рефераты

скачать рефераты

 
 
скачать рефераты скачать рефераты

Меню

Реферат: Защита от вирусов скачать рефераты

программа, и «подсовывают» незара-женные копии этих секторов. Такие вирусы (их

называют вирусы—невидимки) вряд ли удастся обнаружить с помощью стандартного

обращения к функциям ДОС. Для борьбы с ними используют прямое обращение к

BIOS-прерыванию $13.

3.2. Защита вновь создаваемых программ

Ключевую информацию (будем для краткости называть ее ключ) о незараженной

программе можно хранить в отдельном файле, но в этом случае существует

опасность потерять дополнительный файл при копировании про­граммы или ошибочно

уничтожить его. Гораздо надежнее хранить ключ в теле самого защищаемого файла.

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

случае заражения вирус изменит поля PartPag и PageCnt и мы

никогда не сможем определить то место в файле, где он рас­полагается. Вспомним,

что все константы (в том числе и типизированные) создаются на этапе компиляции

программы, таким образом в файле обяза­тельно имеется область данных,

содержащая значения этих констант. Эта область в Турбо Паскалевых программах

располагается в самом конце за­гружаемой части файла (см.рис.6.2).

Следовательно, мы должны объявить в программе типизированную кон­стант,

предназначенную для хранения ключа, а затем в область файла, отве­денную для

ее размещения, поместить нужную информацию.

Каким образом отыскать в ЕХЕ-файле место, занимаемое ключом? Ко­нечно,

можно перед ним в программе разместить какую-либо типизиро­ванную константу с

характерным значением (например, заранее обуслов­ленную текстовую строку) и

затем отыскивать ее в файле. Однако такое ре­шение вряд ли можно признать

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

фрагмент кодов программы со­держит ту же цепочку байт, что и заголовок ключа;

во-вторых, придется просматривать подчас большой по объему ЕХЕ—файл в

поисках нужной константы. Значительно изящнее выглядит решение, основанное на

точном вычислении смещения от начала файла до ключа.

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

предусмотрено никакой информации о начальном значении регистра DS, в

котором хранится сегмент данных. Перед передачей управления про­грамме

загрузчик устанавливает значение этого регистра так, чтобы он ука­зывал на

начало так называемого префикса программного сегмента {PSP), а

запущенная программа уже сама должна установить его надлежащим образом.

Префикс программного сегмента имеет длину 256 байт (16 параграфов) и размещается

загрузчиком в оперативной памяти непосредственно перед за­груженной программой.

В PSP содержится различная служебная информация, которая может быть

достаточно важной для ДОС и работающей программы (в PSP, например,

хранятся параметры обращения к программе), но в нем нет указаний на содержимое

регистра DS. Таким образом, найти начало области данных в файле

достаточно трудно. Однако это нетрудно сделать в работающей программе-для этого

предусмотрена стандартная функция DSeg, возвра­щающая сегмент

данных. Если бы программа могла получить также инфор­мацию о сегменте PSP,

с которого начинается загруженная программа, можно было бы вычислить смещение в

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

MS-DOS с номером $62 возвращает в регистре ВХ значение

сегмента PSP. Следовательно, программа должна полу­чить значения обоих

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

которого начинается область данных.

Остается последняя проблема-как найти нужную константу. Турбо Паскаль размещает

константы в области данных по мере их объявления в программе. Зная размер

каждой константы и порядок их объявления, можно вычислить место размещения

нужной нам типизированной константы. Однако этот метод не годится для

универсальной программы защиты, так как порядок объявления констант может

меняться от программы к программе. К счастью, мы можем использовать операцию

получения адреса @. Результатом приме­нения этой операции к адресу

константы, выбранной в качестве ключа, яв­ляется указатель (четырехбайтный

адрес); смещение адреса, который он со­держит, и является нужным нам смещением

начала ключа относительно начала области данных.

3.3. Модуль F_Anti

В этом параграфе описывается модуль F_Anti, в котором осуществляются все

необходимые действия по установке ключа во вновь создаваемый ЕХЕ-файл и

последующей проверке этого ключа при каждой загрузке программы. Полный текст

модуля см. прил.П7.

В качестве ключа для контроля факта заражения ЕХЕ-файла в модуле

F_Anti используется типизированная константа Head,

соответствующая такой структуре данных:

Type

НТуре = record

НЕ : HeadExeType; {Эталонный заголовок файла}

HL : Longint; {Эталонная длина файла}

HF : Boolean; {Флаг установки ключа}

Key: Word ; {Шифр для защиты ключа}

end;

При создании этой типизированной константы компилятор в поле HF

по­мещает значение False. Запущенная программа анализирует это поле. При

первом прогоне HF = False, в результате чего программа вызывает

процедуру Save, в ходе выполнения которой в файле сохраняются эталонный

заголовок и начальная длина файла. При этом одновременно в поле HF

файле програм­мы!) помещается значение True, поэтому при любом

последующем запуске программы вместо Save будет вызвана процедура

CheckFile, которая осуществит нужный контроль файла. Если в ходе

контроля обнаруживается хотя бы ма­лейшее отличие заголовка файла от его

эталона, хранящегося в Head, про­грамма сообщает о факте заражения и

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

При восстановлении зараженного файла осуществляются следующие действия:

• зараженный файл копируется в файл с расширением VIR-это позволит Вам в

случае неудачной попытки восстановления повторить ее еще раз; кроме того, при

желании Вы сможете передать разработчикам антиви­русных программ копию вируса

для выработки методов его обнаружения и уничтожения;

• анализируется адрес запуска зараженной программы: если относительное

значение сегмента точки запуска у зараженной программы меньше, чем в эталоне,

то это означает, что вирус располагается в начале или в середине.

Если программа запускается на уже зараженном ПК. не исключено,

что заголовок файла будет испорчен вирусом, и тогда система защиты будет

ревностно следить за сохранностью вируса! В этом случае программа предупреждает

пользователя о невозможности восстановления (если Вас заинтересовал описываемый

способ борьбы с вирусами, попробуйте модифицировать программу защиты так, чтобы

она работала и в этом случае);

• если вирус пристыкован в конец файла, то в восстанавливаемый файл переносится

эталонный заголовок и незараженная часть, начиная с байта TablOff +

ReloCnt'4 от начала файла и до байта FileSize-HL

Отмечу следующее обстоятельство. Описанная система защиты дублирует заголовок

файла в тело программы. Ничто не мешает вирусу проверить тело программы на

наличие дубликата и соответствующим образом изменить его. Я далек от мысли, что

Вы,, уважаемый читатель, после знакомства с этим разделом захотите создать

собственный вирус, учитывающий это обстоятельство. Тем не менее я считаю, что

нелишней будет какая-то защита самого ключа. Такая защита реализуется очень

просто: для этого достаточно все 16—битные поля эталона заголовка сложить по

модулю 2 со случайной константой Key, С этой целью в процедуру

Save помещен следующий фрагмент (см. текст модуля в прил.П7):

{Зашифровать ключ:} Randomize; Head.Key := Random($FFFF);

with Head,

Head .HE do for k = I to 14 do

Hem[k] := HE. Hem [k] xor Key;

(массив Hem совмещен в памяти с сохраняемым в файле эталонным

заголов­ком, а НЕ .Нет-с заголовком файла в момент первого запуска).

Инициация генератора случайных чисел с помощью процедуры Randomize

гарантирует, что шифр Head.Key не будет повторяться в различных

програм­мах. В процедуре CheckFile с помощью операторов

{Дешифровать ключ: }

with Н,Н.НЕ do for k := I to 14 do Hem[k] := Hem[k] xor Key;

восстанавливается исходный вид ключа.

Процедура CheckFile, осуществляющая установку или контроль ключа,

вызывается в ходе выполнения установочной части модуля F_Anti

, поэтому для использования описанного метода защиты достаточно указать имя

модуля в предложении Uses. Замечу, что в случае разработки

программы с оверлеями модуль F_Anti можно объявить

оверлейным, если в установочной части любого неоверлейного модуля инициируется

работа администратора оверлея.

В распоряжении программиста имеется глобальная переменная

CheckVirasResult, сигнализирующая о результатах проверки программы.

Зна­чения этой переменной интепретируются следующим образом:

0; {Не обнаружен факт заражения} 1; {Первый запуск, в

программе установлена защита}

-1; {Вирус обезврежен с согласия пользователя}

-2; {Вирус обезврежен автоматически} .

-3; {Контроль подавлен ключом /NOANTI}

-4; {Вирус расположен в начале программы}

Работа процедуры CheckFile может быть подавлена, если программа

за-пускается с ключом /NOANTI. Ключ /NOQUERY

разрешает автоматическое удаление обнаруженного вируса без разрешения

пользователя.

Ключ /NOALARM также разрешает процедуре автоматически удалить вирус, но

за­прещает выдавать на экран предупреждающее сообщение. Наконец, ключ

/NOCOPY запрещает создание резервной копии зараженного файла (с расширением

VIR).

Следующая простая программа иллюстрирует технику использования модуля F-Anti

. Если Вы скомпилируете эту программу в файл testanti.exe, то

после команды testanti на экране появится сообщение

Установлена защита файла TESTANII.EXE

. при первом запуске программы и В файле TESTANTI.EXE вирус

не обнаружен.

при каждом следующем запуске. Если запустить программу командой

testanti /noanti на экран будет выведено сообщение Контроль

блокирован ключом /NOANTI.

Uses FAnti; begin

case CheckVirusResuit of

0: WriteLn(‘B файле ',ParamStr (0),' вирус не обнаружен.*);

1: WriteLn ('Установлена защита файла ',aramStr (0) ,*.*);

-1: WriteLn ('Вирус удален с разрешения пользователя.');

-2: WriteLn ('Вирус удален автоматически.');

-3: WriteLn С Контроль блокирован ключом /NOANTI.*);

-4: WriteLn С Вирус расположен в начале *+

' файла - удаление невозможно.')

end

end.

4. ЗАЩИТА СУЩЕСТВУЮЩИХ ЕХЕ-ФАЙЛОВ

Итак, «вакцинация» вновь разрабатываемых программ не представляет особой

сложности. А как защитить уже существующую ЕХЕ-программу? Для этого

существуют две возможности: либо использовать отдельную программу, которая

хранит ключевую информацию и осуществляет проверку по требо­ванию пользователя

(такая программа обсуждается в следующем разделе), либо пристыковать к

защищаемой программе небольшой код «вирусного фага»-тогда проверка будет

осуществляться автоматически при каждом запуске программы. В этом разделе мы

обсудим технику создания и внедрения в за­щищаемую. программу антивируса—фага,

т.е. небольшой ассемблерной программы, которая использует тот же механизм

перехвата управления, что и обычный вирус, но осуществляет нужную защиту

программы.

Программа – фаг устанавливается специальной программой-установщиком и к

моменту начала своей работы уже должна иметь в своем распоряжении эталонный

заголовок файла. Получив управление, фаг проверяет заголовок соответствующего

файла и, если обнаружены изменения, сообщает об этом пользователю и удаляет

вирус. После окончания работы фаг передает управ­ление защищаемой программе.

Поскольку фаг пишется целиком на ассемблере, его работа протекает очень

быстро без заметного замедления загрузки про­граммы. Если Вы установите такой

фаг на большую часть часто используемых программ, Ваш компьютер будет защищен

очень надежно.

Чтобы правильно спроектировать фаг, нужно хорошо представлять себе механизм

запуска ЕХЕ-программ. Стандартный загрузчик ДОС реализует

следующую последовательность действий при запуске программы.

1) Создается префикс программного сегмента PSP. Обычно для этого

ис­пользуется функция ДОС $26.

2) В некоторую локальную область памяти считываются начальные 28 байт заголовка

ЕХЕ-файла, соответствующие структуре данных HeadExeType.

3) Определяется размер загружаемой части файла по формуле

LengExe = (PageCnt-l)*512 + PartPag

4) Определяется файловое смещение загружаемой части:

SeekExe = HdrSize*16

5) Выбирается сегментный адрес StartSeg для размещения программы.

Обычно StartSeg = Segment {PSP) +16, т.е. программа

размещается сразу за PSP, который имеет длину 256 байт (16 параграфов).

6) Считывается загружаемая часть программы в непрерывную область памяти длиной

LengExe, начинающуюся по адресу StartSeg:0000.

7) Указатель файла устанавливается на начало таблицы перемещения TablOff,

8) Для каждого элемента перемещения (этих элементов ReloCnt):

считывается элемент как два 16-битных слова IternOfs, ItemSeg;

вычисляется ReloSeg === StartSeg+ltemOfs, т.е.

сегментная часть смещения абсолютного адреса перемещаемой ссылки;

• извлекается слово по адресу ReloSeg:ltemOfs-сегментная часть

пере­мещаемой ссылки;

• к этому слову прибавляется StartSeg (осуществляется так называемая

привязка сегмента);

• результат помещается обратно по адресу ReloSeg:ltemOfs.

9) Выделяется память за концом программы в соответствии со значениями

MinMem и МахМет.

10) Инициируются регистры и запускается программа:

• регистры ES и DS получают значение сегмента, в котором располагается PSP',

регистр АХ отражает корректность идентификаторов дисков в

командной строке (при нормальном запуске содержит 0);

SS = StartSeg+ReloSS;

SP = ExeSP;

CS == StartSeg^ReloCS;

• IP= Exelp;

содержимое остальных регистров не имеет значения. Регистры сегмента

кода CS и указателя инструкций IP обычно иниции­руются

следующими тремя командами:

PUSH StartSeg+ReloCs

PUSH Exelp

RETF

(команда RETF дальнего возврата из подпрограммы извлекает из стека два

слова-смещение и сегмент адреса перехода-и помещает их соответственно в IP

и CS).

Таким образом, сразу после получения управления фаг должен сохранить значения

регистров АХ и DS и поместить в DS значение

собственного сегмента данных. На практике сегмент данных в коротких

ассемблерных программах обычно совпадает с сегментом кода, т.е. программа и

Страницы: 1, 2, 3