Слить память процесса Linux в файл

Вопрос или проблема

Можно ли выгрузить текущее выделенное для процесса (по PID) содержимое памяти в файл? Или как-то прочитать его?

Я не уверен, как вы можете выгрузить всю память в файл, не делая это многократно (если кто-то знает автоматизированный способ сделать это с помощью gdb, пожалуйста, дайте мне знать), но следующее работает для любой одной порции памяти, если вы знаете pid:

$ cat /proc/[pid]/maps

Это будет в следующем формате (пример):

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

Выберите одну порцию памяти (например, 00621000-00622000), затем используйте gdb с правами root, чтобы подключиться к процессу и выгрузить эту память:

$ gdb --pid [pid]
(gdb) dump memory /root/output 0x00621000 0x00622000

Затем проанализируйте /root/output с помощью команды strings, если не хотите заполнять весь экран выводом PuTTY.

Я создал скрипт, который выполняет эту задачу.

Идея пришла из ответа Джеймса Лори и этого поста: https://web.archive.org/web/20190921091546/http://www.linuxforums.org/forum/programming-scripting/52375-reading-memory-other-processes-post287195.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

Положите это в файл (например, “dump-all-memory-of-pid.sh”) и сделайте его исполняемым

Использование: ./dump-all-memory-of-pid.sh [pid]

Вывод записывается в файлы с именами: pid-startaddress-stopaddress.dump

Зависимости: gdb

Попробуйте

    gcore $pid

где $pid — это актуальный номер pid; для получения дополнительной информации смотрите: info gcore

Выгрузка может занять некоторое время, и некоторая память может быть недоступна для чтения, но этого достаточно… также обратите внимание, что это может создать большие файлы, я только что создал файл размером 2 ГБ таким образом..

Чистое решение на bash:

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 )
)

Использование: procdump PID

Для более чистой выгрузки отфильтруйте *.so – общие библиотеки и пустые области памяти:

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 )
)

Я также создал свою программу для выгрузки всей памяти процесса, она на C, поэтому её можно кросс-компилировать для Android, что мне и нужно было.

Вы также можете указать IP-адрес и tcp-порт. Исходный код здесь.

man proc говорит :

/proc/[pid]/mem
Этот файл можно использовать для доступа к страницам памяти процесса через open(2), read(2) и lseek(2).

Может быть, это поможет вам

Инструмент для выгрузки процесса в стандартный вывод, pcat/memdump:

Теперь вы можете использовать procdump из пакета SysInternals на Linux:

https://github.com/Microsoft/ProcDump-for-Linux

Если вы хотите выгрузить отдельный сегмент памяти работающего процесса без создания огромного core-файла (скажем, с помощью gcore), вы можете использовать небольшой инструмент здесь.
Есть также однострочник в README, если вы хотите выгрузить все читаемые сегменты в отдельные файлы.

Ответ или решение

Да, возможно создать дамп памяти текущего процесса в файл в Linux, используя различные методы и инструменты. Ниже рассматриваются несколько способов, как это можно сделать:

1. Использование GDB

gdb (GNU Debugger) позволяет прикрепиться к работающему процессу и выполнить дамп его памяти. Для этого выполните следующие шаги:

  1. Просмотрите карты памяти процесса (замените [pid] на фактический идентификатор процесса):

    cat /proc/[pid]/maps
  2. Выберите диапазон памяти, который хотите сохранить. Например:

    00621000-00622000 rw-p 00021000 08:01 592398                             /usr/libexec/dovecot/pop3-login
  3. Прикрепитесь к процессу с помощью gdb:

    sudo gdb --pid [pid]
  4. Выполните дамп выбранного диапазона:

    dump memory /root/output 0x00621000 0x00622000

После этого файл /root/output будет содержать дамп выбранного участка памяти.

2. Скрипт для автоматического дампа всей памяти процесса

Вы можете создать скрипт, который будет проходить по всем разделам памяти, отображаемым в /proc/[pid]/maps, и создавать дампы для каждого из них:

#!/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

Сохраните этот код в файл, например, dump-all-memory-of-pid.sh, и сделайте его исполняемым:

chmod +x dump-all-memory-of-pid.sh

Используйте его следующим образом:

./dump-all-memory-of-pid.sh [pid]

3. Использование команды gcore

Если вам не нужен детальный контроль и вы просто хотите получить полный дамп памяти процесса, можно воспользоваться командой gcore:

gcore [pid]

Эта команда создаст файл дампа, названный core.[pid], который содержит всю память процесса. Учтите, что файл дампа может занимать много места.

4. Чистый Bash способ

Вот пример функции на Bash, которая также выполняет дамп памяти, используя /proc/[pid]/mem:

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 )
)

Используйте функцию, передавая PID процесса:

procdump [pid]

5. Дополнительные инструменты

Существуют и другие инструменты, которые могут помочь с дампом памяти:

  • pcat/memdump – инструменты, которые могут использоваться для вывода памяти процесса в стандартный вывод.
  • ProcDump for Linux – утилита из набора SysInternals, доступная на GitHub, которая может быть использована для дампа процессов в Linux.

Заключение

Все описанные методы могут быть использованы для создания дампа памяти процесса. Выбор конкретного способа зависит от ваших нужд: если вам необходим полный дамп, воспользуйтесь gcore. Если требуется более детальный контроль, используйте gdb или написанный скрипт.

Оцените материал
Добавить комментарий

Капча загружается...