Recuperar dados de páginas na memória de falha na ativação da hibernação

9

O Macbook da minha namorada travou ao tentar restaurar a partir de um arquivo hibernado. A barra de progresso parou em ~ 10%, após o que reiniciamos o computador para uma inicialização normal.

Essa imagem de memória hibernada tinha um documento não salvo aberto no Pages, que gostaríamos de recuperar. Há um sleepimagein /private/var/vm, que eu assumo é a imagem de hibernação que nunca foi restaurada corretamente. Apoiámos essa coisa para mantê-la viva.

Tentamos, strings sleepimage | grep known_substringmas não retornou nada. grep -a known_substring sleepimagetambém não fez nada, portanto, estou assumindo que o Pages não manteve os dados de texto na memória como texto sem formatação.

Edit: Depois de ler esta resposta no grep binário eu tentei perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(null_padded_substring)/g' sleepimage, novamente sendo infrutífero. Eu preenchi com nulos para tentar uma correspondência para o texto UTF-8. Então tentei com .*globs entre cada personagem - ainda sem dados.

Portanto, o Pages provavelmente não armazena texto por nenhuma codificação comum na memória. Eu precisaria encontrar uma regra de tradução entre a string ASCII e a representação de dados do Pages - estou pensando em algum tipo de buffer de string do Objective C. Para mim, parece muito estranho armazenar dados de caracteres como qualquer outra coisa que não uma sequência de caracteres, mas isso parece ser o que o Pages está fazendo.

Se você tem alguma idéia de como descobrir a representação na memória do texto dentro do Pages, pode ser muito útil para resolver esse problema. Talvez eu possa despejar e ler a memória do processo de alguma maneira simples?

Outra solução possível é mais simples - presumo que seja possível reiniciar o computador a partir disso sleepimage, mas não consigo encontrar nenhuma documentação sobre como você procederia com isso. Alguns outros usuários ( macrumores ) parecem ter encontrado isso, mas para todas as perguntas do fórum que encontrei, nenhum deles tem respostas.

A versão do OS X é o Snow Leopard, 10.6.8.

Sugestões complexas envolvendo programação são bem-vindas. Eu faço C e Python.

Obrigado.

sapht
fonte
11
Espero que você tenha feito uma cópia desse arquivo para não examinar uma imagem de sono mais recente que foi gravada após a reinicialização. Em seguida, convém recriar a situação (sem travar) com um máximo de RAM livre - ou seja, abrir apenas páginas. Escrever um texto exclusivo e deixar o sistema operacional gravar uma nova imagem de sono; e comece a examinar isso para o seu texto exclusivo.
iolsmit
@iolsmit Sim, todos os testes são realizados em uma cópia do sleepimage. Peneirar outra imagem em busca de texto exclusivo seria igualmente difícil, pois a imagem ainda teria tamanho de 4 GB e o bloco de memória Pages seria alocado em algum lugar aleatório nesse arquivo. Suponho que eu poderia zerar a RAM, abrir páginas e procurar sequências diferentes de zero na imagem do sono. Mas o Pages consome 200 MB de memória, independentemente - ainda é uma pequena agulha no palheiro.
sapht 27/09/12
Seu texto é armazenado com 0x00 entre cada caractere; portanto, você deve procurar por isso ou por esta sequência: loobsdpkdbik; veja também minha resposta abaixo
iolsmit
As páginas não possuem versões ativadas por padrão, mesmo que você não tenha um backup da máquina do tempo (procure backups móveis nos quais o sistema faz o backup mesmo sem a unidade de backup conectada)? Você descartou maneiras mais fáceis de recuperar o arquivo sem realizar heroicamente uma análise forense no formato do arquivo de imagem de suspensão? (não importa o quão impressionante que será se você retirá-lo;)
bmike
As versões do @bmike só vieram com o Lion, mas essa máquina está no Snow Leopard (10.6.8) e lembro-me de ter perdido um pouco de trabalho por causa do travamento do iWork no SL e por não ter um salvamento automático ...
iolsmit

Respostas:

1

Atualize com fotos:

  • esse loobsdpkdbikidentificador mencionado primeiro, não é um - apenas aconteceu antes do meu texto a primeira vez que o experimentei.

  • parte do texto parece ficar "perdida" (ou seja, não salva em uma extensão contínua de memória) e isso pode piorar com o uso da RAM

  • talvez você não consiga recuperar texto significativo da imagem do sono

Agora meu texto original (com erro de digitação no primeiro parágrafo, sry Mr. Matisse):

Joias escondidas: o Jardim de Esculturas Abby Aldrich Rockefeller do MoMa, projetado por Philip Johnson em 1953, é um oásis urbano espetacular, com suas piscinas refletivas e um belo paisagismo. Esta galeria ao ar livre é instalada com exibições de escultura ao ar livre, incluindo obras de Aristide Maillol, Alexander Calder, Henri Maisse, Pablo Picasso e Richard Serra.

Ao visitar as novas galerias de pintura e escultura no MoMa, não deixe de atravessar a escada que liga o quarto e o quinto andar para ver a imagem monumental de alegria e energia de Henri Matisse, Dance (1909). A pintura foi originalmente projetada para ser pendurada no hall da escada de um palácio russo em Moscou.

E o texto recuperado:

Joias ocultas: Ma Abby Aldrich Rockeller Sculpre Gn, designada por Phip John 1953, é um espetacular ursite que reflete as piscinas em um cenário bonito. Esta galeria ao ar livre é composta por exposições em constante mudança de esculturas externas, incluindo obras de Aristide Maillol, Alexander Calder, Henri Maisse, Pabloicasso e o antigo mar.

Enquanto estiver examinando as novas galerias de escultura em Ma, certifique-se de percorrer a quarta quarta ordem de pensamento de Henri Matse sobre a imagem de alegria e olhos, Dan (19). A pintura intencionalmente mostrava o salão da escada do palácio Rsian de Moscou.

E as capturas de tela:

Texto original em páginas

Texto recuperado da imagem do sono


Parece que para um (unsaved) documento do Pages (quase) todos os caracteres do texto são separados por 0x00na memória - assim, STRINGtorna-se S.T.R.I.N.Gcom .estar 0x00. Então você precisa procurar por isso; Posso recomendar 0xED para um front-end gráfico ... ..ou procurar loobsdpkdbikqual parece ser (parte de) um identificador, que vem 5 bytes antes do texto (pelo menos apenas em um caso).

iolsmit
fonte
Hmm, fiz uma pesquisa por "loobsdpkdbik", mas ainda estou vazio. Esse identificador apareceu antes de todas as variantes do documento não salvo? Talvez isso signifique algo sobre o documento - como herança de janela, fonte padrão, etc ... Procurei uma string preenchida com nulo usando perl anteriormente, ou seja s\0u\0b\0s\0t\0r\0i\0n\0g, não funcionou, mais descrições estão na minha pergunta original. Oh - como você descobriu isso?
sapht 28/09/12
Eu atualizei minha resposta; parece que o texto não é armazenado em uma extensão contínua na memória, o que tornaria impossível a recuperação da imagem do sono. E esse "loobsdpkdbik" não está relacionado ao documento do Pages, apenas aconteceu antes do meu texto.
iolsmit
Talvez o substring estivesse entre as palavras murmuradas da memória descontínua na época. Ainda não encontrei nenhum dado na imagem do sono, mas talvez precisemos procurar a substring correta. Ou o bloco de memória nunca foi gravado. Bom trabalho investigando a imagem do sono, obrigado.
sapht
@sapht Se a imagem do sono não estiver corrompida, ela deverá conter o texto completo do documento do Pages - pois a restauração da RAM o colocaria onde estava o sistema quando ele hibernou. Eu recomendaria tentar a imagem do sono em uma máquina virtual: Instale qualquer OS X suportado em uma máquina virtual (ou use o VMware fusion 4.1 ;) - depois clone sua máquina no HDD virtual e tente inicializar a partir da imagem do sono.
Iolsmit # 1/12
2

Primeira tentativa, se a string_conhecida foi armazenada em texto sem formatação (não é o caso)

Eu acho que você poderia tentar usar

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

A partir disso, o parâmetro -U especifica a pesquisa em arquivos binários, -b especifica que o deslocamento em bytes da parte correspondente deve ser exibido e, por último, -o especifica que apenas a parte correspondente deve ser impressa.

Se isso funcionar, você saberia o deslocamento em bytes para chegar a essa região, mas eu não saberia exatamente como proceder lá. Dependendo do tipo de arquivo, você provavelmente pode verificar a assinatura do tipo de arquivo próximo ao deslocamento informado e tentar isolar apenas os bytes que fazem parte desse arquivo. Para isso, acho que você pode escrever um programa em C para fazer isso ou talvez executar hexdump -s known_offset sleepimagee tentar obter apenas os bytes relacionados ao arquivo que você precisa.

Por exemplo, suponha que eu queira saber algo sobre o Chrome:

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

Então, eu sei que tive uma ocorrência de cromo no deslocamento de bytes 3775011731. Portanto, pude:

$ 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

A parte complicada seria obter apenas os bytes que você deseja. Se o tipo de arquivo tiver um cabeçalho conhecido, talvez você possa subtrair o tamanho do cabeçalho em bytes do deslocamento hexdump, para obter o arquivo "desde o início". Se o tipo de arquivo tiver uma assinatura "EOF" conhecida, você poderá tentar procurá-la também e, portanto, obter apenas os bytes até esse ponto.

Qual é o seu tipo de arquivo? Você acha que algum procedimento como esse poderia ser usado no seu caso? Note que eu nunca fiz isso antes e estou me baseando em muitas "suposições", mas suponho que algo assim tenha poucas chances de funcionar ..

Segunda tentativa, um método lento para analisar todos os bytes

O método anterior não funciona porque também procura apenas texto sem formatação, minha aposta. Para este segundo texto, criei um programa C simples, contendo:

#include <stdio.h>

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

Então, eu poderia procurar por "assim", que seria sua string conhecida, nesse texto. Para saber quais bytes procurar, fiz:

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

Portanto, devo encontrar "61 73 73 69 6d". Depois de compilar essa fonte C simples no programa "tt", fiz o seguinte:

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

O que voltou para mim:

insira a descrição da imagem aqui

Se você fez algo assim, acho que você poderia obter seus dados ... Seria muito lento analisar 2 a 8 GB de bytes ...

Observe que nesta abordagem você deve encontrar os hexágonos em letras maiúsculas (escreva 6D em vez de 6d no último grep), não em letras minúsculas e use \ n em vez de espaços em branco (para que você possa usar -A e - B para o grep). Você poderia usar grep -ipara não diferenciar maiúsculas de minúsculas, mas seria um pouco mais lento. Portanto, basta usar maiúsculas se isso for usado.

Ou, se você quiser um "script" automatizado de tudo:

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
fonte
O texto é armazenado apenas na memória, pois o arquivo nunca foi salvo. Portanto, não existe um tipo de arquivo real, apenas o tipo de representação que o Pages mantém internamente para os dados. Passar -Upara grepnão parece fazer muita diferença ( aé a abreviação de --binary-files=text). Se eu tivesse o desvio de bytes, eu poderia continuar, mas o arquivo está corrompido ou o Pages está armazenando os dados de alguma maneira não ASCII. Talvez UTF-8, mas grepnão aceitará bytes nulos para um caractere de correspondência.
sapht 27/09/12
Eu editei o post com outra tentativa .. parece funcionar .. mas é realmente lento e você terá que "adivinhar" quantos bytes deseja antes e após a ocorrência da string_conhecida. Nota: quando eu echo -n "assim" | hexdumprecebo o hexdump para a codificação UTF-8, você pode tentar echo -n "assim" | iconv -t UTF-16 | hexdumpoutras codificações, UTF-16, neste caso, não tenho idéia de como ele é armazenado na memória. Mas, no meu caso, ele foi armazenado como UTF-8 na verdade :)
FernandoH
Hmm, bem, o dump hexadecimal do seu programa C imprime o texto, pois ele é realmente incorporado no binário - o gcc é compilado dessa maneira para que todos os buffers de caracteres estáticos sejam armazenados no próprio programa para referência na memória. Mas, para o Pages, esses dados foram criados no site da Runti e. Atualizei minha resposta com uma nova correspondência que tentei via perl, que foi infrutífera, por isso tenho certeza de que o texto é armazenado de uma maneira estranha e não-padrão, pois os bytes ASCII não são os mesmos. Talvez algum objetivo buffer de string C ...
sapht
Hummm .. E se você tentasse procurar pela string "Pages.app"? Eu não saberia como proceder a partir daí se algo fosse encontrado (como o que pertence ao aplicativo e qual é o seu documento?), Mas se mantivéssemos essa linha de pensamento, poderia ser o começo de uma tentativa. Embora eu deva admitir que deve haver alternativas mais fáceis, essa seria bem trabalhosa #
FernandoH
Na verdade, você se lembra de peças daquele arquivo de documentos? Mesmo que tenha sido armazenado na memória, se você souber algumas frases exatas que foram escritas lá (se você se lembra ou se possui uma versão anterior do arquivo), tente tentar pesquisá-las diretamente! Acho que seria muito mais fácil :) E como o Pages é um programa de edição de palavras, acho que você deseja recuperar o que foi escrito, certo? Se for esse o caso, procurar o conteúdo em vez de meta-informação, pode ser mais fácil .. Espero, pelo menos ..
FernandoH