Récupérer les données des pages en mémoire après l'échec du réveil en veille prolongée

9

Le Macbook de ma copine s'est écrasé lors d'une tentative de restauration à partir d'un fichier en veille prolongée. La barre de progression s'est arrêtée à ~ 10%, après quoi nous avons redémarré l'ordinateur pour un démarrage normal.

Cette image mémoire mise en veille prolongée avait un document non enregistré ouvert dans Pages, que nous aimerions récupérer. Il y a un sleepimagein /private/var/vm, qui je suppose est l'image d'hibernation qui n'a jamais été correctement restaurée. Nous avons sauvegardé cette chose pour la garder en vie.

Nous avons essayé strings sleepimage | grep known_substringmais cela n'a rien donné. grep -a known_substring sleepimagen'a également rien fait, donc je suppose que Pages n'a pas gardé les données de texte en mémoire sous forme de texte brut.

Edit: Après avoir lu cette réponse sur grep binaire, j'ai essayé perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(null_padded_substring)/g' sleepimage, encore une fois sans résultat. Je l'ai rembourré avec des valeurs nulles afin d'essayer une correspondance pour le texte UTF-8. Ensuite, j'ai essayé avec des .*globes entre chaque personnage - toujours pas de dés.

Donc, Pages ne stocke probablement pas de texte par un encodage commun en mémoire. Il faudrait que je trouve une règle de traduction entre la chaîne ASCII et la représentation des données Pages - je pense peut-être à une sorte de tampon de chaîne Objective C. Pour moi, il semble très étrange de stocker des données de caractères autrement que comme une séquence de caractères, mais cela semble être ce que Pages fait.

Si vous avez une idée sur la façon de comprendre la représentation en mémoire du texte dans Pages, cela peut être très utile pour résoudre ce problème. Peut-être que je peux vider et lire la mémoire de processus d'une manière simple?

Une autre solution possible est plus simple - je suppose qu'il est possible de redémarrer l'ordinateur à partir de cela sleepimage, mais je ne trouve aucune documentation sur la façon dont vous procéderiez. Certains autres utilisateurs ( macrumors ) semblent avoir rencontré cela, mais pour toutes les questions du forum que j'ai trouvées, aucun d'entre eux n'a de réponse.

La version OS X est Snow Leopard, 10.6.8.

Les suggestions complexes concernant la programmation sont les bienvenues. Je fais du C et du Python.

Je vous remercie.

sapht
la source
1
J'espère que vous avez fait une copie de ce fichier afin de ne pas finir par examiner une image de sommeil plus récente qui a été écrite après le redémarrage. Ensuite, vous voudrez peut-être recréer la situation (sans planter) avec une RAM libre maximale - c'est-à-dire que seules les pages ouvertes écrivent un texte unique et laissent le système d'exploitation écrire une nouvelle image de veille; puis commencez à examiner cela pour votre texte unique.
iolsmit
@iolsmit Oui, tous les tests sont effectués sur une copie de sleepimage. Passer au crible une autre image à la recherche d'un texte unique serait tout aussi difficile, car l'image aurait toujours une taille de 4 Go et le bloc de mémoire Pages serait alloué quelque part au hasard dans ce fichier. Je suppose que je pourrais mettre à zéro la RAM, puis ouvrir des pages, puis rechercher des séquences non nulles dans l'image de sommeil, cependant. Mais Pages mange jusqu'à 200 Mo de mémoire malgré tout - toujours une petite aiguille dans la botte de foin.
sapht
Votre texte est stocké avec 0x00 entre chaque caractère, vous devez donc rechercher cela ou cette chaîne: loobsdpkdbik; voir aussi ma réponse ci
iolsmit
Les pages n'ont-elles pas de versions activées par défaut même si vous n'avez pas de sauvegarde Time Machine (recherchez les sauvegardes mobiles où le système sauvegarde les choses même sans le lecteur de sauvegarde connecté)? Avez-vous exclu des moyens plus faciles de récupérer le fichier sans effectuer héroïquement une analyse médico-légale sur le format de fichier d'image de sommeil? (peu importe à quel point ce sera génial si vous le retirez;)
bmike
@bmike Versions est venu uniquement avec Lion mais cette machine est sur Snow Leopard (10.6.8) et je me souviens avoir perdu pas mal de travail à cause d'iWork qui plantait sur SL et n'ayant pas de sauvegarde automatique ...
iolsmit

Réponses:

1

Mise à jour avec photos:

  • cet loobsdpkdbikidentifiant mentionné en premier, n'en est pas un - il est juste arrivé d'être devant mon texte la première fois que je l'ai essayé.

  • une partie du texte semble "perdue" (c'est-à-dire qu'elle n'est pas enregistrée dans un tronçon de mémoire continu) et cela peut empirer avec l'utilisation de la RAM

  • vous ne pourrez peut-être pas récupérer de texte significatif à partir de l'image de sommeil

Maintenant mon texte original (avec une faute de frappe au 1er paragraphe, monsieur M. Matisse):

Gemmes cachées: le jardin de sculptures Abby Aldrich Rockefeller de MoMa, conçu par Philip Johnson en 1953, est une oasis urbaine spectaculaire avec ses piscines réfléchissantes et son magnifique aménagement paysager. Cette galerie extérieure est installée avec des expositions changeantes de sculpture extérieure, y compris des œuvres d'Aristide Maillol, d'Alexander Calder, d'Henri Maisse, de Pablo Picasso et de Richard Serra.

En visitant les nouvelles galeries de peinture et de sculpture du MoMa, assurez-vous de traverser l'escalier reliant les quatrième et cinquième étages afin de voir l'image monumentale de joie et d'énergie d'Henri Matisse, Dance (1909). Le tableau était à l'origine destiné à être accroché dans le hall d'escalier d'un palais russe à Moscou.

Et le texte récupéré:

Gemmes cachées: Ma's Abby Aldrich Rockeller Sculpre Gn, conçue par Phip John 1953, est une spectaculaire piscine à miroir réfléchissant autifulandscapg. Cette galerie extérieure est remplie d'expositions changeantes de sculpre extérieur, y compris les travaux d'Aristide Maillol, d'Alexander Calder, d'Henri Maisse, de Pabloicasso et d'Anchard Sea.

Pendant que vous visitez la nouvelle sculpture de peinture gallies à Ma, assurez-vous de traverser la stase en faisant le pont entre le quatrième et le dernier ordre de Henri Matse, une image métallique de la joie et de la vue, Dan (19). Le tableau est intégré à la salle d'escalier HG T du palais Rsian à Moscou.

Et les captures d'écran:

Texte d'origine dans Pages

Texte récupéré de sleepimage


Il semble que pour un document Pages (non enregistré) (presque) tous les caractères de votre texte soient séparés par 0x00en mémoire - STRINGdevient ainsi S.T.R.I.N.Gavec l' .être 0x00. Vous devez donc soit rechercher cela; Je peux recommander 0xED pour une interface graphique ... ... ou vous recherchez loobsdpkdbikqui semble être (une partie de) un identifiant, qui vient 5 octets avant le texte (au moins seulement dans un cas).

iolsmit
la source
Hmm, j'ai fait une recherche sur "loobsdpkdbik", mais toujours vide. Cet identifiant est-il apparu avant chaque variante du document non enregistré? Peut-être que cela signifie quelque chose à propos du document - comme l'héritage de fenêtre, la police par défaut, etc ... J'ai cherché une chaîne complétée par null en utilisant perl plus tôt, c'est s\0u\0b\0s\0t\0r\0i\0n\0g-à- dire , n'a pas fonctionné, plus de description est dans ma question d'origine. Oh - comment avez-vous découvert cela?
sapht
@sapht j'ai mis à jour ma réponse; il semble que le texte ne soit pas stocké en continu dans la mémoire, ce qui pourrait rendre impossible la récupération de l'image de sommeil. Et que "loobsdpkdbik" n'est pas lié au document Pages, il se trouve que c'est juste avant mon texte.
iolsmit
Peut-être que la sous-chaîne faisait alors partie des mots marmonnés d'une mémoire discontinue. Je n'ai toujours pas trouvé de données dans l'image de sommeil, mais nous devrons peut-être simplement rechercher la bonne sous-chaîne. Ou le bloc mémoire n'a jamais été écrit. Bon travail d'enquête sur l'image du sommeil, merci.
1er
@sapht Si votre image de sommeil n'est pas corrompue, elle devrait contenir le texte intégral du document Pages - car la restauration de la RAM la placerait là où se trouvait le système lorsqu'il hibernait. Je recommanderais d'essayer l'image de sommeil dans une machine virtuelle: installez n'importe quel OS X pris en charge dans une machine virtuelle (ou utilisez VMware fusion 4.1 ;) - puis clonez votre machine sur le disque dur virtuel et essayez de démarrer à partir de l'image de sommeil.
iolsmit
2

Essayez d'abord, SI chaîne_connue était stockée en texte brut (pas le cas)

Je suppose que vous pourriez essayer d'utiliser

grep -Ubo --binary-files=text "known_substring" sleepimage 

A partir de cela, le paramètre -U spécifie la recherche sur les fichiers binaires, -b spécifie que le décalage en octets vers la partie correspondante doit être affiché et, enfin, -o spécifie que seule la partie correspondante doit être imprimée.

Si cela fonctionne, vous connaîtrez l'offset en octets pour accéder à cette région, mais je ne saurais pas exactement comment y procéder. Selon le type de fichier, vous pouvez probablement vérifier la signature de type de fichier près de l'offset informé et essayer d'isoler uniquement les octets qui font partie de ce fichier. Pour cela, je suppose que vous pouvez soit écrire un programme C pour cela, soit exécuter hexdump -s known_offset sleepimageet essayer d'obtenir uniquement les octets liés au fichier dont vous avez besoin.

Par exemple, supposons que je veuille savoir quelque chose sur Chrome:

$ sudo grep -Ubo --binary-files=text -i "chrome" sleepimage
3775011731:chrome

Je sais donc que j'ai eu une occurrence de chrome au décalage d'octet 3775011731. Par conséquent, je pouvais:

$ sudo hexdump -s 3775011731 sleepimage | head -n 3
e1021b93 09 09 3c 73 74 72 69 6e 67 3e 2e 63 68 72 6f 6d
e1021ba3 65 2e 67 6f 6f 67 6c 65 2e 63 6f 6d 3c 2f 73 74
e1021bb3 72 69 6e 67 3e 0a 09 09 3c 6b 65 79 3e 45 78 70

La partie délicate serait d'obtenir uniquement les octets souhaités. Si le type de fichier a un en-tête connu, vous pouvez peut-être soustraire la taille de l'en-tête en octets de l'offset hexdump, ainsi vous obtenez le fichier "depuis le début". Si le type de fichier a une signature "EOF" connue, vous pouvez également essayer de le rechercher et donc obtenir uniquement les octets jusqu'à ce point.

Quel est votre type de fichier? Pensez-vous qu'une telle procédure pourrait être utilisée dans votre cas? Notez que je n'ai jamais fait cela auparavant, et je me base sur beaucoup de "suppositions", mais je suppose que quelque chose comme ça a une petite chance de fonctionner ..

Deuxième essai, une méthode lente pour analyser tous les octets

La méthode précédente ne fonctionne pas car elle ne recherche également que du texte brut, mon pari. Pour ce deuxième texte, j'ai créé un simple programme C contenant:

#include <stdio.h>

int main () {
  printf("assim");
  return 0;
}

Je pouvais donc rechercher "assim", qui serait votre chaîne connue, dans ce texte. Afin de savoir quels octets rechercher j'ai fait:

$ echo -n "assim" | hexdump
0000000 61 73 73 69 6d                                 
0000005

Par conséquent, je dois trouver "61 73 73 69 6d". Après avoir compilé cette simple source C dans le programme "tt", j'ai fait ce qui suit:

hexdump -v -e '/1 "%02X\n"' tt | # format output for hexdump of file tt
    pcregrep -M --color -A 3 -B 3 "61\n73\n73\n69\n6D" # get 3 bytes A-fter and 3 bytes B-fore the occurence

Qui me revient:

entrez la description de l'image ici

Si vous avez fait quelque chose comme ça, je suppose que vous pourriez obtenir vos données .. Il serait plutôt lent d'analyser 2 à 8 Go d'octets ...

Notez que dans cette approche, vous devez trouver les hexagones en majuscule (écrivez 6D au lieu de 6d sur le dernier grep), pas en lettres minuscules, et utilisez \ n au lieu des espaces blancs (vous pouvez donc utiliser -A et - B pour le grep). Vous pouvez l'utiliser grep -ipour qu'il devienne insensible à la casse, mais ce serait un peu plus lent. Par conséquent, utilisez simplement des majuscules si cela est utilisé.

Ou, si vous voulez un "script" automatisé à tout faire:

FILENAME=tt # file to parse looking for string
BEFORE=3 # bytes before occurrence
AFER=3 # bytes after occurrence
KNOWNSTRING="assim" # string to search for

ks_bytes="$(echo -n "$KNOWNSTRING" | hexdump | head -n1 | cut -d " " -f2- | tr '[:lower:]' '[:upper:]' | sed -e 's/ *$//g' -e 's/ /\\n/g')"

hexdump -v -e '/1 "%02X\n"' $FILENAME | pcregrep -M --color -A $AFER -B $BEFORE $ks_bytes
FernandoH
la source
Le texte est uniquement stocké en mémoire, car le fichier n'a jamais été enregistré. Il n'y a donc pas de véritable type de fichier, seulement le type de représentation que Pages conserve en interne pour les données. Passer -Uà grepne semble pas faire beaucoup de différence ( ac'est l'abréviation de --binary-files=text). Si j'avais le décalage d'octet, je pourrais certainement continuer, mais soit le fichier est corrompu, soit Pages stocke les données d'une manière non ASCII. Peut-être UTF-8, mais grepn'acceptera pas d'octets nuls pour un caractère de correspondance.
sapht
J'ai édité le message avec un autre essai .. il semble fonctionner .. mais est vraiment lent et vous devrez "deviner" combien d'octets vous voulez avant et après l'occurrence de la chaîne connue. Remarque: lorsque je echo -n "assim" | hexdumpreçois le vidage hexadécimal pour l'encodage UTF-8, vous pouvez essayer echo -n "assim" | iconv -t UTF-16 | hexdumpd'autres encodages, UTF-16 dans ce cas, je n'ai aucune idée sur la façon dont il est stocké en mémoire .. Mais dans mon cas, il a été stocké comme UTF-8 en effet :)
FernandoH
Hmm, eh bien, le vidage hexadécimal de votre programme C imprime le texte car il est en fait intégré dans le binaire - gcc compile de cette façon afin que tous les tampons de caractères statiques soient stockés dans le programme lui-même pour référence en mémoire. Mais pour les pages, ces données ont été créées sur runti e. J'ai mis à jour ma réponse avec une nouvelle correspondance que j'ai essayée via Perl, qui était inutile, donc je suis presque sûr que le texte est stocké d'une manière non standard bizarre, car les octets ASCII ne sont même pas les mêmes. Peut-être un tampon de chaîne C objectif ...
sapht
Hummm .. Et si vous tentiez plutôt de rechercher la chaîne "Pages.app"? Je ne saurais pas comment procéder à partir de là si quelque chose a été trouvé (comme ce qui appartient à l'application et quel est votre document?), Mais si nous devions garder cette ligne de pensée, cela pourrait être le début d'un essai. Bien que je dois admettre qu'il doit y avoir des alternatives plus faciles, ce serait assez laborieux
FernandoH
En fait, vous souvenez-vous des morceaux de ce dossier Papers? Même s'il a été stocké en mémoire, si vous connaissez des phrases exactes qui y ont été écrites (si vous vous en souvenez ou si vous avez une version précédente du fichier), vous pouvez essayer de les rechercher directement! Ce serait beaucoup plus facile, je suppose :) Et comme Pages est un programme d'édition de mots, je suppose que vous voulez récupérer ce qui a été écrit, non? Si tel est le cas, recherchez le contenu plutôt que les méta-informations, cela peut être plus facile .. J'espère, au moins ..
FernandoH