Как я могу перевернуть один бит в файле?

Я хочу преднамеренно повредить файл, чтобы проверить утверждения о том, что btrfs может излечить себя . В статье рассказывается о том, как отключить файловую систему, повредить фотографию, «перевернув» один бит, а затем перемонтировав ее. В старых файловых системах это было бы просто повреждено, но это должно исправить себя в btrfs. В теории это имеет смысл, но я действительно хочу это проверить.

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

Я должен также указать, что это должно быть сделано в автономной файловой системе, чтобы btrfs не видит мои записи как намеренные.

Редактировать: Хотя вопрос (и обсуждение) много говорит о btrfs, я хотел бы знать, существуют ли независимые от файловой системы методы реализации такого рода повреждения (чтобы его можно было сравнить между различные типы RAID / контроллеры / и т. д.).

35
задан 26 April 2014 в 22:30

5 ответов

Я не эксперт, но пакет btrfs-progs на самом деле включает в себя инструмент, специально предназначенный для этого, хотя вам, возможно, придется строить из исходного кода. В любом случае после установки или сборки btrfs-progs вы сможете использовать инструмент btrfs-corrupt-block, который используется разработчиками btrfs для тестирования файловой системы.

Теперь, как я уже сказал, у меня не было много времени, чтобы поиграться с btrfs, поэтому я не знаю точное использование этого инструмента. Но с его помощью вы сможете повредить автономную файловую систему, которая будет исправлена ​​при чтении поврежденного файла (при условии, что вы установили RAID или что-то еще, чтобы использовать другую копию).

0
ответ дан 26 April 2014 в 22:30
  1. Получить значение одного сектора на блочном устройстве (например, /dev/sda1) со смещением в 1 миллион секторов (просто пример):

    sudo dd if=/dev/sda1 of=/root/mysector bs=512 count=1 skip=1M
    

    Это произвольно выбранное смещение 1M * 512 байт просто для того, чтобы убедиться, что вы находитесь вне части метаданных файловой системы и действительно в секторе, который содержит данные.

  2. Отредактируйте необработанные данные сектора, изменив содержимое с помощью шестнадцатеричного редактора. См., Например, Нужен хороший шестнадцатеричный редактор для Linux .

  3. Верните сектор на диск с обратными аргументами if и of:

    sudo dd if=/root/mysector of=/dev/sda1 bs=512 count=1 seek=1M
    
0
ответ дан 26 April 2014 в 22:30

@ Оли - привет, я Джим Солтер, парень, который действительно написал эту статью. Я работал с виртуальной машиной, которая упростила ситуацию. Я начал с файла JPEG и открыл его в шестнадцатеричном редакторе. В частности, я использовал Bless, который вы можете установить в Ubuntu с помощью простого apt-get install bless .

После открытия JPEG в Bless, я несколько раз пролистал страницу вниз, чтобы разобраться с «мясом» JPEG, а затем просто выделил данные размером около пятидесяти байтов, скопировал и вставил их в текстовый редактор. (в моем случае, gEdit). Это дало мне что-то для поиска.

Теперь я сохранил JPEG в каждом массиве на виртуальной машине. Хранилище за массивами представляло собой серию файлов .qcow2. После того, как я сохранил JPEG в массивы, я мог загрузить файлы .qcow2, связанные с каждым массивом, в Bless и искать их - они были не очень большими, они представляли собой не что иное, как JPEG и некоторые метаданные - для этого пятибайтового шаблона Я выделил и скопировал из JPEG. Вуаля, у меня был блок, чтобы развратить! На этом этапе я мог просто вручную редактировать отдельные байты JPEG, хранящиеся на виртуальном диске виртуальной машины, используя Bless - и, что важно, сделать это в точно так же, как для каждого массива.

Единственная проблема заключается в том, что в случае массива RAID5, протестированного в статье, мне нужно было убедиться, что я отредактировал фактическую копию данных в полосе, а не четность для самой полосы - это была небольшая изображение в другом пустом массиве, поэтому в блоке FOLLOWING на полосе не было никаких данных, поэтому блок четности содержит данные, не измененные из блока данных. Если бы я случайно отредактировал блок четности вместо блока данных, изображение выглядело бы как неизменное.

И последнее замечание - вам НЕ НУЖНЫ виртуальные машины, чтобы делать это - вы можете делать то же самое одинаково с голым металлом; это было бы более болезненно, потому что вам нужно было бы работать с целыми необработанными дисками, а не с хорошими небольшими файлами .qcow2, и вам нужно было бы либо извлекать диски и устанавливать их на другой компьютер, либо загружаться в живую (или просто альтернативную) среду, чтобы связываться с ними. (Я тестировал исцеление данных в ZFS именно таким образом, но на реальных машинах с «голым железом» 7 лет назад, когда я впервые заинтересовался файловыми системами следующего поколения.)

Надеюсь, это поможет!

0
ответ дан 26 April 2014 в 22:30

Вы можете попробовать небольшую программу, которая выполнит FIBMAP ioctl(2) для открытого файла.

Благодаря быстрому поиску в Интернете, я нашел этот пост в блоге http://smackerelofopinion.blogspot.tw/2009/06/fibmap-ioctl-file-system-block-number.html , в котором подробно описывается, как это сделать. это - он даже даст вам ссылку на пример программы, которую вы можете скомпилировать и запустить самостоятельно.

$ git clone git://kernel.ubuntu.com/cking/debug-code
$ cd debug-code/block-mapper-fibmap
$ make
$ sudo ./fibmap /path/to/your/image-file.jpg

Именно так и реализуется hdparm --fibmap (упомянутый @falconer).

После нахождения номеров блоков вы можете использовать dd gongfu для изменения файла, как набросал @gertvdijk. Или, может быть, вы могли бы просто изменить вышеописанную программу fibmap.c, чтобы выполнить переворот, напрямую записывая файл устройства в обход уровня файловой системы (три параметра для программы: 1. путь к файлу, 2. файл устройства содержит файловую систему, 3. смещение и бит, который вы хотите изменить).

( Отказ от ответственности: Я не проверял и не могу гарантировать, что FIBMAP ioctl(2) будет работать для файла в устройстве loopback или файловой системе btrfs, но я бы сильно ожидал, что это так. предположим, что hdparm проверит тип устройства перед выполнением ioctl(2) над файлом и, следовательно, не сможет.)

0
ответ дан 26 April 2014 в 22:30
sudo hdparm --fibmap /PATH/TO/FILE

даст вам LBA, в которых находится файл. После этого вы можете использовать ответ @gertvdijk.

0
ответ дан 26 April 2014 в 22:30

Другие вопросы по тегам:

Похожие вопросы: