Микстура против ЧИХ-а
или
по следам "Чернобыльского" вируса

В конце концов мистер Коберман мало отличался от тех цыплят,
которых потрошила, а затем зашивала бабушка.
Р. Бредбери. Жилец из верхней комнаты.

ВВЕДЕНИЕ

Вот уже несколько лет прошло после памятной даты 26 апреля 1999 г., когда сотни тысяч (а, может быть, и миллионы) компьютеров во всем мире в одночасье были превращены "Чернобыльским" вирусом в неработоспособные груды металлов и полупроводников. Но многие ли извлекли из этого события действительно полезные уроки?

Мне кажется, что на этот вопрос следует ответить отрицательно. Единственное, чему научились широкие массы пользователей, системных администраторов и даже программистов, - это устраивать все более дикие и неуправляемые истерики по поводу возникновения каждого нового образца компьютерной "фауны". Огромную роль в раздувании этих истерик играют представители средств массовой информации, а именно - абсолютно безграмотные в компьютерном смысле журналисты, идущие на поводу у стремящихся к прибылям антивирусных компаний.

Такая ситуация была бы невозможна, если хотя бы 1% людей, связанных с компьютерами, умел разбираться в сути проблемы компьютерных вирусов, был способен отличить действительно достоверную информацию от очередной журналистской "утки", и, главное, правильно использовать эту информацию.

Эта статья для тех, кто хочет увидеть собственными глазами и пощупать собственными руками, что собой представляет "Чернобыльский" вирус (официальное наименование – Win95.CIH), и чего стоит ждать от нескольких десятков вирусов, которые уже написаны, и которые продолжают создаваться вирусописателями- плагиаторами по его образу и подобию.

Эта статья принципиально не содержит рецептов по написанию новых вирусов, хотя в ней можно обнаружить немало фрагментов вирусного кода. С другой стороны, я надеюсь, что она выгодно отличается от доступного в Интернете авторского исходника этого вируса, прокомментированного обильно, но малоинформативно. Одним словом, если кому-то хочется считать мою статью "очередным грязным опусом аморальной технокрысы"… что ж, свинья везде грязь отыщет.

МИФ О "ЧЕРНОБЫЛЬСКОМ" ВИРУСЕ

Жил да был, и учился в одном из университетов острова Тайвань молодой человек по имени Чен Инг Хау. Однажды захотелось ему написать компьютерный вирус. Неизвестно, какой он был студент, но программист –очень хороший. Чен Инг Хау умел писать 32-разрядные Windows-приложения на языке ассемблера, к тому же он где-то как-то получил доступ к недокументированным подробностям строения MS Windows 95. (Не похоже, что он сам все "расхакал" – слишком уж глубоко лежат в недрах операционной системы использованные им "секреты", так что для доступа к ним "котлован рыть" надо, а не "скважину бурить"). Сказано-сделано. Всю весну 1998 г. Чен Инг Хау упорно трудился, и вирус у него получился на славу: компактный, рационально написанный и тщательно отлаженный. Настолько тщательно, что на зараженной машине был практически незаметен. Опечалился Чен Инг Хау: кто же на вирус внимание обратит, кто же его автора попомнит незлым тихим словом? Опечалился… и вставил в вирус фрагмент, который две вещи делает: 26 апреля Flash-BIOS компьютера стирает, а вдобавок еще и большие области винчестера (в том числе и системные) "мусором" заполняет.

Потом Чен Инг Хау похвастался этим вирусом перед своими друзьями, которые сами такие вещи писать не умели, зато в течение мая месяца 1998 г. быстро распространили вирус по машинам всего университета. Начальство университета провело "служебное расследование", выявило автора и в два счета отчислило его из студентов. А тут к нему сразу и повестка из военкомата пришла, и отправился Чен Инг Хау в доблестные вооруженные силы острова Тайвань чистить зубной щеткой тайваньские сортиры, стирать тайваньским дедам тайваньские портянки и делать все остальное, что полагается тайваньским солдатам по тайваньскому Уставу.

А вирус пошел дальше, и оказался в Интернете, на сайтах, содержащих различные полезные утилиты. Вероятно, свои шаловливые ручонки к этому приложили друзья Чен Инг Хау, а также друзья этих друзей. Сей факт практически сразу, в начале лета, отметили все антивирусные компании мира, выпустив предупреждающие пресс-релизы и обновления антивирусных баз. Но месяц шел за месяцем, вирус тихо и незаметно расползался по миру, ничего не взрывалось, а пользователи обычно всегда плюют на всякие там пресс-релизы и никогда не запускают свои НортонАнтивирусы и ДокторСоломоны, пока их жареный петух не клюнет в одно место. Дошло до того, что осенью 1998 г. чуть ли не каждый второй CD, изготовленный нашими отечественными компьютерными пиратами, содержал программы, зараженные вирусом Win95.CIH.

Час расплаты настал 26 апреля 1999 г. Компьютерный мир вздрогнул… но было уже поздно.

А Чен Инг Хау перевели из тайваньской казармы в тайваньскую камеру. Несколько месяцев он "парился на киче", его допрашивали и местные тайваньские "копы", и заезжие из Америки "феды"… Потом был суд, на котором выяснилось, что конкретно на острове Тайвань компьютеров пострадало не слишком много, и поэтому сажать автора вроде бы как и не за что. Чен Инг Хау оказался кем-то вроде национального героя и получил предложения от ряда крупных тайваньских фирм заняться интересной высокооплачиваемой работой.

Прошли годы. Но тысячи лазерных дисков с зараженными игрушками и софтом по-прежнему лежат на полочках у пользователей и программистов. Исходные тексты вируса легко найти в Интернете. Чуть ли не каждый второй вновь написанный компьютерный вирус, предназначенный для заражения Windows-программ, содержит готовые куски кода, без особых раздумий и подчас даже без понимания смысла "выдранные" из Win95.CIH.

А это значит – история "Чернобыльского" вируса потихоньку продолжается, и данная статья по-прежнему актуальна.

КАК ИССЛЕДОВАТЬ АЛГОРИТМ РАБОТЫ ВИРУСА?

Поставим простой эксперимент: запустим в своей системе программу, зараженную вирусом Win95.CIH.1003. Именно эта модификация вируса вольготно "гуляла" по нашей стране в 1998-99 гг. Поработаем некоторое время в этой системе, и антивирусный сканер сообщит, что "зараза" уже "пустила корни". В первую очередь заражаются служебные программы RUNDLL32.EXE (если мы запускали Windows-программы) и START.EXE (если мы запускали DOS-программы), а также большинство прикладных программ и утилит, с которыми мы работали.

В качестве объекта для "патолого-анатомических" экспериментов возьмем файл NOTEPAD.EXE длиной 57344 байтов.

Лучший дизассемблер Windows-программ на данный момент – IDA PRO от Ilfak Guilfanov. Но очень много пользы может принести и обычный Hacker View (HIEW) Евгения Сусликова aka SEH. Трассировать фрагменты кода лучше всего при помощи NuMega WinIce.

Итак… Сестра, скальпель!

КАК ВИРУС ВНЕДРЯЕТСЯ В ПРОГРАММЫ?

Длина файла NOTEPAD.EXE после заражения осталась прежней, но антивирус сообщает, что внутри скрывается Win95.CIH. "Напустим" на зараженную программу HIEW. Сравнивая два файла, зараженный и здоровый, несложно обнаружить, что часть фрагментов, которые в здоровом файле были пусты (содержали нулевые коды), в зараженном файле оказались заполненными чем-то непонятным. Вывод однозначен: вирус записался в неиспользуемые фрагменты EXE-файла, благодаря чему и не произошло изменения его (файла) длины.

Интересно разобраться, что это за неиспользуемые фрагменты, и почему они присутствуют в EXE-файле.

Справка. Windows-программа PE-формата представляет собой набор секций (их еще называют "сегментами" или "объектами").

Самая первая по счету секция – не настоящая, это "псевдосекция". Она не имеет имени и содержит заголовки и настроечные таблицы PE-программы. В этой секции сначала размещается обычный заголовок EXE-программы, начинающийся с байтов ‘MZ’. По смещению 3Ch в этом заголовке хранится адрес специфического заголовка PE-программы, начинающегося с байтов ‘PE’. Где-то между этими двумя заголовками лежит код крохотной программки, умеющей выводить сообщение "This program can’t run in Ms-Dos mode". Вот самые важные для нас поля PE-заголовка:

Поле Смещение Длина Назначение
Magic +00 4 Сигнатура ‘PE\0\0’ (0x00004550)
NumberOfSections +06 2 Количество секций (без "псевдосекции")
SizeOfOptionalHeader +14h 2 Размер переменной части заголовка
AddressOfEntryPoint +28h 4 Смещение точки входа в программу
ImageBase +34h 4 Базовый адрес загрузки программы
SectionAlignment +38h 4 Размер блока в памяти
FileAlignment +3Ch 4 Размер блока на диске

Структура этого заголовка описана под именем _IMAGE_OPTIONAL_HEADER в файле WINNT.H, который можно обнаружить в составе таких продуктов, как Borland C/C++ v5.0, Microsoft Visual C/C++, Microsoft Windows 9X/NT/2000/XP DDK и пр.

Все секции (в том числе и "псевдосекция" заголовков) присутствуют и в программном файле, и в памяти, причем располагаются в одном и том же порядке. Отличие только в том, что каждая секция (в том числе и "псевдосекция" заголовков) занимает целое число блоков определенной длины, а размер этих блоков в общем случае различен для случая файла (см. поле FileAlignment, часто его значение равно 512) и для случая памяти (см. поле SecionAlignment, часто его значение равно 4096). Самая первая по счету секция (это "псевдосекция" заголовков) при загрузке в память получит линейный адрес ImageBase (часто его значение равно 400000h). Смещение первой исполняемой команды программы относительно ImageBase хранится в поле AddressOfEntryPoint.

Все секции (кроме "псевдосекции" заголовков) имеют имена. Программный код, как правило, хранится в секции с именем .text или CODE. Области переменных размещаются в секциях .data или DATA. Под текстовые и строковые константы обычно отводится секция .idata, под ресурсы Windows-приложения - секция .rsrc и т.п. Сразу после PE-заголовка (который состоит из постоянной части длиной 0x18 байтов и переменной части длиной SizeOfOptionalHeader байтов) размещается таблица описания всех секций (кроме "псевдосекции" заголовков). Она содержит NumberOfSections записей следующей структуры:

Поле Смещ. Длина Назначение
Name +00h 8 Символьное имя секции
VirtualSize +0Сh 4 Реальное количество информации в секции
VirtualAddress +10h 4 Смещение секции в памяти от ImageBase
SizeOfRawData +14h 4 Размер, зарезервированный для секции на диске
PointerToRawData +18h 4 Смещение секции от начала файла
Characteristics +20h 4 Флаги свойств секции

Подробней с этой структурой можно также ознакомиться, заглянув в файл WINNT.H, там она располагается под именем _IMAGE_SECTION_HEADER.

Обычно SizeOfRawData – это "круглое" число, кратное значению FileAlignment (часто это 512 байтов), а значение поля VirtualSize – число "не круглое", характеризующее реальную длину секции. Значит, между реальным концом области, содержащей "полезные" байты содержимого секции, и концом фрагмента дисковой памяти, зарезервированным за этой секцией, обычно присутствует неиспользуемый "зазор", величина которого может варьироваться от 1 до 511 байтов.

Продолжая глядеть на NOTEPAD.EXE при помощи HIEW, нажмем клавишу F8. Это позволит увидеть содержимое полей специфического PE-заголовка зараженной программы. Вслед за этим нажмем F6 и ознакомимся с таблицей программных секций. Сравнивая два файла, зараженный и незараженный, можно легко увидеть, что:

1) в PE-заголовке изменилось значение поля AddressOfEntryPoint:

  Было Стало
AddressOfEntryPoint 0x10CC 0x270

2) в таблице секций увеличились до предела значения полей VirtualSize для первых двух секций:

 

VirtualSize

SizeOfRawData

Было Стало Было Стало
.text 0x3E9C 0x4000 0x4000 0x4000
.data 0x84C 0x1000 0x1000 0x1000

Графически произошедшие изменения можно изобразить так:

-

Итак, вирус зарезервировал для себя место в "хвостах" нескольких секций и записал туда куски своего кода. Начальный фрагмент своего кода он поместил в неиспользуемую область в "псевдосекции" заголовков.

После этого вирус изменил точку входа в программу таким образом, что она стала указывать на его начальный фрагмент. Выясняется, что Windows при запуске зараженной программы не проверяет местоположение точки входа – ей абсолютно безразлично, находится ли она внутри секции с именем .text, или в какой-нибудь другой секции, или вообще вне секций. Поразительная беспечность!

В КАКИХ ОПЕРАЦИОННЫХ СИСТЕМАХ ВИРУС ЖИВЕТ?

В своей работе вирус использует ряд в общем-то документированных, но малоизвестных особенностей функционирования Windows.

Справка. Каждому запущенному на исполнение потоку Windows ставит в соответствие структуру данных под названием TIB (Thread Information Block – блок информации о потоке). Второе четырехбайтовое поле в этой структуре является линейным адресом текущего SEH (Structured Exception Handler – структурированного обработчика исключений), а первое – адресом следующего в длинной цепочке аналогичных же обработчиков. Обработчики активируются в момент возникновения исключительных ситуаций (например, если программа попытается выполнить недопустимую команду или обратиться в "запрещенный" район памяти).

В момент запуска потока структура TIB доступна по адресу FS:[0].

Для того, чтобы ответить на вопрос об "ареале" распространения вируса, потребуется дизассемблировать и внимательно исследовать его начало (первые несколько десятков байтов, на которые указывает AddressOfEntryPoint). Вот как выглядит этот фрагмент:

push    ebp
lea     eax,[esp-0008]	 
xor     ebx,ebx
xchg    eax,fs:[ebx]
call    $+5	 
pop     ebx			
lea     ecx,[ebx+00042]	; Адрес нового SEH
push    ecx
push    eax

После его выполнения район памяти, в котором расположен стек, будет содержать следующие данные:

Смещение Значение Примечание
ESP Ebp  
ESP-4 Адрес старого SEH  
ESP-8 Адрес нового SEH Сюда указывает FS:[0]

Поскольку стек "растет вниз", то достаточно перевернуть эту табличку "вверх тормашками" и увидеть, что фрагмент стековой памяти, начинающийся с адреса [esp+8], по своему содержимому очень напоминает начало какой-то TIB. Все правильно, именно в этой роли он в дальнейшем и будет использоваться!

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

Итак, первым делом CIH берет на себя обработку исключительных ситуаций. Зачем? Дело в том, что непосредственно вслед за этим он пытается модифицировать системную IDT (Interrupt Descriptor Table – таблицу дескрипторов прерываний) для того, чтобы взять на себя также еще и обработку прерывания номер 3.

push eax
sidt [esp-0002] ; Адрес IDT - в стек
pop  ebx
add  ebx,01C
cli
; Дескриптор 6-байтовый, и модифицируется он по частям
mov  ebp,[ebx]
mov  bp,[ebx-0004]
; Выполняется адресация на новый обработчик
lea  esi,[ecx+00012]
push esi
; Вписывается 1-я половина адреса
mov  [ebx-0004],si
shr  esi,010
; Затем вторая
mov  [ebx+00002],si
pop  esi

Теперь достаточно инициировать вызов прерывания командой Int 3, и управление получит вирусный обработчик этого прерывания. Только вот выполняться этот обработчик будет уже в нулевом кольце защиты, а это значит, что вирус получит недоступные ему прежде системные привилегии.

Но сработает этот прием только в Windows 95/98/ME. А в операционных системах семейства Windows NT/2000 возникнет исключительная ситуация. Вот для чего вирус перехватывал обработчик исключений – чтобы зараженная программа при запуске из-под NT не вылетала, а корректно продолжала свою работу!

Итак, зараженная вирусом программа будет корректно работать в любой операционной системе, но размножаться (т.е. заражать другие программы) вирус способен только в Windows 9X.

КАК ВИРУС ВОЗВРАЩАЕТ УПРАВЛЕНИЕ ЗАРАЖЕННОЙ ПРОГРАММЕ?

Фрагмент возврата управления зараженной программе следует искать в вирусном обработчике исключений. Вот он:

; Старый SEH возвращается на прежнее место
xor  ebx,ebx
mov  eax,fs:[ebx]
mov  esp,[eax]
pop  fs:[ebx]
pop  eax
pop  ebp
; Возврат управления зараженной программе!
push 00040278C
retn

Нетрудно сообразить, что 040278Сh – это и есть сохраненное внутри вируса значение старой точки входа в программу! Достаточно вычесть из него значение поля ImageBase и поместить на свое "законное" место в поле AdressOfEntryPoint. И вирус, формально оставшись внутри программы, никогда больше не получит управления!

Обратим внимание, что "заветное" двойное слово лежит по смещению +5Eh относительно точки входа в вирус. Собственно говоря, теперь мы уже можем написать свой собственный антивирус. Но восстановив точку входа, мы только обезвредим вирус. Ряд антивирусов (например, "Антивирус Касперского" с подключенной базой CIH-TRACE.AVC) способны обнаруживать такой "убитый", но "не похороненный" Win.CIH и устраивать по этому поводу небольшой "скандал".

Кроме того, коварные повадки "заразы" изучены еще не до конца. Поэтому продолжим анализ.

КАК ВИРУС ИЩЕТ ЦЕЛИ ДЛЯ ЗАРАЖЕНИЯ?

CIH относится к классу "резидентных" вирусов, хотя этот термин для многозадачных операционных систем и не имеет смысла. Это значит, что он "сидит" в памяти постоянно, следит за всеми вновь запускаемыми программами и заражает их.

"Слежку" за запускаемыми программами он осуществляет при помощи "секретного", очень скупо документированного фирмой Microsoft механизма обращений к глубинным компонентам ядра операционной системы – к VMM (Virtual Memory Manager – менеджеру виртуальных машин) и к драйверам виртуальных устройств.

Справка. Обращение к компонентам ядра Windows 9X (которое обычно выполняется не из прикладных программ, но из системных DLL) выглядят следующим образом:

int 20h
dw ?    ; Номер функции
dw ?    ; Код компонента, например: 1- VMM, 40h – IFSMgr, и пр.

Необходимые параметры вызова при этом передаются через стек.

Обычно дизассемблеры подобный код отображают в виде высокоуровневых ассемблерных макросов VxDCall и VMMCall.

Этот код не является реентерабельным, поскольку ядро Windows в процессе выполнения подобного запроса искажает несколько байтов в точке, в которую предполагается возврат управления. Для системных DLL это несущественно, а перед вирусами (вернее, перед их авторами) встает ряд трудноразрешимых проблем по восстановлению первоначального кода.

Обращения прикладных и системных программ к файловой системе обслуживаются компонентом ядра под названием IFSMgr (Installed File System Manager - менеджер инсталлированной файловой системы), все эти обращения кодируются числом 40h. Среди нескольких десятков сервисных функций этого компонента интересно выделить:

  • функцию с номером 67h – InstallFileSystemApiHook ("засекреченный" фирмой Microsoft вызов "Заменить обработчик обращений к IFSMgr");
  • функцию с номером 32h – Ring0_FileIO (вызов "Файловые операции ввода-вывода" - открыть, закрыть, записать и пр).

Доступ к вышеописанным механизмам возможен только из нулевого кольца защиты.

Используя вызов InstallFileSystemApiHook, вирус берет на себя обработку обращений к файловой системе и ждет (проверяя каждый раз параметры вызова, сохраненные в стеке) запроса на открытие файла какой-либо программы (это обычно происходит при ее запуске):

; Обработчик уже занят заражением какого-либо файла?
 Test [esi], 001
 Jne SkipInf
; Проверка стековых параметров вызова 
 lea  ebx,[esp+00028]
 cmp  [ebx], 024  ; Открытие файла ?
 jne  SkipInf
; Заражение
...
SkipInf:

Все это очень похоже на перехват каким-нибудь старинным резидентным вирусом прерывания 21h, только происходит теперь уже в 32-битовой многозадачной среде Windows.

КАК ВИРУС ОТЛИЧАЕТ УЖЕ ЗАРАЖЕННУЮ ПРОГРАММУ?

Вот маленький фрагмент вирусной процедуры, выполняющей заражение PE-файла:

Xor  eax,eax
Mov  ah,0D6          ; Код операции чтения
Mov  ebp,eax
Xor  ecx,ecx
Mov  cl,004          ; Кол-во байтов
Xor  edx,edx
Mov  dl,03C          ; Смещение в файле
Call edi             ; Читать
Mov  edx,[esi]
Dec  edx             ; Смещение-1

Проанализировав его, легко понять, что вирус рассчитывает местоположение в файле для PE-заголовка потенциальной "жертвы" и проверяет первый байт перед сигнатурой ‘PE’. В "здоровой" программе этот байт обычно нулевой, а любое ненулевое значение является для вируса признаком зараженности.

Поэтому программу, зараженную вирусом CIH, целесообразно не восстанавливать полностью в исходном виде, но оставить на своем месте хотя бы признак зараженности. В следующий раз вирус эту программу не тронет.

КАК НАПИСАТЬ СВОЙ АНТИВИРУС?

Для того, чтобы "собирать" себя из отдельных "кусочков", вирусу, конечно же, требуется где-то запомнить местоположение этих "кусочков" и их длины. Табличку с этой информацией можно обнаружить в самом начале вирусного кода, непосредственно перед точкой входа в вирус. В зараженном файле NOTEPAD.EXE она выглядит так:

Table:
 Dd 0         ; Признак конца таблички
 Dd 000000F7h ; Длина в секции .data
 Dd 0040584Ch ; Позиция в секции .data
 Dd 00000164h ; Длина в секции .text
 Dd 00404E9Ch ; Позиция в секции .text
 Dd 00000190h ; Длина в псевдосекции заголовков
; Точка входа в вирус
Start:
 Push ebp
...

Убедимся, что вирус действительно читает и использует эту табличку в обратном порядке:

 Lea     eax,[esi-Start] ; Адрес начала таблички
 ...
 mov     esi,eax
More:
 Mov     ecx,[eax-0004] ; Очередная длина
 Repe    movsb   
 Sub     eax,008   ; Адрес очередного "кусочка"
 Mov     esi,[eax]
 Or      esi,esi   ; Конец таблички?
 Je      Enough
 Jmps    More

Итак, мы теперь владеем информацией, достаточной для того, чтобы восстановить зараженную программу в исходном виде:

  • мы знаем, где вирус хранит старое значение точки входа в программу;
  • мы знаем, где вирус хранит табличку с описанием адресов и длин "лишних" фрагментов в концах программных секций.

Разумеется, прежде чем "лечить" программу, нужно предварительно убедиться в том, что она действительно "больна". "Чернобыльский" вирус не относится к классу полиморфных, хранит свой код в программе в неизменном виде и, значит, легко может быть обнаружен по сигнатуре – характерной для него и только для него последовательности байтов.

Не будем особо мудрствовать и возьмем в качестве сигнатуры 8 первых байтов вируса, начиная с точки входа.

/* Компилировать, например, в BC/C++ 5.0 */
#include <stdio.h>
#include <winnt.h>

#define SLEN 8
#define OK   0
#define BAD  1

IMAGE_NT_HEADERS32 pe;
IMAGE_DOS_HEADER mz;
IMAGE_SECTION_HEADER sh;

/* "Проверялка" для Win95.CIH. © Климентьев К., Самара 2001 */
int CheckCIH( char *filename ) {

int  f, i;
char buf[SLEN];
char Sign[SLEN] ={0x55, 0x8D, 0x44, 0x24, 0xF8, 0x33, 0xDB, 0x64};

f=open(filename, O_RDONLY|O_BINARY);
read( f, &mz, sizeof(IMAGE_DOS_HEADER));
if ((mz.e_magic==0x5A4D)&&(mz.e_lfarlc>=0x40)) {
 lseek( f, mz.e_lfanew, SEEK_SET);
 read( f, &pe, sizeof(IMAGE_NT_HEADERS32));
 if (pe.Signature==0x4550) {
  lseek( f, pe.OptionalHeader.AddressOfEntryPoint, SEEK_SET);
  read( f, buf, SLEN); close(f);
  for (i=0;i<SLEN;i++) if (buf[i] != Sign[i]) return OK;
  return BAD;
  }
 }
close(f); return OK;
}

"Лечение" зараженного файла состоит из двух этапов. На первом мы разыскиваем внутри вируса и возвращаем на "законное место" внутри заголовка двойное слово – оригинальный адрес точки входа в программу. Собственно говоря, второй этап совершенно необязателен, т.к вирус уже обезврежен. Тем не менее, дабы "успокоить" некоторые особо бдительные антивирусы, дополнительно просканируем табличку вирусных фрагментов, рассчитаем их местоположение внутри файла и заполним их символом "звездочка".

/* "Лечилка" для Win95.CIH. © Климентьев К., Самара 2001 */
CureCIH( char *filename ) {

Int  f, i, k;
Unsigned char c='*';
DWORD l, p, e, tmp;

F=open(filename, O_RDWR|O_BINARY);

/* Восстановление старой точки входа */
lseek(f,pe.OptionalHeader.AddressOfEntryPoint+0x5E,SEEK_SET);
read(f, &e, 4); e -= pe.OptionalHeader.ImageBase;
lseek(f,mz.e_lfanew+0x28,SEEK_SET);
write(f, &e, 4);

/* Удаление вируса из области заголовков */
lseek( f, pe.OptionalHeader.AddressOfEntryPoint-4, SEEK_SET);
read( f, &l, 4);
lseek(f, pe.OptionalHeader.AddressOfEntryPoint, SEEK_SET);
for (k=0;k<(int)l;k++) write( f, &c, 1);

/* Удаление фрагментов вируса из секций */
tmp = pe.OptionalHeader.AddressOfEntryPoint-12;
while (1) {

/* Чтение таблички описания вирусных фрагментов */
 lseek(f, tmp, SEEK_SET); tmp-=8;
 read( f, &l, 4);  /* Длина фрагмента */
 read( f, &p, 4);  /* Позиция фрагмента в памяти */
 if (!p) goto finish;
 p -= pe.OptionalHeader.ImageBase;

/* Сканирование таблицы секций */
 lseek(f,mz.e_lfanew+0x18+pe.FileHeader.SizeOfOptionalHeader, SEEK_SET);
 for (i=0;i<pe.FileHeader.NumberOfSections;i++) {
  read( f, &sh, sizeof(IMAGE_SECTION_HEADER));
  if ((p>sh.VirtualAddress)&& (p<sh.VirtualAddress+sh.Misc.VirtualSize)) {
   lseek(f, sh.PointerToRawData + (p-sh.VirtualAddress), SEEK_SET);
   for (k=0;k<(int)l;k++) write( f, &c, 1);
   goto done;
   }
  }
done:;
 }
finish: close(f);
}

Эти две процедуры, CureCIH() и CheckCIH() должны вызываться из некой программы примерно вот в таком стиле:

If (CheckCIH(filename)==BAD) CureCIH(filename);

Напишите программу, обходящую дерево дисковых каталогов и проверяющую все встреченные EXE-файлы, самостоятельно. Это очень просто. Вот и все, антивирус для знаменитого "Чернобыльского" вируса готов!

ЗАКЛЮЧЕНИЕ

Итак, представители "электронной микрофауны" совсем не так сложны и непонятны, как могло бы показаться на первый взгляд. Более того, не все вирусописатели столь любознательны и трудолюбивы, как Чен Инг Хау: многие вирусы, в том числе и самые современные, устроены гораздо проще.

Так почему же так много людей, называющих себя "специалистами по программному обеспечению" и "программистами", не знают реальных повадок "электронной заразы", зато охотно верят безграмотным журналистским слухам и сплетням? Почему они не имеют (и не хотят иметь) представления о том, как примерно устроены, что могут и чего не могут делать антивирусные программы?

Конечно, данная статья не способна никоим образом повлиять на сложившуюся ситуацию, но какую-то крохотную подвижку в сознании этих людей она, хочется надеяться, произведет.

Следует упомянуть, что данная статья никогда не была бы не написана без ценных замечаний от участников группы NF.

Благодарю за внимание. С глубочайшим почтением и искреннейшей преданностию есмь, милостивые государи, Ваш покорный слуга

© Климентьев К.Е. aka DrMad: drmad@dr.com * http://drmad.chat.ru
Самара 2001