* parameter pretty printing, improved help doc
* make var descriptions short (put it in help doc), define enumerations
* swap value and description column
* lint
* revert to ' for quoting, fix some tests
* golf the config a bit
* fix config filtering test
* lint
* tls: dump the tls address by default
Use a `dt tcbhead_t <tls_address>` if there is a `tcbhead_t`. If there
is not, use telescope to dump it
Refactor the tls tests and add some new ones based on the change.
* Update pwndbg/commands/tls.py
* Update pwndbg/commands/tls.py
* Update pwndbg/commands/tls.py
* Update tls.py
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Expose list of breakpoint locations in aglib
The list of addresses with active breakpoints can be retrieved using `Debugger.breakpoint_locations()`.
* Highlight breakpoints in `nearpc` output
Addresses in the disassembly which have an active breakpoint attached to them
are prefixed using by `b+` and highlighted in red by default.
This can be configured using the new `highlight-breakpoints`, `nearpc-breakpoint`,
and `nearpc-breakpoint-color` theme config options.
* Fix `breakpoint_locations` on lldb
* Update tests/gdb-tests/tests/test_nearpc.py
* Refactor breakpoint prefix logic
* Account for leading space before prefix again
* Move prefix coloring and preparation outside loop
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Reduce context shaking when quickly stepping
by reserving empty lines after the command prompt
* clarify the extra lines property
* add config option
* disable line-reservation for tests
* lint
We're now using `writelines` to output the context data which wasn't implemented
for the CallOutput redirection layer. Add a smoke test for that output redirection.
Refs #2654
* Allow dumpargs to format bit flags
If flags are supplied for a funciton in `functions_data.py`, the
`dumpargs` command can pretty-print the combination of flags used in the
call.
* Update format for flags arguments.
The format now includes the original integer value *and* the extracted
flag names (if any). A sample output would be `0x03 (FLAG_2|0x01)`.
* Fix lint
* Address review comments
* Remove import after rebase
---------
Co-authored-by: Loren Van Spronsen <lorenvs@google.com>
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Create an authoritative list of architectures that Pwndbg supports. Add test to ensure some important mappings exist - add i8086 pwnlib mapping
* make pwnlib mapping 'none' by default
* Update pwndbg/dbg/gdb/__init__.py
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
* Update pwndbg/lib/arch.py
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
* Update pwndbg/lib/arch.py
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
* More type safety with the list of supported types, handle iwmmxt, iwmmxt2, and xscale manually
---------
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
The output of the expressions section changes even when running `context` multiple times after each other. The output variables in GDB are counted up when reexecuting the watched commands for example. The other sections don't change their output. This caused the history to be extended infinitely when using `ctxp` while having a `cwatch` command executed.
Special case the `expressions` context section in the history handling to avoid reevaluating the watched commands/expressions while browsing the history. This doesn't add the context output to the history when the expressions VALUES change somehow like it is done for the other sections, but since we cannot know if gdb counted up their output variable names from $1 to $2 or the value changed, this is a compromise.
* Fix#2549: block config.<name> assignments
This commit blocks `config.<param> = <value>` assignments as they should be done via `config.<param>.value = <value>`
instead.
* Update config.py
* add .value
* docs: Add missing testing toc entries and other minor formatting
* fix: Adjust nix dev shell packages to properly support jemalloc and qemu tests
* fix(jemalloc): Add more robust error handling to jemalloc commands and fix test
* fix: point JEMALLOC_PATH to correct jemalloc package path
* fix: Use correct aglib-compatible symbol resolution function
* fix: re-enable test_jemalloc_heap test and make slightly more forgiving
* splitting tests passed and skipped variable into two, solving issue #2485
* Fixing bugs in PR #2495
* jemalloc.py: remove unused Arena class (#2492)
* Fixes canary command when no canaries are there (#2496)
Fixes the following bug uncovered by our test_commands[canary] test suite:
```
(.venv) root@pwndbg:~/pwndbg# RUN_FLAKY=1 ./tests.sh 'test_commands' --pdb
Will run tests in serial and with Python debugger
ZIGPATH set to /root/pwndbg/.zig
make: Nothing to be done for 'all'.
pwndbg: loaded 173 pwndbg commands and 47 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $base, $bn_sym, $bn_var, $bn_eval, $ida GDB functions (can be used with print/break)
Launching pytest with args: ['/root/pwndbg/tests/gdb-tests/tests/test_commands.py::test_commands[canary]', '-vvv', '-s', '--showlocals', '--color=yes', '--pdb']
======================================================================== test session starts ========================================================================
platform linux -- Python 3.11.6, pytest-8.0.2, pluggy-1.5.0 -- /usr/bin/python
cachedir: .pytest_cache
rootdir: /root/pwndbg/tests
plugins: cov-4.1.0
collected 1 item
gdb-tests/tests/test_commands.py::test_commands[canary] Running command canary
This GDB supports auto-downloading debuginfo from the following URLs:
<https://debuginfod.ubuntu.com>
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
Program stopped.
0x00007ffff7fe4b40 in _start () from /lib64/ld-linux-x86-64.so.2
AT_RANDOM = 0x7fffffffe3d9 # points to (not masked) global canary value
Canary = 0x37492280ae2b3000 (may be incorrect on != glibc)
No canaries found.
Traceback (most recent call last):
File "/root/pwndbg/pwndbg/commands/__init__.py", line 187, in __call__
return self.function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/__init__.py", line 378, in _OnlyWhenRunning
return function(*a, **kw)
^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/canary.py", line 91, in canary
if some_canaries_not_shown is True:
^^^^^^^^^^^^^^^^^^^^^^^
UnboundLocalError: cannot access local variable 'some_canaries_not_shown' where it is not associated with a value
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/root/pwndbg/pwndbg/dbg/gdb.py", line 871, in invoke
self.handler(self.debugger, args, from_tty)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 105, in _handler
self.invoke(arguments, is_interactive)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 153, in invoke
self(*args, **kwargs)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 192, in __call__
pwndbg.exception.handle(self.function.__name__)
File "/root/pwndbg/pwndbg/exception.py", line 106, in handle
raise e
File "/root/pwndbg/pwndbg/commands/__init__.py", line 187, in __call__
return self.function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/__init__.py", line 378, in _OnlyWhenRunning
return function(*a, **kw)
^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/canary.py", line 91, in canary
if some_canaries_not_shown is True:
^^^^^^^^^^^^^^^^^^^^^^^
UnboundLocalError: cannot access local variable 'some_canaries_not_shown' where it is not associated with a value
```
* Fix gdt command: require address argument (#2497)
Before this commit, the `gdt` command incorrectly did not require the `address` argument, while it was required.
Because of that, the command crashed like this:
```
pwndbg> gdt
'gdt': Decode X86-64 GDT entries at address
See also:
* https://wiki.osdev.org/Global_Descriptor_Table
* https://wiki.osdev.org/GDT_Tutorial
Note:
In 64-bit mode, the Base and Limit values are ignored, each descriptor covers the entire linear address space regardless of what they are set to.
Exception occurred: gdt: int() argument must be a string, a bytes-like object or a real number, not 'NoneType' (<class 'TypeError'>)
For more info invoke `set exception-verbose on` and rerun the command
or debug it by yourself with `set exception-debugger on`
```
* Add better handling for exceptions originating in execution controllers under LLDB (#2488)
* Fix try_free command: make addr argument required (#2499)
Fixes the following problem:
```
pwndbg> try_free
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
> /root/pwndbg/pwndbg/commands/heap.py(1195)try_free()
1194 def try_free(addr: str | int) -> None:
-> 1195 addr = int(addr)
1196
```
* Fix ctxp command (#2498)
* Fix ctxp and ctxn commands
Before this commit the `ctxp` could fail with:
```
Launching pytest with args: ['/root/pwndbg/tests/gdb-tests/tests/test_commands.py::test_commands[ctxp]', '-vvv', '-s', '--showlocals', '--color=yes', '--pdb']
======================================================================== test session starts ========================================================================
platform linux -- Python 3.11.6, pytest-8.0.2, pluggy-1.5.0 -- /usr/bin/python
cachedir: .pytest_cache
rootdir: /root/pwndbg/tests
plugins: cov-4.1.0
collected 1 item
gdb-tests/tests/test_commands.py::test_commands[ctxp] Running command ctxp
This GDB supports auto-downloading debuginfo from the following URLs:
<https://debuginfod.ubuntu.com>
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
Program stopped.
0x00007ffff7fe4b40 in _start () from /lib64/ld-linux-x86-64.so.2
Traceback (most recent call last):
File "/root/pwndbg/pwndbg/commands/__init__.py", line 187, in __call__
return self.function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/context.py", line 363, in contextprev
longest_history = max(len(h) for h in context_history.values())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: max() arg is an empty sequence
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/root/pwndbg/pwndbg/dbg/gdb.py", line 871, in invoke
self.handler(self.debugger, args, from_tty)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 105, in _handler
self.invoke(arguments, is_interactive)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 153, in invoke
self(*args, **kwargs)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 192, in __call__
pwndbg.exception.handle(self.function.__name__)
File "/root/pwndbg/pwndbg/exception.py", line 106, in handle
raise e
File "/root/pwndbg/pwndbg/commands/__init__.py", line 187, in __call__
return self.function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/context.py", line 363, in contextprev
longest_history = max(len(h) for h in context_history.values())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: max() arg is an empty sequence
XFAIL (flaky test)
```
* fix
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
Co-authored-by: Matt. <dark.ryu.550@gmail.com>
* Fix terminal width to 80 columns in tests
Set a `PWNDBG_IN_TEST`environment variable when running gdb in tests. Use the dimensions in `LINES` and `COLUMNS` when looking up the window size when that envvar is set.
This makes context output always be 80 columns wide which allows to compare to hardcoded output.
* Use `width` and `height` parameters for cmd window size
They are updated to the correct values when switching between tui and cli mode. So it's unnecessary to parse `info win`.
* Remove workarounds for terminal size in DEVELOPING
* Don't bother updating the env of the debuggee
* Add history of context output
Every context section is cached individually to allow to display older output again. You can scroll through the old context output using `contextprev` and `contextnext`.
This allows to "scroll" in TUI mode.
* Add button TUI window to control context history
* Simplify history status output generation
* Fix attachp tests when ptrace_scope is missing
Assume we can attach to any process when ptrace_scope is not available. This is the case in WSL2.
* Update tests/gdb-tests/tests/test_attachp.py
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Make last-signal context section selectable
There exists a context section to display the reason for the last stop, but it wasn't registered anywhere.
Add it to the list of available sections to choose from.
* Fix default context sections "heap-tracker"
The section name is derived from the function name.
The function is called `context_heap_tracker` so `heap-tracker` wouldn't work:
```
pwndbg> set context-sections heap-tracker
Invalid section: heap-tracker, valid values: args, regs, disasm, stack, backtrace, code, expressions, ghidra, heap_tracker, threads
```
The validator doesn't appear to run for the default value :D
* Update help text to include all available context sections
* Replace bash with sleep in attachp commands to fix crash due to reading from terminal
* Update tests/gdb-tests/tests/test_attachp.py
* Update test_attachp.py
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Fixed bug where plist()'s argument sentinel had incorrect type
* Fixed bug where if sentinel was different from zero, plist tried to dereference a null address
* Fixed bug where some error message in plist displayed 0x0x{address} due to incorrect formatting
* Added additional tests for plist's bugfixes
* Added types to hexdump()'s parameters
* hexdump(): upgraded format strings to f-strings, while fixing the offset when data is empty
* hexdump(): offset is now correctly computed and updated accross repeated calls to hexdump.
This fixes two bugs:
1. Offset was increased by the number of lines displayed by the hexdump() command,
which was incorrect, as some lines may be compressed;
2. When dumping a number of bytes that is not divisible by the number of bytes per line,
offset would be incorrectly updated.
* Linter
* hexdump: fixed type of retrieved config entry hexdump_group_use_big_endian
* Fixed test_hexdump_saved_address_and_offset test to account for random stack address
* Upgraded the linked-lists.c test program to 6 items in order to test the "deference-limit" setting
* Chain: changes to the deference-limit parameter were not reflected in the program due to an early cast to int()
* Linter
* Added support for `--offset` and `--count` for plist
* Added typing to commands.plist's prototype
* Updated documentation for plist tests
* Add informational message when plist --count is zero or under
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Handle case, in plist, where the default value for count is zero
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Added types to hexdump()'s parameters
* hexdump(): upgraded format strings to f-strings, while fixing the offset when data is empty
* hexdump(): offset is now correctly computed and updated accross repeated calls to hexdump.
This fixes two bugs:
1. Offset was increased by the number of lines displayed by the hexdump() command,
which was incorrect, as some lines may be compressed;
2. When dumping a number of bytes that is not divisible by the number of bytes per line,
offset would be incorrectly updated.
* Linter
* hexdump: fixed type of retrieved config entry hexdump_group_use_big_endian
* Fixed test_hexdump_saved_address_and_offset test to account for random stack address
* Upgraded the linked-lists.c test program to 6 items in order to test the "deference-limit" setting
* Chain: changes to the deference-limit parameter were not reflected in the program due to an early cast to int()
* Linter