Don't print aliases as commands in pwndbg output (#1460)

Fixes https://github.com/pwndbg/pwndbg/issues/1290
pull/1464/head
Gulshan Singh 3 years ago committed by GitHub
parent 4b49085092
commit 513dcdf870
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -52,7 +52,11 @@ class Command(gdb.Command):
builtin_override_whitelist = {"up", "down", "search", "pwd", "start", "ignore"}
history = {} # type: Dict[int,str]
def __init__(self, function, prefix=False, command_name=None, shell=False):
def __init__(
self, function, prefix=False, command_name=None, shell=False, is_alias=False, aliases=[]
):
self.is_alias = is_alias
self.aliases = aliases
self.shell = shell
if command_name is None:
@ -417,7 +421,7 @@ def OnlyWithResolvedHeapSyms(function):
class _ArgparsedCommand(Command):
def __init__(self, parser, function, command_name=None, *a, **kw):
def __init__(self, parser, function, command_name=None, is_alias=False, aliases=[], *a, **kw):
self.parser = parser
if command_name is None:
self.parser.prog = function.__name__
@ -431,7 +435,9 @@ class _ArgparsedCommand(Command):
# Note: function.__doc__ is used in the `pwndbg [filter]` command display
function.__doc__ = self.parser.description.strip()
super(_ArgparsedCommand, self).__init__(function, command_name=command_name, *a, **kw)
super(_ArgparsedCommand, self).__init__(
function, command_name=command_name, is_alias=is_alias, aliases=aliases, *a, **kw
)
def split_args(self, argument):
argv = gdb.string_to_argv(argument)
@ -464,8 +470,10 @@ class ArgparsedCommand:
def __call__(self, function):
for alias in self.aliases:
_ArgparsedCommand(self.parser, function, command_name=alias)
return _ArgparsedCommand(self.parser, function, command_name=self._command_name)
_ArgparsedCommand(self.parser, function, command_name=alias, is_alias=True)
return _ArgparsedCommand(
self.parser, function, command_name=self._command_name, aliases=self.aliases
)
# We use a 64-bit max value literal here instead of pwndbg.gdblib.arch.current

@ -4,6 +4,7 @@ import errno
import gdb
import pwndbg.auxv
import pwndbg.color as C
import pwndbg.commands
import pwndbg.gdblib.regs
import pwndbg.gdblib.symbol
@ -84,8 +85,22 @@ def pwndbg_(filter_pattern, shell, all_):
shell_cmds = False
pwndbg_cmds = True
for name, docs in list_and_filter_commands(filter_pattern, pwndbg_cmds, shell_cmds):
print("%-20s %s" % (name, docs))
from tabulate import tabulate
table_data = []
for name, aliases, docs in list_and_filter_commands(filter_pattern, pwndbg_cmds, shell_cmds):
alias_str = ""
aliases_len = 0
if aliases:
aliases = map(C.blue, aliases)
alias_str = f" [{', '.join(aliases)}]"
command_names = C.green(name) + alias_str
table_data.append((command_names, docs))
print(
tabulate(table_data, headers=[f"{C.green('Command')} [{C.blue('Aliases')}]", "Description"])
)
parser = argparse.ArgumentParser(description="Print the distance between the two arguments.")
@ -125,6 +140,10 @@ def list_and_filter_commands(filter_str, pwndbg_cmds=True, shell_cmds=False):
if not c.shell and not pwndbg_cmds:
continue
# Don't print aliases
if c.is_alias:
continue
name = c.__name__
docs = c.__doc__
@ -134,6 +153,6 @@ def list_and_filter_commands(filter_str, pwndbg_cmds=True, shell_cmds=False):
docs = docs.splitlines()[0]
if not filter_str or filter_str in name.lower() or (docs and filter_str in docs.lower()):
results.append((name, docs))
results.append((name, c.aliases, docs))
return results

@ -14,7 +14,9 @@ from pwndbg.lib.tips import get_tip_of_the_day
funcs_list_str = ", ".join(message.notice("$" + f.name) for f in pwndbg.gdblib.functions.functions)
num_pwndbg_cmds = sum(1 for _ in filter(lambda c: not c.shell, pwndbg.commands.commands))
num_pwndbg_cmds = sum(
1 for _ in filter(lambda c: not (c.shell or c.is_alias), pwndbg.commands.commands)
)
num_shell_cmds = sum(1 for _ in filter(lambda c: c.shell, pwndbg.commands.commands))
hint_lines = (
"loaded %i pwndbg commands and %i shell commands. Type %s for a list."

@ -1,13 +1,15 @@
import pytest
import pwndbg.commands
from pwndbg.commands.misc import list_and_filter_commands
STACK_COMMANDS = [
("canary", "Print out the current stack canary."),
("context", "Print out the current register, instruction, and stack context."),
("down", "Select and print stack frame called by this one."),
("retaddr", "Print out the stack addresses that contain return addresses."),
("stack", "Dereferences on stack data with specified count and offset."),
("up", "Select and print stack frame that called this one."),
("canary", [], "Print out the current stack canary."),
("context", ["ctx"], "Print out the current register, instruction, and stack context."),
("down", [], "Select and print stack frame called by this one."),
("retaddr", [], "Print out the stack addresses that contain return addresses."),
("stack", [], "Dereferences on stack data with specified count and offset."),
("up", [], "Select and print stack frame that called this one."),
]
@ -16,37 +18,20 @@ def test_list_and_filter_commands_filter():
assert cmd in list_and_filter_commands("stack")
def test_list_and_filter_commands_full_list():
all_commands = list_and_filter_commands("", pwndbg_cmds=True, shell_cmds=True)
def get_doc(c):
return c.__doc__.strip().splitlines()[0] if c.__doc__ else None
cmd_name_docs = [(c.__name__, get_doc(c)) for c in pwndbg.commands.commands]
cmd_name_docs.sort()
assert all_commands == cmd_name_docs
def test_list_and_filter_commands_shell():
all_commands = list_and_filter_commands("", pwndbg_cmds=False, shell_cmds=True)
@pytest.mark.parametrize("pwndbg_cmds,shell_cmds", [(True, True), (False, True), (True, False)])
def test_list_and_filter_commands_full_list(pwndbg_cmds, shell_cmds):
all_commands = list_and_filter_commands("", pwndbg_cmds=pwndbg_cmds, shell_cmds=shell_cmds)
def get_doc(c):
return c.__doc__.strip().splitlines()[0] if c.__doc__ else None
cmd_name_docs = [(c.__name__, get_doc(c)) for c in pwndbg.commands.commands if c.shell]
cmd_name_docs.sort()
assert all_commands == cmd_name_docs
def test_list_and_filter_commands_pwndbg_cmds():
all_commands = list_and_filter_commands("", pwndbg_cmds=True, shell_cmds=False)
def get_doc(c):
return c.__doc__.strip().splitlines()[0] if c.__doc__ else None
commands = []
if pwndbg_cmds:
commands.extend([c for c in pwndbg.commands.commands if not c.is_alias and not c.shell])
if shell_cmds:
commands.extend([c for c in pwndbg.commands.commands if not c.is_alias and c.shell])
cmd_name_docs = [(c.__name__, get_doc(c)) for c in pwndbg.commands.commands if not c.shell]
cmd_name_docs = [(c.__name__, c.aliases, get_doc(c)) for c in commands]
cmd_name_docs.sort()
assert all_commands == cmd_name_docs

Loading…
Cancel
Save