Деструктивные потоки A.M.D.F. (amdf@mera.net.ru) Xakep, номер #069, стр. 069-076-3 Если в самом файле присутствуют какие-либо данные, их тоже можно представить в виде потока. Имена потоков строятся так: «имя_файла:имя_потока:атрибут». Стандартный атрибут потока, в котором находятся данные, называется $Data. Есть много других атрибутов, имена которых также начинаются со знака «$». Содержимое файла находится в безымянном потоке (имя_файла::$DATA). С этим свойством файловой системы представлять содержимое файла в виде потока был связан баг в старых версиях Microsoft IIS. В то далекое время хакер, который хотел узнать текст какого-либо сценария на уязвимом сервере, просто добавлял к его имени «::$DATA», и сервер вместо того, чтобы выполнить скрипт, выдавал его исходный код. Работа с потоками, в общем-то, похожа на работу с файлами. В качестве простого примера я написал программу, создающую файл с потоком и записывающую в него информацию. Вот ее код: Пример создания потока #include <windows.h> int main() { DWORD dwRet; HANDLE hStream = CreateFile("testfile:stream", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, NULL, NULL ); WriteFile( hFile, "This is a stream", 17, &dwRet, NULL); CloseHandle(hStream); return 0; } Если тебе захочется протестить программу на своей системе, не нужно перебивать исходник из журнала – готовый бинарник и исходный код лежит на нашем диске. После запуска этой программы в ее каталоге появится абсолютно пустой (по мнению любого файлового менеджера) файл testfile. Увидеть содержимое прикрепленного потока можно, набрав в командной строке more < testfile:stream. Как видишь, имя потока указывается после имени файла, отделенное от него знаком двоеточия. Самое трудное при работе с потоками – это получить их список для конкретного файла. Стандартной функции нет, и поэтому придется писать ее самому. Давай напишем небольшую консольную программу, которая бы возвращала список потоков по имени файла. Такая прога есть у ребят из Sysinternals, причем она поставляется открытым кодом, но мне не понравился их способ. Они используют вызовы Native API, и поэтому их код большой и трудный для понимания. Мы же напишем свою софтину, которая будет работать из командной строки, с алгоритмом попроще и со стандартными API-функциями. Получаем список потоков Как же можно получить список потоков, прикрепленных к файлу? Тут все совсем не сложно. Мы воспользуемся стандартной функцией BackupRead, предназначенной для резервного копирования файлов. Когда делаешь резервную копию файла, важно сохранить как можно больше данных, включая и инфу в файловых потоках. Информация берется из структуры WIN32_STREAM_ID. Оттуда можно достать имя потока, его тип и размер. Нам понадобятся только потоки типа BACKUP_ALTERNATE_DATA. Все функции и структуры описаны в заголовочном файле winnt.h. |