waqur: (Евро)
[personal profile] waqur


Ребята из Майкрософт изрядно наложили в штаны, когда появился руткит, который захватывал контроль над машиной в режиме ядра через своп файл и прямой доступ к диску. Его написала Joanna Rutkowska, и он работал по простой схеме:

1) заставить ядро вытеснить в своп заданную страницу памяти c кодом
2) за счёт прямого доступа к диску, заменить код в странице на требуемый
3) дождаться, пока внедрённый код получит управление в режиме ядра

Поскольку вся винда написана через то место, на котором сидят, и своппинг идёт не в отдельный раздел, а в регулярный файл, простым запретом прямого доступа к смонтированной своп-партиции тут проблему не решишь.

Корпоративная культура Майкрософта, предполагающая принятие всех решений "на бегу" в War Rooms исключает такой режим работы как "остановиться и немного подумать", поэтому, по сообщениям в интернете мелкомягкие просто тупо запретили прямой доступ к диску, начиная с Vista RC2.

Создав тем самым массу геморроя разработчикам всяких дисковых системных утилит - дефрагментаторов, восстанавливателей данных из повреждённых ФС, программ типа PartitionMagic, backup software, wipe software, undelete tools, unformat tools и так далее. Типа, всё, ребята, вылезай, приехали - http://support.microsoft.com/kb/942448/en-us - можно писать в бутсектор, неиспользуемую область, ещё в какую-то задницу, но не в область файловой системы. Можно в область файловой системы, но сначала размонтируйте раздел. А если нужен физический доступ не к разделу, а ко всему блочному устройству? С целью создания/удаления разделов, например? ERROR_ACCESS_DENIED, ага.

И если об оно было нормально описано в той же Knowledge Base статье, так было б ещё ничего. А то ж фактически информации нет. Статья из KB выглядит так, как будто её тоже писали в War Room'е, честное слово.

На этом фоне активизировались всякие хитрож*пые умники, которые начали предлагать дрова для прямого доступа к диску в обход всей этой кухни - http://www.eldos.com/rawdisk/ например. The sectors can be read or written from user-mode processes, thus going around direct access ban imposed by the operating systems. 500 евро, между прочим.

Однако, неделя траханий, несомненно увлекательных экспериментов с доступом к диску в новой винде (а потом и вдумчивое чтение статей по CreateFile и FSCTL_LOCK_VOLUME в MSDN и KB 942448 - когда уже всё получилось, ну конечно же) показали, что способ есть. Никакой драйвер не нужен, и разговоры про "direct access ban for user-mode processes" - это просто басни для лохов, у которых есть лишних 500 евро.

Также, не нужно делать и "жёсткое" размонтирование тома через DeleteVolumeMountPoint - это совершенно не помогает, к тому же это просто садизм над конченным юзером: после этой процедуры буквы дисков удалятся навсегда, это правило пропишется в реестре, и в случае краха вашей программы юзеру придётся возвращать буквы дисков к жизни через Панель Управления - Администрирование - Управление Компьютером - Управление Дисками или при помощи команды mountvol. Не поможет ни переподключение устройства, ни перезагрузка компьютера.

Не работают также и попытки вывести диск "в оффлайн" (типа, как вынутая дискета - буква есть, а читать нельзя) через IOCTL_VOLUME_OFFLINE и IOCTL_VOLUME_ONLINE.


Правильный способ открыть физический диск на запись под Вистой таков:

Шаг 1. Определяем список смонтированных разделов на этом физическом диске.
Как? Ну, можно получить список всех томов в системе через FindFirstVolume/FindNextVolume/FindVolumeClose, далее открыть каждый из них и через IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS или IOCTL_STORAGE_GET_DEVICE_NUMBER выяснить номер объемлющего физического диска, и сравнить с номером физического диска, который мы хотим открыть на запись.

Шаг 2. Размонтируем все найденные разделы, находящиеся на нашем физическом диске. Для этого их надо открыть на чтение-и-запись, с share mode, допускающим share read и share write, диспозиция - OPEN_EXISTING, и на каждом из них выполнить DeviceIoControl с кодами FSCTL_LOCK_VOLUME и FSCTL_DISMOUNT_VOLUME.

Программисты-параноики, которые боятся скрытых разделов, которые смонтированы без присвоения буквы (и помешают прямому доступу к диску, если их так оставить), могут сделать перечисление всех объектов вида \Device\HardDiskN\PartitionM в пространстве имён NT Object Manager'а, и поразмонтировать их через NtCreateFile/NtDeviceIoControl, не связываясь с DOSоподобными буквами и Win32 API.

Шаг 3. Наконец, открываем физический диск (CreateFile "\\.\PhysicalDriveN" или NtCreateFile "\Device\HardDiskN"). Режим - эксклюзивный (share mode = 0), права - чтение и запись, буферизация - выключена (FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH), диспозиция - OPEN_EXISTING. После открытия - опять FSCTL_LOCK_VOLUME и FSCTL_DISMOUNT_VOLUME (уже для всего физического диска в целом). Хендлы разделов диска не отпускаем, продолжаем удерживать их всех в заблокированном состоянии.

Шаг 4. Работаем с диском. Читаем, пишем, всё что угодно.

Шаг 5. FSCTL_UNLOCK_VOLUME и CloseHandle/NtClose для физического диска.

Шаг 6. FSCTL_UNLOCK_VOLUME и CloseHandle/NtClose для каждого из бывших логических дисков.

Шаг 7. Передёргиваем через Setup API storage driver физического диска, чтобы он в процессе переинициализации сообщил виндовому mount manager'у, о том, что у него новая таблица разделов. Это чтобы всем новым разделам были назначены новые Volume GUID'ы, а старые - "правильно" забыты.

Любые отклонения от этой процедуры приводят к катастрофическим последствиям. Это вам не XPшка, где можно всё делать в любом порядке. Закроете хендлы логических разделов раньше времени (сразу после открытия физического) - винда перемонтирует логические диски, включит защиту области FATа и каталогов - и посыпятся рандомом ошибки - то ERROR_ACCESS_DENIED, то WriteFile возвращает нулевую длину без кода ошибки, то WriteFile вообще не возвращает ошибок, но данные на диск не пишутся. Это всё гонки (race condition) с FASTFAT.SYS и NTFS.SYS.

А теперь, если внимательно и вдумчиво почитать KB 942448, то в хитросплетениях правил и ограничений, можно увидеть процедуру, которую я описал выше. Правда, здорово Майкрософт пишет мануалы?

UPD. Трёхчасовой стресс-тест, запускающий поочерёдно i386 и amd64 сборку одной программы, которая реализует вышеуказанный алгоритм, не выявил никаких проблем.

Date: 2010-11-11 08:58 am (UTC)
From: [identity profile] waqur.livejournal.com
да

только в Harddisk(N)\DR(M) N не всегда равно M

если флешку вынуть/вставить несколько раз, то M поменяется, а N - нет

M после загрузки Винды растёт строго инкрементально, и никогда не повторяется

N может переиспользоваться, если слот жёсткого диска освободился в результате отключения устройства

March 2024

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
31      

На этой странице

Автор стиля

Развернуть

No cut tags
Page generated 2026-05-07 05:28 pm
Powered by Dreamwidth Studios