Основи розробки антивірусного сканера

Зміст
1. Введення
2. Найпростіші типи вірусів
3. Методи детектування
4. Контрольні суми і технологія їх розрахунку
5. Використання контрольних сум для детектування вірусів
6. Алгоритм пошуку файлів
7. Основи побудови вірусної бази
8. Основи роботи з вірусною базою
9. Нотатки з лікування вірусів
10. Висновок
1. Введення

У цій статті мова піде про розробку примітивного антивірусного програмного забезпечення, точніше сказати антивірусного сканера.

Сканерами називають програми, які перевіряють файли на предмет зараженості їх відомими програмі вірусами.

Прочитавши цю статтю, я не гарантую, того, що ви в той же момент станете найрозумнішим вірусним аналітиком, ця галузь програмування досить незвичайна і важка для розуміння. Стикаючись з нею (областю) «впритул» в перший раз дуже важко відразу «взяти бика за роги». Але в цій статті я спробую викласти основи, так що цілком можливо, те, що буде описано нижче ви вже знали.

Перш ніж читати статтю, необхідно упевнитися, що ваш рівень знань асемблера не обмежується умінням писати красиві інтерфейси і менюшки, в антивірусних програмах це не головне. Звичайно без зручного (дружелюбного) інтерфейсу ваша праця не буде затребувана. Але все ж, необхідно мати деякі поняття про:
* Контрольні суми ділянок даних, що це таке і приблизний алгоритм розрахунку
* Віруси і троянські коні в бінарних файлах (виконуваних файлах), а так само написані на скриптових мовах (VBS, JavaScript)
* Методи роботи з файлами (пошук, запис, читання і тд)
2. Найпростіші віруси

Вірус програма дуже маленьких розмірів, основним завданням якої є поширення з комп’ютерів користувачів, за рахунок різних хитрих алгоритмів та помилок користувачів.

Віруси це дуже складні програми, їх можна розділити на безліч видів, але ми обмежимося лише двома. Розділимо віруси на найпростіші і файлові віруси. Файлові віруси це ті, які вміють заражати файли різних форматів (завантажувальні PE, документи, файли допомоги і ще безліч інших), зазвичай ці віруси написані на мові асемблера, і для їх виявлення необхідно дуже добре знати структуру файлів, які вони вражають. Під поняттям найпростіших вірусів я маю на увазі різних черв’яків і сюди ж можна приписати троянських коней.

Файловий вірус вірус, який поширюється через заражені файли різних форматів, зазвичай виконуються. Тобто хтось комусь передав програму, один з виконуваних файлів якої був заражений вірусом.

Черв’як вірус, який поширюється самостійно (не вражаючи будь-які файли), зазвичай через глобальні мережі, шляхом розсилки себе в листах; авторами черв’яків часто є хакери і для свого поширення черв’яки використовують різні дірки в операційних системах.

Троянські коні програми, у яких відсутні функції самостійного розповсюдження (тобто вони поширюються різними людьми спеціально), але обов’язково присутні різні деструктивні функції.

Деструкція алгоритм, заподіює шкоду комп’ютера і користувачі, іноді не тільки моральний, але й матеріальний. Деструктивні алгоритми часто використовуються у вірусах і завжди використовуються в троянських конях.

Деструкція троянських конях це алгоритми, які можуть здійснювати різні капості, починаючи від форматування жорсткого диска або перезапису flashbios і закінчуючи крадіжкою «важливих файлів (паролів для доступу в інтернет) з комп’ютера користувача.

3. Методи детектування

Головне, що хробаки та троянські коні не вміють заражати інші файли, за цим завжди поширюються в одному і тому ж вигляді. Т. е. у вигляді не змінюється файлу. Припустимо, у нас є файл з вірусом-хробаком, який займає 10 кілобайт. Хробак поширюється у вигляді виконуваного файлу PortableExecutable. Нам необхідно написати програму антивірус проти цього хробака.
* Програма буде шукати PE-файли у вказаному каталозі
* Кожен знайдений файл розміром 10 кілобайт і більше відкриватиметься
* Перші 10кб будуть зчитуватися, і звірятися з тими, які були взяті з «тіла» вірусу
* Якщо вміст буде збігатися, то значить перед нами черв’як і потрібно його вилікувати
Ми склали примітивний алгоритм детектування вірусу хробака. Тепер припустимо, що таким способом ваша програма пізнає, і лікує 100 вірусів. Як сигнатури (даних, за якими визначається зараженість об’єкту тим або іншим вірусом) використовується повний вірусний код, припустимо для кожного вірусу по 10 кб. В результаті вірусна база (база даних програми містить алгоритми з детектування і лікування вірусів) програми буде займати 1 мегабайт, а це дуже багато. Найбільші антивірусні програми знаходять кілька десятків тисяч найрізноманітніших вірусів, і їх вірусні бази займають всього декілька мегабайт.

Детектування (виявлення) вірусів, не змінюють своєї структури, є примитивнейшим заняттям. І так сигнатура для детектування вірусів може займати всього 3 подвійних слова, тобто 12 байт і бути дуже надійною, якщо використовувати контрольні суми

4. Контрольні суми і технологія їх розрахунку

Контрольна сума-це 32 бітове число (дуже рідко 16 біт), яке характеризує певний ділянку коду. Є безліч способів підрахунку контрольної суми, для кращого сприйняття цього терміна розглянемо приклад найпримітивнішого підрахунку:

Наприклад, у нас є ділянка коду, що складається з 5 байт (десяткова система): 001 004 005 000 100

На нашу примітивного підрахунку, контрольна сума його буде дорівнювати 1+4+0+5+100=110. Тобто прочитавши контрольну суму іншої ділянки, ми отримаємо інше значення. Проте, використовуючи такий примітивний алгоритм розрахунку, контрольні суми, що абсолютно відрізняються ділянок можуть збігатися, для цього використовуються більш просунуті процедури підрахунку.
———————–
; підрахунок контрольної суми ділянки коду sbuf, довжини dlen
; після підрахунків контрольна сума буде
«покладена» в crc_buf
calculate_crc
proc crc_buf: dword, sbuf:
dword, dlen: dword
push eax ecx edx ebx esi edi
cld
mov esi,sbuf
mov edi,dlen
mov ecx,-1
mov edx,ecx

next_byte:
sub eax,eax
sub ebx,ebx
lodsb
xor al,cl
mov cl,ch
mov ch,dl
mov dl,dh
mov dh,8

next_bit:
shr ebx,1
rcr eax,1
jnc no_carry
xor eax,8320h
xor ebx,0edb8h

no_carry:
dec dh
jnz next_bit
xor ecx,eax
sub edx,ebx
dec edi
jnz next_byte
not edx
not ecx
mov eax,edx
ror eax,cl
add eax,ecx
mov edi,crc_buf
mov word ptr [edi],dx
mov word ptr [edi+2],cx
pop edi esi ebx edx ecx eax
ret

endp

Коментарі до алгоритму розрахунку контрольної суми (crc) відсутні тому, що достатньо розуміти сенс підрахунку crc, стандарту підрахунку не існує, а описувати операції, вироблені в цій процедурі досить важко і безглуздо. З часом буде з’являтися досвід в подібних речах і якщо буде необхідно, то ви і самі розберетеся в коді.

5. Використання контрольних сум для детектування вірусів

Якщо потрібно обчислити контрольну суму ділянки в кілька кілобайт, то це звичайно не миттєва процедура. Якщо вважати контрольну суму кожного знайденого файлу то процес перевірки не буде проходити так швидко як хотілося б.

Візьмемо в якості прикладу вірус BAT.Sys.602, що поширюється у вигляді файлу BAT, написаного на примітивному мовою Batch, що входять в комплект операційної системи DOS. Зовні вірус-хробак являє собою звичайний текст.

Для розпізнавання наявності цього вірусу в BAT-файли зовсім не обов’язково вважати контрольну суму всього вірусного коду, достатньо взяти ділянку коду, що складається з декількох рядків. Так само просто необхідно запам’ятати їх розташування у вірусному файлі і довжину цих рядків (всіх разом). Припустимо, нам сподобалися рядки 4 та 5.

Як ми бачимо, рядок 4 починається у файлі зі зміщення 75 (4Bhex) і закінчується 150 (96 hex). Тобто розмір двох рядків становить 75 байт.

Але брати в якості сигнатури певні рядки не зовсім обов’язково, можна взяти будь-шматок коду, розмір бажано до 100 байт, що б час на розрахунок контрольної суми витрачалося мінімальне.

Вашій увазі пропонується приклад програми, яка вважає контрольну суму ділянки коду обраного вище (зміщення 75, довжина-75 байт) в sys-файлі.bat
; компілювати: tasm32 ml getcrc32.asm
; tlink32 -Tpe -c -x getcrc32.obj,,, import32
;
.386P
.model flat, stdcall
extrn
extrn
extrn
extrn
extrn
extrn
include

FILE_BEGIN
OPEN_EXISTING
GENERIC_READ
ExitProcess:near
ReadFile:near
CreateFileA:near
CloseHandle:near
GetFileSize:near
SetFilePointer:near
crc_proc.inc

equ 0
equ 3
equ 80000000h
; список API використовуються програмою
; тут знаходиться вищевказана процедура
; підрахунку контрольної суми
; для перекладу покажчика
; відкрити вже існуючий файл
; читання даних з файлу
ENTRY_SIZE
equ 1+260+4+318
; розмір однієї чарунки для процесу пошуку
.data
; сегмент даних
number
handle
crc32_buf
crc32_code_loc
crc32_code_len
file_name
buffer
dd ?
dd ?
dd ?
dd 75
dd 75
db sys.bat,0
db 1000 dup (?)

; файловий номер
; для зберігання порахованою crc ділянки коду
; місце розташування ділянки коду у файлі
; довжина ділянки коду
; файл з яким будемо працювати
; буфер для зберігання ділянки коду
.code
; сегмент коду
start:
push 0 0
push OPEN_EXISTING
push 0 0
push GENERIC_READ
push offset file_name
call CreateFileA
cmp eax,-1
jnz read_file
; відкриваємо існуючий файл sys.bat
; для читання

; якщо все пройшло успішно, продовжимо
error_opening:

——————————————–
jmp exit
; «процесор» помилки відкриття файлу
read_file:
handle mov,eax
push eax 0
call GetFileSize
mov ecx,dword ptr [crc32_code_loc]
add ecx,dword ptr [crc32_code_len]
cmp ecx,eax
jle set_pointer
push handle
call CloseHandle
jmp exit
; збережемо файловий номер в handle
; eax розмір відкритого файлу в байтах
; ecx розташування ділянки у файлі
; ecx зміщення на кінець ділянки
; якщо зсув на кінець ділянки менше
; ніж розмір файлу, значить файл підходить
; інакше не той файл
; закриємо файл
; вийдемо в ОС
set_pointer:
push FILE_BEGIN
push 0
push crc32_code_loc
push handle
call SetFilePointer

; встановимо покажчик розташування
; необхідного ділянки у файлі
push 0
push offset number
push crc32_code_len
push offset buffer
push handle
call ReadFile
push handle
call CloseHandle
; прочитаємо в buffer дані розміром; crc32_code_len изфайла; закроемфайл
push crc32_code_len
push offset buffer
push offset crc32_buf
call calculate_crc
; довжина ділянки crc якого потрібно порахувати
; розміщення даних ділянки
; куди «покласти» посчитанную crc
; вважаємо crc ділянки
exit:

push 0
call ExitProcess
end start
; вийдемо в ОС
6. Алгоритм пошуку файлів

Як ви вже, напевно, знаєте для пошуку файлів? використовуються API: FindFirstFile, FindNextFile, FindClose.

ПараметрамиFindFirstFile є маска для пошуку «місце» під структуру для пошуку (оголошену структуру офіційного типу або буфер, розмір якого не менше розміру офіційної структури). Маскою для пошуку є звичайна рядок, що містить шлях до каталогу, в якому буде проводитися пошук, а так само маску пошуку (зазвичай використовується *.*).

Вид офіційної структури для пошуку:
fnd_struc
atr
cr_time
ac_time
wr_time
size_high
size_low
reserved
long_name
dos_name
fnd_struc
struc
dd ?
dd 2
dup (?)
dd 2
dup (?)
dd 2
dup (?)
dd ?
dd ?
dd 2
dup (?)
db
260 dup (?)
db 14
dup (?)
ends

атрибут файлу
час створення файлу
час доступу до файлу
час модифікації файлу
розмір файлу

резерв
довге ім’я файлу
коротке ім’я файлу
Можна оголошувати цю структуру, а можна використовувати еквівалент findbuf db 314 dup (?). Трохи розбираючись в програмуванні можна здогадатися, що ім’я знайденого файлу буде знаходитися по зсуву 44 від початку findbuf.Використовуємо movesi,offsetfindbuf + 44 і регістр esi вказує на ім’я знайденого файлу або каталогу.

Після виконання API FindFirstFile, регістр eax буде містити ідентифікатор пошуку або в разі помилки 1.

Виклик FindFirstFile використовується тільки один раз, далі в справу вступає FindNextFile. Параметрами цієї апі є ідентифікатор пошуку (який ми отримали від виклику FindFirstFile і повинні були зберегти) і та же структура для пошуку (яка так само використовувалася при першому пошуку). Пошук ведеться до тих пір, поки регістр eax не буде дорівнювати нулю.

Ці API шукають файли або каталоги пошуку по масці, тобто не можна шукати тільки файли або тільки каталоги. Коли використовується маска *.* то будуть знайдені всі каталоги та файли, що містяться в зазначеному перед маскою каталозі.

Все звичайно добре, але необхідно що б наша антивірусна програма могла перевіряти файли не тільки в зазначеному каталозі, але і в тих, що розташовані нижче. Для цього ми повинні писати рекурсивні процедуру, тобто таку, яка вміє викликати сама себе.

Насамперед, необхідно оголосити змінну для пошуку в каталогах, що містять безліч інших підкаталогів. Думаю, що користувачів, у яких кількість підкаталогів в каталозі перевищує 50 одиниці, за цього обмежимося цим числом. І так, для процесу пошуку в кожному каталозі повинні бути індивідуальними (не використовуватися в інших процесах) маска пошуку (максимум 260 символів) ідентифікатор пошуку (подвійне слово, 4 байти), структура для пошуку (318 байт) і прапор (розміром 1 байт, а для чого потрібен цей прапор, я поясню пізніше). У результаті ми повинні оголосити змінну а/ля buf db ( ( 1 + 260 + 4 + 318 ) * 50 ). Осередок для кожного процесу пошуку займатиме 1+260+4+318 = 583 байта і одночасно може вестися 50 процесів (не більше). Звичайно, можна використовувати пам’ять з стека, але це буде важче пояснити.

Структура розміщення даних у комірці може бути такою, яка зручна для вас.

Я пропоную структуру такого типу:
flag
mask
search_handle
find_structure
db ?
db
260 dup (?)
dd ?
db 318 dup (?)
прапор пошуку (0 шукаємо тільки файли, 1 тільки каталоги)
маска для пошуку в каталозі
ідентифікатор пошуку
структура для пошуку
Тепер поговоримо про алгоритмі пошуку. Спочатку необхідно обробити всі файли поточного каталогу, а потім вже підкаталоги. Але API спочатку знаходять підкаталоги, а потім уже файли. Ось для цього і потрібен прапор.

При першому пошуку прапор налаштовується тільки на пошук файлів, якщо ті значення прапора не збігається з необхідним, то знайдені каталоги просто ігноруються. По закінченню пошуку прапор перенастроюється на пошук тільки каталогів, і тепер вже пропускаються файли.

Давайте розглянемо приклад програми обходящей дерево каталогів в пошуку всіх файлів
; компілювати: tasm32 -ml walk.asm
; tlink32 -Tpe -c
-x walk.obj ,,, import32
;
.386P
.model flat, stdcall
extrn
extrn
extrn
extrn
extrn
lstrlenA:near
ExitProcess:near
FindFirstFileA:near
FindNextFileA:near
FindClose:near
; список API використовуються програмою
ENTRY_SIZE
equ 1+260+4+318
; розмір однієї чарунки для процесу пошуку
.data
; сегмент даних
mask
search_dir
buffer
db *.*,0
db c:Program files,0
db (ENTRY_SIZE*50)
dup (?)
; маска для пошуку
; початковий каталог пошуку
; буфер під 50 «одночасних» процесів пошуку
.code
; сегмент коду
start:

mov esi,offset search_dir
push esi
call lstrlenA
xchg eax,ecx
inc ecx
mov edi,offset buffer
inc edi
rep movsb
; esi шлях для пошуку файлів

; одержимо розмір шляху в ASCII символи в eax
; обміняємо значеннями ecx і eax
; ecx = розмір шляхи + NULL

; перенесемо «напів готову» маску для
; першого процесу пошуку
push offset buffer
call find
; покажчик на готову структуру для пошуку
push 0
call ExitProcess

; вийдемо в ОС
———————–
; пошук файлів з використанням зазначеної в soff клітинки (і наступних)
find
proc soff: dword

mov ebx, soff
mov byte ptr [ebx],0
mov edi,ebx
inc edi
push edi
call lstrlenA
add edi,eax
cmp byte ptr [edi-1,*
jz first_find
; ebx покажчик на поточну комірку
; встановимо прапор
(значення 0) на пошук файлів
; edi1 поточний каталог

; eax — довжина шляху в ASCII символи

; якщо маска вже присутня у шляху
; шукаємо перший об’єкт (файл або каталог)
check_slash:
mov esi,offset mask
cmp byte ptr [edi-1],
jnz nneed_slash
inc esi
; esi зміщення загальної маски для пошуку
; проветим, є слеш в кінці шляху

; якщо є, то пропустимо
nneed_slash:

push esi
call lstrlenA
inc eax
xchg eax,ecx
rep movsb

; eax довжина маски
; додамо NULL до довжини

; доповнимо шлях маскою і слешем (якщо необхідно)
find_first:
mov edx,ebx
add edx,1+260+4
push edx
mov edx,ebx
inc edx
push edx
call FindFirstFileA
cmp eax,-1
jnz save_fnd_hndl
; edx вказує на клітинку процесу пошуку
; edx вказує на структуру для пошуку
; перший параметр для API FindFirstFileA
; edx вказує на клітинку процесу пошуку
; edx вказує на маску для пошуку
; другий параметр
; виконаємо API
; якщо eax = -1 означає сталася помилка
; інакше перевіримо знайдений об’єкт
test_fod:
cmp byte ptr [ebx],1
jz end_find
; якщо прапор = 1, то пошук підкаталогів був вже
; проведено в цьому каталозі, залишилося закінчити
; процес
set_filesfind:
inc byte ptr [ebx]
jmp first_find
; якщо прапор = 0, то всі файли в каталозі
; були оброблені, встановлюємо прапору
; значення 1 і обробляємо підкаталоги
end_find:
push dword ptr [ebx+1+260]
call FindClose
ret
; ebx = ebx + 1 + 260 = ідентифікатор пошуку
; припинимо процес пошуку в каталозі
; ———————-
; процес перевірки знайденого об’єкта
save_fnd_hndl:
mov dword ptr
[ebx+1+260],eax
; збережемо ідентифікатор пошуку
lf:
cmp byte
ptr [ebx+1+260+4+44],.
je find_next
; пропустимо підкаталоги. і ..
test_if_dir:
test byte ptr
[ebx+1+260+4],10h
jz found_file

; перейдемо якщо знайшли файл
proc_dir:
cmp byte ptr [ebx],1
jnz find_next
; якщо шукаємо тільки файли (прапор = 0), то
; каталоги не чіпаємо
;———————-
; якщо файли каталогу були перевірені, то по черзі будуть перевірятися підкаталоги.
; готуємо маску пошуку для знайденого підкаталогу в наступній комірці і запускаємо себе
prepare_rec:
mov edi,ebx
add edi,( ( ENTRY_SIZE ) + 1 )
mov esi,ebx
inc esi
push esi
call lstrlenA
xchg eax,ecx
sub ecx,4
cmp byte ptr [esi+ecx],
jnz not_root
inc ecx
; edi осередок поточного процесу пошуку
; edi осередок наступного процесу пошуку+1
; esi осередок поточного процесу пошуку
; esi маска пошуку поточного процесу

; eax — довжина маски пошуку поточного процесу

; віднімемо від довжини 4 символи (маску і слеш)

; кореневий каталог,
; залишимо слеш
not_root:
rep movsb
; перенесемо «напів готову маску»
; наступну комірку
mov esi,ebx
add esi,1+260+4+44
push esi
call lstrlenA
inc eax
xchg eax,ecx
rep movsb
add ebx,(ENTRY_SIZE)
push ebx
call find
sub ebx,(ENTRY_SIZE)
jmp find_next

; esi ім’я знайденого підкаталогу

; eax довжина знайденого підкаталогу
; eax довжина знайденого підкаталогу + 0

; доповнити маску знайденим подкаталогом
; ebx осередок наступного процесу пошуку
; параметр для виклику себе
; шукаємо в підкаталозі
; ebx осередок цього процесу пошуку
; шукаємо наступний об’єкт
found_file:

cmp byte ptr [ebx],1
jz find_next
——————————————–
; якщо шукаємо каталоги, файли не чіпаємо

; код для роботи з файлами знайденими
find_next:
mov edx,ebx
add edx,1+260+4
push edx
push dword ptr [ebx+1+260]
call FindNextFileA
cmp eax,0
jnz
lf
jmp test_fod

; edx вказує на структуру для пошуку
; перший параметр для API FindNextFileA
; другий параметр ідентифікатор пошуку
; виконаємо API

; якщо знайшли об’єкт, проведемо його аналіз
; якщо нічого не знайшли
endp

end start

7. Основи побудови вірусної бази

Дані необхідні для пошуку і лікування вірусів зазвичай зберігаються у вірусній базі. Її формат може бути будь-яким, стандартів не існує. Ми розглянемо приклад вірусної бази для детектування скрипт вірусів, яка буде міститися в вихідному коді програми, а не в окремому файлі.
vir_no
vir_001_name

vir_001_sig
dd 3
db BAT.Sys.602,0
db 8 dup (?)
dd 161412090
кількість вірусів у базі даних
назва вірусу в ASCII кодуванні
розмір назви 20 байт, що залишилися байти
сигнатура ділянки довжиною 75 байт, по зсуву 75 коду вірусу,
вона ж сигнатура для детектування
vir_002_name

vir_002_crc32
db VBS.Links,0
db 010 dup (?)
dd 1138651542

vir_003_name

vir_003_sig
db VBS.ILoveYou,0
db 7 dup (?)
dd 3434909282

Ось ми маємо найпростішу вірусну базу для трьох вірусів. Розмір однієї вірусної запису даних про одному вірусі, необхідних для його детектування та лікування) в даному випадку становить 20 + 4 = 24 байта.

Якщо ж вірусна база зберігається в окремому файлі, то при старті антивірусний сканер повинен завантажити її в пам’ять, для того, щоб до даних, що зберігаються в ній, було швидше і простіше «звертатися» до потреби. Для цього пишуться спеціальні процедури розбору, ну і звичайно ж вірусні записи містять набагато більше даних, наприклад, таких як тип вірусу, адреси процедур для детектування та лікування Але про це наступного разу, в наступних статтях.

8. Основи роботи з вірусною базою

В нашому випадку, необхідно писати процедуру для роботи з знайденими файлами, тобто читати дані з файлу по зсуву 75 і розміром 75 байт, вважати контрольну суму і порівнювати по черзі з зазначеної у всіх доступних (в нашому випадку 2) вірусних записах у вірусній базі. Якщо співпадає, виводить інформацію про те, що знайдений файл заражений визначеним вірусом.

Припустимо, програма знайшла файл, прочитала з нього 75 байт по зсуву 75 і підрахувала контрольну суму цієї ділянки. Контрольна сума міститься в змінній crc32_buf. Ось як має виглядати процес перевірки на зараженість відомими програмі вірусами:

mov eax,dword ptr crc32_buf
mov ecx,dword ptr vir_no
mov esi,offset vir_001_name

; eax контрольна сума ділянки
; ecx кількість вірусів в базі
; esi початок першої вірусної запису
cmp_crc32_loop:

push ecx esi
cmp eax,dword ptr [esi+20]
jnz next_crc
pop esi ecx

; запам’ятаємо дані регістрів
; перевіримо контрольну суму з вірусною
; якщо не збігається перейдемо до next_crc
; востановим значення регістрів
infected:

; якщо файл заражений вірусом
next_crc:

pop esi ecx
add esi,24
loop
cmp_crc32_loop

; відновимо значення регістрів
; перейдемо до наступної вірусної запису
; цикл
9. Нотатки з лікування вірусів

В даному випадку знайдені файли з вірусами можна просто видаляти, але це найпростіші віруси. Зазвичай кожен вірус змінює щось у файлах налаштуваннях операційної системи, намагається сховатися від чужих очей. Навіть для вірусів, файли носії яких (дропперы) можна просто видаляти це (швидше за все) не буде сто відсотковим лікуванням. Необхідний аналіз алгоритму роботи вірусу, цілком можливо він вже (наприклад) встиг прописати свій виклик в WIN.INI з «потайного місця». Так як ці типи вірусів не заражають файли, то від них міг би позбутися будь-який початківець користувач. Автори таких вірусів знають це і для цього вживають різноманітні хитрі методи для того, що б вірус міг вижити після «чистки», повернутися «до життя» другий раз.

10. Висновок

Відповідно якщо Ви зацікавилися цією областю програмування, доведеться розбиратися і вивчати (хоча б основи) безліч скрипт мов програмування. Я не кажу про основи будови виконуваних файлів написаних не на асемблері, а на мовах високого рівня. Якраз на них і пишеться більшість троянських коней. Необхідно буде розбиратися з різними пакувальниками і шифровщиками виконуваних файлів, будовою архівів