Add `context [section(s)] [--on|--off]` to disable sections (#2442)

Allow to temporarily disable sections in the context output without touching the `context-sections` config parameter.
pull/2439/head^2
peace-maker 1 year ago committed by GitHub
parent 57c9f1c6b8
commit c6c5f1dec1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -96,7 +96,7 @@ config_max_threads_display = pwndbg.config.add_param(
# Storing output configuration per section
outputs: Dict[str, str] = {}
output_settings = {}
output_settings: DefaultDict[str, Dict[str, Any]] = defaultdict(dict)
@pwndbg.config.trigger(config_context_sections)
@ -246,12 +246,25 @@ def contextoutput(section, path, clearing, banner="both", width: int = None):
raise argparse.ArgumentError(banner_arg, f"banner can not be '{banner}'")
outputs[section] = path
output_settings[section] = {
"clearing": clearing,
"width": width,
"banner_top": banner in ["both", "top"],
"banner_bottom": banner in ["both", "bottom"],
}
output_settings[section].update(
{
"clearing": clearing,
"width": width,
"banner_top": banner in ["both", "top"],
"banner_bottom": banner in ["both", "bottom"],
}
)
def resetcontextoutput(section):
target = outputs.pop(section, None)
if target:
# Remove all settings except for the ones that are not related to output redirection
output_settings[section] = {
k: v
for k, v in output_settings[section].items()
if k not in ["clearing", "width", "banner_top", "banner_bottom"]
}
# Watches
@ -372,13 +385,27 @@ parser.add_argument(
nargs="*",
type=str,
default=None,
help="Submenu to display: 'reg', 'disasm', 'code', 'stack', 'backtrace', 'ghidra', 'args', 'threads', 'heap_tracker', 'expressions', and/or 'last_signal'",
help="Submenu to display: 'regs', 'disasm', 'code', 'stack', 'backtrace', 'ghidra', 'args', 'threads', 'heap_tracker', 'expressions', and/or 'last_signal'",
)
parser.add_argument(
"--on",
dest="enabled",
action="store_true",
default=None,
help="Show the section(s) in subsequent context commands again. The section(s) have to be in the 'context-sections' list.",
)
parser.add_argument(
"--off",
dest="enabled",
action="store_false",
default=None,
help="Do not show the section(s) in subsequent context commands even though they might be in the 'context-sections' list.",
)
@pwndbg.commands.ArgparsedCommand(parser, aliases=["ctx"], category=CommandCategory.CONTEXT)
@pwndbg.commands.OnlyWhenRunning
def context(subcontext=None) -> None:
def context(subcontext=None, enabled=None) -> None:
"""
Print out the current register, instruction, and stack context.
@ -400,16 +427,19 @@ def context(subcontext=None) -> None:
if func:
target = output(section)
# Last section of an output decides about output settings
settings = output_settings.get(section, {})
result_settings[target].update(settings)
with target as out:
result[target].extend(
func(
target=out,
width=settings.get("width", None),
with_banner=settings.get("banner_top", True),
settings = output_settings[section]
if enabled is not None:
settings["enabled"] = enabled
if settings.get("enabled", True):
result_settings[target].update(settings)
with target as out:
result[target].extend(
func(
target=out,
width=settings.get("width", None),
with_banner=settings.get("banner_top", True),
)
)
)
for target, res in result.items():
settings = result_settings[target]

@ -10,8 +10,7 @@ import gdb
from pwndbg.commands.context import context
from pwndbg.commands.context import context_sections
from pwndbg.commands.context import contextoutput
from pwndbg.commands.context import output_settings
from pwndbg.commands.context import outputs
from pwndbg.commands.context import resetcontextoutput
class ContextTUIWindow:
@ -101,8 +100,7 @@ class ContextTUIWindow:
def _disable(self):
_static_enabled = False
self._old_width = 0
del outputs[self._section]
del output_settings[self._section]
resetcontextoutput(self._section)
self._enabled = False
def _update(self):

@ -417,3 +417,43 @@ def test_context_disasm_call_instruction_split(start_binary):
)
assert dis == expected
def test_context_hide_sections(start_binary):
start_binary(SYSCALLS_BINARY)
# Disable one section
out = gdb.execute("context", to_string=True)
assert "REGISTERS" in out
assert "STACK" in out
gdb.execute("context regs --off")
out = gdb.execute("context", to_string=True)
assert "REGISTERS" not in out
assert "STACK" in out
gdb.execute("context regs --on")
out = gdb.execute("context", to_string=True)
assert "REGISTERS" in out
assert "STACK" in out
# Disable multiple sections
gdb.execute("context stack disasm --off")
out = gdb.execute("context", to_string=True)
assert "STACK" not in out
assert "DISASM" not in out
gdb.execute("context stack --on")
out = gdb.execute("context", to_string=True)
assert "STACK" in out
assert "DISASM" not in out
gdb.execute("context stack disasm --on")
out = gdb.execute("context", to_string=True)
assert "STACK" in out
assert "DISASM" in out
# Disable all sections at once
gdb.execute("context --off")
out = gdb.execute("context", to_string=True)
assert len(out) == 0
gdb.execute("context --on")
out = gdb.execute("context", to_string=True)
assert "REGISTERS" in out
assert "DISASM" in out

Loading…
Cancel
Save