Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Comment extraire un fichier d'un disque dur, bloc par bloc

+3 votes

Ce samedi et dimanche, j'ai bossé sur un script de récupération de données sur disque dur en passant par le numéro d'inode via ls -i, et la récupération du début de bloc via debugfs et stat. avec dd, j'arrive a reconstruire mon fichier, cependant, quand j'essaie de reproduire en python, ça ne fonctionne pas. Je suis resté bloqué une bonne demi journée la dessus, sans succes. j'ai raté un truc ....

big = file('/dev/sda2')
big.seek(17334340)#position du bloc
#big.seek(0)
out = big.read(4096)# taille d'un bloc

final = ''.join([hex(ord(character))[2:].upper().zfill(2) for character in out])
binary_string = binascii.unhexlify(final)

conversion en bin

sortie = open('out.txt','w')
sortie.write(binary_string)
sortie.close()
demandé 16-Mar-2015 par LoLo972
reclassée 16-Mar-2015 par max

quand j'essaye chez moi, j'ai que des 0, ce qui n'est pas très cohérent... tu es sur que la valeur du seek à entrer est bien le numéro d'inode?

c'est pas le numéro de l'inode que je met, mais le numéro de secteur que tu récupéres en faisant :
debugfs sda2
puis :
stat

1 Réponse

+2 votes

Je ne sais pas si c'est exactement ton problème, mais en ouvrant le disque en mode binaire, ça marche.
Disclaimer: je teste ça sous python3.4

Avec dd:

sudo dd if=/dev/sda of=mbr.bin bs=512 count=1

Avec python3.4:

with open('/dev/sda', 'rb') as disk:
    disk.seek(0)
    mbr = disk.read(512)

with open('mbr_with_python.bin', 'wb') as out:
    out.write(mbr)

Et si je compare les 2 fichiers, ils sont bien identique:

diff mbr.bin mbr_with_python.bin

Je suis pas sûr de pas bien comprendre les 2 dernières lignes de ton code. Il semblerait que tu transforme ton buffer binaire en string (représentation hexadécimal), pour après le remettre de nouveau dans un buffer binaire. Est-ce que tu souhaiterais pas utiliser directement le buffer binaire?

Edit: Avec un offset: le fichier mbr.bin a l'inode 4116789, le block c'est le 43372366, la taille du block: 4096, donc comme tu l'as dit en commentaire, il faut multiplier les 2:

block = 43372366
block_size = 4096

with open('/dev/sdc3', 'rb') as disk:
    disk.seek(block * block_size)
    mbr = disk.read(512)

with open('buf_with_python.bin', 'wb') as out:
    out.write(mbr)

Et le diff m'indique bien 2 fichiers identiques:
diff mbr.bin buf.bin

Ou par hexdump:

$ hexdump -C buf.bin 
00000000  fa b8 00 10 8e d0 bc 00  b0 b8 00 00 8e d8 8e c0  |................|
00000010  fb be 00 7c bf 00 06 b9  00 02 f3 a4 ea 21 06 00  |...|.........!..|
00000020  00 be be 07 38 04 75 0b  83 c6 10 81 fe fe 07 75  |....8.u........u|
00000030  f3 eb 16 b4 02 b0 01 bb  00 7c b2 80 8a 74 01 8b  |.........|...t..|
00000040  4c 02 cd 13 ea 00 7c 00  00 eb fe 00 00 00 00 00  |L.....|.........|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001b0  00 00 00 00 00 00 00 00  2e 00 01 00 00 00 00 01  |................|
000001c0  01 00 83 fe ff ff 3f 00  00 00 82 59 70 74 00 00  |......?....Ypt..|
000001d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200

$ hexdump -C mbr.bin 
00000000  fa b8 00 10 8e d0 bc 00  b0 b8 00 00 8e d8 8e c0  |................|
00000010  fb be 00 7c bf 00 06 b9  00 02 f3 a4 ea 21 06 00  |...|.........!..|
00000020  00 be be 07 38 04 75 0b  83 c6 10 81 fe fe 07 75  |....8.u........u|
00000030  f3 eb 16 b4 02 b0 01 bb  00 7c b2 80 8a 74 01 8b  |.........|...t..|
00000040  4c 02 cd 13 ea 00 7c 00  00 eb fe 00 00 00 00 00  |L.....|.........|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001b0  00 00 00 00 00 00 00 00  2e 00 01 00 00 00 00 01  |................|
000001c0  01 00 83 fe ff ff 3f 00  00 00 82 59 70 74 00 00  |......?....Ypt..|
000001d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200
répondu 18-Mar-2015 par bulange (618 points)
edité 20-Mar-2015 par bulange

en fait je n'avais pas compris que :
big.seek(17334340*4096), a multiplier par la taille des blocs.

Il faudrait partir d'un autre endroit que 0, car le probleme viens peut etre de la définition de la position de bloc que je n'ai pas saisi, ensuite, la conversion en string me permettait de regarder la tete du fichier, car si tu n'as que des zeros partout, tu ne montres rien non plus.

J'ai rajouté le bout de code dans la réponse pour que ce soit plus facile pour les suivants de la trouver. :)

...