Reading living process memory without interrupting it

If you have root access and are on a linux system, you can use the following linux script (adapted from Gilles’ excellent unix.stackexchange.com answer and the answer originally given in the question above but including SyntaxErrors and not being pythonic):

#!/usr/bin/env python3

import re
import sys

def print_memory_of_pid(pid, only_writable=True):
    """ 
    Run as root, take an integer PID and return the contents of memory to STDOUT
    """
    memory_permissions = b'rw' if only_writable else b'r-'
    sys.stderr.write("PID = %d" % pid)
    with open("/proc/%d/maps" % pid, 'rb') as maps_file:
        with open("/proc/%d/mem" % pid, 'rb', 0) as mem_file:
            for line in maps_file.readlines():  # for each mapped region
                m = re.match(rb'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r][-w])', line)
                if m.group(3) == memory_permissions:
                    sys.stderr.buffer.write(b"\nOK : \n" + line + b"\n")
                    start = int(m.group(1), 16)
                    if start > 0xFFFFFFFFFFFF:
                        continue
                    end = int(m.group(2), 16)
                    sys.stderr.write("start = " + str(start) + "\n")
                    mem_file.seek(start)  # seek to region start
                    chunk = mem_file.read(end - start)  # read region contents
                    sys.stdout.buffer.write(chunk)  # dump contents to standard output
                else:
                    sys.stderr.buffer.write(b"\nPASS : \n" + line + b"\n")

if __name__ == '__main__': # Execute this code when run from the commandline.
    try:
        assert len(sys.argv) == 2, "Provide exactly 1 PID (process ID)"
        pid = int(sys.argv[1])
        print_memory_of_pid(pid)
    except (AssertionError, ValueError) as e:
        print("Please provide 1 PID as a commandline argument.")
        print("You entered: %s" % ' '.join(sys.argv))
        raise e

If you save this as write_mem.py, you can run this with python3 (for python2.5–2.7, see the edit history of this answer) as:

sudo python3 write_mem.py 1234 > pid1234_memory_dump

to dump pid1234 memory to the file pid1234_memory_dump. To suppress the debug messages printed to stderr, 2>/dev/null can be added.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)