Wie kann ich ein einzelnes Bit in einer Datei spiegeln?

35

Ich möchte eine Datei absichtlich beschädigen, um die Behauptungen zu testen , dass btrfs sich selbst heilen kann . In dem Artikel geht es darum, das Dateisystem zu entfernen, ein Foto zu beschädigen, indem ein einzelnes Bit "umgedreht" und dann wieder angehängt wird. In älteren Dateisystemen wäre dies nur beschädigt, aber es soll sich in btrfs selbst beheben. Theoretisch ist das sinnvoll, aber ich möchte es unbedingt testen.

Das Problem ist, dass der Artikel nicht erklärt, wie man das macht.
Wie gehe ich vor, um ein einzelnes Bit in einem bestimmten Teil eines Dateisystems zu ändern?

Ich möchte auch darauf hinweisen , dass dies muss auf einem Offline - Dateisystem durchgeführt werden , so dass Btrfs nicht meine Schreib als intentionale sehen.

Bearbeiten: Während die Frage (und Diskussion) viel über btrfs spricht, würde ich gerne wissen, ob es dateisystemunabhängige Methoden gibt, um diese Art von Beschädigung zu implementieren (damit sie über verschiedene RAID-Typen / Controller / usw. hinweg verglichen werden können).

Oli
quelle
@Dan Ich meine, wenn ich die Datei direkt bearbeite, würde btrfs (oder ein anderes Dateisystem) dies als gültigen Schreibzugriff betrachten. Es würde nicht die Korruption geben, die ich suche.
Oli
Handelt es sich um ein Test-Dateisystem (dh Sie interessieren sich nicht für den Inhalt oder sind in Ordnung für die Wiederherstellung von einem Backup). Verwenden Sie auch eine einzelne btrfs-Partition auf einem einzelnen Laufwerk oder eine einzelne Partition auf einem RAID-Array , oder eine andere Konfiguration?
Darth Android
1
Wenn btrfs die richtigen Ioctls unterstützt (nicht sicher, ob dies der Fall ist), können Sie mithilfe filefrag -vvon herausfinden, wo sich eine Datei genau befindet.
Derobert
3
@Oli Ich vermute, dass Sie auf U & L ein interessierteres Publikum finden würden, sowohl in Bezug auf die Stimmen als auch in Bezug auf die Antworten. Plus, das .
Strugee
1
Schießen Sie einen kosmischen Strahl genau an der richtigen Stelle.
smcg

Antworten:

20

Ich bin kein Experte, aber das btrfs-progsPaket enthält tatsächlich ein spezielles Tool, obwohl Sie möglicherweise aus dem Quellcode erstellen müssen. In jedem Fall sollten Sie nach der Installation oder Erstellung btrfs-progsdas Tool verwenden können btrfs-corrupt-block, das von den btrfs-Entwicklern zum Testen des Dateisystems verwendet wird.

Wie ich bereits sagte, hatte ich nicht viel Zeit, um mit btrfs herumzuspielen, daher kenne ich die genaue Verwendung dieses Tools nicht. Damit sollten Sie jedoch in der Lage sein, ein Offlinedateisystem zu beschädigen, das beim Lesen der beschädigten Datei behoben wird (vorausgesetzt, Sie haben RAID oder etwas anderes eingerichtet, damit eine andere Kopie verwendet werden kann).

strugee
quelle
2
Super Fund! Vorausgesetzt, dass dies btrfs-corrupt-blocktatsächlich ein echter Test und kein "Trick" der btrfs-Entwickler ist, sollte dies genau in die Rechnung passen.
allquixotic
@allquixotic Wenn Sie mehr über BTRFS erfahren möchten, gibt es einen tollen Vortrag von linux.conf.au 2012 . Wie ich schon sagte, btrfs-corrupt-blockwird von den Entwicklern verwendet, also wäre es nicht sehr nützlich, wenn es ein Trick wäre :)
strugee
3
@allquixotic Das ist das Schöne an Open Source: Sie können sich den Quellcode von btrfs ansehen und ihn überprüfen! Sicher, das wird keine leichte Aufgabe sein, aber wenn Sie wirklich wollen, können Sie das tun.
Bakuriu
@ Bakuriu Ich bin mir dessen voll bewusst. Ich habe nie ernsthaft daran gezweifelt, dass dies btrfs-corrupt-blockkein aufrichtiger Test ist, da dies sehr schnell von jemandem herausgefunden werden würde, der an der Quelle herumstochert und als negative PR gegen Oracle verwendet wird (zumindest; ebenso wie alle anderen BTRFS-Entwickler / Mitwirkenden). Es war nur ein kurzer Kommentar.
allquixotic
Ich frage mich, ob das OP (@Oli) einen Block (dh die Dateisystemstruktur) oder eine Datei (dh den Inhalt einer Datei?) Beschädigen möchte Ersteres, nicht Letzteres? [Wie würde ein Dateisystem wissen, welches Bit in einer Datei gespiegelt wurde? eine Art CRC?]. Diese Antwort ist wahrscheinlich in der richtigen, also +1. [aber es kann mehr als ein "einzelnes Bit" ändern? oder etwas ändern, das leichter geheilt werden kann als ein zufälliges Ereignis "überall"?]
Olivier Dulac
16
  1. Ermitteln Sie den Wert eines einzelnen Sektors auf dem Blockgerät (z. B. /dev/sda1) mit einem Versatz von 1 Million Sektoren (nur ein Beispiel):

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

    Dieser willkürlich gewählte Versatz von 1M * 512 Bytes soll nur sicherstellen, dass Sie sich nicht im Metadatenteil des Dateisystems befinden und sich tatsächlich in einem Sektor befinden, der Daten enthält.

  2. Bearbeiten Sie die Rohdaten des Sektors, indem Sie den Inhalt mit einem Hex-Editor ändern. Siehe zum Beispiel Brauchen Sie einen guten Hex-Editor für Linux .

  3. Setzen Sie den Sektor mit den umgekehrten Argumenten ifund wieder auf das Laufwerk of:

    sudo dd if=/root/mysector of=/dev/sda1 bs=512 count=1 seek=1M
    
gertvdijk
quelle
2
Dies hilft ihm nicht beim Testen, es sei denn, der 1-millionste Block ist tatsächlich Teil einer Datei. Wie kann er nachsehen, auf welchem ​​Block eine bestimmte Datei beginnt?
Darth Android
3
Das ist so fast da. Wenn Sie den Befehl dd auf die genaue Position der Datei festlegen können, ist dies wahrscheinlich der beste Weg, dies zu erreichen.
Oli
@Oli Ja, ich weiß, wie man das für die Ext-Familie von Dateisystemen macht, aber ich habe nicht so viel Erfahrung mit btrfs. Lassen Sie mich sehen, ob ich einen Weg finden kann.
Gertvdijk
2
@Oli: Sie können einfach eine Schleife haben, die Block für Block ausgegeben wird (dh wie oben, aber "skip = N", wobei N in 1..max ist), bis Sie eine Zeile aus der zu bearbeitenden Datei abrufen können [Versuchen Sie, eine Zeile zu generieren, die sonst nirgendwo vorkommt ... zum Beispiel aus einem Passwortgenerator und lange genug?]. Dann bearbeiten Sie diesen bestimmten Block. erneut einhängen, testen, ob die Änderung zurückgesetzt wurde (was ich bezweifle, siehe mein Kommentar in der oberen Antwort ... Es scheint eine Verwechslung zwischen Dateidaten (= Inhalt) und der Dateisystemstruktur selbst (= wie Dateien und deren Inhalt organisiert sind) zu geben )?)
Olivier Dulac
16

@Oli - hi, ich bin Jim Salter, der Typ, der den Artikel tatsächlich geschrieben hat. Ich arbeitete mit einer virtuellen Maschine, was die Sache einfacher machte. Ich habe mit einer JPEG-Datei begonnen und sie in einem Hex-Editor geöffnet. Das besondere, das ich verwendet habe, war Bless, das Sie in Ubuntu mit einem einfachen apt-get install bless installieren können .

Nachdem ich das JPEG in Bless geöffnet hatte, blätterte ich ein paar Mal nach unten, um mich mit dem "Fleisch" des JPEG vertraut zu machen. Dann wurden nur Daten im Wert von etwa fünfzig Bytes hervorgehoben und kopiert und in einen Texteditor eingefügt (in meinem Fall gEdit). Das gab mir etwas zu suchen.

Jetzt habe ich das JPEG in jedem Array auf der VM gespeichert. Der Speicher hinter den Arrays bestand aus einer Reihe von .qcow2-Dateien. Sobald ich das JPEG in den Arrays gespeichert hatte, konnte ich die mit jedem Array verknüpften .qcow2-Dateien in Bless laden und sie - sie waren nicht sehr groß, da es sich nur um das JPEG und einige Metadaten handelte - nach diesem 50-Byte-Muster durchsuchen Ich hatte aus dem JPEG hervorgehoben und kopiert. Voila, ich hatte den Block zu korrumpieren! Zu diesem Zeitpunkt konnte ich einzelne Bytes des JPEGs, wie sie auf der virtuellen Festplatte der VM gespeichert sind, mit Bless manuell bearbeiten - und zwar auf genau dieselbe Weise für jedes Array.

Der einzige Nachteil ist, dass ich bei dem im Artikel getesteten RAID5-Array sicherstellen musste, dass ich die tatsächliche Kopie der Daten im Streifen bearbeitet habe und nicht die Parität für den Streifen selbst - es war ein kleines Bild auf einem Andernfalls ist das Array leer, sodass im FOLLOWING-Block im Stripe keine Daten vorhanden sind, sodass der Paritätsblock die Daten enthält, die nicht vom Datenblock geändert wurden. Wenn ich versehentlich den Paritätsblock anstelle des Datenblocks bearbeitet hätte, wäre das Bild unverändert angezeigt worden.

Eine letzte Anmerkung: Sie BRAUCHEN keine virtuellen Maschinen, um dies zu tun. Mit Bare Metal können Sie die gleichen Dinge auf die gleiche Weise tun. Es wäre nur eine größere Belastung, weil Sie mit ganzen Raw-Laufwerken anstatt mit netten kleinen .qcow2-Dateien arbeiten müssten und entweder die Laufwerke ziehen und sie in einen anderen Computer stecken müssten, oder Starten Sie eine Live-Umgebung (oder eine alternative Umgebung), um sich mit ihnen herumzuschlagen. (Ich habe das Heilen von ZFS-Daten genau auf diese Weise getestet, aber auf echten Bare-Metal-Rechnern vor sieben Jahren, als ich mich zum ersten Mal für Dateisysteme der nächsten Generation interessierte.)

Hoffe das hilft!

Jim Salter
quelle
4

Sie könnten ein kleines Programm ausprobieren, das mit der geöffneten Datei funktioniert.FIBMAP ioctl(2)

Durch schnelle Websuche fand ich diesen Blog-Beitrag http://smackerelofopinion.blogspot.tw/2009/06/fibmap-ioctl-file-system-block-number.html , der genau beschreibt, wie das geht - es wird sogar einen Link geben zu einem Beispielprogramm, das Sie selbst kompilieren und ausführen können.

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

Genau so wird hdparm --fibmap(von @falconer erwähnt) implementiert.

Nachdem Sie die Blocknummern gefunden haben, können Sie dddie Datei mit Gongfu ändern, wie in @gertvdijk skizziert. Oder Sie können das fibmap.cobige Programm einfach ändern , um die Bitumkehrung für Sie durchzuführen, indem Sie direkt in die Gerätedatei schreiben und dabei die Dateisystemschicht umgehen (drei Parameter für das Programm: 1. den Pfad zur Datei, 2. die Gerätedatei, die die Datei enthält System, 3. Offset und Bit, die Sie ändern möchten).

( Disclaimer: Ich habe nicht getestet und kann nicht garantiert werden, dass die FIBMAP ioctl(2)für eine Datei im Loopback - Device oder Btrfs - Dateisystem arbeiten, aber ich würde es tut stark erwarte ich bin. Erraten hdparm des Gerätetyp überprüfen , bevor die Durchführung ioctl(2)auf der Datei und ist daher Versagen.)

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

gibt Ihnen die LBAs, in denen sich die Datei befindet. Danach können Sie die Antwort von @gertvdijk verwenden.

Falkner
quelle
Leider scheint dies nicht zu funktionieren. Es spuckt a aus. 0,39: device not found in /devEntweder weil es btrfs ist oder (wahrscheinlicher) weil ich es für Loopback-Dateien verwende. Ich werde versuchen, dies mit einer "richtigen" VM zu erledigen.
Oli
@Oli Hmm. Ich dachte, das hdparmfunktioniert auf jedem Dateisystem, aber vielleicht ist es nicht so.
Falkner