#1 Le 20/04/2020, à 22:58
- Nuliel
[Résolu] extraire des données en bash depuis la MFT
Bonjour,
Dans le but de sortir rapidement des données d'une partition ntfs en mauvais état mais dont la MFT est bonne, j'ai passé cette commande pour créer la structure des dossiers:
grep '/Users/Utilisateur' analyseMFT.csv | grep '"Folder"' | cut -d , -f 8 | xargs -I % mkdir -p ${PWD}%
Ca fonctionne, mais je ne trouve pas ma commande propre. Comment faire cela plus proprement?
Les données qui rentrent sont de ce type:
"33668","Good","Active","Folder","96","18257","61","/Users/Utilisateur/Documents/","2019-01-12 14:23:52.880075","2019-01-12 14:40:24.398773","2019-01-12 14:40:24.398773","2019-01-16 18:16:10.299175","2019-01-12 14:23:52.880075","2019-01-12 14:23:52.880075","2019-01-12 14:23:52.880075","2019-01-12 14:23:52.880075","f4a15d42-165d-11e9-9c42-48e2444e4ab4","00000090-0058-0000-0004-180000000900","00000038-0020-0000-2400-490033003000","00000030-0001-0000-0010-000001000000","Diagramme avec W","2019-01-12 14:23:52.880075","2019-01-12 14:23:52.880075","2019-01-12 14:23:52.880075","2019-01-12 14:23:52.880075","","","","","","","","","","","True","False","True","True","False","False","False","True","True","True","False","False","False","False","False","","N","N","N","N","N"
Je n'arrive pas à faire une commande pour extraire des fichiers avec icat. Voici ma commande qui ne fonctionne pas:
grep '/Users/Utilisateur' analyseMFT.csv | grep '"File"' | cut -d , -f 1,8 | xargs -p -I % icat MFT ${echo -ne % | cut -d'"' -f 2} > $PWD${echo -ne % | cut -d'"' -f 4}
Elle est encore plus crade que l'autre
Voici un exemple de donnée en entrée:
"7747","Good","Active","File","2","6410","2","/Users/Utilisateur/AppData/Local/Packages/unfichier.truc","2016-05-20 17:56:43.087397","2016-07-16 11:42:41.702545","2016-05-20 17:56:43.087397","2017-01-08 13:08:54.037004","2016-05-20 17:56:43.087397","2016-05-20 17:56:43.087397","2016-05-20 17:56:43.087397","2016-05-20 17:56:43.087397","","","","","Classic_{EF462183-352B-4DCF-811C-07FA7CFCD5AC}.settingcontent-ms","2016-05-20 17:56:43.087397","2016-05-20 17:56:43.087397","2016-05-20 17:56:43.087397","2016-05-20 17:56:43.087397","","","","","","","","","","","True","False","True","False","False","False","False","False","False","False","False","False","False","False","False","","N","N","N","N","N"
Je pense que le problème est que ${} il me semble est exécuté dans un sous shell, mais j'aimerais bien que % soit remplacé.
Sinon j'ai aussi essayé:
grep '/Users/Utilisateur' analyseMFT.csv | grep '"File"' | cut -d , -f 1,8 | xargs -p -I % sh -c 'record=${cut -d'"' -f 2 < %};filename=${cut -d'"' -f 4 < %};icat MFT $record > $filename'
mais cela ne fonctionne pas non plus.
Merci d'avance,
Naziel
Dernière modification par Nuliel (Le 21/04/2020, à 18:33)
Hors ligne
#2 Le 20/04/2020, à 23:12
- Watael
Re : [Résolu] extraire des données en bash depuis la MFT
salut,
${} est un Remplacement de paramètres; il n'y a pas d'exécution, et pas de sous-shell, donc.
tu vas trop vite.
on reprend :
tu as un (un seul ?) ficher csv - quelle est son contenu ?
tu veux récupérer des champs, et exécuter des commandes différentes sur le 8° champ selon que le 4° champ est "Folder" ou "File"
c'est un travail pour awk, mais il faudrait être plus précis sur ce que tu veux.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#3 Le 21/04/2020, à 08:46
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Merci watael.
J'ai un seul fichier csv qui s'appelle analyseMFT.csv
Ce fichier contient toutes les entrées de la MFT sous la forme:
"record",2 champs inutiles,"Type",3 champs inutiles,"chemin",Plein d'autres champs inutiles
record est un nombre (une sorte d'inode à la windows), type est soit égal à "Folder", soit égal à "File", et chemin est le chemin absolu vers le fichier ou le dossier (selon le type défini précédemment)
icat (programme venant de sleuthkit) permet d'extraire un fichier à partir de son record et de la partition ntfs (ou d'un fichier normal représentant une partition ntfs)
Il se lance sous la forme:
icat partition record
Par exemple
icat /dev/sdb3 45
On peut enregistrer un fichier en redirigeant la sortie.
La première commande a pour but de recréer l'arborescence du dossier /Users/Utilisateur (donc on ne considère dans analyseMFT.csv que les dossiers et on crée les dossiers en respectant l'arborescence)
La deuxième commande a pour but d'extraire chaque fichier avec icat et l'enregistrer au bon endroit dans l'arborescence nouvellement créée.
Pour la deuxième commande, comme j'ai deux infos dans chaque ligne (record et chemin), j'ai joué avec cut pour récupérer une info puis une autre mais c'est ni propre ni fonctionnel.
Dernière modification par Nuliel (Le 21/04/2020, à 08:49)
Hors ligne
#4 Le 21/04/2020, à 11:50
- kamaris
Re : [Résolu] extraire des données en bash depuis la MFT
Ça ne me semble pas aberrant de séparer la création de l’arborescence de l'écriture dans les fichiers, avec deux commandes séparées.
Pour l'arborescence, tu peux faire ça :
awk -F'"|","' '/\/Users\/Utilisateur/ && /"Folder"/{print ENVIRON["PWD"] $9 }' analyseMFT.csv | xargs -d'\n' mkdir -vp
Pour l'écriture dans les fichiers, je ne comprends pas pourquoi tu mets cut -d'"' -f 4 à la fin, s'il s'agit de récupérer le nom du fichier dans lequel écrire.
Voici en tout cas une manière de faire « sans sortir » de awk :
awk -F'"|","' '/\/Users\/Utilisateur/ && /"File"/{system("icat MFT " $2 " > \"" ENVIRON["PWD"] $9 "\"")}' analyseMFT.csv
Pour voir si la commande qui va être exécutée depuis awk te convient, tu peux remplacer system() par print pour l'afficher :
awk -F'"|","' '/\/Users\/Utilisateur/ && /"File"/{print "icat MFT " $2 " > \"" ENVIRON["PWD"] $9 "\""}' analyseMFT.csv
Hors ligne
#5 Le 21/04/2020, à 12:36
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Merci kamaris.
En fait j'ai fait $PWD${echo -ne % | cut -d'"' -f 4} car j'ai
"7747","/Users/Utilisateur/AppData/Local/Packages/unfichier.truc"
comme entrée (grâce à cut -d , -f 1,8 ) donc en prenant " comme séparateur, la 4eme colonne est le chemin du fichier.
Quand je disais que c'était crade
Je vais tester tes commandes.
Petite précision: il faut remplacer MFT par /dev/sdb3 (je voulais pas faire de bêtises sur mon disque dur de copie, donc j'ai fait des essais sur le premier fichier qui m'est tombé sous la main et j'ai oublié de corriger la commande ici)
Dernière modification par Nuliel (Le 21/04/2020, à 12:37)
Hors ligne
#6 Le 21/04/2020, à 13:06
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Alors je viens de tester, la commande pour créer les dossiers fonctionne bien.
Pourrais tu m'expliquer la commande qui extrait les fichiers?
Est-ce que les messages d'erreur de icat seront aussi affichées s'il y en a?
awk fait il le travail séquentiellement (lit la ligne 1, extrait le fichier 1, puis passe à la ligne 2 puis extrait le fichier 2, ...) ou en parallèle? En fait j'ai presque tous les fichiers qui sont illisibles (sûrement dû à la copie partielle)
En remplaçant par print les redirections contiennent des guillemets doubles (du type > "mon chemin" ). C'est pas grave? (je pense pas mais dans le doute)
J'attends de voir mais la commande n'est pas encore finie (parce qu'il y a visiblement pas mal de trucs à récupérer)
Edit: j'ai oublié un petit truc de grande importance: je viens de blinder au max mon disque dur de 320 Go... Donc la commande ne s'est pas bien exécutée.
Dernière modification par Nuliel (Le 21/04/2020, à 13:53)
Hors ligne
#7 Le 21/04/2020, à 14:46
- Watael
Re : [Résolu] extraire des données en bash depuis la MFT
pour la deuxième commande, je n'aurais pas utilisé system()*; j'aurais simplement passé la sortie (une fois validée) à xargs.
--
* c'est dans ma tête : question de "symétrie"...
et puis je n'aime pas system().
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#8 Le 21/04/2020, à 15:40
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
J'ai en tout 63147 fichiers à récupérer, entre system() et xargs l'un des deux est il plus rapide?
Peux tu indiquer la version xargs? (je ne maitrise pas du tout awk)
J'ai pu récupérer deux trois trucs, mais la majeure partie est corrompue.
Mais je crois qu'il va falloir que je fasse un programme pour vérifier que le fichier peut être extrait (en fait, j'espérais pouvoir récupérer rapidement et facilement la plupart des fichiers avec un one liner en bash, mais comme j'ai une copie partielle du disque dur en mauvais état, il faut que je continue la copie avec en priorité les secteurs contenant des données)
Merci beaucoup à vous deux.
Hors ligne
#9 Le 21/04/2020, à 15:56
- kamaris
Re : [Résolu] extraire des données en bash depuis la MFT
En fait j'ai fait $PWD${echo -ne % | cut -d'"' -f 4} car j'ai
"7747","/Users/Utilisateur/AppData/Local/Packages/unfichier.truc"
comme entrée (grâce à cut -d , -f 1,8 ) donc en prenant " comme séparateur, la 4eme colonne est le chemin du fichier.
Mais oui, bien sûr : j'ai confondu -f 1,8 et -f 1-8 à la lecture, d'où ma question
Pourrais tu m'expliquer la commande qui extrait les fichiers?
Est-ce que les messages d'erreur de icat seront aussi affichées s'il y en a?
awk fait il le travail séquentiellement (lit la ligne 1, extrait le fichier 1, puis passe à la ligne 2 puis extrait le fichier 2, ...) ou en parallèle? En fait j'ai presque tous les fichiers qui sont illisibles (sûrement dû à la copie partielle)
En remplaçant par print les redirections contiennent des guillemets doubles (du type > "mon chemin" ). C'est pas grave? (je pense pas mais dans le doute)
awk va simplement appeler un shell pour exécuter la commande qui se trouve dans system().
Donc oui, les messages d'erreur de icat s'afficheront, de la même manière que si tu faisais
sh -c 'icat MFT 7747 > "/home/user/Users/Utilisateur/AppData/Local/Packages/unfichier.truc"'
depuis le shell courant.
Cet appel va être réalisé à chaque ligne de analyseMFT.csv satisfaisant les critères qui précèdent, séquentiellement.
Les guillemets sont voulus, pour protéger les noms de fichiers dans le contexte du shell appelé par system().
Edit: j'ai oublié un petit truc de grande importance: je viens de blinder au max mon disque dur de 320 Go... Donc la commande ne s'est pas bien exécutée.
Mais sinon, elle fonctionne comme voulu ?
pour la deuxième commande, je n'aurais pas utilisé system()*; j'aurais simplement passé la sortie (une fois validée) à xargs.
--
* c'est dans ma tête : question de "symétrie"...
et puis je n'aime pas system().
Pour la première commande, il y a un traitement possible par lot, mais pas (aussi naturellement) pour la deuxième, d'où la séparation des deux pour moi.
Quant à system(), je trouve que dans ce genre de cas c'est pas mal, mais c'est vrai qu'il ne faut pas en abuser (notamment à cause du code retour qui peut être piégeux).
J'ai en tout 63147 fichiers à récupérer, entre system() et xargs l'un des deux est il plus rapide?
À priori je dirais non.
Ce qui serait plus rapide, ce serait de paralléliser (au moins partiellement) les appels de icat, mais ça me semble être autre chose…
Hors ligne
#10 Le 21/04/2020, à 16:30
- kamaris
Re : [Résolu] extraire des données en bash depuis la MFT
Tu peux essayer ça pour paralléliser les appels de icat :
awk -F'"|","' '/\/Users\/Utilisateur/ && /"File"/{print "icat /dev/sdb3 " $2 " > \"" ENVIRON["PWD"] $9 "\""}' analyseMFT.csv | xargs -d'\n' -L10 bash -c 'while (($#)); do sh -c "$1" & shift; done; wait' _
Le nombre de processus lancés en parallèle se gère au niveau du -L10.
NB : ne pas oublier le underscore final (c'est le nom du mini-script, i.e. $0).
Dernière modification par kamaris (Le 21/04/2020, à 18:58)
Hors ligne
#11 Le 21/04/2020, à 17:02
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Visiblement la commande que tu as proposé fonctionne bien, c'est juste que j'ai manqué de place, donc je n'ai pas pu vérifier à la fin mais la commande a pu extraire des fichiers valides (principalement des photos), il faut que je lance la commande sur un autre dd qui a plus de place. Effectivement les guillemets dans la redirection sont utiles, certains chemins contiennent des espaces.
Nickel pour la parallélisation. Faut vraiment que j'apprenne à utiliser awk!
Dernière modification par Nuliel (Le 21/04/2020, à 17:02)
Hors ligne
#12 Le 21/04/2020, à 18:16
- kamaris
Re : [Résolu] extraire des données en bash depuis la MFT
Pour la parallélisation, c'est à tester.
J'ai tendance à croire qu'en en lançant quelques-uns (peut-être moins que 10), ça sera plus rapide qu'en séquentiel, car je suppose que tu as plusieurs cœurs sur ta machine, donc ça exploitera au moins ça.
Maintenant le problème, c'est que ce sont des commandes qui font des accès disque : c'est là que je sais pas trop ce que ça peut donner.
Ça dépend de la proportion de calculs et d'accès disque dans ce que fait icat notamment…
Hors ligne
#13 Le 21/04/2020, à 18:33
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Surtout qu'il y a le cache du disque qui sera utilisé à son maximum je pense, après je ne connais pas bien icat. Après c'est pas grave si c'est séquentiel, c'est juste que c'est long mais si on peut gagner un peu de temps je suis preneur.
Oui c'est un i5 de 6eme génération que j'utilise actuellement.
Au moins j'ai une idée de la quantité de fichiers corrompus et on a pu récupérer pas mal de fichiers en bon état.
Je vais passer en résolu, merci beaucoup!
Je vais du coup faire le programme plus global qui prendra en compte mon fichier ddrescue.log
Dernière modification par Nuliel (Le 21/04/2020, à 18:33)
Hors ligne
#14 Le 21/04/2020, à 19:14
- kamaris
Re : [Résolu] extraire des données en bash depuis la MFT
Au cas où tu voudrais essayer la parallélisation, j'étais allé trop vite : ce que j'avais proposé en #10 lançait tous les icat en parralèle ( ), par paquets de 10.
J'ai rajouté un wait pour corriger ça, mais ça n'est pas terrible : chaque paquet de 10 devra être intégralement terminé avant d'en lancer un autre, alors que ce qu'il faudrait, c'est relancer un icat dès qu'un autre est fini, sans dépasser 10.
C'est possible bien sûr, par exemple en regardant la sortie d'un pgrep de temps en temps, mais c'est plus compliqué (comme je le présageais plus justement en #9), et peut-être pas si indiqué ici, finalement.
Bref, j'en reste là
Hors ligne
#15 Le 21/04/2020, à 19:23
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Ok, on va rester sur du séquentiel, ça marche c'est le principal!
Hors ligne
#16 Le 22/04/2020, à 19:02
- kamaris
Re : [Résolu] extraire des données en bash depuis la MFT
RTFM! (on a le droit de se le dire à soi-même, c'est pas hors-charte )
-P max-procs, --max-procs=max-procs
Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option or the -L
option with -P; otherwise chances are that only one exec will be done. While xargs is running, you can send its process a SIGUSR1 signal to increase the number of
commands to run simultaneously, or a SIGUSR2 to decrease the number.
Donc, pour la parallélisation non seulement paramétrable, mais réglable en cours de route, il suffit de faire
awk -F'"|","' '/\/Users\/Utilisateur/ && /"File"/{print "icat /dev/sdb3 " $2 " > \"" ENVIRON["PWD"] $9 "\""}' analyseMFT.csv | xargs -d'\n' -L1 -P10 sh -c
Et là, xargs va lancer 10 process (réglable par le -P10), et dès que l'un d'entre eux se terminera, il en lancera un autre.
Cerise sur le gâteau : pour augmenter (resp. diminuer) le nombre de process lancés en parallèle, il suffit d'envoyer à xargs le signal SIGUSR1 (resp. SIGUSR2).
Pour ce faire, on récupère le pid d'xargs, et on fait dans un autre terminal (ou le même si on a lancé la commande ci-dessus en arrière plan) :
kill -sUSR1 $pid_xargs
Ou bien, si on n'a qu'un xargs qui tourne sur sa machine (en tout cas un seul qui utilise l'option -P), on peut faire
pkill -USR1 xargs
J'ai testé tout ça avec des sleep, ça marche au poil
Hors ligne
#17 Le 23/04/2020, à 23:00
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Merci kamaris, c'est un truc qui peut resservir la parallélisation avec xargs!
Je testerai lorsque j'aurais pu avancer sur la récupération avec ddrescue (plus précisément lorsque les zones contenant des données utiles seront récupérées)
Hors ligne
#18 Le 25/04/2020, à 14:56
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Salut,
J'ai un petit problème avec la commande de récupération des fichiers, certains dossiers manquent bizarrement à l'appel (j'ai des erreurs du type "impssible de copier, le dossier n'existe pas"). Y a t'il moyen de compléter l'arborescence en même temps que d'extraire les fichiers? (il me manque peut être un morceau de la MFT, je vois pas d'autre possibilité)
Dernière modification par Nuliel (Le 25/04/2020, à 14:56)
Hors ligne
#19 Le 25/04/2020, à 16:10
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
C'est bon, j'ai trouvé:
awk -F'"|","' '/\/Users\/Utilisateur/ && /"File"/{system("sudo icat /dev/sdX -o offset " $2 " | install -D /dev/stdin \"" ENVIRON["PWD"] $9 "\"")}' analyseMFT.csv
où offset est à adapté (s'il y a besoin de le passer) et /dev/sdX aussi
Hors ligne
#20 Le 25/04/2020, à 20:59
- kamaris
Re : [Résolu] extraire des données en bash depuis la MFT
Oui, on peut le faire comme ça, mais install va te créer des fichiers exécutables par défaut.
Il faudrait lui préciser un -m644 (ou autre).
Sinon, tu peux aussi séparer la partie création de répertoire de l'écriture dans le fichier.
Ça aura le mérite de ne passer à l'écriture dans le fichier que si la création de répertoire s'est bien passée (avec message d'erreur séparé), et aussi de créer automatiquement le fichier avec les droits par défaut de l'utilisateur :
gawk -F'"|","' '/\/Users\/Utilisateur/ && /"File"/{system("mkdir -p \"" gensub("/[^/]*$","",1,ENVIRON["PWD"]$9) "\" && sudo icat /dev/sdX -o offset " $2 " > \"" ENVIRON["PWD"] $9 "\"")}' analyseMFT.csv
NB : par simplicité, j'ai utilisé gensub() de gawk, mais on pourrait le faire en awk posix si on voulait.
Hors ligne
#21 Le 25/04/2020, à 21:28
- Nuliel
Re : [Résolu] extraire des données en bash depuis la MFT
Ok, de toute façon c'est pour du windows donc les permissions ne seront sûrement pas conservées.
Bon, je suis face au théorème connu du "oh il y a rien sur mon disque" alors que c'est pas du tout le cas.. Du coup j'ai arrêté la copie...
Y a t'il moyen de demander à ne pas prendre en compte un dossier à partir du chemin?
Je dirais bien
gawk -F'"|","' '/\/Users\/Utilisateur/ && !(\/mon\/chemin) && /"File"/{system("mkdir -p \"" gensub("/[^/]*$","",1,ENVIRON["PWD"]$9) "\" && sudo icat /dev/sdX -o offset " $2 " > \"" ENVIRON["PWD"] $9 "\"")}' analyseMFT.csv
mais j'aimerais bien confirmation avant
Dernière modification par Nuliel (Le 25/04/2020, à 21:31)
Hors ligne
#22 Le 25/04/2020, à 22:36
- kamaris
Re : [Résolu] extraire des données en bash depuis la MFT
Non, c'est pas tout à fait ça, et il vaudrait mieux aussi restreindre la recherche de correspondance à $9, pour ne pas éliminer des lignes valides :
gawk -F'"|","' '/\/Users\/Utilisateur/ && /"File"/ && ! $9 ~ "/mon/chemin"{…
On pourrait d'ailleurs aussi préciser l'endroit où on cherche /Users/Utilisateur et File :
gawk -F'"|","' '$9 ~ "/Users/Utilisateur" && $5 == "File" && ! $9 ~ "/mon/chemin"{…
Dernière modification par kamaris (Le 25/04/2020, à 22:40)
Hors ligne