Řešení 1:
Vytvořil jsem skript, který tento úkol splňuje.
Myšlenka pochází z odpovědi Jamese Lawrieho a tohoto příspěvku:http://www.linuxforums.org/forum/programming-scripting/52375-reading-memory-other-processes.html#post287195
#!/bin/bash
grep rw-p /proc/$1/maps \
| sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' \
| while read start stop; do \
gdb --batch --pid $1 -ex \
"dump memory $1-$start-$stop.dump 0x$start 0x$stop"; \
done
vložte to do souboru (např. "dump-all-memory-of-pid.sh") a udělejte jej spustitelný
použití:./dump-all-memory-of-pid.sh [pid]
Výstup se vytiskne do souborů s názvy:pid-startaddress-stopaddress.dump
Závislosti:gdb
Řešení 2:
Nejsem si jistý, jak vypsat veškerou paměť do souboru, aniž byste to dělali opakovaně (pokud někdo zná automatizovaný způsob, jak to udělat gdb, dejte mi prosím vědět), ale následující funguje pro jakoukoli jednu dávku paměti za předpokladu, že víte pid:
$ cat /proc/[pid]/maps
Bude to ve formátu (příklad):
00400000-00421000 r-xp 00000000 08:01 592398 /usr/libexec/dovecot/pop3-login
00621000-00622000 rw-p 00021000 08:01 592398 /usr/libexec/dovecot/pop3-login
00622000-0066a000 rw-p 00622000 00:00 0 [heap]
3e73200000-3e7321c000 r-xp 00000000 08:01 229378 /lib64/ld-2.5.so
3e7341b000-3e7341c000 r--p 0001b000 08:01 229378 /lib64/ld-2.5.so
Vyberte jednu dávku paměti (takže například 00621000-00622000), poté použijte gdb jako root pro připojení k procesu a vypište tuto paměť:
$ gdb --pid [pid]
(gdb) dump memory /root/output 0x00621000 0x00622000
Poté analyzujte /root/output pomocí příkazu strings, aniž byste potřebovali PuTTY po celé obrazovce.
Řešení 3:
zkuste
gcore $pid
kde $pid
je skutečné číslo pid; pro více informací viz:info gcore
může nějakou dobu trvat, než dojde k výpisu, a některá paměť nemusí být čitelná, ale je dost dobrá... uvědomte si také, že dokáže vytvářet velké soubory, právě jsem tímto způsobem vytvořil 2GB soubor..
Řešení 4:
Čistý bash řešení:
procdump()
(
cat /proc/$1/maps | grep "rw-p" | awk '{print $1}' | ( IFS="-"
while read a b; do
dd if=/proc/$1/mem bs=$( getconf PAGESIZE ) iflag=skip_bytes,count_bytes \
skip=$(( 0x$a )) count=$(( 0x$b - 0x$a )) of="$1_mem_$a.bin"
done )
)
Použití:procdump PID
pro čistší výpis odfiltrujte *.so
sdílené knihovny mapované do paměti a rozsahy prázdné paměti:
procdump()
(
cat /proc/$1/maps | grep -Fv ".so" | grep " 0 " | awk '{print $1}' | ( IFS="-"
while read a b; do
dd if=/proc/$1/mem bs=$( getconf PAGESIZE ) iflag=skip_bytes,count_bytes \
skip=$(( 0x$a )) count=$(( 0x$b - 0x$a )) of="$1_mem_$a.bin"
done )
)
Řešení 5:
man proc říká:
/proc/[pid]/memTento soubor lze použít pro přístup na stránky paměti procesu pomocí open(2), read(2) a lseek(2).
Možná vám to pomůže