69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
import bisect
|
|
import os
|
|
import re
|
|
import subprocess
|
|
|
|
# __pattern = re.compile(r"([0-9a-f]+)-([0-9a-f]+) [\w-]+ [\w:]+ [\w:]+ \S+ (.*?)\n")
|
|
|
|
|
|
class ProcMapsParser:
|
|
__pattern = re.compile(r"([0-9a-f]+)-([0-9a-f]+) [\w-]+ [\w:]+ [\w:]+ \S+ (.*?)\n")
|
|
|
|
def __init__(self, pid):
|
|
self.ranges = []
|
|
self.names = []
|
|
try:
|
|
with open(f"/proc/{pid}/maps", "r") as f:
|
|
for line in f:
|
|
m = self.__pattern.match(line)
|
|
if m is not None:
|
|
start, end, name = m.groups()
|
|
# remove " "
|
|
name = name.strip()
|
|
start = int(start, 16)
|
|
end = int(end, 16)
|
|
if name == "" or name == None:
|
|
name = None
|
|
elif not os.path.isabs(name):
|
|
name = None
|
|
self.ranges.append((start, end))
|
|
self.names.append(name)
|
|
except FileNotFoundError:
|
|
return None
|
|
|
|
def lookup(self, addr):
|
|
# 内核空间地址通常在高内存区域,我们设定一个阈值为 0x7fffffffffff
|
|
if addr > 0x7FFFFFFFFFFF:
|
|
return "kernel", addr
|
|
i = bisect.bisect(self.ranges, (addr, addr)) - 1
|
|
if i >= 0 and self.ranges[i][0] <= addr < self.ranges[i][1]:
|
|
offset = addr - self.ranges[i][0]
|
|
return self.names[i], offset
|
|
return None, None
|
|
|
|
|
|
__pattern = re.compile(r"([0-9a-f]+) ([Tt]) (.*)")
|
|
|
|
|
|
def addr_to_symbol(path, offset):
|
|
output = subprocess.check_output(["nm", "-D", path])
|
|
lines = output.decode().splitlines()
|
|
lines = [line for line in lines if " " in line]
|
|
lines.sort() # Sort by address
|
|
prev_sym = None
|
|
for line in lines:
|
|
match = __pattern.match(line)
|
|
if match is None: # Skip if the line does not match the pattern
|
|
continue
|
|
addr_str, type_, sym = match.groups()
|
|
addr = int(addr_str, 16)
|
|
if addr > offset:
|
|
return prev_sym
|
|
prev_sym = sym
|
|
return prev_sym
|
|
|
|
|
|
# 使用示例:
|
|
# p = ProcMapsParser(1234) # 请将 1234 替换成你想要查询的进程 ID
|
|
# print(p.lookup(0x7FF6C4D2D000)) # 将这里的地址替换成你想要查询的地址
|