失敗した休止状態のウェイクアップからメモリ内のページデータを回復する


9

私のガールフレンドのMacbookは、休止状態のファイルから復元しようとしたときにクラッシュしました。進行状況バーは約10%で停止し、その後、通常の起動のためにコンピューターを再起動しました。

この休止状態のメモリイメージは、ページで開いている保存されていないドキュメントを開いていました。sleepimagein があり/private/var/vm、これは正しく復元されなかった休止状態のイメージだと思います。私たちはそれを生かしておくためにこの事をバックアップしました。

試しましたstrings sleepimage | grep known_substringが何も返りませんでした。grep -a known_substring sleepimageまた、何もしなかったので、Pagesはテキストデータをプレーンテキストとしてメモリに保持しなかったと想定しています。

編集:Binary grepでこの回答を読んだ後perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(null_padded_substring)/g' sleepimage、私は試してみましたが、再び実を結ばなくなりました。UTF-8テキストとの一致を試みるために、ヌルで埋めました。それから私は.*各キャラクターの間にグロブを試してみました-まだサイコロはありません。

そのため、Pagesはメモリ内の一般的なエンコーディングでテキストを保存しないでしょう。ASCII文字列とページデータ表現の間の変換ルールを見つける必要があります-おそらく、ある種のObjective C文字列バッファだと思っています。私にとっては、文字データを一連の文字以外のものとして格納するのは非常に奇妙に思えますが、これはPagesが行っていることのようです。

Pages内のテキストのメモリ内表現を理解する方法について何か考えがある場合は、この問題を解決するのに非常に役立ちます。たぶん私はいくつかの簡単な方法でプロセスメモリをダンプして読み取ることができますか?

別の可能な解決策はより簡単です-私はこれからコンピュータを再起動することが何らかの形で可能であると想定してsleepimageいますが、それをどのように進めるかについてのドキュメントは見つかりません。他の一部のユーザー(macrumors)がこれに遭遇したようですが、私が見つけたすべてのフォーラムの質問に対して、誰も応答がありません。

OS XバージョンはSnow Leopard、10.6.8です。

プログラミングに関する複雑な提案を歓迎します。CとPythonを使用しています。

ありがとうございました。


1
うまくいけば、そのファイルのコピーを作成したので、再起動後に書き込まれた新しいスリープイメージを調べてしまうことはありません。次に、最大の空きRAMで(クラッシュなしで)状況を再現したい場合があります。つまり、ページのみを開いて固有のテキストを書き込み、OSに新しいスリープイメージを書き込ませます。そして、あなたのユニークなテキストのためにそれを調べ始めます。
iolsmit 2012

@iolsmitはい、すべてのテストはのコピーで実行されますsleepimage。一意のテキストを探す別の画像をふるいにかけることは、画像のサイズがまだ4GBであり、ページメモリブロックがそのファイルのランダムな場所に割り当てられるため、同様に困難です。RAMをゼロにし、ページを開いてから、スリープイメージでゼロ以外のシーケンスを探すことができると思います。しかし、Pagesは関係なく200MBのメモリを消費します。
2012

テキストは各文字の間に0x00を付けて保存されるため、その文字列または次の文字列を検索する必要があります。loobsdpkdbik; 下記の私の回答も参照してください
iolsmit 2012

Time Machineバックアップがなくても、ページのバージョンはデフォルトでオンになっていないのですか(バックアップドライブが接続されていなくてもシステムがバックアップするモバイルバックアップを探します)?睡眠画像ファイル形式の法医学分析を英雄的に行わずにファイルを取り戻す簡単な方法を除外しましたか?(あなたがそれを引き離した場合、それがどれほど素晴らしいものであっても;)
bmike

@bmikeバージョンはLionにのみ付属していますが、そのマシンはSnow Leopard(10.6.8)上にあり、iWorkがSLでクラッシュし、自動保存がないためにかなりの作業が失われたことを覚えています...
iolsmit

回答:


1

写真で更新:

  • loobsdpkdbik最初に言及したその識別子は1つではありません-たまたま私のテキストの前に、私が試した最初の時間です。

  • テキストの一部が "失われた"(つまり、1回の連続したメモリストレッチで保存されない)ようで、これはRAMの使用により悪化する可能性があります

  • 睡眠画像から意味のあるテキストを復元できない場合があります

さて、私の元のテキスト(最初の段落にタイプミスがあるので、マティスさんに言ってください):

隠された宝石:MoMaのアビーアルドリッチロックフェラー彫刻庭園は、1953年にフィリップジョンソンによって設計され、反射するプールと美しい造園のある壮大な都市のオアシスです。この屋外ギャラリーには、Aristide Maillol、Alexander Calder、Henri Maisse、Pablo Picasso、Richard Serraなどの作品を含む、屋外彫刻の展示が変化しています。

MoMaで新しい絵画と彫刻のギャラリーを訪れているときは、4階と5階を繋いでいる階段を通り抜けて、アンリマティスの喜びとエネルギーの壮大なイメージであるダンス(1909)を見てください。この絵は元々、モスクワのロシア宮殿の階段ホールに飾るつもりでした。

そして回復されたテキスト:

隠された宝石:フィリップジョン1953年に設計された、マ・アビー・アルドリッチ・ロッカー・スカルプGNは、プールを自慢に見せる素晴らしい観客です。この屋外ギャラリーは、アウスタースカルプ、アリスティドマイヨール、アレクサンダーカルダー、アンリメイズ、パブロイカッソ、アンチャードシーなどの作品の変化するディスプレイでいっぱいです。

新しい絵画の彫刻をMaで見ながら、4番目のflrsn ordetoのHenri Matseの心の喜びとダンを橋渡しするようにしてください(19)。絵画はロシア宮殿モスクワのHG T階段ホールにwaininally intted。

そしてスクリーンショット:

ページの元のテキスト

睡眠画像から回復したテキスト


(保存されていない)ページのドキュメントの(ほぼ)テキスト内のすべての文字が区切られていることを思わ0x00メモリ内-これ STRINGになっS.T.R.I.N.G.います0x00。したがって、それを検索する必要があります。グラフィカルなフロントエンドには0xEDをお勧めし ますloobsdpkdbik ... または、識別子の一部であると思われるものを検索します。これは、テキストの5バイト前に来ます(少なくとも 1つの場合のみ)。


うーん、「loobsdpkdbik」を検索しましたが、まだ空です。この識別子は、保存されていないドキュメントのすべてのバリアントの前に表示されましたか?ウィンドウの継承、デフォルトのフォントなど、ドキュメントに関する何かを示しているのかもしれs\0u\0b\0s\0t\0r\0i\0n\0gません。以前にperlを使用してnullでパディングされた文字列を検索したため、機能しませんでした。ああ、どうやってこれを見つけたの?
2012

@sapht私は私の答えを更新しました。テキストはメモリ内の連続したストレッチに保存されていないようで、睡眠画像から回復することが不可能になる可能性があります。そして、その "loobsdpkdbik"はPagesドキュメントとは関係なく、たまたま私のテキストの前にあります。
iolsmit 2012

おそらく、部分文字列は不連続な記憶のつぶやいた言葉の中にあったのかもしれません。スリープイメージにまだデータはありませんが、正しい部分文字列を検索する必要があるだけかもしれません。または、メモリブロックは書き込まれませんでした。睡眠画像を調査する良い仕事、ありがとう。
サフト

@saphtスリープイメージが破損していない場合は、ページドキュメントの全文が含まれている必要があります。RAMを復元すると、システムが休止状態になったときの場所にRAMが置かれるためです。仮想マシンでスリープイメージを試すことをお勧めします。サポートされているOS Xを仮想マシンにインストール(またはVMware Fusion 4.1を使用)してから、マシンを仮想HDDに複製して、スリープイメージから起動してみてください。
iolsmit

2

最初に試してみてください。known_stringがプレーンテキストで保存されている場合(そうでない場合)

私はあなたが使ってみることができると思います

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

それから、-Uパラメーターはバイナリファイルの検索を指定し、-bは一致する部分へのオフセットをバイト単位で表示することを指定し、最後に-oは一致する部分のみを印刷することを指定します。

それが機能する場合、その領域に到達するためのバイト単位のオフセットはわかりますが、そこに進む方法を正確には知りません。ファイルタイプによっては、その通知されたオフセットの近くでファイルタイプの署名を確認し、そのファイルの一部を構成するバイトのみを分離してみることができます。そのためには、Cプログラムを作成してそれを実行するか、実行して、hexdump -s known_offset sleepimage必要なファイルに関連するバイトのみを取得してみるとよいでしょう。

たとえば、Chromeについて何か知りたいとしましょう。

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

つまり、バイトオフセット3775011731でクロムが発生したことを知っています。

$ 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

トリッキーな部分は、必要なバイトのみを取得することです。ファイルタイプに既知のヘッダーがある場合は、16進ダンプオフセットからバイト単位のヘッダーサイズを差し引くと、「最初から」ファイルを取得できます。ファイルタイプに既知の「EOF」署名がある場合は、それも検索して、その時点までのバイトのみを取得することもできます。

あなたのファイルタイプは何ですか?このような手順があなたのケースで使用できると思いますか?これまでにこれを行ったことはなく、多くの「推測」に基づいていることに注意してください。ただし、このようなものは動作する可能性がほとんどないと思います。

2番目の試み、すべてのバイトを解析するための遅い方法

以前の方法は、プレーンテキストのみを検索するため、機能しません。この2番目のテキストでは、以下を含む簡単なCプログラムを作成しました。

#include <stdio.h>

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

だから私はそのテキストであなたのknown_stringである「assim」を検索することができました。どのバイトを検索するかを知るために:

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

したがって、「61 73 73 69 6d」を見つける必要があります。その単純なCソースをプログラム「tt」にコンパイルした後、次のことを行いました。

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

それは私に戻ってきました:

ここに画像の説明を入力してください

あなたがそのようなことをしたなら、あなたはあなたのデータを得ることができると思います。

このアプローチでは、16進数を大文字(最後のgrepで6dではなく6Dと書く)ではなく、小文字ではなく、空白の代わりに\ nを使用する必要があることに注意してください(-Aと-を使用できます)。 grepの場合はB)。grep -i大文字と小文字を区別しないように使用できますが、少し遅くなります。したがって、これを使用する場合は、大文字のみを使用してください。

または、すべてを自動化する「スクリプト」が必要な場合:

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

ファイルは保存されなかったため、テキストはメモリにのみ保存されます。したがって、実際のファイルの種類はなく、Pagesがデータに対して内部的に保持している種類の表現のみが存在します。に渡し-Ugrepも、それほど大きな違いはないようです(のa--binary-files=text)。バイトオフセットがある場合は、確実に続行できますが、ファイルが破損しているか、PagesがデータをASCII以外の方法で格納しています。おそらくUTF-8ですがgrep、一致文字としてnullバイトを受け入れません。
2012

私は別の試みで投稿を編集しました..それはうまくいくようです..しかし、本当に遅いので、known_stringの発生の前後に必要なバイト数を「推測」する必要があります。注:私がecho -n "assim" | hexdumpUTF-8エンコーディングのecho -n "assim" | iconv -t UTF-16 | hexdump16 進ダンプを取得した場合、他のエンコーディングを試すことができます。この場合はUTF-16ですが、メモリにどのように格納されるかはわかりません。しかし、私の場合は実際にUTF-8として:)
FernandoH

ええと、Cプログラムの16進ダンプは、実際にはバイナリに埋め込まれているため、テキストを出力します。gccは、すべての静的文字バッファーがメモリ自体の参照用にプログラム自体に格納されるようにコンパイルされます。ただし、ページの場合、データはランタイムで作成されました。私は答えをperl経由で試した新しいマッチで更新しましたが、それは役に立たなかったので、ASCIIバイトが同じではないので、テキストが奇妙な非標準的な方法で保存されていると確信しています。おそらく、いくつかの客観的なC文字列バッファ...
sapht

うーん..代わりに「Pages.app」という文字列を検索しようとするとどうなるでしょうか。何かが見つかった場合(たとえば、アプリに属しているものやドキュメントは何ですか?) 。私はもっと簡単な代替案があるはずだと認めざるを得ませんが、これはかなり面倒なものになるでしょう
FernandoH

実際、そのPapersファイルの断片を覚えていますか?メモリに保存されていても、そこに書かれた正確な文章がわかっている場合(覚えている場合、またはファイルの以前のバージョンがある場合)、これらを直接検索してみてください。これはずっと簡単だと思います:)そして、Pagesは単語編集プログラムなので、書かれた内容を復元したいと思いますよね?その場合は、コンテンツではなく、メタ情報、それは私が...少なくとも、願っています。..やすいかもしれの検索
FernandoH
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.