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}')
how to open and an analyze this .dump file?
Hello there!
The dump file is a binary blob, so you need some binary viewer to look at it. You can use “hexdump -Cv 1234.dump” to look at the contained bytes, you can look for strings in it using “strings 1234.dump” or you can try to use forensic tools like “volatility”.
Hope that helps!