Now the installation process contains the following steps:
1. Check for any line with source <gdbinit.py> before installation
2. If any, ask the user if they want to proceed
3. After the installation, comment out old source <gdbinit.py> lines if any and add a new source <gdbinit.py> line.
A check for presence of the line set debuginfod enabled on is also added to avoid being appended repeatedly.
* Add largebin reverse lookup tables
* Don't use None value for bin 95 size on i386
* Clarify "bin 95" comment
* Add comment to tables
* Immutable tables
* Make tables class attributes
I can confirm the search bug to happen on GDB 9.2, but not on GDB 10.2:
```
pwndbg> version
Gdb: 9.2
Python: 3.8.10 (default, Nov 14 2022, 12:59:47) [GCC 9.4.0]
Pwndbg: 1.1.1 build: a3f12bc
Capstone: 4.0.1024
Unicorn: 2.0.1
pwndbg> search "GNU C"
Searching for value: 'GNU C'
pwndbg> set remote search-memory-packet off
pwndbg> search "GNU C"
Searching for value: 'GNU C'
libc-2.31.so 0x7ffff7f85b80 0x694c204320554e47 ('GNU C Li')
libc-2.31.so 0x7ffff7f85c9e 'GNU CC version 9.3.0.\nlibc ABIs: UNIQUE IFUNC ABSOLUTE\nFor bug reporting instructions, please see:\n<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.\n'
```
* ai plugin
* ai plugin ready to ship
* ai plugin ready to use
* textwrap on the ai's answer
* linted ai.py
* relaxed openai version requirement
* added pandas to requirements
* removed dependency on openai module, using requests instead
* removed dependency on openai module, using requests instead
* incorporating suggestions on PR
* added types requests and bumped requests version up to the version i'm using here
* lowering version req on requests for ubuntu 18 compat
* removed some 'if True' kludges that i was using to debug things at one point
* better error handling
* more config parameters for ai
* fixed a few config issues
* fixed bug in gdb list command
* now uses chatgpt's gpt-3.5-turbo model, instead of text-davinci-003, and follows a conversational protocol instead of completion.
* ensuring backwards compatibility with older models, like text-davinci-003
* removed unneeded host and path vars
* Changing the arguments to vis_heap_chunks to be clearer
1. --native to --beyond_top
2. --display_all to --no_truncate
* Add print all chunks to vis_heap_chunks
* Preventing the use of the all_chunks argument together with the count argument in vis_heap_chunks
* Use linting for heap.py
* Fix test_vis_heap_chunks.py
According to cdd71a1d82 --display_all/-d moved to --no_truncate/-n
---------
Co-authored-by: Nerya Zadkani <nerya@tokagroup.com>
It seems this function is redundant. If you do:
```
gdbserver 0.0.0.0:1234 ./a.out
```
on a local machine and then do `gdb ./a.out --ex 'target remote :1234'`
the `_add_main_symbol_to_exe` will kick off and run its
`add-symbol-file` command to add the symbols from the binary. However,
the GDB already loaded the binary symbols and so we will do it for the
second time. As a result, we get something like this:
```
pwndbg> info symbol main
main in section .text of /pwndbg/bug/vaccine
main in section .text of /pwndbg/bug/vaccine
```
This function has been in Pwndbg since always and I am not sure why we
needed it. Perhaps an old GDB did not download the binary from the
remote target, but since now GDB does this automagically, this function
seems redundant.
Just for the sake of documenting it, here is how a symbol appears if you
connect to a remote target on a different machine without Pwndbg (the
GDB downloads the binary itself and loads its symbols):
```
(gdb) p main
$1 = {<text variable, no debug info>} 0x55555555466a <main>
(gdb) info symbol main
main in section .text of target:/home/dc/a.out
```
This commit adds a fix and tests for #1600 and #752.
* https://github.com/pwndbg/pwndbg/issues/1600
* https://github.com/pwndbg/pwndbg/issues/752
Generally, for an example like this:
```cpp
struct A {
void foo(int, int) { };
};
int main() {
A a;
a.foo(1, 1);
}
```
The output for `info symbol <address of A::foo>` returns:
```
'A::foo(int, int) [clone.isra.0] + 3 in section .text of /root/pwndbg/tests/gdb-tests/tests/binaries/a.out\n'
```
We then used this code to parse this:
```py
# Expected format looks like this:
# main in section .text of /bin/bash
# main + 3 in section .text of /bin/bash
# system + 1 in section .text of /lib/x86_64-linux-gnu/libc.so.6
# No symbol matches system-1.
a, b, c, _ = result.split(maxsplit=3)
if b == "+":
return "%s+%s" % (a, c)
if b == "in":
return a
return ""
```
The `result.split(maxsplit=3)` here splitted the string to:
```py
['A::foo(int,',
'int)',
'[clone.isra.0] + 3 in section .text of /root/pwndbg/tests/gdb-tests/tests/binaries/a.out\n']
```
And since `b` was not `"+"` or `"in"` we eventually returned an empty
string instead of the `A::foo(int, int)` which would be expected here.
* Fix the bug when using LD_PRELOAD to load libc
The heap heuristics will try to find `libc.so.6` in the output of `info sharedlibrary`, but if we load libc with `LD_PRELOAD`, the filename of the libc might not be `libc.so.6`.
* Add test for `glibc.get_libc_filename_from_info_sharedlibrary`
* ai plugin
* ai plugin ready to ship
* ai plugin ready to use
* textwrap on the ai's answer
* linted ai.py
* relaxed openai version requirement
* added pandas to requirements
* removed dependency on openai module, using requests instead
* removed dependency on openai module, using requests instead
* incorporating suggestions on PR
* added types requests and bumped requests version up to the version i'm using here
* lowering version req on requests for ubuntu 18 compat
* removed some 'if True' kludges that i was using to debug things at one point
* better error handling
* more config parameters for ai
* fixed a few config issues
* fixed bug in gdb list command
In some cases, we might not need to download the file if we can find the file locally, and this can be determined by the return value of the gdb command/API.
For example, the path we get from `pwndbg.gdblib.proc.exe` has different when gdb have loaded the file or not:
If we have executed `file /path/to/exe` before connecting to gdbserver:
```pycon
In [1]: pwndbg.gdblib.proc.exe
Out[1]: '/path/to/exe'
```
The output doesn't have "target:" prefix because gdb is able to find the file locally.
If we haven't executed `file /path/to/exe`, gdb can't find it locally, the output will be:
```pycon
In [1]: pwndbg.gdblib.proc.exe
Out[1]: 'target:/path/to/exe'
```
So if the "target:" prefix doesn't present when using `pwndbg.gdblib.file.get_file(pwndbg.gdblib.proc.exe)`, we don't need to download the file.
(The behavior of file path also occurred in `info files` and `info sharedlibrary` commands output.)
This commit aims to prevent downloading the file when the "target:" prefix doesn't present in the above cases.
* ai plugin
* ai plugin ready to ship
* ai plugin ready to use
* textwrap on the ai's answer
* linted ai.py
* relaxed openai version requirement
* added pandas to requirements
* removed dependency on openai module, using requests instead
* removed dependency on openai module, using requests instead
* incorporating suggestions on PR
* added types requests and bumped requests version up to the version i'm using here
* lowering version req on requests for ubuntu 18 compat
* removed some 'if True' kludges that i was using to debug things at one point
* Refactor `pwndbg.glibc`
- Add type hints
- Use `info sharedlibrary` to find libc
- Update the regex of libc filename
- Rename `get_data_address()` to `get_data_section_address()`
* Add a function to dump libc ELF file's .data section
* Use the new methods to find `main_arena` and `mp_`
With ELF of libc, we can use the default value of `main_arena` and `mp_` to find their address
* Drop some unreliable methods for the heap heuristics
* Update the tests for the heap heuristics
* Show `main_arena` address in the `arenas` command output
* Make the heap hueristics support statically linked targets
* Drop some deprecated TLS functions and refactor the command
- Drop some deprecated TLS functions for the deprecated heap heuristics
- Don't call `pthread_self()` in the `tls` command without `-p` option
- Show the page of TLS in the `tls` command output
* Update the hint for the heap heuristics for multi-threaded
* Fix the wrong usage of the exception
* Fix the outdated description
* Return the default global_max_fast when we cannot find the address
* Enhance the output of `arena` and `mp`
- Show the address of the arena we print in the output of `arena` command if we didn't specify the address by ourselves.
- Avoid the bug that `arena` command might get an error if thread_arena doesn't allocate yet.
- Show the address of `mp_` in the output of the `mp` command
* Remove wrong hint
* Support using brute-force to find the address of main_arena
If the user allows, brute-force the left and right sides of the TLS address to find the closest possible value to the TLS address.
* Refactor the code about thread_arena and add the new brute-force strategy
In the .got section, brute-force search for possible TLS-reference values to find possible thread_arena locations
* Add tests for thread_arena and global_max_fast
- Check if we can get default global_max_fast
- Check if we can use brute-force to find thread_arena
* Update the output of `arenas`
* Add the test for the `tls` command
Add two tests for the `tls` command:
```
test_tls_address_and_command[x86-64] PASSED
test_tls_address_and_command[i386] PASSED
```
* Update and refactor the heuristics for `thread_arena` and `tcache`
- We provide an option for users to brute force `tcache` like what we did for `thread_arena`
- Cache `thread_arena` even when we are single-threaded
- Refactor the code for `thread_arena`, to make it work for `tcache` as well
- Update the tests for `tcache`
- Remove some redundant hint
* Fix the wrong cache mechanism
Cache the address of the arena instead of the instance of `Arena`, because `Arena` will cache the value of the field, resulting in getting the old value the next time the same property is used
* Update the description of some configs about heap heuristics
* Handling the case when tcache is NULL
* Handling the case when thread_arena is NULL
* Fix a bug that occurred when the TLS address could not be found
* Fix#1550
* Show tid only if no address is specified
* Update pwndbg/commands/__init__.py
* Update pwndbg/commands/heap.py
* Update pwndbg/commands/heap.py
* Update pwndbg/commands/heap.py
* Update pwndbg/commands/heap.py
* Update pwndbg/commands/heap.py
* Update pwndbg/commands/heap.py
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Fix lint
* Move some code into `pwndbg.gdblib.elf`
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
This issue can be reproduced with the following command:
```
sudo docker run --privileged --rm -it --net host ubuntu bash -c 'apt update && apt install gdbserver && umount /proc && gdbserver 127.0.0.1:1234 /bin/ls'
```
And then attaching to the gdbserver via:
```
gdb --quiet --ex 'target remote :1234'
```
This results in the following errors:
```
pwndbg> set exception-verbose on
Set whether to print a full stacktrace for exceptions raised in Pwndbg commands to True
Traceback (most recent call last):
File "/root/pwndbg/pwndbg/gdblib/events.py", line 164, in caller
func()
File "/root/pwndbg/pwndbg/lib/memoize.py", line 51, in __call__
value = self.func(*args, **kwargs)
File "/root/pwndbg/pwndbg/stack.py", line 78, in update
start, stop - start, 6 if not is_executable() else 7, 0, "[stack]"
File "/root/pwndbg/pwndbg/lib/memoize.py", line 51, in __call__
value = self.func(*args, **kwargs)
File "/root/pwndbg/pwndbg/stack.py", line 127, in is_executable
ehdr = pwndbg.elf.exe()
File "/root/pwndbg/pwndbg/proc.py", line 78, in wrapper
return func(*a, **kw)
File "/root/pwndbg/pwndbg/lib/memoize.py", line 51, in __call__
value = self.func(*args, **kwargs)
File "/root/pwndbg/pwndbg/elf.py", line 181, in exe
e = entry()
File "/root/pwndbg/pwndbg/proc.py", line 78, in wrapper
return func(*a, **kw)
File "/root/pwndbg/pwndbg/lib/memoize.py", line 51, in __call__
value = self.func(*args, **kwargs)
File "/root/pwndbg/pwndbg/elf.py", line 192, in entry
entry = pwndbg.auxv.get().AT_ENTRY
File "/root/pwndbg/pwndbg/lib/memoize.py", line 51, in __call__
value = self.func(*args, **kwargs)
File "/root/pwndbg/pwndbg/auxv.py", line 103, in get
return use_info_auxv() or walk_stack() or AUXV()
File "/root/pwndbg/pwndbg/auxv.py", line 154, in walk_stack
auxv = walk_stack2(0)
File "/root/pwndbg/pwndbg/auxv.py", line 206, in walk_stack2
while p.dereference() != 0 or (p + 1).dereference() != 0:
gdb.MemoryError: Cannot access memory at address 0xffffdff8
```
* Fix plt and gotplt commands
* Add plt gotplt commands tests
* Fix got and plt commands and test them
* Revert accidental change
* Extend system path
* Hopefully fix PATH problems once and for all?
* fix import
* remove redundant part
Rizin is a fork of Radare2 with almost near perfect command compatibility with r2. Any r2 related plugins need to be replaced with their rz counter parts. Solves #1566
Before this fix, when we compiled a 32-bit prgoram a 'Bad register' bug
would show up on `fsbase` and `gsbase` commands.
Also, those commands weren't protected to not be executed on another
archs, which this commit fixes.
Additionally, this commit introduces 4 tests:
```
test_commands_segments[gsbase-gosample.x64] PASSED
test_commands_segments[gsbase-gosample.x86] PASSED
test_commands_segments[fsbase-gosample.x64] PASSED
test_commands_segments[fsbase-gosample.x86] PASSED
```
Two of those tests, the ones with x86 binaries, applied without other changes would fail.
* gdbinit.py: fix message when locales are wrong
Apparently the suggested solution is not great:
```
nix@33843c903468:~$ locale -a
C
C.UTF-8
POSIX
en_US.utf8
nix@33843c903468:~$ LC_ALL=en_US.UTF-8 PYTHONIOENCODING=UTF-8 pwndbg
/nix/store/qqa28hmysc23yy081d178jfd9a1yk8aw-bash-5.2-p15/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
******
Your encoding (ANSI_X3.4-1968) is different than UTF-8. pwndbg might not work properly.
You might try launching gdb with:
LC_ALL=en_US.UTF-8 PYTHONIOENCODING=UTF-8 gdb
Make sure that en_US.UTF-8 is activated in /etc/locale.gen and you called locale-gen
******
pwndbg: loaded 164 pwndbg commands and 42 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Traceback (most recent call last):
File "/nix/store/x2yncb885vd33dgigwfwc6qamjxs4d7h-pwndbg-2022.12.19/share/pwndbg/gdbinit.py", line 84, in <module>
import pwndbg # noqa: F401
File "/nix/store/x2yncb885vd33dgigwfwc6qamjxs4d7h-pwndbg-2022.12.19/share/pwndbg/pwndbg/__init__.py", line 113, in <module>
config_mod.init_params()
File "/nix/store/x2yncb885vd33dgigwfwc6qamjxs4d7h-pwndbg-2022.12.19/share/pwndbg/pwndbg/gdblib/config.py", line 114, in init_params
Parameter(p)
File "/nix/store/x2yncb885vd33dgigwfwc6qamjxs4d7h-pwndbg-2022.12.19/share/pwndbg/pwndbg/gdblib/config.py", line 46, in __init__
self.value = param.value
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
------- tip of the day (disable with set show-tips off) -------
Use the procinfo command for better process introspection (than the GDB's info proc command)
pwndbg>
quit
nix@33843c903468:~$ LC_ALL=C.UTF-8 PYTHONIOENCODING=UTF-8 pwndbg
pwndbg: loaded 164 pwndbg commands and 42 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
------- tip of the day (disable with set show-tips off) -------
Want to display each context panel in a separate tmux window? See https://github.com/pwndbg/pwndbg/blob/dev/FEATURES.md#splitting--layouting-context
pwndbg>
quit
nix@33843c903468:~$ LC_ALL=C.UTF-8 pwndbg
pwndbg: loaded 164 pwndbg commands and 42 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
------- tip of the day (disable with set show-tips off) -------
Use the telescope command to dereference a given address/pointer multiple times (if the dereferenced value is a valid ptr; see config telescope to configure its behavior)
pwndbg>
quit
```
* fix lint
* Enhance the checks before accessing the memory
- Use `pwndbg.gdblib.memory.peek()` instead of `pwndbg.gdblib.vmmap.find()` to check if the address is valid
- Directly access the memory when searching the `main_arena` in memory and catch the exception
* Make finding `main_arena` in memory more efficient and reliable
We only try the address that is aligned to `pwndbg.gdblib.arch.ptrsize`
* Avoid unnecessary memory accessing if possible
- Before we used `pwndbg.gdblib.memory.peek()` to check if an address is readable for GDB, we used `pwndbg.gdblib.vmmap.find()` to make sure that this address is in one of the pages, since accessing memory for embedded targets might be slow and expensive
- Create a new function: `is_readable_address` for `pwndbg.gdblib.memory`
* Fix wrong test for `main_arena`
The heap object should be reset before testing the multi-threaded condition
* Add the test to make sure the heap heuristics won't be affected by the vmmap result
Previously, we used `pwndbg.gdblib.vmmap.find()` to check whether the address is valid or not, but this might be a false positive for the address in the `[vsyscall]` page or in the page with a range from 0~0xffffffffffffffff (e.g. qemu-user).
This commit aims to include this scenario during the tests, to make sure the heap heuristics won't be affected by this.
* Use `gdb.MemoryError` instead of `Exception`
* Fix#1534: disable emulation if mmap(1G,RWX) fails
TL:DR: Unicorn Engine aborts if mmap(1G, RWX) fails, so we are doing a
best effort check if we can do such allocation before using it for the
first time and if we can't, we disable it.
* add mmap.close() call
* Fix vermin lint
* Update pwndbg/commands/context.py