tl;dr
If you need to acquire the process memory of a process running on a
Linux system, you can use gcore
1 to create a core file or,
alternatively, retrieve its memory areas from /proc/<PID>/maps
and
use GDB 2 itself to dump the content into a file. For a
convenient way to do this, refer to a basic shell script hosted as a
gist named dump_pmem.sh
3.
Motivation
It is well known that process memory contains a wealth of information; therefore, it is often needed to inspect the memory contents of a specific process. Since I wanted to write autopkgtests for the continuous integration of memory forensics software packaged as Debian packages, I was looking for a convenient way to dump the process memory (preferably with on-board equipment).
One-liner solution
I found a neat solution from A. Nilsson on serverfault.com 4,
which I enhanced to create a single output file. Basically, it reads
all memory areas from the proc-filesystem, which is a
pseudo-filesystem providing an interface to kernel data
structures 5 and then utilizies gdb
's memory dumping capability
to copy those memory regions into a file 6.
To use the one-liner-solution, which is a bit ugly indeed, just modify the PID and run the following command:
sudo su -; \ PID=2633; \ grep rw-p /proc/${PID}/maps \ | sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1\t\2/p' \ | while read start stop; \ do sudo gdb --batch --pid ${PID} -ex "append memory ${PID}.dump 0x$start 0x$stop" > /dev/null 2>&1; \ done;
Note, that GDB has to be available on the system, whereas glibc-sources are not required.
Script dump_pmem.sh
Furthermore, I created a basic shell script, which can be found at
https://gist.github.com/jgru/ca473c19fd9b81c045094121827b3548
It simplifies the process of dumping and creates an additional
acquisition log (which is printed to stderr
). Use it, like
illustrated below:
sudo ./dumpmem.sh Usage: dump_pmem.sh <PID> Example: q ./dump_pmem.sh 1137 > 1337.dmp
Note that root-permissions are needed for obvious reasons, and a
process ID has to be supplied as positional argument. The resulting
output has to be redirected to a file. Informational output will be
printed to stderr
, which might look like the following snippet:
2021-05-27T08:48:34+02:00 Starting acquision of process 1337 2021-05-27T08:48:34+02:00 Proc cmdline: "opensslenc-aes-256-cbc-k-p-mdsha1" 2021-05-27T08:48:34+02:00 Dumping 55a195984000 - 55a19598c000 2021-05-27T08:48:34+02:00 Dumping 55a19598c000 - 55a19598e000 <snip> 2021-05-27T08:48:36+02:00 Dumping 7f990d714000 - 7f990d715000 2021-05-27T08:48:37+02:00 Dumping 7ffe3413f000 - 7ffe34160000 2021-05-27T08:48:37+02:00 Resulting SHA512: cb4e949c7b...
Note, that the script currently does not performs zero-padding for recreating the virtual address space as seen by the process.
Footnotes:
gcore
is part of the GNU debugger gdb
, see https://manpages.debian.org/buster/gdb/gcore.1.en.html