[Python]根据地址从maps文件中找相应的库名

/proc/PID/maps提供了进程的memory layout,下面脚本根据给定地址找出相应的库名:

#!/usr/bin/python
from __future__ import print_function
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import bisect
import re
import lp_util

VERBOSE = False 

def process(line, mapset):
	pattern = r'([0-9a-f]+)-([0-9a-f]+) ([rwxps-]+) ([0-9a-f]+) ([0-9a-f:]+) ([0-9]+)s+(S*)'
	match_obj = re.match(pattern, line)
	if match_obj is not None:
		one_mapping = match_obj.group(0)
		addr_start = int(match_obj.group(1), 16)
		addr_end = int(match_obj.group(2), 16)
		permission = match_obj.group(3)
		offset = match_obj.group(4)
		device = match_obj.group(5)
		inode = match_obj.group(6)
		pathname = match_obj.group(7)
		print(hex(addr_start), hex(addr_end), permission, offset, device, inode, pathname)
		mapset.append({'addr_start':addr_start, 'addr_end':addr_end, 'permission':permission, 'offset':offset, 'device':device, 'inode':inode, 'pathname':pathname})
	else:
		print("Invalid maps")

def usage():
	print("usage:", sys.argv[0], "maps_file")

def find_map(mapset, keys, addr):
	addr = int(addr, 16)
	index = bisect.bisect_right(keys, addr)
	if VERBOSE:
		print("addr = ", addr)
		print("index = ", index)
		print(keys)

	if index == 0:
		return None
	if addr < mapset[index - 1]['addr_end']:
		return mapset[index - 1]
	else:
		return None

def main():
	argc = len(sys.argv)
	if argc != 2:
		usage()
		sys.exit()

	try:
		in_file = open(sys.argv[1], "r")
	except:
		sys.exit("Error opening file ", sys.argv[1])

	mapset = []
	while True:
		line = in_file.readline()
		if not line:
			break
		process(line, mapset)
	in_file.close()

	print("Parsing done, item num = ", len(mapset))

	mapset.sort(key = lambda r:r['addr_start'])
	keys = [r['addr_start'] for r in mapset]

	while True:
		addr = raw_input("Please enter an address:")
		if not lp_util.addr_is_valid(addr):
			print("Invalid input")
			continue
		
		map_item = find_map(mapset, keys, addr)
		if map_item is not None:
			print("lib name = ", map_item['pathname'])
		else:
			print("Not found")

if __name__ == "__main__":
    main()


lp_util.py中为一个简单的地址格式检查函数,保证不要错得太离谱

import re

def addr_is_valid(addr):
	match_obj = re.match(r'^(0x)?[0-9a-f]{1,}$', addr)
	return match_obj is not None


如maps文件为:

00400000-00409000 r-xp 00000000 08:01 1835099                            /usr/bin/bluetooth-applet
00608000-00609000 r--p 00008000 08:01 1835099                            /usr/bin/bluetooth-applet
00609000-0060a000 rw-p 00009000 08:01 1835099                            /usr/bin/bluetooth-applet
00861000-00af8000 rw-p 00000000 00:00 0                                  [heap]
7f7164000000-7f7164022000 rw-p 00000000 00:00 0
7f7164022000-7f7168000000 ---p 00000000 00:00 0
7f7168000000-7f7168022000 rw-p 00000000 00:00 0
7f7168022000-7f716c000000 ---p 00000000 00:00 0
7f716d1c3000-7f716d314000 r-xp 00000000 08:01 1836558                    /usr/lib/x86_64-linux-gnu/libxml2.so.2.7.8
7f716d314000-7f716d513000 ---p 00151000 08:01 1836558                    /usr/lib/x86_64-linux-gnu/libxml2.so.2.7.8
7f716d513000-7f716d51b000 r--p 00150000 08:01 1836558                    /usr/lib/x86_64-linux-gnu/libxml2.so.2.7.8
7f716d51b000-7f716d51d000 rw-p 00158000 08:01 1836558                    /usr/lib/x86_64-linux-gnu/libxml2.so.2.7.8
7f716d51d000-7f716d51e000 rw-p 00000000 00:00 0
7f716d51e000-7f716e713000 r--p 00000000 08:01 2917167                    /usr/share/icons/hicolor/icon-theme.cache
7f716e713000-7f716effe000 r--p 00000000 08:01 2752557                    /usr/share/icons/gnome/icon-theme.cache

...


输入0x7f716d513123,输出相应的库名/usr/lib/x86_64-linux-gnu/libxml2.so.2.7.8

原文地址:https://www.cnblogs.com/jiangu66/p/3167724.html