* added/modified registers for kernel pwning
* added a RegisterContext class for more complex register context handling
* cleaned up register context selection and flag bits
* further cleaned up register context selection
* fixing None deref issue
* handling NoneType registers
* linting
* removed most of the extra register classes
* fully removed extra register classes in commands/context.py
* renamed var so that the linter doesn't confuse the var name with dataclass type name
* some comments on newly added classes
* fixed issues based on suggestions
* fixed issues when debug symbols are not present in x64 kernel
* Apply suggestions from code review
Co-authored-by: OBarronCS <55004530+OBarronCS@users.noreply.github.com>
* reduced performance overhead & added some examples for arm biflags & error handling
---------
Co-authored-by: OBarronCS <55004530+OBarronCS@users.noreply.github.com>
* test that gdb and argparse give the same help message
* fix misc test
* rstrip outputs
* added comment explaining the down aliases
* Update pwndbg/commands/ida.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update tests/gdb-tests/tests/test_misc.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* - Use process network namespace instead of debugger network namespace for /proc/net/* files.
- Add tcp6 support
* - use tid
* - fix format ipv6
* fix lint
* add test + fixes
* convert little to big endian
* convert little to big endian
* Use Zig for compiling for cross architecture tests.
* comments/typos
* Check if GDB supports crossarch targets, inline _start definition in assembly, add comments
* expand and add examples to pwndbg convenience functions
* update usage descriptions in _gen_*
* refactor out some common logic
* implement function doc generation
* change some mkdocs defaults around to be better for the general case
* generate function docs
* cleanup some examples, help, and quote escaping explanation
* move fsbase and gsbase definitions (and use decorator)
* cleanup signature for fsbase and gsbase
* autogen functions
* type annotation
* fix ida and binja descriptions
* rename arguments, reorder docs for `help function` and assert convention
* add missing imports
* use inspect.getdoc instead of directly accessing __doc__
for more consistency across python versions
* regen docs with getdoc()
* rewire exit and lint
* let users know about convenience functions through the `pwndbg` command
* sys.exit instead of exit
* Add a test that steps through each instruction in a program in different arches to detect crashes in annotations code
* lint
* Add symlinks so qemu can find libraries, simplify selecting correct qemu version
* lint
* compile cross-arch binaries with -static
* Add map of cross-arch library paths to avoid creating symlink
* lint
* clean up cross-arch makefile, skip the slow tests unless an environment variable is set
* correct compiler versions
* remove empty lines
* Makefile comment
* Add syscall to basic.c
* Increase performance
* Always run the tests
* lint
* initial PwndbgArchitecture
* pwndbg.aglib.arch refers to the PwndbgArchitecture instance
* Update pwndbg/aglib/arch.py
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
* stuff
* Simplify setting the architecture, remove duplicated code
* ABI and SyscallABI now retrieved from the arch object
* lint
* fix syscall abi fetch
* rename
* lint
* Update pwndbg/aglib/arch.py
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
* Update pwndbg/aglib/arch.py
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
* Remove unused comment
* comment
* ABI fetch fix
* lint
* simplify sparc capstone constant
* Change how architectures are registered
* Ensure all uses of function abi/syscall abi have a check to see if they are not None
* More gracefully report error on unrecognized architectures
* Fix ABI function argument fetch
* remove old comment
* Add class for loongarch + s390x, add test to ensure all arches have a class defined
* Add variable 'max_instruction_size' to arch classes
* Rename mock arch to MockAmd64Arch
* Rebase
* Remove Protocol due to bug in __init__ in Python 3.10
* Remove name_raw, add ArchAttribute's + MIPS constants
* add @override decorator
* rebase
---------
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
* Refactor DisassemblyAssistant so they can be used to share/track information between instructions being enhanced in the same pass
* Fix incorrect change in breakonconditionalbranch + add comment
* rebase
* Move disasm/__init__.py -> ../disassembly.py in order to avoid a circular import. Create central list of all DisassemblyAssistant's
* move disassembly.py file back to disasm folder
* Upgrade to Capstone V6
* Fix final bugs related to changes in metadata/shift encoding in Capstone v6. All tests pass
* rebase prep
* Update to Capstone v6 alpha 4
* lint
* Apply patch to fix nixos packaging
* Fix "set glibc 2.31" which got broken recently
I haven't tracked when it got broken, but we were setting a tuple for a string parameter.
It did not work on 2025.02.19 but worked on 2025.01.20.
I also added a testcase for this behavior now.
* Update glibc.py
* 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
* Port Pwndbg to LLDB
* Fix splitting mistakes
* I love typos
* We already check for Python 3.11 manually
* Update pwndbg/dbg/lldb/__init__.py
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
* Fix use of wrong variable name that was preventing the vmmap from being used in LLDB memory reads
* Use cached vmmap for `read_memory` in LLDB
* Fix Pwndbg CLI jank
* Try using SBAddress to resolve objfile names in LLDB vmmap
* Fix missing changes in `pwndbg.gdblib`
* Update pwndbg/aglib/arch.py
* Update pwndbg/aglib/arch.py
* Remove outdated comment about `pwndbg.aglib.arch`
* Update pwndbg/dbg/lldb/repl/io.py
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Fix lints
* Fix new test so that it points to `pwndbg.aglib.disasm`
* Fix lints
---------
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Merge Arm tests
* Integrate MIPS, AArch64, RISC-V tests, and the rest of the ARM edges cases
* add fsbase/gsbase annotation test
* add function call / fin test
* lint
* Fix all bugs found - MIPS JAL, delay slots splits, arm/aarch unconditional jumps, and forcing targets when we know they go to the next instruction in memory, and add a bunch of comments. Arm now detects instructions that write to PC as branches too.
* Fix Arm exclusive stores
* comment update
* Fix arm/aarch64 post-indexed stores - add test
* AArch64 post-index stores
* Fix arm shifts
* comment typo
* Initial version of qemu-user tests
* Refactor testing files to reduce file duplication, introduce qemu-user-tests
* lint and edit github actions workflow file. Move old qemu-user tests to seperate directory
* Add iproute2 so ss command is available
* test ubuntu 24
* funkiness with current working directory...
* Further remote old test_qemu.sh and integrate into a Pytest fixture
* lint
* Disable ASLR, add test for aarch64 jumps
* Use Popen.kill() function to make sure it closes.
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* qemu.kill() on the other fixture as well
* comment
* comment
* lint
* system test path stuff
* remove old try-catch block
* revert
* revert path change
* Use os._exit to pass return code, and move qemu-user tests above system tests because they run significantly faster
* lint
* Flush stdout before os._exit
* Comment out flaky check for the address of main in old qemu tests
* rename qemu-user to cross-arch
* rename qemu-user to cross-arch and hotfix to not run pytest when
cross-arch is used
* remove todo comment
* another comment
* Test pwndbg.gdblib.symbol.address is not None and revert setarch -R
* Revert os.exit change
* Revert os.exit change
* Revert os.exit change
* readd os.exit in new exit places
* lint
* rebase
* delete file introduced in rebase
* break up tests into 3 files to invoke separately. Update GitHub workflow, remove code duplication in existing test
* code coverage
* fix code coverage
* lint
* test difference between Ubuntu 22 and 24 in Kernel tests
* lint
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* basic go value dumping
* better error handling and misc improvements
* minor documentation changes
* satisfy mypy
* struct parsing and bug fix
* satisfy mypy
* deal with evacuated buckets
* better error message for invalid expressions
* convert bytearray to bytes before repr
* support for recursive types and better type dumping
* better QOL for go-dump command
* formatting options and debug/pretty printing
* add go dumping unit tests
* deal with differences in old go version
* lint
* old go versions missing any alias
* proper name dumping for go versions prior to 1.17
* lint
* go is being weird on CI
* warn instead of erroring
* function and interface dumping
* Add event system to the Debugger-agnostic API
* Move uses of `pwndbg.gdblib.events` to the Debugger-agnostic API
* Fix rebase mistakes
* Update pwndbg/commands/context.py
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Update context.py
* Update __init__.py
* Fix nits
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* basic binary ninja integration
* start centralizing integrations into uniform interface
* finish most integrations
* make binja integration contain all ida features
* allow switching servers
* remove unused functions
* format
* fix unit tests
* satisfy mypy + warn instead of error on invalid provider
* fix decompilation not working in function prologue
* better config options and il config
* lint
* fix bn_sym test
* add decomp command
* add bn_eval gdb function
* format binja_script.py
* satisfy mypy again
* doc update
* move integrations to separate subdir + make test_loads more versatile
* format
* forgot to push a file
* format
* highlight next instruction instead of previous one in decomp
* fix disassembly il level
* prefer function tags over data tags
* add bn_var function
* add variable labeling
* more configurability, documentation, bug fixes
* code cleanup
* format
* remove code duplication between chain.py and memory.py
* add short-lived cache for some integration functions
* use every register available to help with frame inference
* lint
* don't waste time checking irrelevant registers
* move performance hit in cache only to except case
* fix issue with conflict resolution
* lint
* fix rebase mistake
* 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
* Improve bin corruption checks
* Update pwndbg/heap/ptmalloc.py
* factor out and clean up bin corruption check
* check chunks even if bin is longer than limit
* add empty bin check
* lint.sh, remove testing if
* dont modify chain in check, allow corruption=0, cleanup
* typing, more reliable empty bin check
* cast params to int, otherwise not detected properly
* add regression test for corruption check
* lint.sh
---------
Co-authored-by: Gulshan Singh <gsingh2011@gmail.com>
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Implement bitwise math rotation operations on numbers of discrete width. Will be used in manually evaluating arm instruction offsets and shifts
* fixes
* Fix caching for pwndbg.gdblib.elf functions
* Add test for cache clear priority
* Fix formatting in files
* switch priority to an enum instead of boolean
* fix logging for start event
* decouple gdblib.events import from lib.cache
* Move syscall number evaluation into instruction.py. This allows us to determine and display future syscalls
* Move string manipulation to color.disasm.py
* lint
* fix padding
* Fix x86 syscall
* comment
* disable debug mode
* Fix a test - we now remember previous syscalls as well
* Move x86 specific syscall logic to the x86 subclass
* lint
* @override decorator added to methods
* comments
* lint
* add test with emulation disabled for syscall annotation
* Fix x86/x86_64 edge cases with syscall register reading, and add test for emulation off for syscalls
* Update an outdated comment
* Tests depend on width of context banner
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Add gdb_version to mock gdblib
* Re-enable unit tests
* Only collect unit test coverage if --cov is passed
* Source venv before running tests in github action
* Add venv path PATH in to Dockerfile
* Only check for "/ls" in `which` test
* Fix i386-32 syscall name printing
pwndbg-git from AUR shows hexadecimal constants in masm syntax
(e.g. 80h) for some reason (as if the option CS_OPT_SYNTAX_MASM was set).
This commit makes syscall name printing work regardless of hex syntax.
* riscv: Fix AssertionError on "jalr ra, ra, 0x252"
When the PC was on this instruction, the pwndbg context would not be
printed due to this AssertionError.
* riscv: Fix AssertionError on "c.jalr a5"
According to the specification, "C.JALR expands to jalr x1, 0(rs1)".
* Modify python test scripts to work from nix
* Update utils.py
* address review feedback
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Only look for readable address in retaddr command
* Rename stack.py to retaddr.py
* Add pwndbg.gdblib.stack.callstack and use it in retaddr
* Add callstack gdb test
* Add QEMU callstack test
* V1 - annotations for values of registers and memory to display result of instructions.
* Emulator telescope(), more x86 instructions
* Emulation change - keep track of before & after instruction execution. Telescope format correctly, read size taken into account
* Add config options to configure emulation and annotations, vmovaps alignment warning, string length in disasm telescope, cache previously annotated instructions
* Create PwndbgInstruction type for better typing and easier future development
* More consistent spacing, options to disable annotations, ADD instruction shows operands
* Rebase from dev
* Correctly go to .next address in disasm view (was incorrectly going to call targets)
* Precompute register str to reduce code duplication
* Correct telescope memory read width, bring target printing back to previous behavior when symbol can be resolved
* More consistent looking annotation spacing/padding, fixed edge case bugs with cached instructions
* Even cleaner padding
* Additional comments and debugging, ironed out last bugs
* debugging tight loops
* Cache fixed - nearpc only annotates what can be statically resolved
* lint and show instructions that cannot dereference
* Reapply btrace crash fix after rebase
* Less code duplication, implement XCHG and AND instructions, moved more methods from x86 subclass to superclass
* aarch64 set flags register in Unicorn correctly
* fix
* Don't recreate emulator regname->const map every time the emulator is instantiated
* Use emulation to set .next within enhancement
* Improve ret instruction target address setting
* Green checkmarks for jumps on all architectures
* Fixed .next and .target setting
* All architectures now have correct logic for determining .next and .target. Green checkmarks for taking conditional branches now appear for all architectures, added things to determine that type of branch being taken, and simplified printing by replacing symbol_addr with new field 'target_string'
* Instruction debug print fix
* Correct jump instruction checking
* Fixed target_string resolution
* Fix conditional jump check, also make default target resolution better
* target_const determined more accurately
* reverse iteration order of last change
* Pwndbg.condition is more retyped and more correct, make manual determinations of condition override the emulators (it can be incorrect in cases). Uncover why MIPS sometimes takes incorrect jumps in the emulator (delay slot)
* MIPS annotations work really good now. Jumps are correctly predicted (with green checkmarks). Implemented manual condition() function for MIPS. Only highlight the correct instance of instruction at PC when there are multiple in view (tight loops). Allow manual .condition to override emulator in determiningg .next.
* Additional debug info on instructions
* Print arch in instruction
* aarch64 branch fix
* aarch64 branch fix (real)
* lint
* Final changes - fixing .size error
* lint
* Add dev_dump_instruction command, add default memory read in resolve_used_value, update comments and remove .size from enhancedoperand as it only exists on x86
* More uniform spacing on annotations
* Various comments converted to docstrings, aarch64 enhancer created, post-rebase
* import aarch64
* Aarch64 mov, ldr, add, sub
* adrp
* ADR
* lint
* Fun with git rebase
* lint
* lint again after re-installing dependencies
* New caching strategy implemented to ensure no state caching when jumping large distances. Handled edge cases of user manually setting a register or memory, 'set regname=2'
* lint
* Fixed two regressions (nearpc shouldn't take jumps, even ones we know statically, and replace all constants in the assembly with symbols). Tweak tests to reflect new annotations
* lint
* one last test
* Fix chain format dereferencing for non-singleton lists, now correctly deferences and displays chains for future instructions when not emulating (dereference until pointer goes to writable memory)
* Add jumps-only setting to emulation (on, off, jumps-only), fixes to chain deferencing and enhancing
* Properly dereference memory before and after execution of instructions, adding a new before_value_resolved field (same for after). This also reduces code duplication.
* Debogusify the format()/telescoping dereferencing logic
* lint
* post-rebase fixes
* Fix case the breaks a test - don't attempt to read larger than ptrsize such as in SIMD instruction memory reads
* Typo in emulate setting
* Developer docs for annotations
* Fix case where emulator attempts to read and unpack very large, 16 byte+ wide values while telescoping
* Add a helper command to find valid one_gadget for current context
* Refactor the function for getting section address
* Rename the command to onegadget for more convenient typing
* Make the output format cleaner
* Add a simple cache mechanism for the one_gadget output
* Update the warning message
* Use MD5 instead of BLAKE2 for computing the file hash
I thought that BLAKE2 was faster than MD5, but it doesn't seem correct here somehow (probably because of the implementation of Python!?)
Here's the script I used for benchmarking:
```python
import hashlib
import timeit
def compute_file_hash_1() -> str:
h = hashlib.blake2b()
with open("/lib/x86_64-linux-gnu/libc.so.6", "rb") as f:
h.update(f.read())
return h.hexdigest()
def compute_file_hash_2() -> str:
h = hashlib.md5()
with open("/lib/x86_64-linux-gnu/libc.so.6", "rb") as f:
h.update(f.read())
return h.hexdigest()
print(timeit.timeit(compute_file_hash_1, number=1000))
print(timeit.timeit(compute_file_hash_2, number=1000))
```
I executed the above script on various machines, and the results seem to show that MD5 outperforms BLAKE2 in this scenario. (On my x86 VM running through QEMU on my M1 MacBook, BLAKE2 even takes almost twice as long as MD5.)
* Add the tests for `onegadget` command
* Fix lint issue
* Try to cover more code
* Fix lint issue
* Fix illogical tests
* Rename one_gadget to onegadget
* Use `pwndbg.lib.tempfile.cachedir` for `onegadget`
* Call `pwndbg.lib.tempfile.cachedir` only once
* Add support for breaking on UAF
* Small fixes and documentation
* Add a command to enable and disable tracking, better diagnostics
* Add initial support for calloc and realloc
* Better safeguard against matching ld.so malloc
* Small fixes
* Better interface for managing the heap tracker. More terse and information dense diagnostics
* Add warning and fix lints
* Update poetry lock
Hopefully fixes#1947 by fetching stacks only when they are used instead
of doing it on each stop event. It will also first try to compute stacks
dictionary based on vmmap and if it fallbacks to exploring stacks if
vmmap is not present.
* [WIP] Port gdb-tests from bash to python
* Use threads instead of processes
* Port gdb tests to python
* Linting
* Fix coverage "again"
* Remove bash tests
---------
Co-authored-by: intrigus <abc123zeus@live.de>
Previously test scripts would just indiscriminately kill all qemu
processes on the system. This would kill other debug sessions I had
running. These changes make the test scripts record the qemu pids they
run and only kill those.
The old scripts would also not allow you to specify a gdb port, so
if you were already running a debug session with port 1234, the tests
would fail. This update allows you to pass --gdb-port=NNNN to use a
non-default port. You can pass -Q to preserve failing qemu instances.
The scripts now also will show qemu errors to console, and will warn
the user if there is a qemu port conflict.
Also update gdb-pt-dump submodule as it has been updated recently to not
throw an exception when multiple qemu processes are running. The
exception thrown in the event of a failure also changed, so
this has also been updated on the pwndbg side.
* get_one_instruction: clear "cont" cache on mem/reg changed
Fixes#1818.
Note that this makes a substantial change: it changes all caches that
are refreshed on `gdb.ContinueEvent` to also be cleared on memory/regs
changed.
This change is needed so that the `get_one_instruction` function which
uses this cache will get its cache cleared when user invokes a command
that changes memory or registers.
While this may sound as too big change: we are changing the whole "cont"
cache to be cleared on two additional events, this should not be an
issue. This is because:
1. We should notice it if we start clearing an important cache too often
2. The "cont" cache is currently only used by the `get_one_instruction`
at this moment.
The 2) also creates a question: when should one use "cont" vs "start"
caches? It is not so clear to me right now.
* Add test for issue #1818
* Clear caches on MemoryChanged events from gdblib.write
Regarding the last part:
Interestingly implementing tests here uncovered another bug: the gdblib.memory.write(..) or rather the gdb.selected_inferior().write_memory(...) API used there does not trigger a gdb.MemoryChanged event. As a result, we never cleared certain caches that should have been cleared when the user used that API.
I have added two tests here, one changes the instructions at $RIP to nops via gdblib.memory.write(..) and another via executing the patch $rip nop;nop;nop;nop;nop command. As a result, we test both scenarios: 1) when we depend on memory changed event being fired via GDB to clear caches; and 2) when we depend on gdblib.memory.write(..) to clear the caches.
This PR also makes a fix to the gdblib.memory.write(..) to actually clear caches that depend on (or rather: are hooked to in order to be cleared) memory changed events.
* Fix glibc-fastbin-bug option of find_fake_fast
Using the find_fake_fast option --glibc-fastbin-bug always resulted in an error, at least on 64-bit platforms.
This was because the option caused only 4 bytes to be read for the size, but then that gets passed to unpack() which expects 8 bytes.
Closes#1773
* Address review comment
* Update arch.py
* Update pwndbg/commands/heap.py
* Fix lint
* Update arch.py
* Update arch.py
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
This commit adds a command that traverses the linked list beginning at a given
element, dumping its contents and the contents of all the elements that come
after it in the list. Traversal is configurable and can handle multiple types
of chains.
This commit adds the `break-if-taken` and `break-if-not-taken` commands,
which attach breakpoints to branch instructions that will stop the
inferior if said branch is taken or is not taken, respectively. It adds
an extra class, `pwndbg.gdblib.bpoint.Breakpoint`, which clears caches
before calling `stop()`, allowing for the use of register values inside
that function in breakpoint classes that derive from it. Additionally,
checking of whether the conditions for a branch to be taken have been
fulfilled is done through `DisassemblyAssistant.condition()`.
* Add `stepuntilasm` command
This commit adds a `stepuntilasm` command that, given a mnemonic and,
optionally, a set of operands, will step until a instruction that
matches both is found. Matching is string-based, as the user will likely
want to spell out the asm directive they want as text, and interpreting
assembly language conventions for all of the platforms pwndbg supports
is probably outside the scope of this change.
* next.py: small code cleanup
* next.py: fix bug introduced in previous commit
op.str -> op_str
* Update next.py
* Update next.py
* Update next.py
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>