ファイル内の1ビットをフリップするにはどうすればよいですか?


35

btrfsがそれ自体を癒すことができるという主張をテストするために、意図的にファイルを損傷したいと思います。この記事では、ファイルシステムを削除し、1ビットを「反転」して写真を損傷し、再マウントすることについて説明しています。古いファイルシステムでは、これは単に破損しますが、btrfsでそれ自体を修正することになっています。理論的には、これは理にかなっていますが、実際にテストしたいと思います。

問題は、その記事でその方法を説明ていないことです。
ファイルシステムの非常に特定の部分で単一のビットを変更するにはどうすればよいですか?

また、これ、btrfsが私の書き込みを意図的なものと見なさないように、オフラインファイルシステムで実行する必要があることを指摘する必要あります。

編集:質問(および議論)ではbtrfsについて多くのことを話しますが、この種の破損を実装するファイルシステムに依存しない方法があるかどうかを知りたいです(異なるRAIDタイプ/コントローラー/などで比較できるように)。


@Danファイルを直接編集すると、btrfs(またはその点で任意のファイルシステム)はそれを有効な書き込みとしてカウントします。それは私が探している汚職を与えないでしょう。
オリ

これはテストファイルシステムですか(つまり、内容を気にしないか、バックアップから復元しても問題ありませんか?また、単一のドライブで単一のbtrfsパーティションを使用していますか、それともRAIDアレイの上部に単一のパーティションを使用していますか、またはその他の構成?
ダースAndroid 14年

1
btrfsが正しいioctlをサポートしている場合(サポートしているかどうかはfilefrag -vわかりません)、ファイルの場所を正確に見つけるために使用できます。
デロバート14年

3
@Oli私は、投票と回答の両方の面で、あなたがU&Lにより興味のある聴衆を見つけると思います。プラス、これ
strugee

1
ちょうど良い場所で宇宙線を撃ちます。
smcg 14年

回答:


20

私は専門家ではありませんが、btrfs-progsパッケージには実際にこれを行うためのツールが含まれていますが、ソースからビルドする必要があります。いずれの場合でも、インストールまたはビルドbtrfs-progsしたらbtrfs-corrupt-block、btrfs開発者がファイルシステムをテストするために使用するツールを使用できます。

さて、私が言ったように、btrfsをいじる時間はあまりないので、このツールの正確な使用法はわかりません。しかし、それを使用すると、オフラインファイルシステムを破損できるはずです。これは、破損したファイルが読み取られると修正されます(使用する別のコピーがあるようにRAIDまたは何かをセットアップしたと仮定します)。


2
素晴らしい発見!それbtrfs-corrupt-blockが実際に本物のテストであり、btrfs開発者による「トリック」ではないと書かれていると仮定すると、これは法案にぴったり合うはずです。
allquixotic

@allquixotic btrfsの詳細を知りたい場合は、linux.conf.au 2012から素晴らしい講演があります。私が言ったようにbtrfs-corrupt-block、開発者によって使用されているので、それがトリックだった場合、それはあまり役に立ちません:)
strugee 14年

3
@allquixoticこれはオープンソースの美しさです。btrfsのソースコードを見て、チェックすることができます!確かに、これは簡単な作業ではありません、本当にやりたい場合は、それ行うことができます。
バクリウ14年

@Bakuriu私はそれを完全に知っています。それbtrfs-corrupt-blockは誠実なテストではないことを真剣に疑ったことはありません。ソースを突っ込んでいる人によって非常に迅速に発見され、Oracleに対する否定的なPRとして使用されるためです(少なくとも、他のbtrfs開発者/貢献者と同様)。それはただのコメントです。
allquixotic

OP(@Oli)がブロック(つまり、ファイルシステム構造)またはファイル(つまり、ファイルのコンテンツ?)を破壊したいのだろうか...そして、自己修復のbtrfs主張は、前者であり、後者ではありませんか?[ファイルシステムは、どのビットがファイルで反転されたかをどのようにして知るのでしょうか?何らかのCRC?]。ただし、この答えはおそらく右側にあるため、+ 1です。[しかし、それは「単一ビット」以上に変化するかもしれない?または、「どこでも」発生するランダムなビットよりも簡単に治癒できるものを変更しますか?]
オリビエデュラック14年

16
  1. ブロックデバイス上の単一セクターの値を取得します(例:/dev/sda1100万セクターオフセットのオフセット(例))。

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

    この任意に選択された1M * 512バイトのオフセットは、ファイルシステムのメタデータ部分から出て、実際にデータを含むセクターにいることを確認するためのものです。

  2. 16進エディターでコンテンツを変更して、未加工のセクターデータを編集します。たとえば、Linux用の優れた16進エディタが必要です。を参照してください。

  3. ドライブ上のセクターを元に戻しifof引数を逆:

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

2
100万番目のブロックが実際にファイルの一部でない限り、これは彼のテストに役立ちません。特定のファイルがどのブロックで始まるかをどのようにして調べることができますか?
ダースアンドロイド14年

3
それがありますので、ほとんどが。ファイルの正確な位置にddコマンドをロックできる場合、これはおそらくこれにアプローチする最良の方法です。
オリ

@Oliはい、Ext-familyのファイルシステムでそれを行う方法は知っていますが、btrfsの経験はあまりありません。方法を見つけることができるかどうか見てみましょう。
gertvdijk 14年

2
@Oli:ループを作成し、編集したいファイルの行をgrepできるようになるまで、ブロックごとにddを吐き出すことができます(つまり、上記のように「skip = N」、Nは1..maxになります)。 [他では発生しない行を生成してみてください。たとえば、パスワードジェネレータから取得し、十分な長さですか?]。次に、その特定のブロックを編集します。再マウントし、変更が元に戻されたかどうかをテストします(疑い、一番上の答えに私のコメントを参照してください...ファイルデータ(=コンテンツ)とファイルシステム構造自体(=ファイルとそのコンテンツの編成方法に混乱があるようです) )?)
オリビエデュラック14年

16

@Oli-こんにちは、私は実際にその記事を書いたジム・ソルターです。私は仮想マシンで作業していたので、物事が簡単になりました。私がやったことは、JPEGファイルで開始し、16進エディターでそれを開いた。私が使用したのはBlessで、これは単純なapt-get install blessでUbuntuにインストールできます。

BlessでJPEGを開いた後、ページを数回押し下げてJPEGの「肉」にうまく入り込み、約50バイト分のデータを強調表示して、テキストエディターにコピーアンドペーストしました(私のケース、gEdit)。これは私に何かを探してくれました。

ここで、VMの各アレイにJPEGを保存しました。アレイの背後のストレージは、一連の.qcow2ファイルでした。JPEGをアレイに保存したら、各アレイに関連付けられた.qcow2ファイルをBlessにロードし、それらを検索できます-それらは50バイトパターンのJPEGといくつかのメタデータ以外の非常に大きくはありませんでした強調表示してJPEGからコピーしました。出来上がり、私はブロックが破損しました!この時点で、Blessを使用してVMの仮想ディスクに保存されているJPEGの個々のバイトを手動で編集できました。そして、重要なこととして、まったく同じ方法で編集できました。各アレイ。

唯一の欠点は、記事でテストしたRAID5アレイの場合、ストライプ自体のパリティではなく、ストライプ内のデータの実際のコピーを編集することを確認する必要があったということです。それ以外の場合は空の配列であるため、ストライプのFOLLOWINGブロックにはデータがなく、パリティブロックにはデータブロックから変更されていないデータが含まれます。データブロックではなくパリティブロックを誤って編集した場合、イメージは変更されていないように見えます。

最後の注意点-これを行うために仮想マシンを必要としない-ベアメタルで同じことを同じ方法で行うことができます。素敵な小さな.qcow2ファイルではなくrawドライブ全体で作業する必要があり、ドライブを引き出して別のマシンに配置する必要があるため、お尻が痛くなるだけです。ライブ(または単なる代替)環境を起動して、それらをいじります。(私はZFSのデータヒーリングをまさにこの方法でテストしましたが、実際のベアメタルマシンでは、7年ほど前に初めて次世代のファイルシステムに興味を持ちました。)

お役に立てれば!


4

開いたファイルで実行する小さなプログラムを試すことができます。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、@ gertvdijkがスケッチしたように、gongfuを使用してファイルを変更できます。または、単に変更することができますfibmap.c上記プログラムをしてビットフリップを行い、ファイルシステムレイヤーをバイパスしてデバイスファイルに直接書き込むこともできます(プログラムの3つのパラメーター:1.ファイルへのパス、2。ファイルを含むデバイスファイルシステム、3。修正したいオフセットとビット)。

免責事項:私はテストしていないと保証できないことをFIBMAP ioctl(2)ループバックデバイスまたはのbtrfsファイルシステム内のファイルのために働くだろうが、私は強く、それがない期待する私は。推測 hdparm実行する前に、デバイスの種類をチェックしioctl(2)、ファイルの上に、したがってあります失敗します。)


3
sudo hdparm --fibmap /PATH/TO/FILE

ファイルが置かれているLBAを提供します。この後、@ gertvdijkの答えを使用できます。


残念ながら、これはうまくいかないようです。それは、0,39: device not found in /devそれがbtrfsであるか、(おそらく)ループバックで保持されたファイルで使用しているためです。「適切な」VMでこれを実行してみます。
オリ

@Oliうーん。私はそれhdparmがすべてのファイルシステムで動作すると思ったが、そうではないかもしれない。
鷹匠14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.