echo "hello world" > text.txt sh bazdmeg.py bazdmeg.py: line 5: syntax error near unexpected token `(' bazdmeg.py: line 5: `c_ptrace = ctypes.CDLL("libc.so.6").ptrace' cat bazdmeg.py #! /usr/bin/env python import ctypes, re, sys ## Partial interface to ptrace(2), only for PTRACE_ATTACH and PTRACE_DETACH. c_ptrace = ctypes.CDLL("libc.so.6").ptrace c_pid_t = ctypes.c_int32 # This assumes pid_t is int32_t c_ptrace.argtypes = [ctypes.c_int, c_pid_t, ctypes.c_void_p, ctypes.c_void_p] def ptrace(attach, pid): op = ctypes.c_int(16 if attach else 17) #PTRACE_ATTACH or PTRACE_DETACH c_pid = c_pid_t(pid) null = ctypes.c_void_p() err = c_ptrace(op, c_pid, null, null) if err != 0: raise SysError, 'ptrace', err ## Parse a line in /proc/$pid/maps. Return the boundaries of the chunk ## the read permission character. def maps_line_range(line): m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) return [int(m.group(1), 16), int(m.group(2), 16), m.group(3)] ## Dump the readable chunks of memory mapped by a process def cat_proc_mem(pid): ## Apparently we need to ptrace(PTRACE_ATTACH, $pid) to read /proc/$pid/mem ptrace(True, int(pid)) ## Read the memory maps to see what address ranges are readable maps_file = open("/proc/" + pid + "/maps", 'r') ranges = map(maps_line_range, maps_file.readlines()) maps_file.close() ## Read the readable mapped ranges mem_file = open("/proc/" + pid + "/mem", 'r', 0) for r in ranges: if r[2] == 'r': mem_file.seek(r[0]) chunk = mem_file.read(r[1] - r[0]) print chunk, mem_file.close() ## Cleanup ptrace(False, int(pid)) if __name__ == "__main__": for pid in sys.argv[1:]: cat_proc_mem(pid)