Fixes the `nextproginst` command and adds two simple tests for it.
The command had two following issues:
1) It assumed that the program vmmap was always the first vmmap with
proc.exe objfile name -- this assumption has two flaws. First, newer
linkers will create the first memory page for the binary file as
read-only. This is because you do not need the ELF header content to be
executable, and that was the case in old linkers or linux distributions.
As an example, see those vmmap from a simple hello world binary compiled
on Ubuntu 18.04 vs Ubuntu 22.04:
Ubuntu 18.04:
```
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x555555554000 0x555555555000 r-xp 1000 0 /home/dc/a.out
0x555555754000 0x555555755000 r--p 1000 0 /home/dc/a.out
0x555555755000 0x555555756000 rw-p 1000 1000 /home/dc/a.out
[...]
```
Ubuntu 22.04:
```
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x555555554000 0x555555555000 r--p 1000 0 /home/user/a.out
0x555555555000 0x555555556000 r-xp 1000 1000 /home/user/a.out
0x555555556000 0x555555557000 r--p 1000 2000 /home/user/a.out
0x555555557000 0x555555558000 r--p 1000 2000 /home/user/a.out
0x555555558000 0x555555559000 rw-p 1000 3000 /home/user/a.out
```
So, before this commit on Ubuntu 22.04 we ended up taking the first
vmmap which was non-executable and we compared the program counter
register against it after each instruction step executed by the
nextproginstr command. As a result, we ended up never getting back to
the user and just finishing the debugged program this way!
Now, after this commit, we will grab only and all the executable pages for
the binary that we debug and compare and compare against them.
2) The second problem was that we printed out the current Pwndbg context
after executing nextproginstr succesfully. This does not seem to make
much sense because the context should be printed by the prompt hook.
(Without removing this, we ended up printing the context twice)
* add patch command
This commit adds the `patch`, `patch_list` and `patch_revert` commands
and adds the `pwntools==4.8.0` as Pwndbg dependency.
The current implementation could be further improved by:
- adding tests :)
- maybe moving `patch_list` and `patch_revert` to `patch --list` and
`patch --revert` flags?
- better handling of incorrect args/pwnlib exceptions
* lint
* 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
Call fetch_lazy() on the gdb.Value acquired in get_heap() and wrap it in
a try/except block. Return None if gdb.MemoryError is raised.
Let get_arena_for_chunk() handle None returned by get_heap().
Fixes#1142
* 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
* Don't exclude pwndbg/lib in .gitignore
* Move which.py to lib/which.py
* move funcparser.py and functions.py to lib/
* moved version.py to lib/
* Move tips.py to lib/
* Update pwndbg/lib/version.py
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
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]
* Fix some bugs of the aarch64 heuristic and a bug about tcache
* Some orders of the aarch64 assembly instructions might have a little bit different, so I make it more general. Some bugs of the older version can reproduce by the libc here (https://github.com/perfectblue/ctf-writeups/tree/master/2019/insomnihack-teaser-2019/nyanc/challenge)
* If we didn't find the correct tcache symbol address via heuristic, we will now use our fallback strategies for it.
* Refactor the code in a cleaner way
See https://github.com/pwndbg/pwndbg/pull/1029#discussion_r945934337
* Update the fallback solution of finding `main_arena`
* Since the arenas are a circular linked list, we can iterate it to check the address we guess is `main_arena` or not (https://github.com/pwndbg/pwndbg/pull/1029#discussion_r945335543)
* Update the boundaries of the address we might guess to avoid some unneeded tests
* Remove guard code for `mp_` before we test the fallback solution
Fix https://github.com/pwndbg/pwndbg/pull/1029#discussion_r945338469
* Refactor TLS features and fix a bug about fsbase/gsbase
* Move TLS features into an external module, and now the user can use the `tls` command to get its address (https://github.com/pwndbg/pwndbg/pull/1029#discussion_r945336737)
* Avoid `ValueError: Bad register` when trying to access fsbase/gsbase if the current arch is i386
* Fix a bug about tls finding for i386: `__errno_location` not always in `libc.so.6`, sometimes it will also in `libpthread-*.so`
* Update the comments about finding tcache
* Use `exit` event to avoid unnecessary reset
* Add a paramter for GLIBC version
* Update some strategies of heuristic
* Try to resolve heap via debug symbols even when using the heuristic
(By doing this, the binary compiled with `--static` flag can work with the heuristics by setting the GLIBC version manually)
* Try to avoid false positives when finding the symbol address and TLS base via heuristic
* Refactor some useless code
* Update the descriptions of the heap config
* Update the tips for the heap heuristics features
* Raise error when user set the GLIBC version in the wrong format
* Use `reset_on_start` with `glibc._get_version`
See https://github.com/pwndbg/pwndbg/pull/1075#discussion_r957899458
* Remove some unnecessary information in the hint message
See https://github.com/pwndbg/pwndbg/pull/1075#discussion_r957900468
* Use black to fix the format
* Fix indent
* Use black to fix the format
* improve start and entry commands description
Now, those commands will display proper description, describing when
they actually stop and what else can you do (e.g. run `starti` command
if u need to stop on first stop!).
* Update start.py
* ArgparsedCommand: fix `help cmd` and `cmd --help` behavior
Before this commit there was always a mismatch of what was displayed
when the user did `<command> --help` or `help <command>`.
With those changes, we fetch the help string from the argument parser
and render it as the command object's `self.__doc__`, so that it will be
displayed during `help <command>`.
Previously, we only displayed the command description during help.
* fix the pwndbg [filter] command that was broken in previous commit
* add riscv:rv64 registers
base on https://github.com/pwndbg/pwndbg/pull/829 by Tobias Faller <faller@endiio.com>
* disassemble without capstone to support other architectures
* ignore gdb.error on context_backtrace
* Don't format gdb-pt-dump with black
* Move isort configuration into pyproject.toml
* Exclude gdb-pt-dump from flake8
* Set flake8 max line length to 100