web-dev-qa-db-fra.com

Comment puis-je retourner un bit dans un fichier?

Je veux endommager intentionnellement un fichier afin de tester les affirmations selon lesquelles btrfs peut se guérir . L'article parle de supprimer le système de fichiers, d'endommager une photo en "retournant" un bit, puis en le remontant. Dans les systèmes de fichiers plus anciens, cela serait simplement corrompu mais il est supposé se corriger lui-même dans btrfs. En théorie, cela a du sens mais je veux vraiment le tester.

Le problème est que l'article n'explique pas comment faire quoi que ce soit.
Comment pourrais-je modifier un bit dans une partie très spécifique d'un système de fichiers?

Je devrais également souligner que cela doit être effectué sur un système de fichiers hors connexion, de sorte que btrfs ne considère pas mon écriture comme intentionnelle.

Edit: Bien que la question (et la discussion) parle beaucoup de btrfs, j'aimerais savoir s'il existe des méthodes indépendantes du système de fichiers pour implémenter ce type de fichier. corruption (afin qu’il puisse être comparé à travers différents types de RAID/contrôleurs/etc).

35
Oli

Je ne suis pas un expert, mais le package btrfs-progs inclut en fait un outil spécialement conçu à cet effet, même si vous devez créer à partir du source. Dans tous les cas, une fois que vous avez installé ou construit btrfs-progs, vous devriez pouvoir utiliser l'outil btrfs-corrupt-block, qui est utilisé par les développeurs de btrfs pour tester le système de fichiers.

Maintenant, comme je l'ai dit, je n'ai pas eu beaucoup de temps pour jouer avec btrfs, alors je ne connais pas l'utilisation exacte de cet outil. Mais avec cela, vous devriez être capable de corrompre un système de fichiers hors connexion, qui sera corrigé lorsque le fichier corrompu sera lu (en supposant que vous ayez configuré RAID ou quelque chose de telle sorte qu'il y ait une autre copie à utiliser).

20
strugee

@Oli - Salut, je suis Jim Salter, le gars qui a écrit cet article. Je travaillais avec une machine virtuelle, ce qui simplifiait les choses. Ce que j'ai fait est démarré avec un fichier JPEG et ouvert dans un éditeur hexadécimal. Celui que j'ai utilisé était Bless, que vous pouvez installer dans Ubuntu avec un simple apt-get install bless.

Après avoir ouvert le fichier JPEG dans Bless, j’ai jeté plusieurs fois la page vers le bas pour bien entrer dans la "viande" du JPEG, puis je viens de mettre en évidence une cinquantaine de octets de données, que je copiais et collais dans un éditeur de texte (dans mon éditeur de texte). cas, gEdit). Cela m'a donné quelque chose à rechercher.

Maintenant, j'ai enregistré le JPEG dans chaque tableau de la VM. Le stockage derrière les baies était constitué d’une série de fichiers .qcow2. Une fois le fichier JPEG sauvegardé dans les tableaux, je pouvais charger dans Bless les fichiers .qcow2 associés à chaque tableau et les rechercher - ils n'étaient pas très volumineux, n'étant rien d'autre que du JPEG et des métadonnées - pour ce modèle de cinquante octets. J'avais mis en évidence et copié à partir du JPEG. Voilà, j'avais le bloc à corrompre! À ce stade, je pouvais simplement éditer manuellement des octets individuels du fichier JPEG stocké sur le disque virtuel de la machine virtuelle à l’aide de Bless - et, ce qui est important, le faire exactement de la même manière sur chaque tableau.

Le seul inconvénient est que, dans le cas de la matrice RAID5 testée dans l'article, je devais m'assurer que j'avais édité la copie réelle des données de la bande, et non la parité de la bande elle-même - il s'agissait d'une petite image sur une sinon, tableau vide, il n'y a donc aucune donnée dans le bloc FOLLOWING dans la bande, ce qui fait que le bloc de parité contient les données non modifiées du bloc de données. Si j'avais édité accidentellement le bloc de parité au lieu du bloc de données, l'image serait restée inchangée.

Une dernière remarque - vous n’AVEZ PAS BESOIN de machines virtuelles pour le faire - vous pouvez faire la même chose de la même manière avec du métal nu; ce serait simplement plus pénible parce que vous auriez besoin de travailler avec des lecteurs bruts entiers plutôt qu'avec de petits fichiers Nice .qcow2, et vous devrez soit extraire les lecteurs et les mettre dans une machine différente, ou démarrer dans un environnement réel (ou simplement alterner) pour jouer avec eux. (J'ai testé la récupération de données de ZFS exactement de cette manière, mais sur de véritables machines nues, il y a sept ans lorsque je me suis intéressé aux systèmes de fichiers de nouvelle génération.)

J'espère que cela t'aides!

16
Jim Salter
  1. Obtenez la valeur d'un seul secteur sur le périphérique de bloc (par exemple /dev/sda1) avec un décalage de 1 million de secteurs (à titre d'exemple):

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

    Ce décalage de 1M * 512 octets, choisi au hasard, sert simplement à vous assurer que vous n'êtes pas dans la partie métadonnées du système de fichiers et que vous vous trouvez dans un secteur contenant des données.

  2. Éditez les données de secteur brutes en modifiant le contenu avec un éditeur hexadécimal. Voir par exemple Besoin d'un bon éditeur hexadécimal pour Linux .

  3. Remettez le secteur sur le lecteur avec les arguments if et of inversés:

    Sudo dd if=/root/mysector of=/dev/sda1 bs=512 count=1 seek=1M
    
16
gertvdijk

Vous pouvez essayer un petit programme qui effectuera FIBMAPioctl(2) sur le fichier ouvert.

En effectuant une recherche rapide sur le Web, j'ai trouvé cet article de blog http://smackerelofopinion.blogspot.tw/2009/06/fibmap-ioctl-file-system-block-number.html détaillant comment procéder - il vous donnera même un lien vers un exemple de programme que vous pouvez compiler et exécuter vous-même.

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

C'est exactement la façon dont hdparm --fibmap (mentionné par @falconer) est implémenté.

Après avoir trouvé les numéros de bloc, vous pouvez utiliser dd gongfu pour modifier le fichier, comme @gertvdijk. Ou peut-être pourriez-vous simplement modifier le programme fibmap.c ci-dessus pour effectuer le retournement de bit pour vous, en écrivant directement dans le fichier de périphérique en contournant la couche du système de fichiers (trois paramètres du programme: 1. le chemin du fichier, 2. le fichier de périphérique contenant le fichier système de fichiers, 3. décalage et bit que vous souhaitez modifier).

( Clause de non-responsabilité: Je n'ai pas testé et ne peux garantir que le FIBMAPioctl(2) fonctionnera pour un fichier dans le système de bouclage ou le système de fichiers btrfs, mais je m'attendrais fortement Je devine hdparm vérifiera le type de périphérique avant d'exécuter la ioctl(2) sur le fichier et échoue donc.)

4
FooF
Sudo hdparm --fibmap /PATH/TO/FILE

vous donnera les LBA où se trouve le fichier. Après cela, vous pouvez utiliser la réponse de @gertvdijk.

3
falconer