|
|
|
@ -310,7 +310,7 @@ def coredump_maps() -> Tuple[pwndbg.lib.memory.Page, ...]:
|
|
|
|
Parses `info proc mappings` and `maintenance info sections`
|
|
|
|
Parses `info proc mappings` and `maintenance info sections`
|
|
|
|
and tries to make sense out of the result :)
|
|
|
|
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
|
|
|
|
started_sections = False
|
|
|
|
for line in gdb.execute("maintenance info sections", to_string=True).splitlines():
|
|
|
|
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)
|
|
|
|
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
|
|
|
|
Parse a line from `info proc mappings` and return a pwndbg.lib.memory.Page
|
|
|
|
object if the line is valid.
|
|
|
|
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:
|
|
|
|
Args:
|
|
|
|
line: A line from `info proc mappings`.
|
|
|
|
line: A line from `info proc mappings`.
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Returns:
|
|
|
|
A pwndbg.lib.memory.Page object or None.
|
|
|
|
A pwndbg.lib.memory.Page object or None.
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
# We look for lines like:
|
|
|
|
|
|
|
|
# ['0x555555555000', '0x555555556000', '0x1000', '0x1000', 'rw-p', '/home/user/a.out']
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
|
|
|
|
# Example line with all fields present: ['0x555555555000', '0x555555556000', '0x1000', '0x1000', 'rw-p', '/home/user/a.out']
|
|
|
|
split_line = line.split()
|
|
|
|
split_line = line.split()
|
|
|
|
|
|
|
|
|
|
|
|
# Permission info is only available in GDB versions >=12.1
|
|
|
|
start_str = split_line[0]
|
|
|
|
# https://github.com/bminor/binutils-gdb/commit/29ef4c0699e1b46d41ade00ae07a54f979ea21cc
|
|
|
|
_end = split_line[1]
|
|
|
|
# Assume "rwxp" on older gdb versions
|
|
|
|
size_str = split_line[2]
|
|
|
|
if len(split_line) < 6:
|
|
|
|
offset_str = split_line[3]
|
|
|
|
start_str, _end, size_str, offset_str, objfile = split_line
|
|
|
|
|
|
|
|
perm = "rwxp"
|
|
|
|
if perms_available:
|
|
|
|
|
|
|
|
perm = split_line[4]
|
|
|
|
|
|
|
|
# The objfile column may be empty.
|
|
|
|
|
|
|
|
objfile = split_line[5] if len(split_line) > 5 else ""
|
|
|
|
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)
|
|
|
|
start, size, offset = int(start_str, 16), int(size_str, 16), int(offset_str, 16)
|
|
|
|
except (IndexError, ValueError):
|
|
|
|
except (IndexError, ValueError):
|
|
|
|
return None
|
|
|
|
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")
|
|
|
|
@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.
|
|
|
|
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.
|
|
|
|
Note: this may return no pages due to a bug/behavior of GDB.
|
|
|
|
See https://sourceware.org/bugzilla/show_bug.cgi?id=31207
|
|
|
|
See https://sourceware.org/bugzilla/show_bug.cgi?id=31207
|
|
|
|
for more information.
|
|
|
|
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.
|
|
|
|
# On qemu user emulation, we may get: gdb.error: Not supported on this target.
|
|
|
|
info_proc_mappings = []
|
|
|
|
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] = []
|
|
|
|
pages: List[pwndbg.lib.memory.Page] = []
|
|
|
|
for line in info_proc_mappings:
|
|
|
|
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:
|
|
|
|
if page is not None:
|
|
|
|
pages.append(page)
|
|
|
|
pages.append(page)
|
|
|
|
|
|
|
|
|
|
|
|
|