Здравствуйте, duke89, Вы писали:
D>Привет всем! Должна моя программа записывать на диск NTFS пару чисел, причем так, чтобы ничего на нем не поломать и чтоб эта информация сохранилась на диске не один день, а вечно(ну или пока диск не отформатируют). Мне посоветовали прочитать вначале MFT, узнать какой сетор еще пустой, записать в этот сектор мои числа и записть в MFT, что сектор типа уже занят, чтоб Виндоуз не записал на следующий день в мой сектор что-нибудь другое. Просто запсывать в сектор и читать из него с помощью АПИ я умею(кстати пишу я прогу на Дельфе), а вот как читать и записывать в MFT — не знаю. Может поможете?
Вообще-то это очень непростая тема.
То что тебе советовали верно только в самых общих чертах.
Поскольку если твой кластер не оформить как файл, то первый же вызов chkdsk пометит твой кластер как free.
Самый простой выход — писать в именованный поток какого-нибудь общего файла.
Большинство программ содержимое дополнительных потоков не показывают.
А на NTFS у многих файлов несколько именованных потоков. Тот же Word пользуется этим постоянно.
Даже WIN32 API предоставляет доступ к этим потокам.
Точно не помню, но по моему что-то типа так CreateFile( "C:\\boot.ini:Stream", ... )
Привет всем! Должна моя программа записывать на диск NTFS пару чисел, причем так, чтобы ничего на нем не поломать и чтоб эта информация сохранилась на диске не один день, а вечно(ну или пока диск не отформатируют). Мне посоветовали прочитать вначале MFT, узнать какой сетор еще пустой, записать в этот сектор мои числа и записть в MFT, что сектор типа уже занят, чтоб Виндоуз не записал на следующий день в мой сектор что-нибудь другое. Просто запсывать в сектор и читать из него с помощью АПИ я умею(кстати пишу я прогу на Дельфе), а вот как читать и записывать в MFT — не знаю. Может поможете?
MShura wrote: > > Даже WIN32 API предоставляет доступ к этим потокам. > Точно не помню, но по моему что-то типа так CreateFile( "C:\\boot.ini:Stream", ... )
Все верно, только если файл сотрут, то и информация эта исчезнет. И даже
если его скопируют (обычными средствами), то она скопирована не будет.
Здравствуйте, MShura, Вы писали:
MS>Ну конечно надо убедиться сначало, что nFileSizeHigh == 0, затем берем MS>читаем nFileSizeLow/512 секторов от начала раздела MS>($Boot единственный файл на NTFS, местоположение данных которого строго фиксировано). MS>Убеждаемся, что последние 512 байт одни нули. MS>Пишем туда, что нам надо. MS>Пишем на диск.
Это, конечно, все очень хорошо, но это — грязный хак. Две таких программы уже не будут корректно работать. ИМХО надо искать какие-то другие способы для решения задачи.
. От себя добавлю, что программу, которая делает такие вещи, ставить просто опасно, и любой антивирус тебе это подтвердит Кстати, что это за программа такая, что ей как минимум администратор нужен? Средство администрирования? Если нет, то в сад такую программу! Защиту от несанкционированного копирования надо делать другими средствами. Легальными с точки зрения ОС. На Королевстве Дельфи была серия статей на эту тему.
P.S.: Знаю случай, когда легально купленную программу пришлось ломать (именно ломать, а не копировать), просто чтобы заставить работать на предназначенной ей машинеКопировалась, кстати, она один к одному за ~5 минут. В защите тоже raw доступ к диску использовался
Здравствуйте, MShura, Вы писали:
MS>А на NTFS у многих файлов несколько именованных потоков. Тот же Word пользуется этим постоянно. MS>Даже WIN32 API предоставляет доступ к этим потокам. MS>Точно не помню, но по моему что-то типа так CreateFile( "C:\\boot.ini:Stream", ... )
Очень интересно, дайте ссылочку (в МСДН или в Веб), где можно прочитать про это.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Привет!
PD>MShura wrote: >> >> Даже WIN32 API предоставляет доступ к этим потокам. >> Точно не помню, но по моему что-то типа так CreateFile( "C:\\boot.ini:Stream", ... )
PD>Все верно, только если файл сотрут, то и информация эта исчезнет. И даже PD>если его скопируют (обычными средствами), то она скопирована не будет.
Для этого надо воспользоваться каким-нибудь общим файлом (я про это упомянул).
А вообще-то есть еще одно место, где можно хранить своё.
Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
Читаешь данные. Эти данные — исполняемый код загрузчика. Теперь основная задача определить размер кода.
Оставляю эту задачу на твоё усмотрение. Обычно размер этого кода меньше полного размера на несколько секторов.
Соответственно в конец можно писать.
Одна из моих программ так и делает....
В некоторых ситуациях, когда размер кластера больше сектора, может получиться "дырка" размером меньше кластера.
Эта "дырка" находится за пределами адресуемого NTFS пространством, но в пределах FDISK размера.
Т.е. если FDISK размер — N секторов, размер кластера M секторов, на разделе K кластеров, то
дырка здесь:
от K*M + 1 до (N — 2) включительно
N-1 — копия boot.
Re[4]: Прямая запись на диск
От:
Аноним
Дата:
04.02.04 18:05
Оценка:
Здравствуйте, MShura, Вы писали:
MS>Здравствуйте, Pavel Dvorkin, Вы писали:
MS>Для этого надо воспользоваться каким-нибудь общим файлом (я про это упомянул). MS>А вообще-то есть еще одно место, где можно хранить своё. MS>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ). MS>Читаешь данные. Эти данные — исполняемый код загрузчика. Теперь основная задача определить размер кода. MS>Оставляю эту задачу на твоё усмотрение. Обычно размер этого кода меньше полного размера на несколько секторов.
MS>Соответственно в конец можно писать.
MS>Одна из моих программ так и делает....
Спасибо, буду пробовать. Насколько я понял, надо использовать data.nFileSizeLow. Затем надо поделить nFileSizeLow на 512(кол-во байтов в кластере) и запиать инфу в последний кластер(мне всего надо записать комбинацию из 20 символов, насколько я понял, одного кластера хватит, а последний кластер $boot всегда пустой. Так?
MS>В некоторых ситуациях, когда размер кластера больше сектора, может получиться "дырка" размером меньше кластера. MS>Эта "дырка" находится за пределами адресуемого NTFS пространством, но в пределах FDISK размера. MS>Т.е. если FDISK размер — N секторов, размер кластера M секторов, на разделе K кластеров, то
MS>дырка здесь: MS>от K*M + 1 до (N — 2) включительно MS>N-1 — копия boot.
Я кажется чего-то не понял. Разве кластер и сектор не одно и то же? (простите за возможно глупые вопросы, я пока новичок в этой области)
MS>>А вообще-то есть еще одно место, где можно хранить своё. MS>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ). MS>>Читаешь данные. Эти данные — исполняемый код загрузчика. Теперь основная задача определить размер кода. MS>>Оставляю эту задачу на твоё усмотрение. Обычно размер этого кода меньше полного размера на несколько секторов.
MS>>Соответственно в конец можно писать.
MS>>Одна из моих программ так и делает....
А>Спасибо, буду пробовать. Насколько я понял, надо использовать data.nFileSizeLow. Затем надо поделить nFileSizeLow на 512(кол-во байтов в кластере) и запиать инфу в последний кластер(мне всего надо записать комбинацию из 20 символов, насколько я понял, одного кластера хватит, а последний кластер $boot всегда пустой. Так?
Чтобы не было путаницы:
сектор — единица емкости физического диска. Минимальный размер при самом низкоуровневом чтении/записи.
Почти всегда 512 байт.
кластер — логическая единица файловой системы. Измеряется в секторах и на всех известных мне файловых системах
кластер = сектор * 2^N.
Ну конечно надо убедиться сначало, что nFileSizeHigh == 0, затем берем
читаем nFileSizeLow/512 секторов от начала раздела
($Boot единственный файл на NTFS, местоположение данных которого строго фиксировано).
Убеждаемся, что последние 512 байт одни нули.
Пишем туда, что нам надо.
Пишем на диск.
Рекоммендую посмотреть первые ~16 секторов на NTFS с помощью любого DiskEditor.
Например DiskProbe.
MS>>В некоторых ситуациях, когда размер кластера больше сектора, может получиться "дырка" размером меньше кластера. MS>>Эта "дырка" находится за пределами адресуемого NTFS пространством, но в пределах FDISK размера. MS>>Т.е. если FDISK размер — N секторов, размер кластера M секторов, на разделе K кластеров, то
MS>>дырка здесь: MS>>от K*M + 1 до (N — 2) включительно MS>>N-1 — копия boot.
А>Я кажется чего-то не понял. Разве кластер и сектор не одно и то же? (простите за возможно глупые вопросы, я пока новичок в этой области)
Все файловые системы оперируют внутри себя в терминах кластеров. Это так сказать единица измерения пространства.
Сектор — характеристика жесткого диска.
Здравствуйте, Вадим Никулин, Вы писали:
ВН>Здравствуйте, MShura, Вы писали:
MS>>Ну конечно надо убедиться сначало, что nFileSizeHigh == 0, затем берем MS>>читаем nFileSizeLow/512 секторов от начала раздела MS>>($Boot единственный файл на NTFS, местоположение данных которого строго фиксировано). MS>>Убеждаемся, что последние 512 байт одни нули. MS>>Пишем туда, что нам надо. MS>>Пишем на диск.
ВН>Это, конечно, все очень хорошо, но это — грязный хак. Две таких программы уже не будут корректно работать. ИМХО надо искать какие-то другие способы для решения задачи.
При данных условиях (см начальный пост) это вполне нормальный вариант.
К тому же предполагается там хранить не обычную информацию, а например информацию о триальности и т.д.
Конечно если другая программа будет пользоваться таким-же подходом, то проблемы неизбежны, однако это проблема общего характера. (Т.е. например ты сохранил свои данные в одном файле, другая программа этот файл поломала, в итоге исходная прога не работает.)
Можно вообще написать свою файловую систему, но правда на диске может не быть места, для её размещения.
Более того на (basic) диске очень много небольших (до размера трэка) неиспользуемых мест.
Но вопрос касался NTFS раздела.
Здравствуйте, MShura, Вы писали:
MS>>>А вообще-то есть еще одно место, где можно хранить своё. MS>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.
Здравствуйте, duke89, Вы писали:
D>Здравствуйте, MShura, Вы писали:
MS>>>>А вообще-то есть еще одно место, где можно хранить своё. MS>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
D>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.
Скорее даже другие файлы она находит, но с Boot почему то никак.
Здравствуйте, duke89, Вы писали:
D>Здравствуйте, duke89, Вы писали:
D>>Здравствуйте, MShura, Вы писали:
MS>>>>>А вообще-то есть еще одно место, где можно хранить своё. MS>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
D>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value. D>Скорее даже другие файлы она находит, но с Boot почему то никак.
Здравствуйте, duke89, Вы писали:
D>Здравствуйте, MShura, Вы писали:
MS>>>>А вообще-то есть еще одно место, где можно хранить своё. MS>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
D>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.
Здравствуйте, MShura, Вы писали:
MS>Здравствуйте, duke89, Вы писали:
D>>Здравствуйте, MShura, Вы писали:
MS>>>>>А вообще-то есть еще одно место, где можно хранить своё. MS>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
D>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.
MS>Скачай сорсы MS>http://www.sysinternals.com/ntw2k/source/ntfsinfo.shtml
MS>Там есть DumpMetaFiles
А может быть такое, что нет метафайла $boot? Что тогда делать?
Здравствуйте, duke89, Вы писали:
D>Здравствуйте, duke89, Вы писали:
D>>Здравствуйте, duke89, Вы писали:
D>>>Здравствуйте, MShura, Вы писали:
MS>>>>>>А вообще-то есть еще одно место, где можно хранить своё. MS>>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
D>>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value. D>>Скорее даже другие файлы она находит, но с Boot почему то никак.
D>А $Boot и Boot.ini — это то же самое?
$Boot — мета файл (часть файловой системы), описывающий положение и размер boot кода.
Положение всегда с 0, а размер зависит от версии NTFS и размера кластера.
Boot.ini — это обычный файл, без которого система может спокойно жить.
Руссинович пишет, что FindFirstFile( "C:\\$Boot", &data ) сработает только под NT...
Здравствуйте, duke89, Вы писали:
D>Здравствуйте, MShura, Вы писали:
MS>>Здравствуйте, duke89, Вы писали:
D>>>Здравствуйте, MShura, Вы писали:
MS>>>>>>А вообще-то есть еще одно место, где можно хранить своё. MS>>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
D>>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.
MS>>Скачай сорсы MS>>http://www.sysinternals.com/ntw2k/source/ntfsinfo.shtml
MS>>Там есть DumpMetaFiles
D>А может быть такое, что нет метафайла $boot? Что тогда делать?
Мета файлы есть всегда, поскольку это часть файловой системы NTFS.
У тебя его утилита показывает DumpMetaFiles?
У меня только под NT показывает, под 2K нет.
По-моему, дело не в функции. Просто доступ к метаданным NTFS из-под администратора был возможен только в версиях NT до Win2K. (На sysinternals была утилитка ntfsinfo, посмотри, если её ещё не убрали.)
Можно попробовать, конечно, под Local System, но это .
В любом случае под простым пользователем работать не будет, и, IMHO, и не должно.
Если цель — причинение геморроя на доступ к твоим данным, то можно попробовать использовать следующий факт:
В WinAPI имена файлов — это 0-terminated строки, в Native NT API — строки с явно заданной длиной.
Соответственно, файл с именем типа "\0MyCoolFile" должен быть доступен в NT, но недоступен в Win32.
Ещё можно с POSIX-семантикой позаморачиваться.
PS: Если я ошибаюсь, уважаемые гуру меня поправят.
PPS: А вообще, нужно ли такое причинение геммороев? Может, сама задача неправильно поставлена? Сдаётся мне, что права доступа штатными средствами надо разруливать, если ты, конечно, не вирус пишешь
Здравствуйте, MShura, Вы писали:
MS>Здравствуйте, duke89, Вы писали:
D>>Здравствуйте, MShura, Вы писали:
MS>>>Здравствуйте, duke89, Вы писали:
D>>>>Здравствуйте, MShura, Вы писали:
MS>>>>>>>А вообще-то есть еще одно место, где можно хранить своё. MS>>>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0. MS>>>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
D>>>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.
MS>>>Скачай сорсы MS>>>http://www.sysinternals.com/ntw2k/source/ntfsinfo.shtml
MS>>>Там есть DumpMetaFiles
D>>А может быть такое, что нет метафайла $boot? Что тогда делать? MS>Мета файлы есть всегда, поскольку это часть файловой системы NTFS.
MS>У тебя его утилита показывает DumpMetaFiles? MS>У меня только под NT показывает, под 2K нет.
В том то и дело, что не показывает. Запускаю я её с правами админа под Win ХР
Здравствуйте, SilverCloud, Вы писали:
SC>По-моему, дело не в функции. Просто доступ к метаданным NTFS из-под администратора был возможен только в версиях NT до Win2K. (На sysinternals была утилитка ntfsinfo, посмотри, если её ещё не убрали.)
NTFSINFO я скачал, метадатафайлы не показывает. Что мне делать, если у меня XP?
SC>Можно попробовать, конечно, под Local System, но это . SC>В любом случае под простым пользователем работать не будет, и, IMHO, и не должно.
Под простым пользователем это и не должно работать, по смыслу программы.
SC>Если цель — причинение геморроя на доступ к твоим данным, то можно попробовать использовать следующий факт:
SC>В WinAPI имена файлов — это 0-terminated строки, в Native NT API — строки с явно заданной длиной. SC>Соответственно, файл с именем типа "\0MyCoolFile" должен быть доступен в NT, но недоступен в Win32. SC>Ещё можно с POSIX-семантикой позаморачиваться.
Так я не понял, как мне размеры boot sector узнать? А вообще, не проще ли прочитать первые сектора, найти первые пустые сектора от начала, которые вроде и будут boot, и записать туда все, что я хочу?
SC>PS: Если я ошибаюсь, уважаемые гуру меня поправят. SC>PPS: А вообще, нужно ли такое причинение геммороев? Может, сама задача неправильно поставлена? Сдаётся мне, что права доступа штатными средствами надо разруливать, если ты, конечно, не вирус пишешь
Дело в том, что пишу я что-то вроде защиты от пиратства, и моя цель-доставить пиратам побольше геммороя.
Re[8]: Прямая запись на диск
От:
Аноним
Дата:
06.02.04 06:36
Оценка:
Здравствуйте, MShura, Вы писали:
ВН>>Это, конечно, все очень хорошо, но это — грязный хак. Две таких программы уже не будут корректно работать. ИМХО надо искать какие-то другие способы для решения задачи.
Вопрос может быть идиотский, но все таки, а в свапе нельзя создавать объекты, способные пережить выгрузку программы? Другой вопрос, а разве к файлу может быть соэдан только один поток?
D>Так я не понял, как мне размеры boot sector узнать? А вообще, не проще ли прочитать первые сектора, найти первые пустые сектора от начала, которые вроде и будут boot, и записать туда все, что я хочу?
Я не встречал, ситуаций когда размер данных $Boot меньше 8К, т.е. это 16 секторов.
Размер самого заргузчика обычно 6-8 секторов.
Вижу два пути получения настоящего размер $Boot под Win2K+:
Получить handle на файл (как это делает Руссинович при получении handle на pagefile.sys)
Имея этот handle можно узнать многое.
К сожалению способ получения я видел и понял из IDA только в общих чертах и если понадобится, то повторю, но это приличные затраты времени.
Второй путь — научиться самому находить эту информацию.
Это несложно. http://linux-ntfs.sourceforge.net/ntfs/index.html
Т.е. тебе надо.
— Прочитать первые 512 байт (boot sector)
— Проверить некоторые поля (это NTFS??)
— Взять начало $MFT (в кластерах) из boot sector
— Умножить на размер кластера, прибавить 14 секторов. Это 7 запись (при условии, что размер записи 1024 байт)
— Прочитать 1024 байт (одну запись)
— Найти в этой записи аттрибут данных
— Воспользоваться значением allocated (в данном случае все размеры в этом аттрибуте будут совпадать)
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, MShura, Вы писали:
ВН>>>Это, конечно, все очень хорошо, но это — грязный хак. Две таких программы уже не будут корректно работать. ИМХО надо искать какие-то другие способы для решения задачи.
А>Вопрос может быть идиотский, но все таки, а в свапе нельзя создавать объекты, способные пережить выгрузку программы? Другой вопрос, а разве к файлу может быть соэдан только один поток?
1) в свопе — нельзя
2) потоков — 1 неименованный и сколько угодно именованных
... << RSDN@Home 1.1.3 beta 1 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.