A estrutura do / proc / kcore na máquina de 64 bits e relação com a memória física

5

Deixe-me iniciar uma pergunta dizendo que encontrei muitas respostas para perguntas semelhantes à minha pergunta, mas para máquinas de 32 bits. No entanto, não consigo encontrar nada para máquinas de 64 bits. Por favor, não há respostas em relação às máquinas de 32 bits.

De acordo com muitas fontes no Stack Exchange, /proc/kcore pode ser literalmente despejado (por exemplo, com dd ) em um arquivo para obter uma cópia da memória física ... Mas isso claramente não funciona para um 64 máquina de bits, para a qual /proc/kcore tem 128TB de tamanho.

Como um aparte, noto que é possível acessar apenas o primeiro MB de memória através de /dev/mem . Isto é por razões de segurança. Contornar isso envolve recompilar o kernel, o que eu não quero fazer ... nem posso fazer para meus propósitos (tenho que trabalhar com o kernel em execução).

Ok ... então, /proc/kcore é um arquivo ELF-core da memória física e pode ser visualizado usando gdb . Por exemplo, com:

gdb /usr/[blah]/vmlinux /proc/kcore

Isso eu posso fazer ... mas, isso não é o que eu quero fazer. Eu gostaria de exportar a memória física para um arquivo para análise offline. Mas estou correndo em problemas.

Por um lado, não posso simplesmente copiar /proc/kcore para um arquivo, já que é 128 TB. Eu quero despejar toda a memória física, mas eu não sei onde está em /proc/kcore . Eu só vejo dados não-zero até o byte 3600 e, em seguida, são todos zeros, tanto quanto eu olhei (cerca de 40GB). Acho que isso pode ter a ver com a forma como a memória é mapeada para /proc/kcore , mas não entendo a estrutura e preciso de orientação.

Mais coisas que eu acho que sei: eu sei que apenas 48 bits são usados para endereçamento, não 64 bits. Isto implica que deve haver 2 48 = 256TB de memória disponível ... mas /proc/kcore é apenas 128TB, o que é eu acho porque o endereçamento é dividido em um pedaço de 0x0000000000000000 para 0x00007fffffffffff (128TB) e um pedaço de 0xffff800000000000 para 0xffffffffffffffff (128TB). Então, de alguma forma isso faz /proc/kcore 128TB ... mas isso é porque um desses pedaços é mapeado para /proc/kcore e um não é? Ou algum outro motivo?

Como exemplo, posso usar gdb para analisar /proc/kcore e encontrar, por exemplo, a localização (?) da sys_call_table:

(gdb) p (unsigned long*) sys_call_table
$1 = (unsigned long *) 0xffffffff811a4f20 <sys_read>

Isso significa que o pedaço de memória de 0xffff8000000000000 para 0xffffffffffffffff é o que está em /proc/kcore ? E se sim, como isso é mapeado para /proc/kcore ? Por exemplo, usando

dd if=/proc/kcore bs=1 skip=2128982200 count=100 | xxd

mostra apenas zeros (2128982200 é um pouco antes 0xffffffffffffffff-0xffffffff811a4f20) ...

Além disso, sei como usar gcore para despejar a memória de um determinado processo para análise. E eu também sei que posso olhar em /proc/PID/maps para ver como é a memória do processo ... mas mesmo assim eu ainda não tenho idéia de como descarregar toda a memória física ... e é meio que me deixando louco. Por favor me ajude a evitar ficar louco ...;)

    
por hft 20.02.2015 / 03:26

2 respostas

4

Depois de muito mais pesquisas, acho que me convenci de que não há uma maneira simples de conseguir o que eu quero.

Então, o que acabei fazendo? Eu instalei o LiME no github ( link )

git clone https://github.com/504ensicsLabs/LiMe
cd /LiME/src
make -C /lib/modules/'uname -r'/build M=$PWD modules

Os comandos acima criam o módulo do kernel lime.ko. Um despejo completo de memória pode ser obtido executando:

insmod ./lime.ko "path=/root/temp/outputDump.bin format=raw dio=0"

que apenas insere o módulo do kernel e a string são os parâmetros que especificam a localização e o formato do arquivo de saída ... E ele funcionou! YAY.

    
por 20.02.2015 / 07:06
1

Você deve dar uma olhada na saída deste comando sudo readelf -e -g -t /proc/kcore . Você pode ter o deslocamento para cada espaço de endereço virtual e, em seguida, despejá-lo por lseek () e read ().

Custou muito para mim descobrir isso. Primeiro, pensei que fosse o mapeamento de endereço virtual somente leitura. Como / dev / kmem, mas sem permissões de gravação ... e quando eu li é um arquivo pseudo ELF com o acesso à RAM, que pode ser acessado com utilitários binários ELF, eu tentei ler-se.

Então, tudo bem.

    
por 02.02.2018 / 06:08