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

@ -4,6 +4,7 @@ import errno
import gdb import gdb
import pwndbg.auxv import pwndbg.auxv
import pwndbg.color as C
import pwndbg.commands import pwndbg.commands
import pwndbg.gdblib.regs import pwndbg.gdblib.regs
import pwndbg.gdblib.symbol import pwndbg.gdblib.symbol
@ -84,8 +85,22 @@ def pwndbg_(filter_pattern, shell, all_):
shell_cmds = False shell_cmds = False
pwndbg_cmds = True pwndbg_cmds = True
for name, docs in list_and_filter_commands(filter_pattern, pwndbg_cmds, shell_cmds): from tabulate import tabulate
print("%-20s %s" % (name, docs))
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.") 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: if not c.shell and not pwndbg_cmds:
continue continue
# Don't print aliases
if c.is_alias:
continue
name = c.__name__ name = c.__name__
docs = c.__doc__ docs = c.__doc__
@ -134,6 +153,6 @@ def list_and_filter_commands(filter_str, pwndbg_cmds=True, shell_cmds=False):
docs = docs.splitlines()[0] docs = docs.splitlines()[0]
if not filter_str or filter_str in name.lower() or (docs and filter_str in docs.lower()): 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 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) 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)) num_shell_cmds = sum(1 for _ in filter(lambda c: c.shell, pwndbg.commands.commands))
hint_lines = ( hint_lines = (
"loaded %i pwndbg commands and %i shell commands. Type %s for a list." "loaded %i pwndbg commands and %i shell commands. Type %s for a list."

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

Loading…
Cancel
Save