Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/commands/vmmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ place). For example, you can learn that ELF running on SPARC architectures alway
and `heap` sections set as Read/Write/Execute.

`vmmap` can accept multiple arguments, either patterns to match again mapping names, or addresses
to determine which section it belongs to:
to determine which section it belongs to, or the permissions of the sections to match:
Comment thread
ValekoZ marked this conversation as resolved.

1. `-a` / `--addr`:
- filter by address -> parses the next argument as an integer or asks gdb to interpret the value
Expand Down
48 changes: 43 additions & 5 deletions gef.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,30 @@ def from_info_mem(cls, perm_str: str) -> "Permission":
if "x" in perm_str: perm |= Permission.EXECUTE
return perm

@classmethod
def from_filter_repr(cls, filter_str: str) -> List["Permission"]:
Comment thread
ValekoZ marked this conversation as resolved.
Outdated
perms = [cls(0)]
Comment thread
ValekoZ marked this conversation as resolved.
Outdated
if filter_str[0] == "r":
Comment thread
ValekoZ marked this conversation as resolved.
Outdated
for i in range(len(perms)):
perms[i] |= Permission.READ
elif filter_str[0] == "?":
for i in range(len(perms)):
perms.append(perms[i] | Permission.READ)
if filter_str[1] == "w":
for i in range(len(perms)):
perms[i] |= Permission.WRITE
elif filter_str[1] == "?":
for i in range(len(perms)):
perms.append(perms[i] | Permission.WRITE)
if filter_str[2] == "x":
for i in range(len(perms)):
perms[i] |= Permission.EXECUTE
elif filter_str[2] == "?":
for i in range(len(perms)):
perms.append(perms[i] | Permission.EXECUTE)
return perms



class Section:
"""GEF representation of process memory sections."""
Expand Down Expand Up @@ -8895,7 +8919,9 @@ class VMMapCommand(GenericCommand):
_example_ = f"{_cmdline_} libc"

@only_if_gdb_running
@parse_arguments({"unknown_types": [""]}, {("--addr", "-a"): [""], ("--name", "-n"): [""]})
@parse_arguments({"unknown_types": [""]}, {("--addr", "-a"): [""],
("--name", "-n"): [""],
("--perms", "-p"): [""]})
def do_invoke(self, _: List[str], **kwargs: Any) -> None:
args : argparse.Namespace = kwargs["arguments"]
vmmap = gef.memory.maps
Expand All @@ -8905,6 +8931,10 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None:

addrs: Dict[str, int] = {x: parse_address(x) for x in args.addr}
names: List[str] = [x for x in args.name]
perms: Set[Permission] = set()

for x in args.perms:
Comment thread
ValekoZ marked this conversation as resolved.
Outdated
perms = perms.union(Permission.from_filter_repr(x))

for arg in args.unknown_types:
if not arg:
Expand All @@ -8916,12 +8946,19 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None:
addr = safe_parse_and_eval(arg)

if addr is None:
if arg[0] in 'r-?' and \
arg[1] in 'w-?' and \
arg[2] in 'x-?':
Comment thread
ValekoZ marked this conversation as resolved.
Outdated
perms = perms.union(Permission.from_filter_repr(arg))
warn(f"`{arg}` has no type specified. We guessed it was a perm filter.")
continue

names.append(arg)
warn(f"`{arg}` has no type specified. We guessed it was a name filter.")
else:
addrs[arg] = int(addr)
warn(f"`{arg}` has no type specified. We guessed it was an address filter.")
warn("You can use --name or --addr before the filter value for specifying its type manually.")
warn("You can use --name, --addr or --perms before the filter value for specifying its type manually.")
gef_print()

if not gef.config["gef.disable_color"]:
Expand All @@ -8938,12 +8975,13 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None:
names_filter = [f"name = '{x}'" for x in names if x in entry.path]
addrs_filter = [f"addr = {self.format_addr_filter(arg, addr)}" for arg, addr in addrs.items()
if entry.page_start <= addr < entry.page_end]
filter_content = f"[{' & '.join([*names_filter, *addrs_filter])}]"
perms_filter = [f"perms = {x}" for x in perms if entry.permission == x]
filter_content = f"[{' & '.join([*names_filter, *addrs_filter, *perms_filter])}]"

if not names and not addrs:
if not names and not addrs and not perms:
self.print_entry(entry)

elif names_filter or addrs_filter:
elif names_filter or addrs_filter or perms_filter:
if filter_content != last_printed_filter:
gef_print() # skip a line between different filters
gef_print(Color.greenify(filter_content))
Expand Down
20 changes: 20 additions & 0 deletions tests/commands/vmmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ def test_cmd_vmmap(self):
assert "`$pc` has no type specified. We guessed it was an address filter." in res
self.assertEqual(len(res.splitlines()), 8)

res = gdb.execute("vmmap r-?", to_string=True)
assert "`r-?` has no type specified. We guessed it was a perm filter." in res
self.assertGreater(len(res.splitlines()), 3)

def test_cmd_vmmap_addr(self):
gef, gdb = self._gef, self._gdb
gdb.execute("start")
Expand All @@ -48,3 +52,19 @@ def test_cmd_vmmap_name(self):

res = gdb.execute("vmmap --name stack", to_string=True)
self.assertEqual(len(res.splitlines()), 5)

def test_cmd_vmmap_perm(self):
gdb = self._gdb
gdb.execute("start")

res = gdb.execute("vmmap -p r?-", to_string=True)
self.assertGreater(len(res.splitlines()), 5)

res = gdb.execute("vmmap --perms r?-", to_string=True)
self.assertGreater(len(res.splitlines()), 5)
Comment thread
ValekoZ marked this conversation as resolved.
Outdated

res = gdb.execute("vmmap -p rw-", to_string=True)
self.assertGreater(len(res.splitlines()), 5)

res = gdb.execute("vmmap --perms rw-", to_string=True)
self.assertGreater(len(res.splitlines()), 5)