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.
This commit enhances the heap commands UX for statically linked binaries
and removes typeinfo module bloat.
The typeinfo module had this typeinfo.load function that was looking up a given type.
If it didn't find the type, it fallbacked to compiling many many system
headers in order to add a symbol for a given type into the program. This was
supposed to be used for missing glibc malloc symbols like malloc_chunk.
However, the exact reason it was used: the struct malloc_chunk was never
defined in a header file and was always defined in a malloc.c or another
.c file in glibc sources.
Another place the typeinfo.load logic of compiling headers was/is used
is the `dt` command, which is a windbg alias for getting struct layout
type information, e.g.:
```
pwndbg> dt 'struct malloc_chunk'
struct malloc_chunk
+0x0000 mchunk_prev_size : size_t
+0x0008 mchunk_size : size_t
+0x0010 fd : struct malloc_chunk *
+0x0018 bk : struct malloc_chunk *
+0x0020 fd_nextsize : struct malloc_chunk *
+0x0028 bk_nextsize : struct malloc_chunk *
pwndbg>
```
However, the whole big issue with typeinfo.load compilation of headers
was that most of the time it didn't work because e.g. some headers
defined in other paths were missing or that two different headers used
the same struct/function name and the compilation failed.
Since this logic almost never gave good results, I am removing it.
Regarding UX for statically linked binaries: we use `info dll` command
to see if a binary is statically linked. While this method is not
robust, as it may give us wrong results if the statically linked binary
used `dlopen(...)` it is probably good enough.
Now, if a heap related command is executed on statically linked binaries, it
will inform the user and set the resolving of libc heap symbols via
heuristics. Then, it also says to the user they have to set the glibc
version and re-run the command.
This commit tries to fix the issue of our `set context-clear-screen on`
option resetting the scrollback buffer on some terminals like
gnome-terminal (fwiw it did not happen on terminator or on tmux).
It also adds info to tips about that option.
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.
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)