Хакерство и защита от него
|
Вирусы: обнаружение заражения |
|
© 2004 год. Наверное, уже все слышали о таком объекте, как компьютерный вирус. Что же представляет эта субстанция и от куда пошло это название? Термин "вирус" пришел к нам из биологии и медицины. Биологический вирус – это неполноценный организм, состоящий из нуклеиновой кислоты (ДНК или РНК, т.е. генетического кода) и защитной белковой оболочки, позволяющей существовать вирусу в закапсулированном состоянии. Биологический вирус оживает лишь тогда, когда попадает в клетку живого организма и встраивает свой генетический код в исходный. Компьютерный вирус действует теме же методами. И так. Компьютерный вирус – это кусок кода (не программа, а всего лишь код), который способен встраиваться в код какой-либо программы, там самым оживая и заражая другие программы. Как и в случае биологического вируса, когда больной человек опасен здоровому, зараженная программа опасна для других программ, т.к. с ее помощью вирус может заражать. При этом в большинстве случаев зараженная программа вполне работоспособна, а не редко ее и не возможно отличить от "здоровой". Чем раньше министерство здравоохранения обнаружит вирусную эпидемию, тем мягче будут последствия и тем быстрее можно будет локализовать очаг заражения и избавиться от заразы. Точно тоже происходит и в мире программ. Чем раньше будет выявлено заражение, тем меньшее число программ окажутся "больными" и тем проще будет вылечить компьютер. О своей болезни первым узнает сам больной и только он может первым выявить начало эпидемии. Так почему бы самим программам не сообщать нам о своем заражении? Ведь присутствие вируса в системе начинает ощущаться тогда, когда уже половина всех программ заражены, а до этого все списывается на мелкие глюки. Как же программа поймет, что она "больна"? Вернемся к биологии: биологический вирус встраивает свой генетический код в код жертвы, тем самым меняя его структуру. Компьютерный вирус поступает также. А изменения могут возникнуть следующие: код станет длиннее или короче исходного; код не изменит своего размера, но изменится сам. Программа должна сама после запуска произвести проверку своего кода на наличие повреждения (заражения) и в случае обнаружения изменений выдать предупреждающее сообщение. Если так будут поступать все программы, то попавший в систему вирус будет сразу же обнаружен, после чего пользователь компьютера, воспользовавшись антивирусными программами, избавится от него. Пришли к следующему: программа лишь обнаруживает свое заражение, даже не пытаясь самолечиться; но этого достаточно для своевременного выявления заразы. Как же программа сможет понять, что ее код изменился? Конечно можно хранить вторую копию кода программы в файле с другим именем и сравнивать после запуска, но это не экономично и не эффективно. На самом деле достаточно хранить всего лишь размер программы и контрольную сумму (число, равное сумме всех байт кода программы). Эти данные могут находиться в отдельном файле и распространяться вместе с самой программой. Важно, что бы генерация этого файла проходила только для "здоровой" программы, предварительно проверенных антивирусом. Может возникнуть вопрос, а что если появятся новые вирусы, способные изменять не только код самой программы, но и данные контрольного файла? Да, это возможно. Но можно действовать не по одному шаблону. Например, в каждом конкретном случае использовать разные функции подсчета контрольной суммы, что не позволит вирусу корректно подстроить значения под себя. В итоге этот метод даст возможность обнаружить как минимум 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;
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.
Распишу алгоритм, по которому можно добиться желаемого результата:
Модуль работает по следующему принципу. После получения управления проверяется наличие контрольного файла. Если он отсутствует, то создается новый, куда записываются размер программы и контрольная сумма. Если контрольный файл есть, то из него считываются данные, записанные при его создании и сравниваются с данными, полученными при текущей генерации. Если старые значения отличаются от новых, то выдается предупреждающее сообщение о возможном заражении.
Для того, что бы из программы можно было бы узнать результаты проверки в модуль включена функция Detection, которая вернет истину, если было обнаружено заражение и ложь в противном случае. С ее помощью можно добавить, к примеру, преждевременное завершение программы в случае заражения, записав в обработчик события FormCreate главной формы такую строку:
Важно подключать модуль Antivirus только когда разработка программы уже завершена и производится последняя компиляция, т.к. при новой компиляции контрольная суммы окажется уже другой. Если все же необходимо перекомпилировать проект, то надо просто удалить контрольный файл и после очередной компиляции создать его снова (что произойдет автоматически). Как известно, большинство программ запускается не напрямую, а через ярлыки. В таком случае подобную антивирусную защиту можно было бы реализовать и на этом уровне. Достаточно было бы в ярлыке хранить информацию о размере файла и контрольную сумму. А затем, если ярлык ссылается на программу (т.е. на exe-файл, т.к. для других типов файлов это не нужно), то автоматически проверять эти значения и в случае несовпадения выдавать предупреждающее сообщение, к тому же не производя запуск подозрительной программы. Такой контроль был бы очень эффективен и любой вирус сразу же был бы обнаружен даже без антивирусных программ. Но это все только идеи, а статью уже пора и заканчивать. Спасибо за внимание! |