Fix vmmap on remote targets (#2386)

pull/2388/head
OBarronCS 1 year ago committed by GitHub
parent 331e61a48e
commit 914110b8a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,6 +1,7 @@
from __future__ import annotations
import argparse
import os
import pwndbg
import pwndbg.color.memory as M
@ -59,6 +60,11 @@ def xinfo_mmap_file(page, addr) -> None:
# to beginning of file in memory and on disk
file_name = page.objfile
# Check if the file exists on the local system, as we may be attached to a gdb-server or qemu.
# Even so, the file might exist locally, if we are doing `target remote localhost:1234`
if not os.path.exists(file_name):
return None
objpages = filter(lambda p: p.objfile == file_name, pwndbg.gdblib.vmmap.get())
first = sorted(objpages, key=lambda p: p.vaddr)[0]

@ -310,7 +310,7 @@ def coredump_maps() -> Tuple[pwndbg.lib.memory.Page, ...]:
Parses `info proc mappings` and `maintenance info sections`
and tries to make sense out of the result :)
"""
pages = list(info_proc_maps())
pages = list(info_proc_maps(parse_flags=False))
started_sections = False
for line in gdb.execute("maintenance info sections", to_string=True).splitlines():
@ -392,31 +392,43 @@ def coredump_maps() -> Tuple[pwndbg.lib.memory.Page, ...]:
return tuple(pages)
def parse_info_proc_mappings_line(line: str, parse_flags: bool) -> Optional[pwndbg.lib.memory.Page]:
def parse_info_proc_mappings_line(
line: str, perms_available: bool, parse_flags: bool
) -> Optional[pwndbg.lib.memory.Page]:
"""
Parse a line from `info proc mappings` and return a pwndbg.lib.memory.Page
object if the line is valid.
Example lines:
0x4c3000 0x4c5000 0x2000 0xc2000 rw-p /root/hello_world/main
0x4c5000 0x4cb000 0x6000 0x0 rw-p
The objfile column might be empty, and the permissions column is only present in GDB versions >= 12.1
https://github.com/bminor/binutils-gdb/commit/29ef4c0699e1b46d41ade00ae07a54f979ea21cc
Args:
line: A line from `info proc mappings`.
Returns:
A pwndbg.lib.memory.Page object or None.
"""
# We look for lines like:
# ['0x555555555000', '0x555555556000', '0x1000', '0x1000', 'rw-p', '/home/user/a.out']
try:
# Example line with all fields present: ['0x555555555000', '0x555555556000', '0x1000', '0x1000', 'rw-p', '/home/user/a.out']
split_line = line.split()
# Permission info is only available in GDB versions >=12.1
# https://github.com/bminor/binutils-gdb/commit/29ef4c0699e1b46d41ade00ae07a54f979ea21cc
# Assume "rwxp" on older gdb versions
if len(split_line) < 6:
start_str, _end, size_str, offset_str, objfile = split_line
perm = "rwxp"
start_str = split_line[0]
_end = split_line[1]
size_str = split_line[2]
offset_str = split_line[3]
if perms_available:
perm = split_line[4]
# The objfile column may be empty.
objfile = split_line[5] if len(split_line) > 5 else ""
else:
start_str, _end, size_str, offset_str, perm, objfile = split_line
perm = "rwxp"
objfile = split_line[4] if len(split_line) > 4 else ""
start, size, offset = int(start_str, 16), int(size_str, 16), int(offset_str, 16)
except (IndexError, ValueError):
return None
@ -434,10 +446,25 @@ def parse_info_proc_mappings_line(line: str, parse_flags: bool) -> Optional[pwnd
@pwndbg.lib.cache.cache_until("start", "stop")
def info_proc_maps(parse_flags=False) -> Tuple[pwndbg.lib.memory.Page, ...]:
def info_proc_maps(parse_flags=True) -> Tuple[pwndbg.lib.memory.Page, ...]:
"""
Parse the result of info proc mappings.
Example output:
Start Addr End Addr Size Offset Perms objfile
0x400000 0x401000 0x1000 0x0 r--p /root/hello_world/main
0x401000 0x497000 0x96000 0x1000 r-xp /root/hello_world/main
0x497000 0x4be000 0x27000 0x97000 r--p /root/hello_world/main
0x4be000 0x4c3000 0x5000 0xbd000 r--p /root/hello_world/main
0x4c3000 0x4c5000 0x2000 0xc2000 rw-p /root/hello_world/main
0x4c5000 0x4cb000 0x6000 0x0 rw-p
0x4cb000 0x4ed000 0x22000 0x0 rw-p [heap]
0x7ffff7ff9000 0x7ffff7ffd000 0x4000 0x0 r--p [vvar]
0x7ffff7ffd000 0x7ffff7fff000 0x2000 0x0 r-xp [vdso]
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 rw-p [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 --xp [vsyscall]
Note: this may return no pages due to a bug/behavior of GDB.
See https://sourceware.org/bugzilla/show_bug.cgi?id=31207
for more information.
@ -453,9 +480,12 @@ def info_proc_maps(parse_flags=False) -> Tuple[pwndbg.lib.memory.Page, ...]:
# On qemu user emulation, we may get: gdb.error: Not supported on this target.
info_proc_mappings = []
# See if "Perms" is in the header line
perms_available = "Perms" in info_proc_mappings[3]
pages: List[pwndbg.lib.memory.Page] = []
for line in info_proc_mappings:
page = parse_info_proc_mappings_line(line, parse_flags)
page = parse_info_proc_mappings_line(line, perms_available, parse_flags)
if page is not None:
pages.append(page)

Loading…
Cancel
Save