Створюємо pe-вірус №1

Віруси стали невід'ємною частиною нашого комп'ютерної (і не тільки) життя. На написання цієї статті мене підштовхнуло те, що, на мій погляд, в Мережі замало інформації, найбільш повно розкриває весь процес написання вірусу. Зовсім недавно мені необхідно було написати просту самораспространяющуюсю програму, яка не проводила б будь-яких шкідливих для системи дій, але в той же час використовувала б вірусні механізми поширення. Скажу, що все-таки в Інтернеті є інформація на цю тему. І навіть зустрічаються вихідні подібних програм. Але в усьому доводиться довго і наполегливо розбиратися, якщо хочеш зробити щось сам. Отже, в чомусь більш-менш розібравшись, я хочу поділитися з вами - читачами - інформацією.

У даній статті буде розглянуто процес написання простого вірусу, що заражає виконувані файли формату PE (Portable Executable) EXE. Також напишемо програму-доктора, яка шукає у вказаній директорії і у всіх піддиректоріях файли, заражені нашим вірусом.

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

Коротко про формат PE

Отже, якщо заглянути всередину типового виконуваного файлу, ми побачимо наступну структуру в спрощеному вигляді:

PE-файл в самому своєму початку (MZ-заголовок) містить програму для ОС DOS. Ця програма називається stub і потрібна для сумісності зі старими ОС. Якщо ми запускаємо PE-файл під ОС DOS або OS / 2, вона виводить на екран консолі текстовий рядок, яка буде сповіщати, що дана програма не сумісна з цією версією ОС. Програміст при лінковке може вказати будь-яку програму DOS, будь-якого розміру. Після цієї DOS-програми йде структура, яка називається IMAGE_NT_HEADERS (PE-заголовок). Ця структура описується наступним чином:

Перший елемент IMAGE_NT_HEADERS - сигнатура PE-файла. Для PE-файлів вона повинна мати значення «PE \ 0 \ 0». Далі йде структура, яка називається файловим заголовком і певна як IMAGE_FILE_HEADER. Файловий заголовок містить найбільш загальні властивості для даного PE-файла. Після файлового заголовка йде опціональний заголовок - IMAGE_OPTIONAL_HEADER32. Він містить специфічні параметри даного PE-файла. Після опционального заголовка починається таблиця секцій (Object Table). У ній міститься інформація про кожній секції. Після таблиці секцій йдуть вихідні дані для секцій. В кінець PE-файла можна записати будь-яку інформацію і від цього функціонування програми не зміниться (якщо там не присутній перевірка контрольної суми або щось подібне).

Способи зараження PE

До сих пір ми нічого не сказали про те, яким способом будемо заражати файл, адже їх кілька:

  • Впровадження в PE-заголовок
  • Розширення останньої секції
  • Додавання нової секції

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

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

Обчислюємо дельта-зміщення

Щоб наш вірус працював, він повинен бути написаний в базонезавісімом коді. У зв'язку з цим з'являється ще одне поняття - дельта-зміщення.

Існує безліч методів пошуку бази kernel32, один з яких - використання механізму структурної обробки виключень SEH (Structured Exception
Handling).

Отже, дельта-зміщення ми визначили. Наведемо тепер код пошуку бази kernel32:

Тепер розглянемо деякі поля PE-заголовка, необхідні нам:

А при пошуку потрібної нам функції ми будемо порівнювати не імена, а хеш-значення імен (підрахувавши попередньо це значення для кожної потрібної нам функції). Тобто допустимо, що ми знайшли якесь ім'я в таблиці імен kernel32. Обчислюємо хеш-значення цього імені і порівнюємо це значення з шуканим з нашої таблиці хешів HashTable. Якщо збігаються - значить, знайшли. Якщо немає - шукаємо
далі:

Але як нам обчислити заздалегідь хеш-значення певного імені? Для цього я написав невелику програму на Visual C ++ з ассемблерной вставкою, посилання на яку можна знайти в кінці статті (з ісходником).

Загальна структура вірусного коду

Все вищесказане було лише прелюдією в процесі написання нашого вірусу. Тепер почнеться найцікавіше. Будемо писати вірус на MASM. Чому я віддаю перевагу цьому пакету? Просто він мені подобається.

Напишемо загальний файл main.asm, який буде включати окремі частини коду:

Дивлячись на цей код, можна задати як мінімум два питання:

  • навіщо нам макрос szText?
  • навіщо підключати бібліотеку kernel32.lib і викликати функцію ExitProcess перед початкової міткою?

Покажи цю статтю друзям:

Схожі статті