Вирусы: обнаружение заражения
Проведем аналогии
Наверное,
уже все слышали о таком объекте, как компьютерный вирус. Что
же представляет эта субстанция и от куда пошло это название?
Термин "вирус" пришел к нам из биологии и медицины.
Биологический вирус – это неполноценный организм, состоящий из
нуклеиновой кислоты (ДНК или РНК, т.е. генетического кода) и
защитной белковой оболочки, позволяющей существовать вирусу в
закапсулированном состоянии. Биологический вирус оживает лишь
тогда, когда попадает в клетку живого организма и встраивает
свой генетический код в исходный. Компьютерный вирус действует
теме же методами. И так.
Компьютерный
вирус – это кусок кода (не программа, а всего лишь код),
который способен встраиваться в код какой-либо программы, там
самым оживая и заражая другие программы. Как и в случае
биологического вируса, когда больной человек опасен здоровому,
зараженная программа опасна для других программ, т.к. с ее
помощью вирус может заражать. При этом в большинстве случаев
зараженная программа вполне работоспособна, а не редко ее и не
возможно отличить от "здоровой".
Чем
раньше министерство здравоохранения обнаружит вирусную
эпидемию, тем мягче будут последствия и тем быстрее можно
будет локализовать очаг заражения и избавиться от заразы.
Точно тоже происходит и в мире программ. Чем раньше будет
выявлено заражение, тем меньшее число программ окажутся
"больными" и тем проще будет вылечить компьютер. О своей
болезни первым узнает сам больной и только он может первым
выявить начало эпидемии. Так почему бы самим программам не
сообщать нам о своем заражении? Ведь присутствие вируса в
системе начинает ощущаться тогда, когда уже половина всех
программ заражены, а до этого все списывается на мелкие глюки.
Как
же программа поймет, что она "больна"? Вернемся к биологии:
биологический вирус встраивает свой генетический код в код
жертвы, тем самым меняя его структуру. Компьютерный вирус
поступает также. А изменения могут возникнуть следующие: код
станет длиннее или короче исходного; код не изменит своего
размера, но изменится сам.
Теория обнаружения заражения
Программа
должна сама после запуска произвести проверку своего кода на
наличие повреждения (заражения) и в случае обнаружения
изменений выдать предупреждающее сообщение. Если так будут
поступать все программы, то попавший в систему вирус будет
сразу же обнаружен, после чего пользователь компьютера,
воспользовавшись антивирусными программами, избавится от него.
Пришли к следующему: программа лишь обнаруживает свое
заражение, даже не пытаясь самолечиться; но этого достаточно
для своевременного выявления заразы.
Как
же программа сможет понять, что ее код изменился? Конечно
можно хранить вторую копию кода программы в файле с другим
именем и сравнивать после запуска, но это не экономично и не
эффективно. На самом деле достаточно хранить всего лишь размер
программы и контрольную сумму (число, равное сумме всех байт
кода программы). Эти данные могут находиться в отдельном файле
и распространяться вместе с самой программой. Важно, что бы
генерация этого файла проходила только для "здоровой"
программы, предварительно проверенных антивирусом.
Может
возникнуть вопрос, а что если появятся новые вирусы, способные
изменять не только код самой программы, но и данные
контрольного файла? Да, это возможно. Но можно действовать не
по одному шаблону. Например, в каждом конкретном случае
использовать разные функции подсчета контрольной суммы, что не
позволит вирусу корректно подстроить значения под себя. В
итоге этот метод даст возможность обнаружить как минимум 99%
вирусов.
Практическая реализация
Основная
цель, которую я перед собой поставил: добиться максимальной
простоты изменения текста программы для добавления контроля
заражения. В итоге все свелось к одному модулю,
экспортирующему всего одну функцию. Сразу приведу текст этого
модуля:
unit Antivirus;
{*******************************************************************************
* Модуль антивирусной защиты программы: ОБНАРУЖЕНИЕ ЗАРАЖЕНИЯ *
* © Акатов Алексей, 2004 год. *
* http://aka-alex.narod.ru *
*******************************************************************************}
interface
uses Windows, SysUtils;
function Detection: Boolean;
implementation
const Infection = 'Программа заражена вирусом или была повреждена.'#10#13 +
'Проведите полную проверку компьютера антивирусной программой!';
Absence = 'Ошибка обращения к контрольному файлу.'#10#13 +
'Создан новый контрольный файл.'#10#13 +
'Возможно наличие вируса в системе!';
Caption = 'Антивирус';
ControlExt = '.cts';
var Detect: Boolean;
function Detection: Boolean;
// Результат проверки:
begin
Result := Detect;
end; {func Detection}
procedure Scanner;
// Проверка заражения:
var ControlName: string;
ProgramName: string;
FW: file of LongWord;
Buf: array[1..1024] of Byte;
H, I, S: Integer;
OldSize, OldSum: LongWord;
Size, Sum: LongWord;
begin
Detect := True;
ProgramName := ParamStr (0);
ControlName := ChangeFileExt (ProgramName, ControlExt);
// Подсчет контрольной суммы и размера программы:
H := FileOpen (ProgramName, fmOpenRead or fmShareDenyWrite);
Size := GetFileSize (H, nil);
Sum := 0;
for I := 1 to 1024 do
Buf[I] := 0;
repeat
S := FileRead (H, Buf, 1024);
for I := 1 to S do
Inc (Sum, Buf[I]);
until S < 1024;
FileClose (H);
// Считывание старых значений:
AssignFile (FW, ControlName);
{$I-}
Reset (FW);
Read (FW, OldSize, OldSum);
CloseFile (FW);
{$I+}
// Проверка результата:
if IOResult <> 0 then
begin
Rewrite (FW);
Write (FW, Size, Sum);
CloseFile (FW);
MessageBox (0, Absence, Caption, MB_ICONWARNING + MB_OK);
end else
if (Size <> OldSize) or (Sum <> OldSum)
then MessageBox (0, Infection, Caption, MB_ICONWARNING + MB_OK)
else Detect := False;
end; {proc Scanner}
initialization
Scanner;
end.
Распишу алгоритм, по которому можно добиться желаемого
результата:
- завершить работу над программой;
- добавить к проекту модуль Antivirus, скопировав его от
сюда;
- прописать модуль Antivirus в разделе uses модуля,
описывающего главную форму программы;
- откомпилировать программу (Ctrl + F9), но не запускать;
- проверить получившийся exe-файл антивирусом;
- если он "здоров", запустить его, в итоге, с выдачей
соответствующего сообщения, будет создан контрольный файл:
"<имя_программы>.cts";
- можно распространять программу вместе с контрольным
файлом.
Модуль
работает по следующему принципу. После получения управления
проверяется наличие контрольного файла. Если он отсутствует,
то создается новый, куда записываются размер программы и
контрольная сумма. Если контрольный файл есть, то из него
считываются данные, записанные при его создании и сравниваются
с данными, полученными при текущей генерации. Если старые
значения отличаются от новых, то выдается предупреждающее
сообщение о возможном заражении.
Для
того, что бы из программы можно было бы узнать результаты
проверки в модуль включена функция Detection, которая вернет
истину, если было обнаружено заражение и ложь в противном
случае. С ее помощью можно добавить, к примеру,
преждевременное завершение программы в случае заражения,
записав в обработчик события FormCreate главной формы такую
строку:
if Detection then Application.Terminate;
В таком варианте в случае заражения после запуска
программы будет выдано предупреждающее сообщение, после чего
программа закроется.
Важно
подключать модуль Antivirus только когда разработка программы
уже завершена и производится последняя компиляция, т.к. при
новой компиляции контрольная суммы окажется уже другой. Если
все же необходимо перекомпилировать проект, то надо просто
удалить контрольный файл и после очередной компиляции создать
его снова (что произойдет автоматически).
В заключении: совет разработчикам корпорации
Microsoft
Как
известно, большинство программ запускается не напрямую, а
через ярлыки. В таком случае подобную антивирусную защиту
можно было бы реализовать и на этом уровне. Достаточно было бы
в ярлыке хранить информацию о размере файла и контрольную
сумму. А затем, если ярлык ссылается на программу (т.е. на
exe-файл, т.к. для других типов файлов это не нужно), то
автоматически проверять эти значения и в случае несовпадения
выдавать предупреждающее сообщение, к тому же не производя
запуск подозрительной программы. Такой контроль был бы очень
эффективен и любой вирус сразу же был бы обнаружен даже без
антивирусных программ.
Но
это все только идеи, а статью уже пора и заканчивать. Спасибо
за внимание!
Автор: Акатов Алексей
Источник: www.aka-alex.narod.ru
|