Skip to content

How to dump process memory in Linux

I wanted to know this for such a long time and never had enough motivation to look it up properly. Turns out it is so easy that no one ever writes down a script to do it properly on the Internet. Also I could not find any tools that reliably dumped the memory of processes, no idea why.

I wrote a quick Python 3 script that reads the relevant files from a Linux OS and dumps everything into a single file. This even worked with my password manager, where I was able to extract some passwords from.

How it works

Linux has a lot of information about processes that you can access by looking at the /proc directory. Assuming our process has the process ID (PID) of 1337, we can look into /proc/1337 and find everything we need to analyze the process. There is also /proc/self which always points to the current process, so a program can analyze itself during runtime.

The relevant files for memory are /proc/<PID>/mem and /proc/<PID>/maps. The former is a link into memory and can be read like any regular file, while the latter is used to discover the actual memory addresses for the process. We will use maps to find the correct addresses

Just gimme the code!

Here it is. Enjoy. Do not forget to execute this as privileged root user, else you can not access any memory outside of your “self” memory. Invocation is:

python3 memdump.py <PID>  # PID can also be 'self'

Here is memdump.py:

#! /usr/bin/env python3
import sys
import re

if __name__ == "__main__":

    if len(sys.argv) != 2:
        print('Usage:', sys.argv[0], '<process PID>', file=sys.stderr)
        exit(1)

    pid = sys.argv[1]

    # maps contains the mapping of memory of a specific project
    map_file = f"/proc/{pid}/maps"
    mem_file = f"/proc/{pid}/mem"

    # output file
    out_file = f'{pid}.dump'

    # iterate over regions
    with open(map_file, 'r') as map_f, open(mem_file, 'rb', 0) as mem_f, open(out_file, 'wb') as out_f:
        for line in map_f.readlines():  # for each mapped region
            m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
            if m.group(3) == 'r':  # readable region
                start = int(m.group(1), 16)
                end = int(m.group(2), 16)
                mem_f.seek(start)  # seek to region start
                print(hex(start), '-', hex(end))
                try:
                    chunk = mem_f.read(end - start)  # read region contents
                    out_f.write(chunk)  # dump contents to standard output
                except OSError:
                    print(hex(start), '-', hex(end), '[error,skipped]', file=sys.stderr)
                    continue
    print(f'Memory dump saved to {out_file}')

Published inIT-SecurityTips and Tricks

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *