Blog. Just Blog

Прямой доступ к диску для записи в Windows 7

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Прямой доступ к диску для записи в Windows 7
Прямой доступ к диску для записи в Windows 7

При разработке программы для защиты флешек от вирусов возникла необходимость записи секторов напрямую на диск. Прямой доступ к диску осуществлялся через функцию CreateFile. Под Windows XP все работало нормально, а под Windows 7 при попытке записи сектора возвращалась ошибка Access Denied, при том, что при открытии диска на запись никаких ошибок не возникало. После длительных поисков причины было выяснено следующее: еще в самом начале разработки в Windows 7 была обнаружена критическая уязвимость. Если не вдаваться в нудные технические подробности, то смысл ее заключался в том, что злоумышленник мог открыть системный диск напрямую для записи и поместить любой злонамеренный код в файл подкачки. В Microsoft решили проблему с присущей им дубовой прямолинейностью - просто взяли и запретили прямую запись на диски. Но поскольку нельзя, но было очень нужно, то способ обхода защиты нашелся очень быстро. Оказывается, что запись на диски запрещена не полностью, система разрешает записывать данные в нулевую дорожку диска и в неразмеченные области. Такое поведение вполне объяснимо: надо же как-то форматировать диски штатными средствами без дополнительных танцев с бубнами. Значит для того, чтобы система разрешила запись в произвольное место диска, она сперва должна определить его как неразмеченный. А это достигается уничтожением нулевого сектора диска перед записью. Естественно, что перед уничтожением надо сохранить все данные из нулевого сектора в сухом прохладном месте, а потом вернуть их обратно.

Порядок действий следующий: открыть диск для чтения-записи, попробовать записать нужный сектор. Если произошла ошибка Access Denied, то надо прочитать нулевой сектор, записать вместо него нули, после этого обязательно закрыть диск. Это нужно, чтобы система при повторном обращении посчитала диск неразмеченным и разрешила запись в любой сектор. Затем снова открываем диск для чтения-записи. После записи нужных данных восстанавливаем нулевой сектор и закрываем диск. Все, наша задача выполнена, данные записаны, система спокойна. У этого способа есть и минусы. Так, если работа вашей программы по какой-то причине завершилась аварийно до момента, когда она восстановила нулевую дорожку, то данные на диске могут стать недоступны или вообще потеряться. Способ проверен и хорошо работает на съемных дисках с файловой системой FAT/FAT32, на стационарных жестких дисках и других файловых системах я его не проверял.

Вот фрагмент кода на Ассемблере, взятый из рабочего проекта. При необходимости его можно легко портировать на другие языки программирования.
  1.         ; Открыть диск для чтения и записи
  2.         invoke  CreateFile,drvName,GENERIC_READ+GENERIC_WRITE,\
  3.                 FILE_SHARE_READ+FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL
  4.         ; Сохранить хэндл
  5.         mov     [hFile],eax
  6.  
  7.         ; Сразу прочитать нулевую дорожку
  8.         invoke  ReadFile,[hFile],mbr,512,tmp,NULL
  9.  
  10.         ; Установить смещение на нужный сектор
  11.         invoke  SetFilePointer,[hFile],512*numberofsector,0,FILE_BEGIN
  12.  
  13.         ; Попытаться записать нужный сектор
  14.         invoke  WriteFile,[hFile],new_sector,512,tmp,NULL
  15.         or      eax,eax
  16.         ; Ошибок записи не произошло
  17.         jnz     close_drive_and_exit
  18.  
  19.         ; Получить код последней ошибки
  20.         invoke  GetLastError
  21.         ; Ошибка Access Denied?
  22.         cmp     eax,5
  23.         ; Произошла какая-то другая критическая ошибка
  24.         jne     close_drive_and_exit
  25.  
  26.         ; Уничтожить нулевую дорожку
  27.         invoke  SetFilePointer,[hFile],0,0,FILE_BEGIN
  28.         invoke  WriteFile,[hFile],zerobuff,512,tmp,NULL
  29.         ; Закрыть диск
  30.         invoke  CloseHandle,[hFile]
  31.  
  32.         ; Открыть заново диск с уничтоженной дорожкой
  33.         invoke  CreateFile,drvName,GENERIC_READ+GENERIC_WRITE,\
  34.                 FILE_SHARE_READ+FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL
  35.         ; Сохранить хэндл
  36.         mov     [hFile],eax
  37.  
  38.         ; Установить смещение на нужный сектор
  39.         invoke  SetFilePointer,[hFile],512*numberofsector,0,FILE_BEGIN
  40.  
  41.         ; Записать нужный сектор
  42.         invoke  WriteFile,[hFile],new_sector,512,tmp,NULL
  43.  
  44.         ; Записать нулевую дорожку обратно
  45.         invoke  SetFilePointer,[hFile],0,0,FILE_BEGIN
  46.         invoke  WriteFile,[hFile],mbr,512,tmp,NULL
  47.  
  48. close_drive_and_exit:
  49.         ; Закрыть диск
  50.         invoke  CloseHandle,[hFile]
Код приведен минимально необходимый, без дополнительной обработки возможных ошибок. В реальной ситуации, конечно, надо позаботиться о лучшей сохранности прочитанной нулевой дорожки, об обработке ситуации в случае ошибки записи данных на диск с уничтоженной нулевой дорожкой и т.д. Все это вы можете сделать самостоятельно.

Не зря говорится: "Что бы русский ни делал - все равно получается автомат Калашникова". Хотел как лучше, а в результате нашел способ как лишний раз наклонить защиту системы :)

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 13181 | Комментариев: 6

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
novikey (02.09.2011 в 16:41):
Win7 x64 + SSD HDD SATA2 (NTFS) - способ не помогает. Можно записать первые 63 сектора от начала диска, на 64ом - отказано в доступе, независимо от заполнения нулевого сектора.
AyTkACT (07.03.2010 в 21:30):
ManHunter, сори, не обратил внимания что твой камент который приведён ниже - один из первых и очень стар.
ManHunter  (28.09.2009 в 22:59):
Программа НЕ работает под Windows 7, я ищу причину и возможность это исправить.
ManHunter (07.03.2010 в 20:11):
AyTkACT, FDP и так работает под Win7. А эту статью я выложил только по просьбам трудящихся, которым стало интересно, как я это сделал.
AyTkACT (07.03.2010 в 20:05):
bigcatwar, USB Disk Security спасает только от творений криворуких кодеров.
Основная опасность зловредов на флешках - это автозапуск через авторан.ини.
Авторан.ини (папка) созданная говнопродуктом от немецких "специалистов" (программой USB Disk Security) тупо может быть переименована, а большего для записи своего авторан.ини и не надо.
Flash Drive Protector 1.0 от товарища Manhunter'a является в этом смысле настоящей защитой, ибо защита на уровне файловой системы.

P.S.Если криворукие программисты добавят несколько строк в свои "крутые вирусы" хотя бы тупо прибивающие процесс USB Disk Security и переименовывающие папку созданную им, то "великая и могучая" защита просто тупо сойдёт на нет. Как вариант под конец можно портить или удалять этот "замечательный" продукт от фрицов.

P.P.S. Извините за оффтоп, но уж больно запарила эта тема.

P.P.P.S. Я так понимаю скоро выйдет новая версия Flash Drive Protector работающая и на win 7 ?
Mihas999 (06.03.2010 в 23:53):
Спасибо за ваш сайт)))
bigcatwar (06.03.2010 в 19:04):
пока такое я не встречал а вот ета прг USB_Disk_Security_v5.3.0.12 спасает от заразы на фляшах

ManHunter СПАСИБО!!

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0036 сек.) / Память: 4.5 Mb
Наверх