Защита программ от компьютерных вирусов
Инициация генератора случайных чисел с помощью
процедуры 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.
Итак, «вакцинация» вновь разрабатываемых
программ не представляет особой сложности. А как защитить уже существующую ЕХЕ-программу? Для
этого существуют две возможности: либо использовать отдельную программу,
которая хранит ключевую информацию и осуществляет проверку по требованию пользователя (такая программа обсуждается в
следующем разделе), либо пристыковать к защищаемой
программе небольшой код «вирусного фага»-тогда проверка будет осуществляться
автоматически при каждом запуске программы. В этом разделе мы обсудим технику
создания и внедрения в защищаемую. программу
антивируса—фага, т.е. небольшой ассемблерной программы,
которая использует тот же механизм перехвата управления, что и обычный вирус,
но осуществляет нужную защиту программы.
Программа
– фаг устанавливается специальной программой-установщиком и к моменту начала
своей работы уже должна иметь в своем распоряжении эталонный заголовок файла.
Получив управление, фаг проверяет заголовок соответствующего файла и, если
обнаружены изменения, сообщает об этом пользователю и удаляет вирус. После
окончания работы фаг передает управление
защищаемой программе. Поскольку фаг пишется целиком на ассемблере, его работа
протекает очень быстро без заметного замедления загрузки программы. Если Вы установите такой фаг на большую часть
часто используемых программ, Ваш компьютер будет защищен очень надежно.
Чтобы правильно спроектировать фаг, нужно хорошо
представлять себе механизм запуска ЕХЕ-программ.
Стандартный загрузчик ДОС реализует следующую последовательность действий при
запуске программы.
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 значение собственного сегмента данных. На
практике сегмент данных в коротких ассемблерных программах обычно совпадает с
сегментом кода, т.е. программа и данные размещаются в одном сегменте. Сегмент
стека SS можно не изменять, т.к. программа-установщик фага должна позаботиться о том, чтобы стек
не разрушил код самого фага, и соответствующим образом настроить ReloSS и/или ExelP. Обычно в ЕХЕ-программе начальное значение ReloSS
таково, что стек размещается сразу за концом
программы, т.е. в том месте, куда программа-установщик
помещает "код фага. Длина стека ExeSP как правило более чем достаточна для того,
чтобы работа фага со стеком не привела к разрушению кода фага, поэтому в
большинстве случаев установщик оставляет начальные значения ReloSS
и ExeSP без изменения.
В этом параграфе описываются программы SetFag.pas и Fag.asm, с помощью которых реализуется описанный выше
механизм защиты. Программа SetFag
(прил.П8.1) осуществляет
установку фага, а программа Fag.asm (прил.П8.2) содержит сам фаг. Если Вы
захотите воспользоваться предлагаемыми программами,
откомпилируйте Турбо Ассемблером файл Fag.asm командой
tasm fag /L
В ходе компиляции на экран будет выведено 13 предупреждений вида
Warning* Open procedure: XXXXXX
а в конце сводка:
Error
message: None Warning message: 13 Passes: I Remainig memory: XXXК
Если
в строке Error message вместо None указано число обнаруженных ошибок,
просмотрите файл листинга компиляции fag.lst, отыщите в нем •сообщения компилятора об
ошибках и устраните их. Затем преобразуйте полученный
файл fag.obj в программу Fag.prg командой
tiink fag, fag.prg
Компоновщик должен сообщить Warning: No stack
Замечу, что программа Fag.prg не может работать самостоятельно без
предварительной настройки установщиком SetFag.exe, поэтому в целях предосторожности ей
присваивается нестандартное расширение PRG. Для установки защиты на любой ЕХЕ-фаил следует дать команду
setfag NAME,
где NAME-имя
защищаемого файла. Иными словами, имя файла передается программе установки фага
SetFag.exe с помощью параметров запуска. В имени NAME
можно опускать стандартное расширение ЕХЕ, а
также разрешается указать маршрут поиска файла и/или символы—заменители ДОС «*» и«?» для определения
группового имени-в этом случае защита будет установлена на каждый файл,
соответствующий групповому имени. Например, команда
setfag d:\mydir *
означает требование установить защиту на все ЕХЕ-файлы
из каталога MYDIR на
диске D.
Перед установкой зашиты программа осуществляет
серию проверок файла. Она проверяет заголовок файла и блокирует установку
защиты, если первые два байта заголовка не соответствуют сигнатуре «MZ» (признаку ЕХЕ-файла). Кроме того, она
проверяет «хвост» файла с тем, чтобы убедиться в отсутствии кода фага, и блокирует повторную установку защиты
на уже защищенный файл. Далее, защита не устанвливается
также в том случае, если длина загружаемой части файла станет слишком большой (превысит
доступную память). Если в конце файла обнаружена незагружаемая часть, программа
информирует об этом пользователя и запрашивает у него подтверждение на
установку за-щиты. После завершения всех проверок программа создает резервную
копию исходного файла с расширением ВАК. Создание ВАК-файла можно
запретить, если команду вызова дополнить ключом /NOBAK, например setfag myprog /nobak.
Для защиты используется ключ, соответствующий такой структуре данных:
Type
HeadType = record
case Byte of
1:(Sign : Word; {Сигнатура 'MZ' = $5MD}
PartPag:
Word; {Часть
неполного сектора}
Страницы: 1, 2, 3, 4
|