以下python 脚本可以读取一个进程的某个内存区域的内容:
#!/usr/bin/env python
import re
import sys
def dump_memory_region_by_pid(pid, region, of):
print "PID = %d, find region ..." % pid
with open("/proc/%d/maps" % pid, 'r') as maps_file:
with open("/proc/%d/mem" % pid, 'r') as mem_file:
for line in maps_file.readlines(): # for each mapped region
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-rw][-rw])(.*)\[(.*)\]', line)
if m == None:
continue
if m.group(5) == region:
print "find region " + m.group(5)
start = int(m.group(1), 16)
end = int(m.group(2), 16)
if start > 0xFFFFFFFFFFFF:
print "start too big: " + str(start) + ", skip"
continue
print "start = " + str(start) + ", end = " + str(end)
mem_file.seek(start) # seek to region start
chunk = mem_file.read(end - start) # read region contents
with open(of, 'w') as of_file:
of_file.write(chunk)
print "dumped " + region + " to file " + of
break
else:
print "skip region " + m.group(5)
if __name__ == '__main__':
try:
assert len(sys.argv) == 2, "Provide exactly 1 PID (process ID)"
pid = int(sys.argv[1])
dump_memory_region_by_pid(pid, "vdso", "vdso.dd")
except (AssertionError, ValueError) as e:
print "Please provide 1 PID as a commandline argument."
print "You entered: %s" % ' '.join(sys.argv)
raise e
其实通过以下命令也可以手动来dump,但我在使用的过程中遇到dd报skip的错。
1)查看内存区域的起始位置和长度,从下面的输出可以知道xxx区域的起始位置为0xffffffc000,长度是0x4000
$ cat /proc/xxx/maps |grep xxxx
ffffffc000-10000000000 r-xp 00000000 00:00 0 [xxxx]
2)使用dd读取内存区域的内容,其中的skip就是该内存区域的起始位置,count为长度,都是10进制
$ dd if=/proc/xxx/mem of=xxx.dd bs=1 skip=1099511611392 count=16384
参考资料
1 https://stackoverflow.com/questions/12977179/reading-living-process-memory-without-interrupting-it