Move main configuration object from `pwndbg.gdblib.config` to `pwndbg.config` (#2244)

* Split move from `pwndbg.gdblib.config` to `pwndbg.config`

* Move `pwndbg.config` to `pwndbg`

* Fix lints and pytest mocks
This commit is contained in:
Matt 2024-06-21 16:31:38 -03:00 committed by GitHub
parent f21000356f
commit 2ecdce4ea8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
54 changed files with 374 additions and 280 deletions

View File

@ -4,6 +4,12 @@ import signal
import gdb
# isort: off
import pwndbg.lib.config
config: pwndbg.lib.config.Config = pwndbg.lib.config.Config()
# isort: on
import pwndbg.color
import pwndbg.commands
import pwndbg.gdblib
@ -81,6 +87,10 @@ from pwndbg.commands import comments
comments.init()
from pwndbg.gdblib import config_mod
from pwndbg.gdblib import config_mod as gdblib_config_mod
config_mod.init_params()
gdblib_config_mod.init_params()
from pwndbg.gdblib.prompt import show_hint
show_hint()

View File

@ -15,7 +15,7 @@ from pwndbg.color import ColorConfig
from pwndbg.color import ColorParamSpec
from pwndbg.color import theme
LIMIT = pwndbg.gdblib.config.add_param(
LIMIT = pwndbg.config.add_param(
"dereference-limit", 5, "max number of pointers to dereference in a chain"
)

View File

@ -2,9 +2,9 @@ from __future__ import annotations
from typing import List
from pwndbg import config
from pwndbg.color import generateColorFunction
from pwndbg.color import theme
from pwndbg.gdblib import config
from pwndbg.lib.regs import BitFlags
config_prefix_color = theme.add_color_param(

View File

@ -31,7 +31,7 @@ def one_instruction(ins: PwndbgInstruction) -> str:
asm = ins.asm_string
# Highlight the current line if enabled
if pwndbg.gdblib.config.highlight_pc and ins.address == pwndbg.gdblib.regs.pc:
if pwndbg.config.highlight_pc and ins.address == pwndbg.gdblib.regs.pc:
asm = C.highlight(asm)
is_call_or_jump = ins.groups_set & capstone_branch_groups

View File

@ -1,8 +1,8 @@
from __future__ import annotations
from pwndbg import config
from pwndbg.color import generateColorFunction
from pwndbg.color import theme
from pwndbg.gdblib import config
config_integer_color = theme.add_color_param(
"enhance-integer-value-color", "none", "color of value enhance (integer)"

View File

@ -1,8 +1,8 @@
from __future__ import annotations
from pwndbg import config
from pwndbg.color import generateColorFunction
from pwndbg.color import theme
from pwndbg.gdblib import config
config_normal = theme.add_color_param(
"hexdump-normal-color", "none", "color for hexdump command (normal bytes)"

View File

@ -1,8 +1,9 @@
from __future__ import annotations
import pwndbg.lib.config
from pwndbg import config
from pwndbg.color import generateColorFunction
from pwndbg.color import theme
from pwndbg.gdblib import config
config_status_on_color = theme.add_color_param(
"message-status-on-color", "green", "color of on status messages"
@ -36,7 +37,9 @@ config_signal_color = theme.add_color_param(
"message-signal-color", "bold,red", "color of signal messages"
)
config_prompt_color = theme.add_color_param("prompt-color", "bold,red", "prompt color")
config_prompt_color: pwndbg.lib.config.Parameter = theme.add_color_param(
"prompt-color", "bold,red", "prompt color"
)
def on(msg: object) -> str:

View File

@ -11,12 +11,12 @@ import pygments.lexers
import pygments.util
from pwnlib.lexer import PwntoolsLexer
import pwndbg.gdblib.config
import pwndbg
from pwndbg.color import disable_colors
from pwndbg.color import message
from pwndbg.color import theme
pwndbg.gdblib.config.add_param("syntax-highlight", True, "Source code / assembly syntax highlight")
pwndbg.config.add_param("syntax-highlight", True, "Source code / assembly syntax highlight")
style = theme.add_param(
"syntax-highlight-style",
"monokai",
@ -28,7 +28,7 @@ pwntools_lexer = PwntoolsLexer()
lexer_cache: Dict[str, Any] = {}
@pwndbg.gdblib.config.trigger(style)
@pwndbg.config.trigger(style)
def check_style() -> None:
global formatter
try:

View File

@ -1,8 +1,8 @@
from __future__ import annotations
from pwndbg import config
from pwndbg.color import generateColorFunction
from pwndbg.color import theme
from pwndbg.gdblib import config
offset_color = theme.add_color_param(
"telescope-offset-color", "normal", "color of the telescope command (offset prefix)"

View File

@ -2,7 +2,7 @@ from __future__ import annotations
from typing import Any
from pwndbg.gdblib import config
from pwndbg import config
from pwndbg.lib.config import Parameter

View File

@ -416,7 +416,7 @@ def _try2run_heap_command(function: Callable[P, T], *a: P.args, **kw: P.kwargs)
w(
f"You can try to determine the libc symbols addresses manually and set them appropriately. For this, see the `heap_config` command output and set the config for `{err.symbol}`."
)
if pwndbg.gdblib.config.exception_verbose or pwndbg.gdblib.config.exception_debugger:
if pwndbg.config.exception_verbose or pwndbg.config.exception_debugger:
raise err
pwndbg.exception.inform_verbose_and_debug()
@ -428,7 +428,7 @@ def _try2run_heap_command(function: Callable[P, T], *a: P.args, **kw: P.kwargs)
)
else:
w("You can try `set resolve-heap-via-heuristic force` and re-run this command.\n")
if pwndbg.gdblib.config.exception_verbose or pwndbg.gdblib.config.exception_debugger:
if pwndbg.config.exception_verbose or pwndbg.config.exception_debugger:
raise err
pwndbg.exception.inform_verbose_and_debug()
@ -442,7 +442,7 @@ def OnlyWithResolvedHeapSyms(function: Callable[P, T]) -> Callable[P, T | None]:
w = lambda s: print(message.warn(s))
if (
isinstance(pwndbg.gdblib.heap.current, HeuristicHeap)
and pwndbg.gdblib.config.resolve_heap_via_heuristic == "auto"
and pwndbg.config.resolve_heap_via_heuristic == "auto"
and DebugSymsHeap().can_be_resolved()
):
# In auto mode, we will try to use the debug symbols if possible
@ -456,7 +456,7 @@ def OnlyWithResolvedHeapSyms(function: Callable[P, T]) -> Callable[P, T | None]:
else:
if (
isinstance(pwndbg.gdblib.heap.current, DebugSymsHeap)
and pwndbg.gdblib.config.resolve_heap_via_heuristic == "auto"
and pwndbg.config.resolve_heap_via_heuristic == "auto"
):
# In auto mode, if the debug symbols are not enough, we will try to use the heuristic if possible
heuristic_heap = HeuristicHeap()
@ -484,7 +484,7 @@ def OnlyWithResolvedHeapSyms(function: Callable[P, T]) -> Callable[P, T | None]:
)
elif (
isinstance(pwndbg.gdblib.heap.current, DebugSymsHeap)
and pwndbg.gdblib.config.resolve_heap_via_heuristic == "force"
and pwndbg.config.resolve_heap_via_heuristic == "force"
):
e(
"You are forcing to resolve the heap symbols via heuristic, but we cannot resolve the heap via the debug symbols."

View File

@ -19,9 +19,9 @@ import pwndbg
import pwndbg.color.message as M
import pwndbg.commands
import pwndbg.lib.strings
from pwndbg import config
from pwndbg.commands import CommandCategory
from pwndbg.commands import context
from pwndbg.gdblib import config
from pwndbg.gdblib import regs as REGS
config.add_param(

View File

@ -21,7 +21,7 @@ _NEWEST = "newest"
_ASK = "ask"
_OPTIONS = [_NONE, _OLDEST, _NEWEST, _ASK]
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"attachp-resolution-method",
_ASK,
f'how to determine the process to attach when multiple candidates exists ("{_OLDEST}", "{_NEWEST}", "{_NONE}" or "{_ASK}"(default))',
@ -87,7 +87,7 @@ def attachp(no_truncate, target) -> None:
return
if len(pids) > 1:
method = pwndbg.gdblib.config.attachp_resolution_method
method = pwndbg.config.attachp_resolution_method
if method not in _OPTIONS:
print(

View File

@ -6,8 +6,10 @@ from __future__ import annotations
import argparse
import pwndbg
import pwndbg.commands
import pwndbg.gdblib.config
import pwndbg.lib.config
from pwndbg.color import generateColorFunction
from pwndbg.color import ljust_colored
from pwndbg.color import strip
@ -41,7 +43,7 @@ def extend_value_with_default(value, default):
def get_config_parameters(scope, filter_pattern):
values = [
v
for k, v in pwndbg.gdblib.config.params.items()
for k, v in pwndbg.config.params.items()
if isinstance(v, pwndbg.lib.config.Parameter) and v.scope == scope
]
@ -151,7 +153,7 @@ def themefile(show_all=False) -> None:
def configfile_print_scope(scope: str, show_all: bool = False) -> None:
params = pwndbg.gdblib.config.get_params(scope)
params = pwndbg.config.get_params(scope)
if not show_all:
params = list(filter(lambda p: p.is_changed, params))
@ -161,10 +163,10 @@ def configfile_print_scope(scope: str, show_all: bool = False) -> None:
print(hint("Showing only changed values:"))
for p in params:
native_default = pwndbg.gdblib.config_mod.Parameter._value_to_gdb_native(
p.default, param_class=p.param_class
p.default, param_class=pwndbg.gdblib.config.CLASS_MAPPING[p.param_class]
)
native_value = pwndbg.gdblib.config_mod.Parameter._value_to_gdb_native(
p.value, param_class=p.param_class
p.value, param_class=pwndbg.gdblib.config.CLASS_MAPPING[p.param_class]
)
print(f"# {p.name}: {p.set_show_doc}")
print(f"# default: {native_default}")

View File

@ -13,6 +13,7 @@ from typing import Tuple
import gdb
import pwndbg
import pwndbg.arguments
import pwndbg.chain
import pwndbg.color
@ -21,7 +22,6 @@ import pwndbg.color.memory as M
import pwndbg.color.syntax_highlight as H
import pwndbg.commands
import pwndbg.commands.telescope
import pwndbg.gdblib.config
import pwndbg.gdblib.disasm
import pwndbg.gdblib.events
import pwndbg.gdblib.heap_tracking
@ -75,18 +75,18 @@ def clear_screen(out=sys.stdout) -> None:
out.write("\x1b[H\x1b[2J")
config_clear_screen = pwndbg.gdblib.config.add_param(
config_clear_screen = pwndbg.config.add_param(
"context-clear-screen", False, "whether to clear the screen before printing the context"
)
config_output = pwndbg.gdblib.config.add_param(
config_output = pwndbg.config.add_param(
"context-output", "stdout", 'where pwndbg should output ("stdout" or file/tty).'
)
config_context_sections = pwndbg.gdblib.config.add_param(
config_context_sections = pwndbg.config.add_param(
"context-sections",
"regs disasm code ghidra stack backtrace expressions threads heap-tracker",
"which context sections are displayed (controls order)",
)
config_max_threads_display = pwndbg.gdblib.config.add_param(
config_max_threads_display = pwndbg.config.add_param(
"context-max-threads",
4,
"maximum number of threads displayed by the context command",
@ -97,7 +97,7 @@ outputs: Dict[str, str] = {}
output_settings = {}
@pwndbg.gdblib.config.trigger(config_context_sections)
@pwndbg.config.trigger(config_context_sections)
def validate_context_sections() -> None:
valid_values = [
context.__name__.replace("context_", "") for context in context_sections.values()
@ -330,7 +330,7 @@ def context_expressions(target=sys.stdout, with_banner=True, width=None):
return banner + output if with_banner else output
config_context_ghidra = pwndbg.gdblib.config.add_param(
config_context_ghidra = pwndbg.config.add_param(
"context-ghidra",
"never",
"when to try to decompile the current function with ghidra (slow and requires radare2/r2pipe or rizin/rzpipe) (valid values: always, never, if-no-source)",
@ -427,16 +427,14 @@ def context(subcontext=None) -> None:
out.flush()
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"show-compact-regs", False, "whether to show a compact register view with columns"
)
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"show-compact-regs-columns", 2, "the number of columns (0 for dynamic number of columns)"
)
pwndbg.gdblib.config.add_param(
"show-compact-regs-min-width", 20, "the minimum width of each column"
)
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param("show-compact-regs-min-width", 20, "the minimum width of each column")
pwndbg.config.add_param(
"show-compact-regs-separation", 4, "the number of spaces separating columns"
)
@ -449,9 +447,9 @@ def calculate_padding_to_align(length, align):
def compact_regs(regs, width=None, target=sys.stdout):
columns = max(0, int(pwndbg.gdblib.config.show_compact_regs_columns))
min_width = max(1, int(pwndbg.gdblib.config.show_compact_regs_min_width))
separation = max(1, int(pwndbg.gdblib.config.show_compact_regs_separation))
columns = max(0, int(pwndbg.config.show_compact_regs_columns))
min_width = max(1, int(pwndbg.config.show_compact_regs_min_width))
separation = max(1, int(pwndbg.config.show_compact_regs_separation))
if width is None: # auto width. In case of stdout, it's better to use stdin (b/c GdbOutputFile)
_height, width = pwndbg.ui.get_window_size(
@ -513,12 +511,12 @@ def compact_regs(regs, width=None, target=sys.stdout):
def context_regs(target=sys.stdout, with_banner=True, width=None):
regs = get_regs()
if pwndbg.gdblib.config.show_compact_regs:
if pwndbg.config.show_compact_regs:
regs = compact_regs(regs, target=target, width=width)
info = " / show-flags {} / show-compact-regs {}".format(
"on" if pwndbg.gdblib.config.show_flags else "off",
"on" if pwndbg.gdblib.config.show_compact_regs else "off",
"on" if pwndbg.config.show_flags else "off",
"on" if pwndbg.config.show_compact_regs else "off",
)
banner = [pwndbg.ui.banner("registers", target=target, width=width, extra=info)]
return banner + regs if with_banner else regs
@ -550,8 +548,8 @@ def regs(regs=[]) -> None:
print("\n".join(get_regs(regs)))
pwndbg.gdblib.config.add_param("show-flags", False, "whether to show flags registers")
pwndbg.gdblib.config.add_param("show-retaddr-reg", False, "whether to show return address register")
pwndbg.config.add_param("show-flags", False, "whether to show flags registers")
pwndbg.config.add_param("show-retaddr-reg", False, "whether to show return address register")
def get_regs(regs: List[str] = None):
@ -566,12 +564,12 @@ def get_regs(regs: List[str] = None):
regs.append(pwndbg.gdblib.regs.frame)
regs.append(pwndbg.gdblib.regs.stack)
if pwndbg.gdblib.config.show_retaddr_reg:
if pwndbg.config.show_retaddr_reg:
regs += pwndbg.gdblib.regs.retaddr
regs.append(pwndbg.gdblib.regs.current.pc)
if pwndbg.gdblib.config.show_flags:
if pwndbg.config.show_flags:
regs += pwndbg.gdblib.regs.flags.keys()
changed = pwndbg.gdblib.regs.changed
@ -610,7 +608,7 @@ def get_regs(regs: List[str] = None):
return result
code_lines = pwndbg.gdblib.config.add_param(
code_lines = pwndbg.config.add_param(
"context-code-lines", 10, "number of additional lines to print in the code context"
)
@ -635,14 +633,14 @@ def context_disasm(target=sys.stdout, with_banner=True, width=None):
result = pwndbg.gdblib.nearpc.nearpc(
lines=code_lines // 2,
emulate=bool(not pwndbg.gdblib.config.emulate == "off"),
emulate=bool(not pwndbg.config.emulate == "off"),
use_cache=True,
)
# Note: we must fetch emulate value again after disasm since
# we check if we can actually use emulation in `can_run_first_emulate`
# and this call may disable it
info = " / {} / set emulate {}".format(pwndbg.gdblib.arch.current, pwndbg.gdblib.config.emulate)
info = " / {} / set emulate {}".format(pwndbg.gdblib.arch.current, pwndbg.config.emulate)
banner = [pwndbg.ui.banner("disasm", target=target, width=width, extra=info)]
# If we didn't disassemble backward, try to make sure
@ -654,10 +652,10 @@ def context_disasm(target=sys.stdout, with_banner=True, width=None):
theme.add_param("highlight-source", True, "whether to highlight the closest source line")
source_code_lines = pwndbg.gdblib.config.add_param(
source_code_lines = pwndbg.config.add_param(
"context-source-code-lines", 10, "number of source code lines to print by the context command"
)
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"context-source-code-tabstop", 8, "number of spaces that a <tab> in the source code counts for"
)
theme.add_param("code-prefix", "", "prefix marker for 'context code' command")
@ -669,7 +667,7 @@ def get_highlight_source(filename: str) -> Tuple[str, ...]:
with open(filename, encoding="utf-8", errors="ignore") as f:
source = f.read()
if pwndbg.gdblib.config.syntax_highlight:
if pwndbg.config.syntax_highlight:
source = H.syntax_highlight(source, filename)
source_lines = source.split("\n")
@ -711,16 +709,16 @@ def get_filename_and_formatted_source():
source = source[start:end]
# Compute the prefix_sign length
prefix_sign = C.prefix(str(pwndbg.gdblib.config.code_prefix))
prefix_sign = C.prefix(str(pwndbg.config.code_prefix))
prefix_width = len(prefix_sign)
# Format the output
formatted_source = []
for line_number, code in enumerate(source, start=start + 1):
if pwndbg.gdblib.config.context_source_code_tabstop > 0:
code = code.replace("\t", " " * pwndbg.gdblib.config.context_source_code_tabstop)
if pwndbg.config.context_source_code_tabstop > 0:
code = code.replace("\t", " " * pwndbg.config.context_source_code_tabstop)
fmt = " {prefix_sign:{prefix_width}} {line_number:>{num_width}} {code}"
if pwndbg.gdblib.config.highlight_source and line_number == closest_line:
if pwndbg.config.highlight_source and line_number == closest_line:
fmt = C.highlight(fmt)
line = fmt.format(
@ -768,7 +766,7 @@ def context_code(target=sys.stdout, with_banner=True, width=None):
return []
stack_lines = pwndbg.gdblib.config.add_param(
stack_lines = pwndbg.config.add_param(
"context-stack-lines", 8, "number of lines to print in the stack context"
)
@ -783,7 +781,7 @@ def context_stack(target=sys.stdout, with_banner=True, width=None):
return result
backtrace_lines = pwndbg.gdblib.config.add_param(
backtrace_lines = pwndbg.config.add_param(
"context-backtrace-lines", 8, "number of lines to print in the backtrace context"
)
backtrace_frame_label = theme.add_param(
@ -820,7 +818,7 @@ def context_backtrace(with_banner=True, target=sys.stdout, width=None):
frame = newest_frame
i = 0
bt_prefix = "%s" % pwndbg.gdblib.config.backtrace_prefix
bt_prefix = "%s" % pwndbg.config.backtrace_prefix
while True:
prefix = bt_prefix if frame == this_frame else " " * len(bt_prefix)
prefix = f" {c.prefix(prefix)}"

View File

@ -30,6 +30,7 @@ from typing_extensions import Protocol
import pwndbg
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.lib.config
import pwndbg.lib.gcc
import pwndbg.lib.tempfile
from pwndbg.color import message
@ -37,18 +38,18 @@ from pwndbg.color import message
P = ParamSpec("P")
T = TypeVar("T")
gcc_compiler_path = pwndbg.gdblib.config.add_param(
gcc_compiler_path = pwndbg.config.add_param(
"gcc-compiler-path",
"",
"path to the gcc/g++ toolchain for generating imported symbols",
param_class=gdb.PARAM_OPTIONAL_FILENAME,
param_class=pwndbg.lib.config.PARAM_OPTIONAL_FILENAME,
)
cymbol_editor = pwndbg.gdblib.config.add_param(
cymbol_editor = pwndbg.config.add_param(
"cymbol-editor",
"",
"path to the editor for editing custom structures",
param_class=gdb.PARAM_OPTIONAL_FILENAME,
param_class=pwndbg.lib.config.PARAM_OPTIONAL_FILENAME,
)
# Remeber loaded symbols. This would be useful for 'remove-symbol-file'.

View File

@ -53,9 +53,7 @@ def dev_dump_instruction(address=None, force_emulate=False, no_emulate=False) ->
# None if not overridden
override_setting = True if force_emulate else (False if no_emulate else None)
use_emulation = (
bool(pwndbg.gdblib.config.emulate == "on")
if override_setting is None
else override_setting
bool(pwndbg.config.emulate == "on") if override_setting is None else override_setting
)
instructions, index_of_pc = pwndbg.gdblib.disasm.near(

View File

@ -10,11 +10,11 @@ from typing import Set
import gdb
from tabulate import tabulate
import pwndbg
import pwndbg.chain
import pwndbg.color.context as C
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.gdblib.config
import pwndbg.gdblib.heap
import pwndbg.gdblib.memory
import pwndbg.gdblib.proc
@ -920,13 +920,13 @@ def find_fake_fast(
break
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"max-visualize-chunk-size",
0,
"max display size for heap chunks visualization (0 for display all)",
)
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"default-visualize-chunk-number",
10,
"default number of chunks to visualize (default is 10)",
@ -943,7 +943,7 @@ group.add_argument(
"count",
nargs="?",
type=lambda n: max(int(n, 0), 1),
default=pwndbg.gdblib.config.default_visualize_chunk_number,
default=pwndbg.config.default_visualize_chunk_number,
help="Number of chunks to visualize.",
)
parser.add_argument("addr", nargs="?", default=None, help="Address of the first chunk.")
@ -1065,10 +1065,7 @@ def vis_heap_chunks(
has_huge_chunk = False
# round up to align with 4*ptr_size and get half
half_max_size = (
pwndbg.lib.memory.round_up(
int(pwndbg.gdblib.config.max_visualize_chunk_size), ptr_size << 2
)
>> 1
pwndbg.lib.memory.round_up(int(pwndbg.config.max_visualize_chunk_size), ptr_size << 2) >> 1
)
bin_labels_map: Dict[int, List[str]] = bin_labels_mapping(bin_collections)
@ -1120,7 +1117,7 @@ def vis_heap_chunks(
print(out)
if has_huge_chunk and pwndbg.gdblib.config.max_visualize_chunk_size == 0:
if has_huge_chunk and pwndbg.config.max_visualize_chunk_size == 0:
print(
message.warn(
"You can try `set max-visualize-chunk-size 0x500` and re-run this command.\n"

View File

@ -4,23 +4,23 @@ import argparse
import gdb
import pwndbg
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.config
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
import pwndbg.hexdump
from pwndbg.color import message
from pwndbg.commands import CommandCategory
pwndbg.gdblib.config.add_param("hexdump-width", 16, "line width of hexdump command")
pwndbg.gdblib.config.add_param("hexdump-bytes", 64, "number of bytes printed by hexdump command")
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param("hexdump-width", 16, "line width of hexdump command")
pwndbg.config.add_param("hexdump-bytes", 64, "number of bytes printed by hexdump command")
pwndbg.config.add_param(
"hexdump-group-width",
-1,
"number of bytes grouped in hexdump command (If -1, the architecture's pointer size is used)",
)
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"hexdump-group-use-big-endian",
False,
"whether to use big-endian within each group of bytes in hexdump command",
@ -56,13 +56,13 @@ parser.add_argument(
help="Address or module name to dump",
)
parser.add_argument(
"count", nargs="?", default=pwndbg.gdblib.config.hexdump_bytes, help="Number of bytes to dump"
"count", nargs="?", default=pwndbg.config.hexdump_bytes, help="Number of bytes to dump"
)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.MEMORY)
@pwndbg.commands.OnlyWhenRunning
def hexdump(address, count=pwndbg.gdblib.config.hexdump_bytes) -> None:
def hexdump(address, count=pwndbg.config.hexdump_bytes) -> None:
if hexdump.repeat:
address = hexdump.last_address
hexdump.offset += 1
@ -80,14 +80,14 @@ def hexdump(address, count=pwndbg.gdblib.config.hexdump_bytes) -> None:
address = new_address
count = max(int(count), 0)
width = int(pwndbg.gdblib.config.hexdump_width)
width = int(pwndbg.config.hexdump_width)
group_width = int(pwndbg.gdblib.config.hexdump_group_width)
group_width = int(pwndbg.config.hexdump_group_width)
group_width = pwndbg.gdblib.typeinfo.ptrsize if group_width == -1 else group_width
# TODO: What if arch endian is big, and use_big_endian is false?
flip_group_endianness = (
pwndbg.gdblib.config.hexdump_group_use_big_endian and pwndbg.gdblib.arch.endian == "little"
pwndbg.config.hexdump_group_use_big_endian and pwndbg.gdblib.arch.endian == "little"
)
# The user may have input the start and end range to dump instead of the

View File

@ -7,8 +7,8 @@ import gdb
import pwndbg.color.message as M
import pwndbg.commands
import pwndbg.gdblib.kernel
from pwndbg import config
from pwndbg.commands import CommandCategory
from pwndbg.gdblib.config import config
parser = argparse.ArgumentParser(description="Finds the kernel virtual base address.")

View File

@ -11,9 +11,9 @@ from typing import List
import gdb
import pwndbg
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.gdblib.config
import pwndbg.gdblib.vmmap
from pwndbg.chain import c as C
from pwndbg.color import message
@ -25,7 +25,7 @@ from pwndbg.commands import CommandCategory
# visited_map is a map of children -> (parent,parent_start)
def get_rec_addr_string(addr, visited_map):
page = pwndbg.gdblib.vmmap.find(addr)
arrow_right = C.arrow(" %s " % pwndbg.gdblib.config.chain_arrow_right)
arrow_right = C.arrow(" %s " % pwndbg.config.chain_arrow_right)
if page is not None:
if addr not in visited_map:
@ -178,7 +178,7 @@ def leakfind(
# A map of length->list of lines. Used to let us print in a somewhat nice manner.
output_map: Dict[int, List[str]] = {}
arrow_right = C.arrow(" %s " % pwndbg.gdblib.config.chain_arrow_right)
arrow_right = C.arrow(" %s " % pwndbg.config.chain_arrow_right)
for child in visited_map:
child_page = pwndbg.gdblib.vmmap.find(child)

View File

@ -10,11 +10,11 @@ from typing import Set
import gdb
import pwnlib
import pwndbg
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.enhance
import pwndbg.gdblib.arch
import pwndbg.gdblib.config
import pwndbg.gdblib.disasm
import pwndbg.gdblib.vmmap
import pwndbg.search
@ -47,7 +47,7 @@ def print_search_hit(address) -> None:
print(region, addr, display)
auto_save = pwndbg.gdblib.config.add_param(
auto_save = pwndbg.config.add_param(
"auto-save-search", False, 'automatically pass --save to "search" command'
)
parser = argparse.ArgumentParser(
@ -209,7 +209,7 @@ def search(
type = {4: "dword", 8: "qword"}[pwndbg.gdblib.arch.ptrsize]
if save is None:
save = bool(pwndbg.gdblib.config.auto_save_search)
save = bool(pwndbg.config.auto_save_search)
if hex:
try:

View File

@ -13,31 +13,31 @@ from typing import DefaultDict
from typing import Dict
from typing import List
import pwndbg
import pwndbg.chain
import pwndbg.color.telescope as T
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.config
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
import pwndbg.gdblib.typeinfo
from pwndbg.color import theme
from pwndbg.commands import CommandCategory
telescope_lines = pwndbg.gdblib.config.add_param(
telescope_lines = pwndbg.config.add_param(
"telescope-lines", 8, "number of lines to printed by the telescope command"
)
skip_repeating_values = pwndbg.gdblib.config.add_param(
skip_repeating_values = pwndbg.config.add_param(
"telescope-skip-repeating-val",
True,
"whether to skip repeating values of the telescope command",
)
skip_repeating_values_minimum = pwndbg.gdblib.config.add_param(
skip_repeating_values_minimum = pwndbg.config.add_param(
"telescope-skip-repeating-val-minimum",
3,
"minimum amount of repeated values before skipping lines",
)
print_framepointer_offset = pwndbg.gdblib.config.add_param(
print_framepointer_offset = pwndbg.config.add_param(
"telescope-framepointer-offset",
True,
"print offset to framepointer for each address, if sufficiently small",

View File

@ -255,7 +255,7 @@ def vmmap(
if page in filtered_pages:
# If page was one of the original results, add an arrow for clarity
backtrace_prefix = str(pwndbg.gdblib.config.backtrace_prefix)
backtrace_prefix = str(pwndbg.config.backtrace_prefix)
# If the page is the only filtered page, insert offset
if len(filtered_pages) == 1 and isinstance(gdbval_or_str, integer_types):

View File

@ -2,10 +2,10 @@ from __future__ import annotations
import argparse
import pwndbg
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.config
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
import pwndbg.gdblib.stack

View File

@ -413,7 +413,7 @@ class Emulator:
pwndbg_instr = pwndbg.gdblib.disasm.one_raw(value)
if pwndbg_instr:
instr = f"{pwndbg_instr.mnemonic} {pwndbg_instr.op_str}"
if pwndbg.gdblib.config.syntax_highlight:
if pwndbg.config.syntax_highlight:
instr = syntax_highlight(instr)
# szval = pwndbg.gdblib.strings.get(value) or None

View File

@ -12,10 +12,10 @@ from __future__ import annotations
import string
from typing import Tuple
import pwndbg
import pwndbg.color.enhance as E
import pwndbg.color.memory
import pwndbg.gdblib.arch
import pwndbg.gdblib.config
import pwndbg.gdblib.disasm
import pwndbg.gdblib.memory
import pwndbg.gdblib.strings
@ -120,7 +120,7 @@ def enhance(
pwndbg_instr = pwndbg.gdblib.disasm.one(value, enhance=False)
if pwndbg_instr:
instr = f"{pwndbg_instr.mnemonic} {pwndbg_instr.op_str}"
if pwndbg.gdblib.config.syntax_highlight:
if pwndbg.config.syntax_highlight:
instr = syntax_highlight(instr)
szval = pwndbg.gdblib.strings.get(value, maxlen=enhance_string_len) or None

View File

@ -8,8 +8,8 @@ import gdb
import pwndbg.lib.cache
import pwndbg.lib.stdio
from pwndbg import config
from pwndbg.color import message
from pwndbg.gdblib import config
try:
import ipdb as pdb

View File

@ -11,7 +11,6 @@ import gdb
from pwndbg.gdblib import arch as arch_mod
from pwndbg.gdblib import config as config_mod
from pwndbg.gdblib.arch import arch as arch
from pwndbg.gdblib.config import config as config
regs = None

View File

@ -2,7 +2,7 @@
Dynamic configuration system for pwndbg, using GDB's built-in Parameter
mechanism.
To create a new pwndbg configuration point, call ``pwndbg.gdblib.config.add_param``.
To create a new pwndbg configuration point, call ``pwndbg.config.add_param``.
Parameters should be declared in the module in which they are primarily
used, or in this module for general-purpose parameters.
@ -10,8 +10,8 @@ used, or in this module for general-purpose parameters.
All pwndbg Parameter types are accessible via property access on this
module, for example:
>>> pwndbg.gdblib.config.add_param('example-value', 7, 'an example')
>>> int(pwndbg.gdblib.config.example_value)
>>> pwndbg.config.add_param('example-value', 7, 'an example')
>>> int(pwndbg.config.example_value)
7
"""
@ -21,10 +21,22 @@ from typing import Any
import gdb
import pwndbg
import pwndbg.decorators
import pwndbg.lib.config
config = pwndbg.lib.config.Config()
CLASS_MAPPING = {
pwndbg.lib.config.PARAM_BOOLEAN: gdb.PARAM_BOOLEAN,
pwndbg.lib.config.PARAM_AUTO_BOOLEAN: gdb.PARAM_AUTO_BOOLEAN,
pwndbg.lib.config.PARAM_ZINTEGER: gdb.PARAM_ZINTEGER,
pwndbg.lib.config.PARAM_STRING: gdb.PARAM_STRING,
pwndbg.lib.config.PARAM_ZUINTEGER: gdb.PARAM_ZUINTEGER,
pwndbg.lib.config.PARAM_ENUM: gdb.PARAM_ENUM,
pwndbg.lib.config.PARAM_OPTIONAL_FILENAME: gdb.PARAM_OPTIONAL_FILENAME,
pwndbg.lib.config.PARAM_ZUINTEGER_UNLIMITED: gdb.PARAM_ZUINTEGER_UNLIMITED,
pwndbg.lib.config.PARAM_INTEGER: gdb.PARAM_INTEGER,
pwndbg.lib.config.PARAM_UINTEGER: gdb.PARAM_UINTEGER,
}
# See this for details about the API of `gdb.Parameter`:
@ -44,30 +56,36 @@ class Parameter(gdb.Parameter):
def init_super(self, param: pwndbg.lib.config.Parameter) -> None:
"""Initializes the super class for GDB >= 9"""
if param.param_class == gdb.PARAM_ENUM:
c = CLASS_MAPPING[param.param_class]
if c == gdb.PARAM_ENUM:
super().__init__(
param.name,
gdb.COMMAND_SUPPORT,
param.param_class,
c,
param.enum_sequence,
)
return
super().__init__(param.name, gdb.COMMAND_SUPPORT, param.param_class)
super().__init__(param.name, gdb.COMMAND_SUPPORT, c)
@property
def native_value(self):
return Parameter._value_to_gdb_native(self.param.value, param_class=self.param.param_class)
return Parameter._value_to_gdb_native(
self.param.value, param_class=CLASS_MAPPING[self.param.param_class]
)
@property
def native_default(self):
return Parameter._value_to_gdb_native(
self.param.default, param_class=self.param.param_class
self.param.default, param_class=CLASS_MAPPING[self.param.param_class]
)
def get_set_string(self) -> str:
"""Handles the GDB `set <param>`"""
# GDB will set `self.value` to the user's input
if self.value is None and self.param.param_class in (gdb.PARAM_UINTEGER, gdb.PARAM_INTEGER):
if self.value is None and CLASS_MAPPING[self.param.param_class] in (
gdb.PARAM_UINTEGER,
gdb.PARAM_INTEGER,
):
# Note: This is really weird, according to GDB docs, 0 should mean "unlimited" for gdb.PARAM_UINTEGER and gdb.PARAM_INTEGER, but somehow GDB sets the value to `None` actually :/
# And hilarious thing is that GDB won't let you set the default value to `None` when you construct the `gdb.Parameter` object with `gdb.PARAM_UINTEGER` or `gdb.PARAM_INTEGER` lol
# Maybe it's a bug of GDB?
@ -76,7 +94,7 @@ class Parameter(gdb.Parameter):
else:
self.param.value = self.value
for trigger in config.triggers[self.param.name]:
for trigger in pwndbg.config.triggers[self.param.name]:
trigger()
# No need to print anything if this is set before we get to a prompt,
@ -101,13 +119,13 @@ class Parameter(gdb.Parameter):
if isinstance(value, bool):
# Convert booleans to "on" or "off".
return "on" if value else "off"
elif value is None and param_class == gdb.PARAM_AUTO_BOOLEAN:
elif value is None and CLASS_MAPPING[param_class] == gdb.PARAM_AUTO_BOOLEAN:
# None for gdb.PARAM_AUTO_BOOLEAN means "auto".
return "auto"
elif value == 0 and param_class in (gdb.PARAM_UINTEGER, gdb.PARAM_INTEGER):
elif value == 0 and CLASS_MAPPING[param_class] in (gdb.PARAM_UINTEGER, gdb.PARAM_INTEGER):
# 0 for gdb.PARAM_UINTEGER and gdb.PARAM_INTEGER means "unlimited".
return "unlimited"
elif value == -1 and param_class == gdb.PARAM_ZUINTEGER_UNLIMITED:
elif value == -1 and CLASS_MAPPING[param_class] == gdb.PARAM_ZUINTEGER_UNLIMITED:
# -1 for gdb.PARAM_ZUINTEGER_UNLIMITED means "unlimited".
return "unlimited"
@ -117,6 +135,6 @@ class Parameter(gdb.Parameter):
def init_params() -> None:
# Create a gdb.Parameter for each parameter
for p in pwndbg.gdblib.config.params.values():
for p in pwndbg.config.params.values():
# We don't need to store this anywhere, GDB will handle this
Parameter(p)

View File

@ -46,7 +46,7 @@ class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant):
# Emulating determined the value that was set in the destination register
if left.after_value is not None:
TELESCOPE_DEPTH = max(0, int(pwndbg.gdblib.config.disasm_telescope_depth))
TELESCOPE_DEPTH = max(0, int(pwndbg.config.disasm_telescope_depth))
# Telescope the address
telescope_addresses = super()._telescope(

View File

@ -14,12 +14,13 @@ import pwndbg.gdblib.memory
import pwndbg.gdblib.symbol
import pwndbg.gdblib.typeinfo
import pwndbg.gdblib.vmmap
import pwndbg.lib.config
from pwndbg.emu.emulator import Emulator
from pwndbg.gdblib.disasm.instruction import EnhancedOperand
from pwndbg.gdblib.disasm.instruction import InstructionCondition
from pwndbg.gdblib.disasm.instruction import PwndbgInstruction
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"emulate",
"on",
"""
@ -34,13 +35,13 @@ on - emulation is done to resolve registers/memory values etc.
Emulation can slow down Pwndbg. Disabling it may improve performance.
Emulation requires >1GB RAM being available on the system and ability to allocate RWX memory.
""",
param_class=gdb.PARAM_ENUM,
param_class=pwndbg.lib.config.PARAM_ENUM,
enum_sequence=["on", "off", "jumps-only"],
)
# Even if this is disabled, branch instructions will still have targets printed
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"disasm-annotations",
True,
"""
@ -48,7 +49,7 @@ Display annotations for instructions to provide context on operands and results
""",
)
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"emulate-annotations",
True,
"""
@ -57,7 +58,7 @@ Unicorn emulation for register and memory value annotations on instructions
)
# If this is false, emulation is only used for the current instruction (if emulate-annotations is enabled)
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"emulate-future-annotations",
True,
"""
@ -66,12 +67,10 @@ Unicorn emulation to annotate instructions after the current program counter
)
# Effects future instructions, as past ones have already been cached and reflect the process state at the time
pwndbg.gdblib.config.add_param(
"disasm-telescope-depth", 3, "Depth of telescope for disasm annotations"
)
pwndbg.config.add_param("disasm-telescope-depth", 3, "Depth of telescope for disasm annotations")
# In disasm view, long telescoped strings might cause lines wraps
pwndbg.gdblib.config.add_param(
pwndbg.config.add_param(
"disasm-telescope-string-length",
50,
"Number of characters in strings to display in disasm annotations",
@ -160,18 +159,18 @@ class DisassemblyAssistant:
# Get another reference to the emulator for the purposes of jumps
jump_emu = emu
if pwndbg.gdblib.config.emulate != "on":
if pwndbg.config.emulate != "on":
emu = None
# For both cases below, set emu to None so we don't use it for annotation
if emu and not bool(pwndbg.gdblib.config.emulate_annotations):
if emu and not bool(pwndbg.config.emulate_annotations):
emu = None
# Disable emulation for future annotations based on setting
if (
emu
and pwndbg.gdblib.regs.pc != instruction.address
and not bool(pwndbg.gdblib.config.emulate_future_annotations)
and not bool(pwndbg.config.emulate_future_annotations)
):
emu = None
@ -214,7 +213,7 @@ class DisassemblyAssistant:
# Set the .target and .next fields
enhancer._enhance_next(instruction, emu, jump_emu)
if bool(pwndbg.gdblib.config.disasm_annotations):
if bool(pwndbg.config.disasm_annotations):
enhancer.set_annotation_string(instruction, emu)
# Disable emulation after CALL instructions. We do it after enhancement, as we can use emulation
@ -269,7 +268,7 @@ class DisassemblyAssistant:
"""
# Apply syntax highlighting to the assembly
if pwndbg.gdblib.config.syntax_highlight:
if pwndbg.config.syntax_highlight:
instruction.asm_string = syntax_highlight(instruction.asm_string)
# Populate the "operands" list of the instruction
@ -492,7 +491,7 @@ class DisassemblyAssistant:
# It is assumed proper checks have been made BEFORE calling this function so that pwndbg.chain.format
# will return values accurate to the program state at the time of instruction executing.
enhance_string_len = int(pwndbg.gdblib.config.disasm_telescope_string_length)
enhance_string_len = int(pwndbg.config.disasm_telescope_string_length)
if emu:
return emu.format_telescope_list(

View File

@ -78,7 +78,7 @@ class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant):
# Read from right operand
if right.before_value is not None:
TELESCOPE_DEPTH = max(0, int(pwndbg.gdblib.config.disasm_telescope_depth))
TELESCOPE_DEPTH = max(0, int(pwndbg.config.disasm_telescope_depth))
# +1 to ensure we telescope enough to read at least one address for the last "elif" below
telescope_addresses = super()._telescope(
@ -165,7 +165,7 @@ class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant):
# Example: lea rdx, [rax*8]
left, right = instruction.operands
TELESCOPE_DEPTH = max(0, int(pwndbg.gdblib.config.disasm_telescope_depth))
TELESCOPE_DEPTH = max(0, int(pwndbg.config.disasm_telescope_depth))
if right.before_value is not None:
telescope_addresses = super()._telescope(

View File

@ -19,7 +19,7 @@ from typing import TypeVar
import gdb
from typing_extensions import ParamSpec
from pwndbg.gdblib.config import config
from pwndbg import config
debug = config.add_param("debug-events", False, "display internal event debugging info")

View File

@ -5,11 +5,12 @@ from typing import Sequence
import gdb
import pwndbg.gdblib.config
import pwndbg
import pwndbg.gdblib.events
import pwndbg.gdblib.heap.heap
import pwndbg.gdblib.proc
import pwndbg.gdblib.symbol
import pwndbg.lib.config
from pwndbg.color import message
current: pwndbg.gdblib.heap.heap.MemoryAllocator | None = None
@ -24,7 +25,7 @@ def add_heap_param(
param_class: int | None = None,
enum_sequence: Sequence[str] | None = None,
):
return pwndbg.gdblib.config.add_param(
return pwndbg.config.add_param(
name,
default,
set_show_doc,
@ -75,7 +76,7 @@ sudo apt-get install libc-dbg:i386
If you used setup.sh on Arch based distro you'll need to do a power cycle or set environment variable manually like this: export DEBUGINFOD_URLS=https://debuginfod.archlinux.org
""",
param_class=gdb.PARAM_ENUM,
param_class=pwndbg.lib.config.PARAM_ENUM,
enum_sequence=["auto", "force", "never"],
)
@ -95,7 +96,7 @@ def reset() -> None:
symbol.value = "0"
@pwndbg.gdblib.config.trigger(resolve_heap_via_heuristic)
@pwndbg.config.trigger(resolve_heap_via_heuristic)
def resolve_heap(is_first_run: bool = False) -> None:
import pwndbg.gdblib.heap.ptmalloc

View File

@ -26,8 +26,8 @@ from typing import TypeVar
import gdb
import pwndbg
import pwndbg.chain
import pwndbg.gdblib.config
import pwndbg.gdblib.events
import pwndbg.gdblib.heap
import pwndbg.gdblib.heap.heap
@ -466,6 +466,9 @@ class Heap:
"first_chunk",
)
start: int
end: int
def __init__(self, addr: int, arena: Arena | None = None) -> None:
"""Build a Heap object given an address on that heap.
Heap regions are treated differently depending on their arena:
@ -1662,7 +1665,7 @@ class HeuristicHeap(
@property
def main_arena(self) -> Arena | None:
main_arena_via_config = int(str(pwndbg.gdblib.config.main_arena), 0)
main_arena_via_config = int(str(pwndbg.config.main_arena), 0)
main_arena_via_symbol = pwndbg.gdblib.symbol.static_linkage_symbol_address(
"main_arena"
) or pwndbg.gdblib.symbol.address("main_arena")
@ -1883,7 +1886,7 @@ class HeuristicHeap(
if thread_arena_via_symbol:
thread_arena_value = pwndbg.gdblib.memory.pvoid(thread_arena_via_symbol)
return Arena(thread_arena_value) if thread_arena_value else None
thread_arena_via_config = int(str(pwndbg.gdblib.config.thread_arena), 0)
thread_arena_via_config = int(str(pwndbg.config.thread_arena), 0)
if thread_arena_via_config:
return Arena(thread_arena_via_config)
@ -1944,7 +1947,7 @@ class HeuristicHeap(
print(message.warn("This version of GLIBC was not compiled with tcache support."))
return None
tps = self.tcache_perthread_struct
thread_cache_via_config = int(str(pwndbg.gdblib.config.tcache), 0)
thread_cache_via_config = int(str(pwndbg.config.tcache), 0)
thread_cache_via_symbol = pwndbg.gdblib.symbol.static_linkage_symbol_address(
"tcache"
) or pwndbg.gdblib.symbol.address("tcache")
@ -2017,7 +2020,7 @@ class HeuristicHeap(
@property
def mp(self) -> "pwndbg.gdblib.heap.structs.CStruct2GDB":
mp_via_config = int(str(pwndbg.gdblib.config.mp), 0)
mp_via_config = int(str(pwndbg.config.mp), 0)
mp_via_symbol = pwndbg.gdblib.symbol.static_linkage_symbol_address(
"mp_"
) or pwndbg.gdblib.symbol.address("mp_")
@ -2048,7 +2051,7 @@ class HeuristicHeap(
@property
def global_max_fast(self) -> int:
global_max_fast_via_config = int(str(pwndbg.gdblib.config.global_max_fast), 0)
global_max_fast_via_config = int(str(pwndbg.config.global_max_fast), 0)
global_max_fast_via_symbol = pwndbg.gdblib.symbol.static_linkage_symbol_address(
"global_max_fast"
) or pwndbg.gdblib.symbol.address("global_max_fast")

View File

@ -5,19 +5,20 @@ from typing import List
import gdb
from capstone import * # noqa: F403
import pwndbg
import pwndbg.arguments
import pwndbg.color
import pwndbg.color.context as C
import pwndbg.color.disasm as D
import pwndbg.color.theme
import pwndbg.commands.comments
import pwndbg.gdblib.config
import pwndbg.gdblib.disasm
import pwndbg.gdblib.regs
import pwndbg.gdblib.strings
import pwndbg.gdblib.symbol
import pwndbg.gdblib.vmmap
import pwndbg.ida
import pwndbg.lib.config
import pwndbg.lib.functions
import pwndbg.ui
from pwndbg.color import ColorConfig
@ -51,24 +52,24 @@ nearpc_branch_marker_contiguous = pwndbg.color.theme.add_param(
)
pwndbg.color.theme.add_param("highlight-pc", True, "whether to highlight the current instruction")
pwndbg.color.theme.add_param("nearpc-prefix", "", "prefix marker for nearpc command")
pwndbg.gdblib.config.add_param("left-pad-disasm", True, "whether to left-pad disassembly")
nearpc_lines = pwndbg.gdblib.config.add_param(
pwndbg.config.add_param("left-pad-disasm", True, "whether to left-pad disassembly")
nearpc_lines = pwndbg.config.add_param(
"nearpc-lines", 10, "number of additional lines to print for the nearpc command"
)
show_args = pwndbg.gdblib.config.add_param(
show_args = pwndbg.config.add_param(
"nearpc-show-args", True, "whether to show call arguments below instruction"
)
show_opcode_bytes = pwndbg.gdblib.config.add_param(
show_opcode_bytes = pwndbg.config.add_param(
"nearpc-num-opcode-bytes",
0,
"number of opcode bytes to print for each instruction",
param_class=gdb.PARAM_ZUINTEGER,
param_class=pwndbg.lib.config.PARAM_ZUINTEGER,
)
opcode_separator_bytes = pwndbg.gdblib.config.add_param(
opcode_separator_bytes = pwndbg.config.add_param(
"nearpc-opcode-separator-bytes",
1,
"number of spaces between opcode bytes",
param_class=gdb.PARAM_ZUINTEGER,
param_class=pwndbg.lib.config.PARAM_ZUINTEGER,
)
@ -150,7 +151,7 @@ def nearpc(
symbols = [f"<{sym}> " if sym else "" for sym in symbols]
# Pad out all of the symbols and addresses
if pwndbg.gdblib.config.left_pad_disasm and not repeat:
if pwndbg.config.left_pad_disasm and not repeat:
symbols = ljust_padding(symbols)
addresses = ljust_padding(addresses)
@ -162,7 +163,7 @@ def nearpc(
for i, (address_str, symbol, instr, asm) in enumerate(
zip(addresses, symbols, instructions, assembly_strings)
):
prefix_sign = pwndbg.gdblib.config.nearpc_prefix
prefix_sign = pwndbg.config.nearpc_prefix
# Show prefix only on the specified address and don't show it while in repeat-mode
# or when showing current instruction for the second time
@ -178,10 +179,10 @@ def nearpc(
# symbol is fetched from gdb and it can be e.g. '<main+8>'
# In case there are duplicate instances of an instruction (tight loop),
# ones that the instruction pointer is not at stick out a little, to indicate the repetition
if not pwndbg.gdblib.config.highlight_pc or instr.address != pc or repeat:
if not pwndbg.config.highlight_pc or instr.address != pc or repeat:
address_str = c.address(address_str)
symbol = c.symbol(symbol)
elif pwndbg.gdblib.config.highlight_pc and i == index_of_pc:
elif pwndbg.config.highlight_pc and i == index_of_pc:
# If this instruction is the one the PC is at.
# In case of tight loops, with emulation we may display the same instruction multiple times.
# Only highlight current instance, not past or future times.
@ -281,7 +282,7 @@ def nearpc(
# the length of gray("...") is 12, so we need to add extra 9 (12-3) alignment length for the invisible characters
align += 9 # len(pwndbg.color.gray(""))
opcodes = opcodes.ljust(align)
if pwndbg.gdblib.config.highlight_pc and i == index_of_pc:
if pwndbg.config.highlight_pc and i == index_of_pc:
opcodes = C.highlight(opcodes)
# Example line:

View File

@ -19,23 +19,8 @@ from pwndbg.color import message
from pwndbg.lib.tips import color_tip
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 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."
% (num_pwndbg_cmds, num_shell_cmds, message.notice("pwndbg [--shell | --all] [filter]")),
f"created {funcs_list_str} GDB functions (can be used with print/break)",
)
for line in hint_lines:
print(message.prompt("pwndbg: ") + message.system(line))
# noinspection PyPackageRequirements
show_tip = pwndbg.gdblib.config.add_param(
show_tip = pwndbg.config.add_param(
"show-tips", True, "whether to display the tip of the day on startup"
)
@ -64,6 +49,25 @@ def initial_hook(*a: Any) -> None:
context_shown = False
def show_hint() -> None:
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 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."
% (num_pwndbg_cmds, num_shell_cmds, message.notice("pwndbg [--shell | --all] [filter]")),
f"created {funcs_list_str} GDB functions (can be used with print/break)",
)
for line in hint_lines:
print(message.prompt("pwndbg: ") + message.system(line))
def prompt_hook(*a: Any) -> None:
global cur, context_shown
@ -84,7 +88,7 @@ def reset_context_shown(*a: Any) -> None:
context_shown = False
@pwndbg.gdblib.config.trigger(message.config_prompt_color, disable_colors)
@pwndbg.config.trigger(message.config_prompt_color, disable_colors)
def set_prompt() -> None:
prompt = "pwndbg> "

View File

@ -287,5 +287,5 @@ def update_last() -> None:
M: module = cast(module, sys.modules[__name__])
M.previous = M.last
M.last = {k: M[k] for k in M.common}
if pwndbg.gdblib.config.show_retaddr_reg:
if pwndbg.config.show_retaddr_reg:
M.last.update({k: M[k] for k in M.retaddr})

View File

@ -13,6 +13,11 @@ import pwnlib.asm
import pwnlib.shellcraft
import pwndbg
import pwndbg.gdblib.arch
import pwndbg.gdblib.memory
import pwndbg.gdblib.prompt
import pwndbg.gdblib.regs
import pwndbg.gdblib.vmmap
def _get_syscall_return_value():

View File

@ -32,6 +32,7 @@ import pwndbg.gdblib.remote
import pwndbg.gdblib.stack
import pwndbg.gdblib.typeinfo
import pwndbg.lib.cache
import pwndbg.lib.config
import pwndbg.lib.memory
# List of manually-explored pages which were discovered
@ -42,14 +43,14 @@ explored_pages: List[pwndbg.lib.memory.Page] = []
custom_pages: List[pwndbg.lib.memory.Page] = []
kernel_vmmap_via_pt = pwndbg.gdblib.config.add_param(
kernel_vmmap_via_pt = pwndbg.config.add_param(
"kernel-vmmap-via-page-tables",
"deprecated",
"the deprecated config of the method get kernel vmmap",
help_docstring="Deprecated in favor of `kernel-vmmap`",
)
kernel_vmmap = pwndbg.gdblib.config.add_param(
kernel_vmmap = pwndbg.config.add_param(
"kernel-vmmap",
"page-tables",
"the method to get vmmap information when debugging via QEMU kernel",
@ -61,7 +62,7 @@ none - disable vmmap rendering; useful if rendering is particularly sl
Note that the page-tables method will require the QEMU kernel process to be on the same machine and within the same PID namespace. Running QEMU kernel and GDB in different Docker containers will not work. Consider running both containers with --pid=host (meaning they will see and so be able to interact with all processes on the machine).
""",
param_class=gdb.PARAM_ENUM,
param_class=pwndbg.lib.config.PARAM_ENUM,
enum_sequence=["page-tables", "monitor", "none"],
)

View File

@ -11,12 +11,12 @@ import pwndbg.radare2
import pwndbg.rizin
from pwndbg.color import message
r2decompiler = pwndbg.gdblib.config.add_param(
r2decompiler = pwndbg.config.add_param(
"r2decompiler", "radare2", "framework that your ghidra plugin installed (radare2/rizin)"
)
@pwndbg.gdblib.config.trigger(r2decompiler)
@pwndbg.config.trigger(r2decompiler)
def set_r2decompiler() -> None:
if r2decompiler.value in ["radare2", "rizin"]:
return
@ -87,11 +87,11 @@ def decompile(func=None):
source = source.split("\n")
line = source[curline]
if line.startswith(" "):
line = line[min(4, len(pwndbg.gdblib.config.code_prefix) + 1) :]
line = line[min(4, len(pwndbg.config.code_prefix) + 1) :]
source[curline] = current_line_marker + " " + line
source = "\n".join(source)
if pwndbg.gdblib.config.syntax_highlight:
if pwndbg.config.syntax_highlight:
# highlighting depends on the file extension to guess the language, so try to get one...
src_filename = pwndbg.gdblib.symbol.selected_frame_source_absolute_filename()
if not src_filename:
@ -100,5 +100,5 @@ def decompile(func=None):
source = H.syntax_highlight(source, src_filename)
# Replace code prefix marker after syntax highlighting
source = source.replace(current_line_marker, C.prefix(pwndbg.gdblib.config.code_prefix), 1)
source = source.replace(current_line_marker, C.prefix(pwndbg.config.code_prefix), 1)
return source

View File

@ -14,7 +14,6 @@ from typing import TypeVar
from typing import Union
from typing import cast
import gdb
from elftools.elf.relocation import Relocation
from typing_extensions import ParamSpec
@ -26,25 +25,26 @@ import pwndbg.gdblib.memory
import pwndbg.gdblib.proc
import pwndbg.gdblib.symbol
import pwndbg.lib.cache
import pwndbg.lib.config
import pwndbg.search
from pwndbg.color import message
P = ParamSpec("P")
T = TypeVar("T")
safe_lnk = pwndbg.gdblib.config.add_param(
safe_lnk = pwndbg.config.add_param(
"safe-linking",
None,
"whether glibc use safe-linking (on/off/auto)",
param_class=gdb.PARAM_AUTO_BOOLEAN,
param_class=pwndbg.lib.config.PARAM_AUTO_BOOLEAN,
)
glibc_version = pwndbg.gdblib.config.add_param(
glibc_version = pwndbg.config.add_param(
"glibc", "", "GLIBC version for heap heuristics resolution (e.g. 2.31)", scope="heap"
)
@pwndbg.gdblib.config.trigger(glibc_version)
@pwndbg.config.trigger(glibc_version)
def set_glibc_version() -> None:
ret = re.search(r"(\d+)\.(\d+)", glibc_version.value)
if ret:

View File

@ -10,8 +10,8 @@ import string
import gdb
import pwnlib.util.lists
import pwndbg
import pwndbg.color.hexdump as H
import pwndbg.gdblib.config
import pwndbg.gdblib.typeinfo
from pwndbg.color import theme
from pwndbg.commands.windbg import enhex
@ -37,7 +37,7 @@ config_byte_separator = theme.add_param(
)
@pwndbg.gdblib.config.trigger(
@pwndbg.config.trigger(
H.config_normal, H.config_zero, H.config_special, H.config_printable, config_colorize_ascii
)
def load_color_scheme() -> None:
@ -54,16 +54,16 @@ def load_color_scheme() -> None:
):
color_scheme[c] = H.printable("%02x" % c)
printable[c] = (
H.printable(f"{chr(c)}") if pwndbg.gdblib.config.hexdump_colorize_ascii else f"{chr(c)}"
H.printable(f"{chr(c)}") if pwndbg.config.hexdump_colorize_ascii else f"{chr(c)}"
)
for c in bytearray(b"\x00"):
color_scheme[c] = H.zero("%02x" % c)
printable[c] = H.zero(".") if pwndbg.gdblib.config.hexdump_colorize_ascii else "."
printable[c] = H.zero(".") if pwndbg.config.hexdump_colorize_ascii else "."
for c in bytearray(b"\xff\x7f\x80"):
color_scheme[c] = H.special("%02x" % c)
printable[c] = H.special(".") if pwndbg.gdblib.config.hexdump_colorize_ascii else "."
printable[c] = H.special(".") if pwndbg.config.hexdump_colorize_ascii else "."
color_scheme[-1] = " "
printable[-1] = " "

View File

@ -23,9 +23,9 @@ import gdb
from typing_extensions import Concatenate
from typing_extensions import ParamSpec
import pwndbg
import pwndbg.decorators
import pwndbg.gdblib.arch
import pwndbg.gdblib.config
import pwndbg.gdblib.elf
import pwndbg.gdblib.events
import pwndbg.gdblib.memory
@ -33,16 +33,10 @@ import pwndbg.gdblib.regs
import pwndbg.lib.cache
from pwndbg.color import message
ida_rpc_host = pwndbg.gdblib.config.add_param(
"ida-rpc-host", "127.0.0.1", "ida xmlrpc server address"
)
ida_rpc_port = pwndbg.gdblib.config.add_param("ida-rpc-port", 31337, "ida xmlrpc server port")
ida_enabled = pwndbg.gdblib.config.add_param(
"ida-enabled", False, "whether to enable ida integration"
)
ida_timeout = pwndbg.gdblib.config.add_param(
"ida-timeout", 2, "time to wait for ida xmlrpc in seconds"
)
ida_rpc_host = pwndbg.config.add_param("ida-rpc-host", "127.0.0.1", "ida xmlrpc server address")
ida_rpc_port = pwndbg.config.add_param("ida-rpc-port", 31337, "ida xmlrpc server port")
ida_enabled = pwndbg.config.add_param("ida-enabled", False, "whether to enable ida integration")
ida_timeout = pwndbg.config.add_param("ida-timeout", 2, "time to wait for ida xmlrpc in seconds")
xmlrpc.client.Marshaller.dispatch[int] = lambda _, v, w: w("<value><i8>%d</i8></value>" % v)
@ -60,7 +54,7 @@ T = TypeVar("T")
@pwndbg.decorators.only_after_first_prompt()
@pwndbg.gdblib.config.trigger(ida_rpc_host, ida_rpc_port, ida_enabled, ida_timeout)
@pwndbg.config.trigger(ida_rpc_host, ida_rpc_port, ida_enabled, ida_timeout)
def init_ida_rpc_client() -> None:
global _ida, _ida_last_exception, _ida_last_connection_check
@ -96,10 +90,7 @@ def init_ida_rpc_client() -> None:
not isinstance(_ida_last_exception, exception[0])
or _ida_last_exception.args != exception[1].args
):
if (
hasattr(pwndbg.gdblib.config, "exception_verbose")
and pwndbg.gdblib.config.exception_verbose
):
if hasattr(pwndbg.config, "exception_verbose") and pwndbg.config.exception_verbose:
print(message.error("[!] Ida Pro xmlrpc error"))
traceback.print_exception(*exception)
else:

View File

@ -10,19 +10,39 @@ from typing import List
from typing import Sequence
from typing import TypeVar
import gdb
T = TypeVar("T")
# Boolean value. True or False, same as in Python.
PARAM_BOOLEAN = 0
# Signed integer value.
PARAM_ZINTEGER = 1
# String value. Accepts escape sequences.
PARAM_STRING = 2
# Unsigned integer value.
PARAM_ZUINTEGER = 3
# String value, accepts only one of a number of possible values, specified at
# parameter creation.
PARAM_ENUM = 4
# String value corresponding to the name of a file, if present.
PARAM_OPTIONAL_FILENAME = 5
# Boolean value, or 'auto'.
PARAM_AUTO_BOOLEAN = 6
# Unlimited ZUINTEGER.
PARAM_ZUINTEGER_UNLIMITED = 7
# Signed integer value. Disallows zero.
PARAM_INTEGER = 8
# Unsigned integer value. Disallows zero.
PARAM_UINTEGER = 9
PARAM_CLASSES = {
# The Python boolean values, True and False are the only valid values.
bool: gdb.PARAM_BOOLEAN,
bool: PARAM_BOOLEAN,
# This is like PARAM_INTEGER, except 0 is interpreted as itself.
int: gdb.PARAM_ZINTEGER,
int: PARAM_ZINTEGER,
# When the user modifies the string, any escape sequences,
# such as \t, \f, and octal escapes, are translated into
# corresponding characters and encoded into the current host charset.
str: gdb.PARAM_STRING,
str: PARAM_STRING,
}

View File

@ -14,12 +14,12 @@ import gdb
import pwndbg.color.context as C
import pwndbg.gdblib.arch
from pwndbg import config
from pwndbg.color import ljust_colored
from pwndbg.color import message
from pwndbg.color import rjust_colored
from pwndbg.color import strip
from pwndbg.color import theme
from pwndbg.gdblib import config
theme.add_param("banner-separator", "", "repeated banner separator character")
theme.add_param("banner-title-surrounding-left", "[ ", "banner title surrounding char (left side)")
@ -53,12 +53,14 @@ def banner(title, target=sys.stdin, width=None, extra=""):
config.banner_title_surrounding_right,
)
if "left" == title_position:
banner = ljust_colored(title, width, config.banner_separator)
banner = ljust_colored(title, width, str(config.banner_separator))
elif "right" == title_position:
banner = rjust_colored(title, width, config.banner_separator)
banner = rjust_colored(title, width, str(config.banner_separator))
else:
banner = rjust_colored(title, (width + len(strip(title))) // 2, config.banner_separator)
banner = ljust_colored(banner, width, config.banner_separator)
banner = rjust_colored(
title, (width + len(strip(title))) // 2, str(config.banner_separator)
)
banner = ljust_colored(banner, width, str(config.banner_separator))
return C.banner(banner)

View File

@ -112,13 +112,13 @@ module = [
disable_error_code = ["name-defined", "attr-defined"]
[[tool.mypy.overrides]]
module = ["capstone.*", "unicorn.*", "pwnlib.*", "elftools.*", "ipdb.*", "r2pipe", "rzpipe", "rich.*", "pt_gdb"]
module = ["capstone.*", "unicorn.*", "pwnlib.*", "elftools.*", "ipdb.*", "r2pipe", "rzpipe", "rich.*", "pt_gdb", "lldb.*"]
ignore_missing_imports = true
[tool.isort]
profile = "black"
force_single_line = true
known_third_party = ["capstone", "unicorn", "psutil", "pycparser", "gdb"]
known_third_party = ["capstone", "unicorn", "psutil", "pycparser", "gdb", "lldb"]
add_imports = "from __future__ import annotations"
[tool.coverage.run]

View File

@ -72,12 +72,12 @@ def test_vis_heap_chunk_command(start_binary):
## This time using `default-visualize-chunk-number` to set `count`, to make sure that the config can work
gdb.execute("set default-visualize-chunk-number 1")
assert pwndbg.gdblib.config.default_visualize_chunk_number == 1
assert pwndbg.config.default_visualize_chunk_number == 1
result = gdb.execute("vis_heap_chunk", to_string=True).splitlines()
assert result == expected
gdb.execute(
"set default-visualize-chunk-number %d"
% pwndbg.gdblib.config.default_visualize_chunk_number.default
% pwndbg.config.default_visualize_chunk_number.default
)
del result

View File

@ -82,17 +82,17 @@ def test_empty_context_sections(start_binary, sections):
# Sanity check
default_ctx_sects = "regs disasm code ghidra stack backtrace expressions threads heap-tracker"
assert pwndbg.gdblib.config.context_sections.value == default_ctx_sects
assert pwndbg.config.context_sections.value == default_ctx_sects
assert gdb.execute("context", to_string=True) != ""
# Actual test check
gdb.execute(f"set context-sections {sections}", to_string=True)
assert pwndbg.gdblib.config.context_sections.value == ""
assert pwndbg.config.context_sections.value == ""
assert gdb.execute("context", to_string=True) == ""
# Bring back old values && sanity check
gdb.execute(f"set context-sections {default_ctx_sects}")
assert pwndbg.gdblib.config.context_sections.value == default_ctx_sects
assert pwndbg.config.context_sections.value == default_ctx_sects
assert gdb.execute("context", to_string=True) != ""

View File

@ -3,7 +3,8 @@ from __future__ import annotations
import gdb
import pytest
import pwndbg.gdblib.config
import pwndbg
import pwndbg.lib.config
@pytest.mark.parametrize(
@ -13,14 +14,17 @@ import pwndbg.gdblib.config
("bool", True, "on", {}),
("bool", False, "off", {}),
("string", "some-string-val", "some-string-val", {}),
("auto-bool", None, "auto", {"param_class": gdb.PARAM_AUTO_BOOLEAN}),
("unlimited-uint", 0, "unlimited", {"param_class": gdb.PARAM_UINTEGER}),
("unlimited-int", 0, "unlimited", {"param_class": gdb.PARAM_INTEGER}),
("auto-bool", None, "auto", {"param_class": pwndbg.lib.config.PARAM_AUTO_BOOLEAN}),
("unlimited-uint", 0, "unlimited", {"param_class": pwndbg.lib.config.PARAM_UINTEGER}),
("unlimited-int", 0, "unlimited", {"param_class": pwndbg.lib.config.PARAM_INTEGER}),
(
"enum",
"enum1",
"enum1",
{"param_class": gdb.PARAM_ENUM, "enum_sequence": ["enum1", "enum2", "enum3"]},
{
"param_class": pwndbg.lib.config.PARAM_ENUM,
"enum_sequence": ["enum1", "enum2", "enum3"],
},
),
# Note: GDB < 9 does not support PARAM_ZUINTEGER*, so we implement it by ourselves for consistency
(
@ -29,7 +33,9 @@ import pwndbg.gdblib.config
"0",
{
"param_class": (
gdb.PARAM_ZUINTEGER if hasattr(gdb, "PARAM_ZUINTEGER") else "PARAM_ZUINTEGER"
pwndbg.lib.config.PARAM_ZUINTEGER
if hasattr(gdb, "PARAM_ZUINTEGER")
else "PARAM_ZUINTEGER"
)
},
),
@ -39,7 +45,7 @@ import pwndbg.gdblib.config
"unlimited",
{
"param_class": (
gdb.PARAM_ZUINTEGER_UNLIMITED
pwndbg.lib.config.PARAM_ZUINTEGER_UNLIMITED
if hasattr(gdb, "PARAM_ZUINTEGER_UNLIMITED")
else "PARAM_ZUINTEGER_UNLIMITED"
)
@ -58,7 +64,7 @@ def test_gdb_parameter_default_value_works(start_binary, params):
set_show_doc = "the value of the foo"
param = pwndbg.gdblib.config.add_param(
param = pwndbg.config.add_param(
param_name,
default_value,
set_show_doc,
@ -75,7 +81,8 @@ def test_gdb_parameter_default_value_works(start_binary, params):
== f"{set_show_doc.capitalize()} is {displayed_value!r}. See `help set {param_name}` for more information.\n"
)
if (
optional_kwargs.get("param_class") in (gdb.PARAM_UINTEGER, gdb.PARAM_INTEGER)
optional_kwargs.get("param_class")
in (pwndbg.lib.config.PARAM_UINTEGER, pwndbg.lib.config.PARAM_INTEGER)
and default_value == 0
):
# Note: This is really weird, according to GDB docs, 0 should mean "unlimited" for gdb.PARAM_UINTEGER and gdb.PARAM_INTEGER, but somehow GDB sets the value to `None` actually :/

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import gdb
from pwnlib.util.cyclic import cyclic
import pwndbg.gdblib.config
import pwndbg
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
import pwndbg.gdblib.vmmap
@ -13,7 +13,7 @@ BINARY = tests.binaries.get("reference-binary.out")
def run_tests(stack, use_big_endian, expected):
pwndbg.gdblib.config.hexdump_group_use_big_endian = use_big_endian
pwndbg.config.hexdump_group_use_big_endian = use_big_endian
# Put some data onto the stack
pwndbg.gdblib.memory.write(stack, cyclic(0x100))
@ -35,7 +35,7 @@ def run_tests(stack, use_big_endian, expected):
def test_hexdump(start_binary):
start_binary(BINARY)
pwndbg.gdblib.config.hexdump_group_width = -1
pwndbg.config.hexdump_group_width = -1
# TODO: Setting theme options with Python isn't working
gdb.execute("set hexdump-byte-separator")

View File

@ -4,7 +4,8 @@ from unittest import mock
import gdb
from pwndbg.gdblib import config
import pwndbg.lib.config
from pwndbg import config
def set_show(param_name, value):
@ -13,39 +14,64 @@ def set_show(param_name, value):
gdb.execute(f"show {param_name}")
def single_param(param_name, triggers):
p = getattr(config, param_name.replace("-", "_"))
mock_triggers = []
for trigger in triggers:
mock_triggers.append(mock.Mock(side_effect=trigger))
orig_triggers = config.triggers[param_name]
config.triggers[param_name] = mock_triggers
if p.value is True:
set_show(param_name, "off")
elif p.value is False:
set_show(param_name, "on")
elif isinstance(p.value, int):
set_show(param_name, 0)
set_show(param_name, 1)
set_show(param_name, -1)
elif isinstance(p.value, str) and p.param_class != pwndbg.lib.config.PARAM_ENUM:
set_show(param_name, "")
set_show(param_name, "some invalid text")
set_show(param_name, "red")
set_show(param_name, "bold,yellow")
elif isinstance(p.value, str) and p.param_class == pwndbg.lib.config.PARAM_ENUM:
# Only valid values are allowed, invalid values will cause an error
for enum in p.enum_sequence:
set_show(param_name, enum)
else:
print(p.value, type(p.value))
assert False
for mock_trigger in mock_triggers:
mock_trigger.assert_called()
config.triggers[param_name] = orig_triggers
def test_triggers():
# The behavior of some triggers depend on the value of other parameters!
#
# This means that the order in which we run through the parameters matters,
# and, in particular, some instances will cause the test to fail, where
# others will not. If this test starts failing seemingly for no reason after
# a change to the order of imports, this might be the reason.
#
# Important time dependencies to keep in mind:
# - `disable-colors` will normally be disabled during the test, so we
# must ensure this only happens after this test case has gone through
# all parameters that set color, or the test will likely fail.
#
deferred = []
for param_name, triggers in config.triggers.items():
p = getattr(config, param_name.replace("-", "_"))
if param_name == "disable-colors":
deferred.append((param_name, triggers))
continue
mock_triggers = []
for trigger in triggers:
mock_triggers.append(mock.Mock(side_effect=trigger))
single_param(param_name, triggers)
orig_triggers = config.triggers[param_name]
config.triggers[param_name] = mock_triggers
if p.value is True:
set_show(param_name, "off")
elif p.value is False:
set_show(param_name, "on")
elif isinstance(p.value, int):
set_show(param_name, 0)
set_show(param_name, 1)
set_show(param_name, -1)
elif isinstance(p.value, str) and p.param_class != gdb.PARAM_ENUM:
set_show(param_name, "")
set_show(param_name, "some invalid text")
set_show(param_name, "red")
set_show(param_name, "bold,yellow")
elif isinstance(p.value, str) and p.param_class == gdb.PARAM_ENUM:
# Only valid values are allowed, invalid values will cause an error
for enum in p.enum_sequence:
set_show(param_name, enum)
else:
print(p.value, type(p.value))
assert False
for mock_trigger in mock_triggers:
mock_trigger.assert_called()
config.triggers[param_name] = orig_triggers
for param_name, triggers in deferred:
single_param(param_name, triggers)

View File

@ -9,6 +9,14 @@ from mocks.config import Config
from mocks.typeinfo import Amd64TypeInfo
class GdbLibPrompt(types.ModuleType):
def __init__(self, module_name):
super().__init__(module_name)
def show_hint(self):
pass
class GdbLib(types.ModuleType):
def __init__(self, module_name):
super().__init__(module_name)
@ -19,13 +27,13 @@ class GdbLib(types.ModuleType):
self.arch = Amd64Arch(module_name + ".arch")
self.typeinfo = Amd64TypeInfo(module_name + ".typeinfo")
self.regs = MagicMock(__name__=module_name + ".regs")
self.prompt = MagicMock()
self.prompt = MagicMock(__name__=module_name + ".prompt")
sys.modules[self.config_mod.__name__] = self.config_mod
sys.modules[self.arch.__name__] = self.arch
sys.modules[self.typeinfo.__name__] = self.typeinfo
sys.modules[self.regs.__name__] = self.regs
sys.modules[self.prompt.__name__] = self.prompt
def load_gdblib(self):
pass