Skip to main content
stick to a python 2/3 polyglot to avoid clutter
Source Link
Gilles 'SO- stop being evil'
  • 865.9k
  • 205
  • 1.8k
  • 2.3k
#! /usr/bin/env python2python import re maps_file = open("/proc/self/maps", 'r') mem_file = open("/proc/self/mem", 'r''rb', 0) output_file = open("self.dump", 'wb') for line in maps_file.readlines(): # for each mapped region m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) if m.group(3) == 'r': # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start chunk = mem_file.read(end - start) # read region contents print output_file.write(chunk,) # dump contents to standard output maps_file.close() mem_file.close() 

Or in Python3:

#! /usr/bin/env python3 import re with open("/proc/self/maps", "r") as maps_file: maps = maps_file.readlines() with open("/proc/self/mem", "rb", 0) as mem_file: for line in maps: # for each mapped region m = re.match(r"([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])", line) if not m: continue  if m.group(3) == "r": # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start try: chunk = mem_fileoutput_file.read(end - start) # read region contents printclose(chunk) # dump contents to standard output except IOError: pass 
#! /usr/bin/env python2 import re maps_file = open("/proc/self/maps", 'r') mem_file = open("/proc/self/mem", 'r', 0) for line in maps_file.readlines(): # for each mapped region m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) if m.group(3) == 'r': # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start chunk = mem_file.read(end - start) # read region contents print chunk, # dump contents to standard output maps_file.close() mem_file.close() 

Or in Python3:

#! /usr/bin/env python3 import re with open("/proc/self/maps", "r") as maps_file: maps = maps_file.readlines() with open("/proc/self/mem", "rb", 0) as mem_file: for line in maps: # for each mapped region m = re.match(r"([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])", line) if not m: continue  if m.group(3) == "r": # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start try: chunk = mem_file.read(end - start) # read region contents print(chunk) # dump contents to standard output except IOError: pass 
#! /usr/bin/env python import re maps_file = open("/proc/self/maps", 'r') mem_file = open("/proc/self/mem", 'rb', 0) output_file = open("self.dump", 'wb') for line in maps_file.readlines(): # for each mapped region m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) if m.group(3) == 'r': # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start chunk = mem_file.read(end - start) # read region contents output_file.write(chunk) # dump contents to standard output maps_file.close() mem_file.close() output_file.close() 
#! /usr/bin/env pythonpython2 import re maps_file = open("/proc/self/maps", 'r') mem_file = open("/proc/self/mem", 'r', 0) for line in maps_file.readlines(): # for each mapped region m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) if m.group(3) == 'r': # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start chunk = mem_file.read(end - start) # read region contents print chunk, # dump contents to standard output maps_file.close() mem_file.close() 

Or in Python3:

#! /usr/bin/env python3 import re with open("/proc/self/maps", "r") as maps_file: maps = maps_file.readlines() with open("/proc/self/mem", "rb", 0) as mem_file: for line in maps: # for each mapped region m = re.match(r"([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])", line) if not m: continue if m.group(3) == "r": # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start try: chunk = mem_file.read(end - start) # read region contents print(chunk) # dump contents to standard output except IOError: pass 
#! /usr/bin/env python import re maps_file = open("/proc/self/maps", 'r') mem_file = open("/proc/self/mem", 'r', 0) for line in maps_file.readlines(): # for each mapped region m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) if m.group(3) == 'r': # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start chunk = mem_file.read(end - start) # read region contents print chunk, # dump contents to standard output maps_file.close() mem_file.close() 
#! /usr/bin/env python2 import re maps_file = open("/proc/self/maps", 'r') mem_file = open("/proc/self/mem", 'r', 0) for line in maps_file.readlines(): # for each mapped region m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) if m.group(3) == 'r': # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start chunk = mem_file.read(end - start) # read region contents print chunk, # dump contents to standard output maps_file.close() mem_file.close() 

Or in Python3:

#! /usr/bin/env python3 import re with open("/proc/self/maps", "r") as maps_file: maps = maps_file.readlines() with open("/proc/self/mem", "rb", 0) as mem_file: for line in maps: # for each mapped region m = re.match(r"([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])", line) if not m: continue if m.group(3) == "r": # if this is a readable region start = int(m.group(1), 16) end = int(m.group(2), 16) mem_file.seek(start) # seek to region start try: chunk = mem_file.read(end - start) # read region contents print(chunk) # dump contents to standard output except IOError: pass 
deleted 11 characters in body
Source Link
Gilles 'SO- stop being evil'
  • 865.9k
  • 205
  • 1.8k
  • 2.3k

[The following is for historical interest. It does not apply to current kernels.]

Since 2012version 3.3 of the kernel, you can access /proc/$pid/mem normally as long as $pid is a dumpable process of yours (i.e. not setuid/setgid/set-caps/etc) or you access only access it at mapped offsets and you have CAP_SYS_PTRACE capabilitypermission to trace it (i.e. you're rootsame permissions as ptrace for read-only access).

  But at the time this answer was writtenin older kernels, there were some additional complications.

[the following is for historical interest; it no longer applies to any recent system]

Since 2012, you can access /proc/$pid/mem normally as long as $pid is a dumpable process of yours (i.e. not setuid/setgid/set-caps/etc) or you have CAP_SYS_PTRACE capability (i.e. you're root).

  But at the time this answer was written, there were some additional complications.

[the following is for historical interest; it no longer applies to any recent system]

[The following is for historical interest. It does not apply to current kernels.]

Since version 3.3 of the kernel, you can access /proc/$pid/mem normally as long as you access only access it at mapped offsets and you have permission to trace it (same permissions as ptrace for read-only access). But in older kernels, there were some additional complications.

Clarify the conditions which should be met for reading another process's memory. Make clear to people who come here from searches that the security considerations about permissions / source code references / etc from the latter part are no longer current
Source Link
Loading
deleted 24 characters in body
Source Link
Gilles 'SO- stop being evil'
  • 865.9k
  • 205
  • 1.8k
  • 2.3k
Loading
content warning; NOTE that "constructive criticism" was submitted since more than a year, but no action was taken; MOREOVER this answer is the first thing which appears in searches, despite a wealth of primary sources and correct information on the matter
Source Link
Loading
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
Loading
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/
Source Link
Loading
discuss root observer
Source Link
Gilles 'SO- stop being evil'
  • 865.9k
  • 205
  • 1.8k
  • 2.3k
Loading
Source Link
Gilles 'SO- stop being evil'
  • 865.9k
  • 205
  • 1.8k
  • 2.3k
Loading