Еще одна проблема заключается в том, что вирус не корректирует длину целевого файла, и после внедрения она станет равной 4 Кбайт (именно таков размер текущей версии xcode.exe). Это плохо, так как пользователь тут же заподозрит подвох (файл explorer.exe, занимающий 4 Кбайт, выглядит довольно забавно), занервничает и начнет запускать антивирусы. Чтобы устранить этот недостаток, можно запомнить длину инфицируемого файла перед внедрением, затем скопировать в основной поток тело вируса, открыть файл на запись и вызвать функцию
SetFilePointer
для установки указателя на оригинальный размер, увеличивая размер инфицированного файла до исходного значения.
Предложенная стратегия внедрения, конечно, не является идеальной, но все же это намного лучше, чем прописываться в реестре, который контролируется множеством утилит мониторинга. Наконец, чтобы не пострадать от своего же собственного вируса, каждый вирусописатель всегда должен иметь под рукой противоядие. Командный файл, приведенный в листинге 6.6, извлекает оригинальное содержимое файла из потока bar и записывает его в файл reborn.exe.
Листинг 6.6. Командный файл, восстанавливающий зараженные файлы в исходное состояние
more < %1:bar > reborn.exe
ECHO I'm reborn now!
Энумерация потоков
Как определить, что за потоки содержатся внутри файла? Штатными средствами операционной системы сделать это невозможно. Функции для работы с потоками не документированы и доступны только через Native API. Вот эти функции:
NtCreateFile
,
NtQueryEaFile
и
NtSetEaFile
. Их описание можно найти в следующей книге: "The Undocumented Functions Microsoft Windows NT/2000" by Tomasz Nowak. Электронную копию этой книги можно бесплатно скачать по следующему адресу:
http://undocumented.ntinternals.net/title.html. Кроме того, рекомендуется прочесть статью "Win2k.Stream" из 5-го номера вирусного журнала #29А, да и другие журналы пролистать не мешает.
Создание нового потока осуществляется вызовом функции
NtCreateFile
, среди прочих аргументов принимающей указатель на структуру
FILE_FULL_EA_INFORMATION
, передаваемый через
EaBuffer
. Можно также воспользоваться функцией
NtSetEaFile
, передав ей дескриптор, возращенный функцией
NtCreateFile
, открывающей файл обычным образом. Перечислением (и чтением) всех имеющихся потоков занимается функция
NtQueryEaFile
. Прототипы всех функций и определения структур содержатся в файле NTDDK.H, в котором присутствует достаточное количество комментариев, позволяющее заинтересованному читателю самостоятельно разобраться в данном вопросе.
Полезные ссылки
□ http://www.wasm.ru — море полезных материалов по вирусам и ассемблеру, форум на котором тусуется множество матерых профессионалов, да и просто сайт, приятный во всех отношениях.
□ http://vx.netlux.org/ — гигантская коллекция вирусов и учебников по их написанию.
□ http://flatassembler.net/fasmw160.zip — бесплатная Windows-версия ассемблера FASM — самого правильного ассемблера из всех.
Глава 7
Восстановление ошибочно удаленных файлов на разделах NTFS
Надежность NTFS — это одно, а ошибочно удаленные файлы — совсем другое. Файловая система, даже такая мощная, как NTFS, бессильна защитить пользователя от себя самого. Но вот предусмотреть "откат" последних выполненных действий она вполне может, тем более что транзакции и ведение их журнала в NTFS уже реализованы. До совершенства остается всего лишь один шаг. Однако, к сожалению, Microsoft не торопится сделать этот шаг, возможно, оставляя эти усовершенствования как задел для будущих версий. "Защита" от непреднамеренного удаления реализована исключительно на интерфейсном уровне, а это не только неудобно, но и ненадежно.
Прекрасно, если удаленный файл сохранился в "Корзине", но что делать, если там его не окажется? Эта глава рассказывает о методах ручного восстановления файлов, в том числе и файлов с отсутствующей файловой записью, которые приходится собирать буквально по кластерам.
Пакет FILE_DISPOSITION_INFORMATION
IPR_MJ_SET_INFORMATION
/
FILE_DISPOSITION_INFORMATION
— это пакеты, посылаемые драйверу при удалении файла (имейте это в виду при дезассемблировании). Чтобы уметь восстанавливать удаленные файлы, необходимо отчетливо представлять, что происходит в процессе удаления файла с раздела NTFS. Последовательность выполняемых при этом действий приведена ниже.
1. Корректируется файл
/$MFT:$BITMAP
, каждый бит которого определяет "занятость" соответствующей файловой записи (FILE Record) в MFT (значение 0 говорит о том, что запись не используется).
2. Корректируется файл
/$BITMAP
, каждый бит которого определяет "занятость" соответствующего кластера (значение 0 говорит о том, что кластер не используется).
3. Файловые записи, соответствующие файлу, помечаются как удаленные (поле
FLAG
, находящееся по смещению
16h
от начала файловой записи, сбрасывается в ноль).
4. Ссылка на файл удаляется из двоичного дерева индексов. Технические подробности этого процесса здесь не рассматриваются, поскольку восстановить таблицу индексов вручную сможет только гуру. Кроме того, в таком восстановлении нет необходимости. Ведь в NTFS индексы играют вспомогательную роль, и гораздо проще переиндексировать каталог заново, чем восстанавливать сбалансированное двоичное дерево (B*tree).
5. Обновляется атрибут
$STANDARD_INFORMATION
каталога, в котором хранится удаляемый файл (время последнего доступа и т.д.).
6. В файле
/$LogFile
обновляется поле
Sequence Number
(изменения, происходящие в журнале транзакций, здесь не рассматриваются).
7. Поля
Update Sequence Number
следующих файловых записей увеличиваются на единицу: сам удаляемый файл, текущий каталог,
/$MFT
,
/$MFT:$BITMAP
,
/$BITMAP
,
/$BOOT
,
/$TRACKING.LOG
.
Каталоги удаляются практически так же, как и файлы. В этом нет ничего удивительного, так как с точки зрения файловой системы каталог тоже представляет файл особого вида, содержащий внутри себя двоичное дерево индексов (B*tree).
Ни в том, ни в другом случае физического удаления файла не происходит, и он может быть легко восстановлен. Легкое и быстрое восстановление возможно до тех пор, пока не будет затерта файловая запись (FILE Record), принадлежащая этому файлу и хранящая его резидентное тело или список отрезков (run-list) нерезидентного содержимого. Утрата файловой записи крайне неприятна, поскольку в этом случае файл придется собирать по кластерам. При этом стоит заметить, что чем сильнее был фрагментирован удаленный файл, тем сложнее будет эта задача. К счастью, в отличие от FAT, NTFS не затирает первого символа имени файла, что значительно упрощает восстановление.