-
-
Notifications
You must be signed in to change notification settings - Fork 745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[cmd] Allow for filtering about maps permissions in vmmap
#1111
base: main
Are you sure you want to change the base?
Changes from 7 commits
7b53621
95d14fe
d68a6dd
10cb8fa
ad16e98
3ed4e36
ba83306
e604c6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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"]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be worth adding unit test for this function alone. |
||
perms = [cls(0)] | ||
if filter_str[0] == "r": | ||
ValekoZ marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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.""" | ||
|
@@ -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 | ||
|
@@ -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: | ||
perms = perms.union(Permission.from_filter_repr(x)) | ||
|
||
for arg in args.unknown_types: | ||
if not arg: | ||
|
@@ -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-?': | ||
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"]: | ||
|
@@ -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)) | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -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") | ||||||||||||||||||||||||||||||||||
|
@@ -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 on lines
+60
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can go further in checking the output, this doesn't really check the output is as intended. Also those tests being equivalent, you can thoroughly check the strings in the 1st assert, then check that the 1st result equals the 2nd.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some examples of
--perms
would be nice too