* fix shlint
* Fix crash when unable to get ehdr and fix vmmap coredump test
This commit fixes two issues and test them.
1. It changes the reads in `get_ehdr` to partial reads so that inability
to read the `vmmap.start` address there will not crash Pwndbg with
`gdb.error` but instead we will simply return `None` as expected from
this function. This crash could happen on Debian 10 (GDB 8.2.1) and
Ubuntu 18.04 (not sure which GDB) when you did:
- gdb ./binary-that-crashes
- `run`
- `generate-core-file /tmp/core`
- `file` - to unload the binary
- `core-file /tmp/core` - to load the generated core
At this point I think we may have preserved the old vmmap info and use
it in `get_ehdr` maybe, which then crashed? I am not sure, but this fix
here works.
To test this behavior properly I also added the `unload_file`
parametrization to the
`test_command_vmmap_on_coredump_on_crash_simple_binary` test.
2. We fix the vmmap coredump test case when the `info proc mappings` returns nothing on core
dumps on old GDBs. In such case we are missing the vmmap info about
the binary mapping, so now we properly remove it in the test.
This fixes the weird error that appeared on debian10 CI:
```
root@98cc3841eab9:/pwndbg/tests/gdb-tests/tests/binaries# ld -Ttext 0x400000 -o memory.out memory.o
ld: section .note.gnu.property LMA [00000000004000e8,0000000000400107] overlaps section .text LMA [0000000000400000,00000000004001a4]
```
It turned out that the .note.gnu.property address was choosen to be the
same as our hardcoded .text address and so we got into this issue.
This PR hardcodes the gnu section address.
* Fix tests reporting in parallel execution
Fix issue where parallel test execution was unable to track failed tests and inform about their number.
* Fix logic in tests.sh
* Add get_sbrk_heap_region() method
* Use SIZE_BITS in Chunk.real_size()
* Add non_contiguous property to Arena class
* Improve Heap class
* More accurate arena detection
* Integrate Heap class into Chunk class
* Don't parse bins when no arena in find_fake_fast
* Add active_heap property to Arena class
* Add more functionality to heap classes
* next_chunk method for Chunk class
* prev property & __str__ method for Heap class
* heaps property for Arena class
* arenas command updated to reflect changes to Arena class
* Use deepcopy() in get_region() to avoid changing vmmap command output
* Import fiddling to deal with unrelated bug
* Attempt at integration with heap commands
With debug syms looks good, still issues to iron out with heuristics
* Remove redundant heap functions
* Remove redundant functions from tests
* Add system_mem property to Arena class
* thread_arena returns main_arena if single thread
* Fix some issues for GDB < 9.x
* GDB < 9.x doesn't have `gdb.lookup_static_symbol`
* GDB < 9.x doesn't have `gdb.PARAM_ZUINTEGER_UNLIMITED`
* Better error handling for the heap commands
* Inform users to `set exception-* on` when they encounter some error during using some heap commands
* Bug fix for heap region finding of `HeuristicHeap`
* Before this commit, `get_heap_boundaries()` of `HeuristicHeap` will always return the page whose name is `[heap]`, this won't work for multithreaded cases and won't work if the heap region of the main thread is not `[heap]` (e.g., when using QEMU, sometimes the name of heap region is something like: `[anon_deadbeaf]`)
* Fallback to `gdb.lookup_symbol` if we do not have `gdb.lookup_static_symbol`
* Add more features for `pwndbg.gdblib.config`
* Support all parameter-class
* Use `get_show_string` to render better output when using `show <param>`
* Show more information when using `help set <param>` and `help show <param>` if we create a config with `help_docstring` parameter.
Some examples of the updates included in this commit:
1. `gdb.PARAM_AUTO_BOOLEAN` with `help_docstring`
In Python script:
```
pwndbg.gdblib.config.add_param(
"test",
None,
"test",
"on == AAAA\noff == BBBB\nauto == CCCC",
gdb.PARAM_AUTO_BOOLEAN,
scope="test",
)
```
In GDB:
```
pwndbg> show test
The current value of 'test' is 'auto'
pwndbg> set test on
Set test to 'on'
pwndbg> set test off
Set test to 'off'
pwndbg> set test auto_with_typo
"on", "off" or "auto" expected.
pwndbg> show test
The current value of 'test' is 'off'
pwndbg> set test auto
Set test to 'auto'
pwndbg> show test
The current value of 'test' is 'auto'
pwndbg> help show test
Show test
on == AAAA
off == BBBB
auto == CCCC
pwndbg> help set test
Set test
on == AAAA
off == BBBB
auto == CCCC
```
2. `gdb.PARAM_AUTO_BOOLEAN` with `help_docstring`
In Python script:
```
pwndbg.gdblib.config.add_param(
"test",
"A",
"test",
"A == AAAA\nB == BBBB\nC == CCCC",
gdb.PARAM_ENUM,
["A", "B", "C"],
scope="test",
)
```
In GDB:
```
pwndbg> show test
The current value of 'test' is 'A'
pwndbg> set test B
Set test to 'B'
pwndbg> set test C
Set test to 'C'
pwndbg> set test D
Undefined item: "D".
pwndbg> show test
The current value of 'test' is 'C'
pwndbg> help show test
Show test
A == AAAA
B == BBBB
C == CCCC
pwndbg> help set test
Set test
A == AAAA
B == BBBB
C == CCCC
```
* Update the tests for gdblib parameter
* Use auto boolean for `safe-linking`
* Fix some comments
* Pass `help_docstring` directly
* Force callers of `add_param` to use keyword arguments
* Create `add_heap_param()` to avoid setting the scope of param everytime
* Add a header to the vmmap table
A simple header has been added to the output of vmmap which helps new users identify the columns.
* fix: lint
* fix: failing test
Adjust the length of expected vmmaps
* fix: tests again
* Fix parameter default values
Before this commit the created gdb.Parameter default values were not set
properly. Now, we set the object's .value field properly with the
provided default value.
* fix issue with set/show docstring
* fix lint
* fix lint
* fix lint
* fix parameter further...
* fix flake8 lint
* Increase CI timeout to 20 minutes
* Fixes: set context-sections '' and add more opts to set empty sections
The `validate_context_sections` function started to receive a string of
`"''"` after the changes in eabab31. Before those changes, it always
received an empty string (`""`).
I am not sure why this behavior changed in that commit, but the current
behavior resembles the native GDB behavior more. We can see this here on
a GDB native parameter:
```
(gdb) set exec-wrapper ''
(gdb) show exec-wrapper
The wrapper for running programs is "''".
```
And so we will keep this native behavior for our config variables for
now. But since this changed, I want to keep the old behavior of: `set
context-sections ''` working, and so this commit brings it.
Additionally, we also now allow setting empty context via multiple
values: empty string, empty quotations or double quotations and with
strings like `-` or `none`.
...and this commit comes with tests for this behavior so it will be
harder to introduce such issues anymore :)
* added Bin classes from old PR #1063 back
* added Bin classes from pr #1063
* added more properties to Arena class
* integrated Bin classes with the malloc_chunk command
* integrated Bin classes with vis and try_free. passed all heap tests
* very small change
* fixed lint
* fixed lint
* fixed lint..
* finally fixed lint
* Delete .err.txt
Co-authored-by: Gulshan Singh <gsingh2011@gmail.com>
Co-authored-by: Tingfeng Yu <tingfeng.yu@anu.edu.au>
* fix: make mprotect command truly multi-arch
Added register saving based on reg_sets defined for each processor architecture, additionally shellcraft is used to generate the arch-specific shellcode.
Unfortunately this command is not currently tested on platforms other than x86_64.
* Update pwndbg/commands/mprotect.py
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* mprotect: Add parsing, alignment to the addr argument
This change makes sure that the addr argument is parsed as an gdb expression (so you can use registers for example) and aligns it to the nearest page boundary.
* mprotect: Clean up register saving, print the result
Cleaned up saving of registers and added printing of the results, as per disconnect's sugesstions.
* Simplify the test for mprotect
Simplify the code and remove the useless binary
* Update tests/test_mprotect.py
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Add reset_on_thread decorator
* Apply reset_on_thread to Heap.multithreaded
* Add multithreaded malloc_chunk tests
* Clarify comment in C source
* Clarify expected thread number with assert in test
* Fix#1256: fixes next cmds hangs on segfaults
Before this commit the next/step commands like `nextret`, `stepret`,
`nextsyscall`, `nextproginstr` etc. would hang if they approach a
segfault. This commit fixes it by checking for ANY signals by executing
the GDB's `info prog` command and parsing its output.
* fix lint
* Move symbol.py to gdblib
* Renamed private methods
* Renamed pwndbg.symbol to pwndbg.gdblib.symbol
* Cleanup symbol.py
* Fix lint issues
* Handle tls error on symbol lookup
* Fix merge conflicts
* Remove old way of looking up symbols
This commit adds a test for context disasm showing of file descriptors
file paths in syscalls like read() or close().
It also fixes a small issue when Pwndbg is run with PWNDBG_DISABLE_COLORS=1
This issue was that executing:
```
pi '{a:2}'.format(a=pwndbg.color.context.prefix(pwndbg.config.code_prefix))
```
Failed when Pwndbg was run with disabled colors. It failed because our
generate color functions in pwndbg/color/* ended up not processing the
input argument -- which here is a Pwndbg config Paramater object -- so
that we got a very non obvious exception:
```
Exception occurred: context: unsupported format string passed to Parameter.__format__ (<class 'TypeError'>)
```
This issue could hypothetically also exist if our config value would be
empty I think. So with the fix in this commit, where we do str(x) over
the color funciton argument should fix this issue in all cases.
Turns out the mprotect command didn't ever work, as it was amd64 only, but used x86 syscall numbers to call mprotect. I have refactored the command to use shellcraft to generate the shellcode that calls mprotect. I have also unit-tested this command.
* Improve vmmap on coredump files
With this commit we now recognize coredumps better and also finally have
a simple test for vmmap commands on:
- a running binary
- on a loaded coredump file with loaded binary
- on a loaded coredump file without a loaded binary
We also stop saving vmmaps for `maintenance info sections` sections
which have a start address of 0x0. While there could potentially be a
coredump file from a binary with start=0x0, this should work in most
cases.
We could in theory do a slighty better: we could take the vmmap at 0 and
try to read memory from it. However, I am not sure if it is a good idea
to try such memory read?
* remove unused import
* add missing crash_simple.asm
* fix vmmap coredump test on different ubuntu mem layouts
* use /proc/$pid/maps for vmmap tests
* fix formatting
* fix import
* fix test
* fix test
* fix test
* fix lint
* fix test
* fix test
* fix test
* fix test
* fix lint
* another fixup for ubuntu 22.04
* another fixup for ubuntu 22.04
* lint
* Add a regression test for find_fake_fast
The test program creates a fake chunk size field in its .data section
with a set NON_MAIN_ARENA flag. The Python test runs the find_fake_fast
command on an address succeeding the fake chunk. A gdb.MemoryError
indicates regression - issue #1142
* Make linter happy
* fix#1111 errno command edge case
This commit fixes the case when errno command causes a binary to
segfault when the `__errno_location` symbol was defined but its .plt.got
entry was not filled yet by the dynamic loader (ld.so), so e.g. when the
glibc library was not loaded yet.
In such a case, us triggering a call to `__errno_location` function
triggered a jump to an unmapped address. Now, we dereference that
.plt.got symbol and see if it lives in mapped memory.
* add tip about errno command
* errno: fix case when __errno_location@got.plt is missing
* fix lint
* fix sh lint
* fix errno test
This should fix things like:
> tests/test_heap.py::test_try_free_invalid_next_size_fast Dwarf Error: DW_FORM_strx1 found in non-DWO CU [in module /pwndbg/tests/binaries/heap_bugs.out]
* Make ZIGPATH configurable and provide defaults
Mostly fixes docker/docker-compose environment where building zig into
$pwd/.zig doesn't work well because it is later overwritten by mounting
the volume in /pwndbg.
With current approach during the docker build zig is put in /opt/zig
instead, and when you run it without docker it's possible to configure a
different path (with sane defaults)
* remove Makefile
* add ZIGPATH to tests.sh for CI
* move ZIGPATH setting before make in tests
* tools: change zig to install from a tarball
Migrate from using snap, we install from a cheksumed tarball
* fix: add sudo
* fix: install zig to .zig in PWD
Co-authored-by: Albert Koczy <albert.koczy@asseco.pl>
* Add Bins classes and refactor allocator methods to return them
* Refactor bins() and related commands
* Refactor malloc_chunk
* Use chunk_size_nomask in top_chunk()
* Refactor vis_heap_chunks
* Rename read_chunk to read_chunk_from_gdb and move to ptmalloc.py
* Add get_first_chunk_in_heap and use it in heap and vis_heap_chunks commands
* Move some methods from DebugSymsHeap to Heap base class
* Strip type hints from heap.py and ptmalloc.py
* Set heap_region before using it
* Fix test_heap_bins test
* Fix try_free
When we moved to argparse command parsing we introduced `gdb_sloppy_parse` which wasn't perfect: e.g. for `gdb.parse_and_eval("__libc_start_main")` would return a `gdb.Value()` whose `.type.name` was `long long`.
As a result when code that used `gdb_sloppy_parse` then casted the result to `int(gdb_value)` it crashed because for some reason GDB errored.
This commit fixes the issues related to it by adding `AddressExpr` and `HexOrAddressExpr` functions.
It also adds tests for some of the windbg compatibility commands and fixes some nifty details here and there.
Those lines are redundant in our case: pwndbg is not imported or launched directly.
Also, the coding lines were relevant in Py2 but are not really needed in Py3.
* Tests launcher: show passed and failed count
* Build nearpc, emulate, u, pdisass test binaries
* Add tests for emulate, nearpc, pdisass, u
* Refactored disasm and emulator
* Fix nearpc following jumps w/o emulation
* Prevent tests from calling start_binary twice
* Add test for emulate_disasm_loop
* Fix isort
* Add nasm to travis install
* Add --eval-command quit to tests invocation
This should prevent travis from staying in gdb/stalled build when something fails in weird way (like a file is missing)
```
[+] Building 'emulate_disasm.o'
make: nasm: Command not found
make: *** [emulate_disasm.o] Error 127
gdbinit.py: No such file or directory.
pytests_collect.py: No such file or directory.
No output has been received in the last 10m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received
```
* Add test binaries
* it would be cool to have tests that run within GDB so that we don't have to parse GDB output and deal with weird problems
* we can't run all tests in one GDB session as `file x; entry; <some pwndbg command>; file y; entry; <some wndbg command>;` may have different results - it seems either us or GDB fails to cleanup everything properly
* Add prototype of unit tests for pwndbg
* Add test for pwndbg [filter]
* Fix isort, e2e tests, add pytest requirement
* Add comment about not handling exceptions for unittests
* Fixes after rebase
* Fix test_loads_without_crashing
* e2e tests: no colors & loading pwndbg tests
* Fix isort
* Add example of no file loaded test
* Move tests to unit_tests, add binary, add memory tests
* Isort fixes
* Move from e2e/unit tests to tests
* Add info about tests to DEVELOPING.md
* Fix tests
* review fixes
* commands filtering test: check for contents, not for equality
* Add tests launcher bash script
* Change tests launcher name from unittests to pytests
* Cleanup; better test file paths
* Add theme param to disable colors
* Better test_loads
* Skip some tests locally that can run on travis
* Fix test_loads according to travis
* Fix travis tests
* Make chain.get() to check vmmap first in bare metal mode
Make chain.get() limit to de-reference within the known page in
bare metal mode.
Since the address are all valid when mmu is not enable and all
the value are valid physical address. It will be de-referenced
even these addresses are not used and actually, it is data in
the most of case. Ex. 0x1 often means the value 1, not the
address 0x1.
Also, for issue #371, some addresses may be the MMIO registers.
The read operation on these address will break the state.
It is better to limit the de-reference address range. This patch
will also fix it, hopefully.
* Add custom vmmap add/del API in vmmap.py
In some cases, ex. bare metal, the pages information can not be
detected automatically. Also, the most of pwndbg feature rely on
page information such as highlighting.
User may want to create page information manually and maintain it
by himself.
This commit add python APIs to manually add/del page information
and they are isolated.
* Fix stack page detection in bare metal mode
We can not detect the stack page size in bare metal mode by
1. finding the ELF location after the stack page
2. page fault
A simple workaround is returning the current $sp page
and assume it is the stack page.
* Add vmmap control command to add/del customized vmmap
In some cases, ex. bare metal, the pages information can not be
detected automatically. Also, the most of pwndbg feature rely on
page information such as highlighting.
User may want to create page information manually and maintain it
by himself.
I add few commands to make user can add/del pages and load page
information from ELF sections.
* Fix the command amount for auto test to pass CI
* Add warning message
* Fix descriptions
* Fix cache issue and use bisect in insert API
* Keep LinuxOnly in find_elf_magic
* remove XXX
Adds `$rebase(offset)` gdbfunction that can be used to set up a breakpoint
over an offset from program image base.
Also changed a bit the pwndbg banner displayed at startup.