Giter Site home page Giter Site logo

pwndbg / pwndbg Goto Github PK

View Code? Open in Web Editor NEW
6.7K 139.0 834.0 32.61 MB

Exploit Development and Reverse Engineering with GDB Made Easy

Home Page: https://pwndbg.re/

License: MIT License

Python 97.23% Shell 1.21% C 0.85% Makefile 0.19% Assembly 0.11% Go 0.01% Dockerfile 0.06% C++ 0.01% Nix 0.35%
python gdb peda gdbinit pwndbg reverse-engineering debugging ctf gef hack

pwndbg's Introduction

repository-open-graph

pwndbg

license Unit tests codecov.io Discord

pwndbg (/paʊnˈdiˌbʌɡ/) is a GDB plug-in that makes debugging with GDB suck less, with a focus on features needed by low-level software developers, hardware hackers, reverse-engineers and exploit developers.

It has a boatload of features, see FEATURES.md and CHEATSHEET (feel free to print it!).

Why?

Vanilla GDB is terrible to use for reverse engineering and exploit development. Typing x/g30x $esp is not fun, and does not confer much information. The year is 2024 and GDB still lacks a real hexdump command! GDB's syntax is arcane and difficult to approach. Windbg users are completely lost when they occasionally need to bump into GDB.

What?

Pwndbg is a Python module which is loaded directly into GDB, and provides a suite of utilities and crutches to hack around all of the cruft that is GDB and smooth out the rough edges.

Many other projects from the past (e.g., gdbinit, PEDA) and present (e.g. GEF) exist to fill some these gaps. Each provides an excellent experience and great features -- but they're difficult to extend (some are unmaintained, and all are a single 100KB, 200KB, or 363KB file (respectively)).

Pwndbg exists not only to replace all of its predecessors, but also to have a clean implementation that runs quickly and is resilient against all the weird corner cases that come up. It also comes batteries-included, so all of its features are available if you run setup.sh.

How?

For a portable version with no external dependencies, scroll down for the Portable Installation section.

Installation from source is straightforward:

git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

Or install via the Nix package manager (you can use Nix on any distribution):

nix shell github:pwndbg/pwndbg
pwndbg ./your-binary

Pwndbg is supported on Ubuntu 20.04, and 22.04 with GDB 9.2 and later. We do not test on any older versions of Ubuntu, so pwndbg may not work on these versions (for Ubuntu 18.04 use the 2023.07.17: ubuntu18.04-final release). We may accept pull requests fixing issues in older versions on a case by case basis, please discuss this with us on Discord first. You can also always checkout an older version of pwndbg from around the time the Ubuntu version you're interested in was still supported by Canonical, or you can attempt to build a newer version of GDB from source.

Other Linux distributions are also supported via setup.sh, including:

  • Debian-based OSes (via apt-get)
  • Fedora and Red Hat (via dnf)
  • Clear (via swiped)
  • OpenSUSE LEAP (via zypper)
  • Arch and Manjaro (via community AUR packages)
  • Void (via xbps)
  • Gentoo (via emerge)

If you use any Linux distribution other than Ubuntu, we recommend using the latest available GDB built from source. You can build it as:

cd <gdb-sources-dir>
mkdir build && cd build
sudo apt install libgmp-dev libmpfr-dev libreadline-dev texinfo  # required by build
../configure --disable-nls --disable-werror --with-system-readline --with-python=`which python3` --with-system-gdbinit=/etc/gdb/gdbinit --enable-targets=all
make -j7

Portable Installation:

The portable version includes all necessary dependencies and should work without the need to install additional packages.

Download the Portable Version:

Download the portable version from the Pwndbg releases page by selecting the desired version. Choose the appropriate version for your system architecture (x86_64 or aarch64).

Installation on RPM-based Systems (CentOS/Alma/Rocky/RHEL):

dnf install ./pwndbg-2023.07.17.x86_64.rpm
# pwndbg

Installation on DEB-based Systems (Debian/Ubuntu/Kali):

apt install ./pwndbg_2023.07.17_amd64.deb
# pwndbg

Installation on Alpine:

apk add --allow-untrusted ./pwndbg_2023.07.17_x86_64.apk
# pwndbg

Installation on Arch Linux:

pacman -U ./pwndbg-2023.07.17-1-x86_64.pkg.tar.zst
# pwndbg

Generic Linux Installation:

tar -v -xf ./pwndbg_2023.07.17_amd64.tar.gz
# ./pwndbg/bin/pwndbg

What can I do with that?

For further info about features/functionalities, see FEATURES.

Who?

Pwndbg is an open-source project, maintained by many contributors!

Pwndbg was originally created by Zach Riggle, who is no longer with us. We want to thank Zach for all of his contributions to Pwndbg and the wider security community.

Want to help with development? Read CONTRIBUTING or join our Discord server!

How to develop?

To run tests locally you can do this in docker image, after cloning repo run simply

docker-compose run main ./tests.sh 

Disclaimer - this won't work on apple silicon macs.

Contact

If you have any questions not worthy of a bug report, feel free to ping anybody on Discord and ask away.

pwndbg's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pwndbg's Issues

heap command displays unnecessary data

Given a simple binary below, breaking at function B produces the output below.

The flags must be incorrect, as they are all marked PREV_INUSE. The first entry has no prev, so that must be incorrect.

All of the entries display fd and bk and fd_nextsize and bk_nextsize even if the fields don't make sense to display in these instances.

We should not display fields that are unnecessary. This means diverging from usage of GDB-provided symbols and type info, and declaring our own, similar to how it's done in GEF (#30), libheap (#5) and gdb-heap (#4).

pwndbg> break B
pwndbg> set env MALLOC_PERTURB_=85
pwndbg> run
...
pwndbg> heap
Top Chunk: 0x6020a0
Last Remainder: 0

0x602000 PREV_INUSE
{
  prev_size = 0x0,
  size = 0x31,
  fd = 0xaaaaaaaaaaaaaaaa,
  bk = 0xaaaaaaaaaaaaaaaa,
  fd_nextsize = 0xaaaaaaaaaaaaaaaa,
  bk_nextsize = 0xaaaaaaaaaaaaaaaa
}
0x602030 PREV_INUSE
{
  prev_size = 0x700000000000004,
  size = 0x21,
  fd = 0xaaaaaaaaaaaaaaaa,
  bk = 0xaaaaaaaaaaaaaaaa,
  fd_nextsize = 0x700000000000002,
  bk_nextsize = 0x51
}
0x602050 PREV_INUSE
{
  prev_size = 0x700000000000002,
  size = 0x51,
  fd = 0xaaaaaaaaaaaaaaaa,
  bk = 0xaaaaaaaaaaaaaaaa,
  fd_nextsize = 0xaaaaaaaaaaaaaaaa,
  bk_nextsize = 0xaaaaaaaaaaaaaaaa
}
0x6020a0 PREV_INUSE
{
  prev_size = 0x70000000000000e,
  size = 0x20f61,
  fd = 0x0,
  bk = 0x0,
  fd_nextsize = 0x0,
  bk_nextsize = 0x0
}

Example binary:

#include <malloc.h>

void A() {}
void B() {}
void C() {}
void D() {}
void E() {}
void F() {}

int main() {
    A();

    void* a = malloc(32);
    void* b = malloc(16);
    void* c = malloc(64);

    B();

    free(b);

    C();

    free(a);

    D();

    void* d = malloc(48);

    E();

    free(d);
    free(c);

    F();
}

The integer argument in ArgparsedCommand will be consider as hex

Give you an example.

> hexdump $sp 9
+0000 0x7fffffffdc70  d0 74 ff f7  ff 7f 00 00  18                        |.t..|....|.   |    |
+0009 0x7fffffffdc79
> hexdump $sp 10
+0000 0x7fffffffdc70  d0 74 ff f7  ff 7f 00 00  18 dd ff ff  ff 7f 00 00  |.t..|....|....|....|
+0010 0x7fffffffdc80

Because in pwndbg/commands/__init__.py, you will try to call fix_int if the argument type is int, then the fix_int() use gdb.parse_and_eval() to fix the integer (maybe you want to do some symbol resolution via gdb), but it will consider the integer is hex.

> python print(gdb.parse_and_eval('10'))
0x10

I think the input should be checked. If it is a pure integer string, then just convert it as integer (or use try except to convert it first.) You accept this kind of patch, I can make a PR for this.

gdb version (Ubuntu 16.04 build-in):

$ gdb --version
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1

link_map structure should get walked

For dynamically-linked binaries run under qemu-user, we have no mechanism to autodetect other libraries.

We should support extracting the link_map from the linker, via the GOT/PLT, or via DT_DEBUG segments.

This will only be possible if we can get a local copy of the ELF on disk, since we can't find those, since the headers are not resident in memory.

Improve function docs

At the very least, we could use inspect to print out things like the argument names when you run help on a command.

Program received signal SIGBUS, Bus error.

I received the following stack trace while debugging the binary unexploitable from pwnable.kr in pwndbg. I'm on Ubuntu 14.04 and using GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1. I don't have a repro that doesn't share parts of the solution for the challenge, so for now I'll just include the stack trace in case you can figure it out from there, or someone else sees the same issue:

Program received signal SIGBUS, Bus error.
ptmalloc_init () at arena.c:399
399     arena.c: No such file or directory.
Traceback (most recent call last):
  File "/home/vagrant/tools/pwndbg/pwndbg/commands/__init__.py", line 54, in __call__
    return self.function(*args, **kwargs)
  File "/home/vagrant/tools/pwndbg/pwndbg/commands/__init__.py", line 112, in _OnlyWhenRunning
    return function(*a, **kw)
  File "/home/vagrant/tools/pwndbg/pwndbg/commands/nearpc.py", line 71, in nearpc
    instructions = pwndbg.disasm.near(pc, lines, emulate=emulate)
  File "/home/vagrant/tools/pwndbg/pwndbg/disasm/__init__.py", line 180, in near
    target_candidate, size_candidate = emu.single_step()
  File "/home/vagrant/tools/pwndbg/pwndbg/emu/emulator.py", line 399, in single_step
    insn = pwndbg.disasm.one(pc)
  File "/home/vagrant/tools/pwndbg/pwndbg/disasm/__init__.py", line 81, in one
    for insn in get(address, 1):
  File "/home/vagrant/tools/pwndbg/pwndbg/disasm/__init__.py", line 101, in get
    i = get_one_instruction(address)
  File "/home/vagrant/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/vagrant/tools/pwndbg/pwndbg/disasm/__init__.py", line 73, in get_one_instruction
    pwndbg.disasm.arch.DisassemblyAssistant.enhance(ins)
  File "/home/vagrant/tools/pwndbg/pwndbg/disasm/arch.py", line 51, in enhance
    enhancer.enhance_next(instruction)
  File "/home/vagrant/tools/pwndbg/pwndbg/disasm/arch.py", line 107, in enhance_next
    instruction.target = self.next(instruction, call=True)
  File "/home/vagrant/tools/pwndbg/pwndbg/disasm/x86.py", line 110, in next
    return super(DisassemblyAssistant, self).next(instruction, call)
  File "/home/vagrant/tools/pwndbg/pwndbg/disasm/arch.py", line 143, in next
    addr = int(pwndbg.memory.poi(pwndbg.typeinfo.ppvoid, addr))
  File "/home/vagrant/tools/pwndbg/pwndbg/memory.py", line 113, in poi
    def poi(type, addr): return gdb.Value(addr).cast(type.pointer()).dereference()
gdb.error: The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(malloc) will be abandoned.
When the function is done executing, GDB will silently stop.

Dafaq x2

Why is the next instruction wrong? This is either a pwndbg.disasm.arch issue or a Unicorn issue.

screen shot 2016-07-01 at 12 39 03 am

screen shot 2016-07-01 at 12 38 58 am

pwndbg is slow when connect to debug server of pintool

Pintool can use -appdebug to create a debugger server (like gdbserver) then gdb can use target remote to connect.
I try to use pwndbg but it will block on some event (I just add a timer in debug log of event to record the time usage):

Slow: 'start' pwndbg.argv.update () finished in 2.202494s
Slow: 'obj' pwndbg.events._start_newobjfile (<gdb.NewObjFileEvent object at 0x7fdab28f02a0>,) finished in 2.334072s
Slow: 'stop' pwndbg.stack.update (<gdb.SignalEvent object at 0x7fdab28f02d0>,) finished in 57.476584s
Slow: 'stop' pwndbg.vmmap.explore_registers (<gdb.SignalEvent object at 0x7fdab28f02d0>,) finished in 1.282561s
Slow: 'start' pwndbg.argv.update () finished in 2.198303s
Slow: 'start' pwndbg.argv.update () finished in 2.208627s
Slow: 'obj' pwndbg.events._start_newobjfile () finished in 2.212299s
Slow: 'stop' pwndbg.vmmap.explore_registers () finished in 1.245921s
Slow: 'stop' pwndbg.symbol.add_main_exe_to_symbols () finished in 56.673910s

Also, command telescope is slow because of lots memory query.

I traced some function and found out that pintool's server didn't provide some information (f.e. auxv) and pwndbg will try to scan memory to retrieve this information, but the gdb.Value().dereference is so slow. I haven't looked all slow function, so there may be the other bottlenecks.

I don't have a good idea to fix this. Mabe we need to

  1. Add more cache.
  2. Reduce unnecessary memory scan. (f.e. reduce unnecessary update functions on each event)

I use pin-3.0-76991-gcc-linux on ubuntu 16.04 vm.

$ ./pin-3.0-76991-gcc-linux/pin -version     
Pin 3.0
Copyright (c) 2003-2016, Intel Corporation. All rights reserved.
@CHARM-VERSION: $Rev: 76887

BTW, Why memoize.__reset_on_start will be invoked by stop event? The stop event of gdb will be trigger when the inferior has stopped. That is, it will be trigger when gdb stops the inferior and change the control back to you. So, memoize.reset_on_start cache will be reset when you use some commands like si, continue. Is this behavior what you want?

Feature parity with GDBINIT

https://github.com/gdbinit/Gdbinit/blob/master/gdbinit

  • init - Run program and break on _init
  • start - Run program and break on _start
  • sstart - Run program and break on __libc_start_main
  • main - Run program and break on main
  • argv - Show argv
  • stack - Print backtrace
  • frame - Show info {frame, args, locals}
  • lib(s) - Display shared libraries
  • go - Step one instruction
    (Windbg compatibility of go is favored)
  • n - Step N instructions
  • pret - Finish frame, print return value
    Won't implement, use the finish command.
  • stepo - Step over calls
  • stepoh - Uses hardware breakpoints
  • skip - Skip over N instructions
  • nop - Nop out address
  • null - Zero out address
  • int3 - Patch in an int3 / BKPT at address
  • unpatch - Restore original value pre-patch
  • entry_point - Prints entrypoint

Interesting settings:

  • set arm show-opcode-bytes 1

Useful aliases:

  • bl / bpl - List breakpoints
  • bp - Breakpoint
  • bc / bpc - Clear breakpoint
  • be / bpe - Enable breakpoint
  • bd / bpd - Disable breakpoint

Improper output formatting

From the recent merge @br0ns, it seems to clear the home and end key issue in prompt, but the coloured output seems to come out weird. Upon looking into code of color.py which has

SOH            = "\x01"
STX            = "\x02"
NORMAL         = SOH + "\x1b[0m" + STX
BLACK          = SOH + "\x1b[30m" + STX
RED            = SOH + "\x1b[31m" + STX
GREEN          = SOH + "\x1b[32m" + STX
YELLOW         = SOH + "\x1b[33m" + STX
BLUE           = SOH + "\x1b[34m" + STX
PURPLE         = SOH + "\x1b[35m" + STX
CYAN           = SOH + "\x1b[36m" + STX
GREY = GRAY    = SOH + "\x1b[90m" + STX
BOLD           = SOH + "\x1b[1m" + STX
UNDERLINE      = SOH + "\x1b[4m" + STX

Here is the link to image of output.
instead using it as it was before:

NORMAL         = "\x1b[0m"
BLACK          = "\x1b[30m"
RED            = "\x1b[31m"
GREEN          = "\x1b[32m"
YELLOW         = "\x1b[33m"
BLUE           = "\x1b[34m"
PURPLE         = "\x1b[35m"
CYAN           = "\x1b[36m"
GREY = GRAY    = "\x1b[90m"
BOLD           = "\x1b[1m"
UNDERLINE      = "\x1b[4m"

and adding following line to __init__.py:

prompt = "pwn> "
prompt = "\x01" + prompt + "\x02"    # SOH + prompt + STX
prompt = pwndbg.color.red(prompt)
prompt = pwndbg.color.bold(prompt)

Should fix the error of home and end key in prompt while not interfering with the coloured output due to other functions.

Above changes solves both issues correctly on my system and if you think it is valid to do so, I can submit a pull request.

Linker detection is incorrect under qemu-user.

Given a trivial ARM binary which needs a linker:

pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
    0x8000     0x9000 r-xp     1000 0      /home/user/a.out
    0x9000    0x10000 ---p     7000 0      /home/user/a.out
   0x10000    0x11000 r--p     1000 0      /home/user/a.out
   0x11000    0x12000 rw-p     1000 1000   /home/user/a.out
0xf67dd000 0xf67f5000 r--p    18000 0      [linker] <=== Note page permissions and start address
0xf6ffd000 0xf7000000 rw-p     3000 0      [stack]
pwndbg> aux
AT_BASE                  0xf67de000 <-- 0x464c457f <=== Note correct address and ELF header

Windbg Aliases / Feature Parity

Needs more Windbg.

  • Dot-prefixed aliases are not possible.
    • .attach (`attach is builtin)
    • .detach (detach is builtin)
    • .restart (restart is builtin)
    • .echo (echo is builtin)
    • .holdmem
    • .frame (frame is builtin)
  • Bang-prefixed aliases are not possible.
    • !peb (implemented as peb)
    • !avrf
    • !address (implemented as address)
    • !vprot (implemented as vprot)
  • Tilde prefix is not possible
    • ~
  • ln
  • lm
  • ta
  • tt
  • pc
  • tc (would trample tcatch command)
  • r (would trample run command)
  • c (would trample continue command)
  • m
  • f (would trample frame command)

Don't show stacktrace when ebp points to invalid memory

Otherwise you get something like this:

Traceback (most recent call last):
  File "/vagrant/pwndbg/pwndbg/events.py", line 98, in caller
    func()
  File "/vagrant/pwndbg/pwndbg/arch.py", line 32, in update
    m.current = fix_arch(gdb.selected_frame().architecture().name())
gdb.MemoryError: Cannot access memory at address 0x41414145
Python Exception <class 'gdb.MemoryError'> Cannot access memory at address 0x41414145:

AttributeError: 'module' object has no attribute 'memoize'

After installing pwndbg with setup.sh, when loading gdb pwndbg complained about missing psutil. After installing psutil, I get this:

Traceback (most recent call last):
  File "/home/vagrant/tools/pwndbg/gdbinit.py", line 11, in <module>
    import pwndbg
  File "/home/vagrant/tools/pwndbg/pwndbg/__init__.py", line 6, in <module>
    import pwndbg.arch
  File "/home/vagrant/tools/pwndbg/pwndbg/arch.py", line 11, in <module>
    import pwndbg.regs
  File "/home/vagrant/tools/pwndbg/pwndbg/regs.py", line 19, in <module>
    import pwndbg.proc
  File "/home/vagrant/tools/pwndbg/pwndbg/proc.py", line 14, in <module>
    import pwndbg.qemu
  File "/home/vagrant/tools/pwndbg/pwndbg/qemu.py", line 14, in <module>
    @pwndbg.memoize.reset_on_stop
AttributeError: 'module' object has no attribute 'memoize'

This is on a fresh Ubuntu 14.04 Vagrant VM.

pwndbg prints an error when calling 'disasm' and pwntools is not installed.

The pwndbg setup.sh does not install pwntools. Calling disasm without it installs just prints an error.

pwndbg> disasm
Traceback (most recent call last):
  File "/home/ekse/git/pwndbg/pwndbg/commands/__init__.py", line 54, in __call__
    return self.function(*args, **kwargs)
  File "/home/ekse/git/pwndbg/pwndbg/commands/shell.py", line 76, in handler
    os.execvp(cmd, (cmd,) + a)
  File "/usr/lib/python3.5/os.py", line 615, in execvp
    _execvpe(file, args)
  File "/usr/lib/python3.5/os.py", line 660, in _execvpe
    raise last_exc.with_traceback(tb)
  File "/usr/lib/python3.5/os.py", line 650, in _execvpe
    exec_func(fullname, *argrest)
FileNotFoundError: [Errno 2] No such file or directory

'pwndbg' command

There is not currently an easy way of getting all commands currently available to a user. pwndbg could dump all commands with possibly their doc string.

Cannot get GDB to work with pwndbg and Capstone

Hello,

When I try to run GDB, I get the following stack trace below. This was from a fresh clone from Git and running sudo ./setup.sh. Here's my environment:

uname -a
Linux ubux64DVRF 4.4.0-28-generic #47-Ubuntu SMP Fri Jun 24 10:09:13 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

GNU gdb (Ubuntu 7.11-0ubuntu1) 7.11
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
http://www.gnu.org/software/gdb/documentation/.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Traceback (most recent call last):
File "/home/andy/Downloads/pwndbg/gdbinit.py", line 13, in
import pwndbg # isort:skip
File "/home/andy/Downloads/pwndbg/pwndbg/init.py", line 9, in
import pwndbg.android
File "/home/andy/Downloads/pwndbg/pwndbg/android.py", line 5, in
import pwndbg.color
File "/home/andy/Downloads/pwndbg/pwndbg/color.py", line 11, in
import pwndbg.enhance
File "/home/andy/Downloads/pwndbg/pwndbg/enhance.py", line 18, in
import pwndbg.disasm
File "/home/andy/Downloads/pwndbg/pwndbg/disasm/init.py", line 34, in
'arm': Cs(CS_ARCH_ARM, CS_MODE_ARM),
File "/usr/local/lib/python3.5/dist-packages/capstone/init.py", line 661, in init
raise CsError(CS_ERR_VERSION)
capstone.CsError: <exception str() failed>
(gdb) quit

Exception when attaching to QEMU gdb stub

Thanks for all your work on this project. I'm having trouble attaching to a process suspended by QEMU with a gdb stub. The specific target is the stack_bof_01 binary in the DVRF project. The DVRF setup process was followed as per the Getting Started blog post; while the pwndbg setup process was followed as per @ctfhacker's EpicTreasure et_setup.sh.

The target is started as follows:

$ sudo chroot . ./qemu-mipsel-static -g 1234 /pwnable/Intro/stack_bof_01 AAAA

When attaching with gdb, auxv.py raises a TypeError exception.

$ gdb
Loaded 92 commands.  Type pwndbg for a list.
pwndbg> target remote 127.0.0.1:1234
Remote debugging using 127.0.0.1:1234
0x00000000 in ?? ()
Traceback (most recent call last):
  File "/home/int0x80/tools/pwndbg/pwndbg/events.py", line 107, in caller
    func()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/stack.py", line 76, in update
    page  = pwndbg.memory.Page(start, stop-start, 6 if not is_executable() else 7, 0, '[stack]')
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/stack.py", line 122, in is_executable
    ehdr         = pwndbg.elf.exe()
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 52, in exe
    return load(entry())
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 60, in entry
    entry = pwndbg.auxv.get().AT_ENTRY
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/auxv.py", line 103, in get
    return use_info_auxv() or walk_stack() or AUXV()
  File "/home/int0x80/tools/pwndbg/pwndbg/auxv.py", line 154, in walk_stack
    if not auxv['AT_EXECFN']:
TypeError: 'NoneType' object is not subscriptable
Python Exception <class 'TypeError'> 'NoneType' object is not subscriptable: 
Traceback (most recent call last):
  File "/home/int0x80/tools/pwndbg/pwndbg/events.py", line 107, in caller
    func()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/stack.py", line 122, in is_executable
    ehdr         = pwndbg.elf.exe()
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 52, in exe
    return load(entry())
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 60, in entry
    entry = pwndbg.auxv.get().AT_ENTRY
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/auxv.py", line 103, in get
    return use_info_auxv() or walk_stack() or AUXV()
  File "/home/int0x80/tools/pwndbg/pwndbg/auxv.py", line 154, in walk_stack
    if not auxv['AT_EXECFN']:
TypeError: 'NoneType' object is not subscriptable
Python Exception <class 'TypeError'> 'NoneType' object is not subscriptable: 
Traceback (most recent call last):
  File "/home/int0x80/tools/pwndbg/pwndbg/events.py", line 107, in caller
    func()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/symbol.py", line 215, in add_main_exe_to_symbols
    exe  = pwndbg.elf.exe()
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 52, in exe
    return load(entry())
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 60, in entry
    entry = pwndbg.auxv.get().AT_ENTRY
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/auxv.py", line 103, in get
    return use_info_auxv() or walk_stack() or AUXV()
  File "/home/int0x80/tools/pwndbg/pwndbg/auxv.py", line 154, in walk_stack
    if not auxv['AT_EXECFN']:
TypeError: 'NoneType' object is not subscriptable
Python Exception <class 'TypeError'> 'NoneType' object is not subscriptable: 
Traceback (most recent call last):
  File "/home/int0x80/tools/pwndbg/pwndbg/events.py", line 107, in caller
    func()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/vmmap.py", line 39, in get
    pages.extend(info_auxv())
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/vmmap.py", line 303, in info_auxv
    auxv = pwndbg.auxv.get()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/auxv.py", line 103, in get
    return use_info_auxv() or walk_stack() or AUXV()
  File "/home/int0x80/tools/pwndbg/pwndbg/auxv.py", line 154, in walk_stack
    if not auxv['AT_EXECFN']:
TypeError: 'NoneType' object is not subscriptable
Python Exception <class 'TypeError'> 'NoneType' object is not subscriptable: 

If I wrap the offending lines with a simple try and except, like so

    try:
      if not auxv['AT_EXECFN']:
          auxv['AT_EXECFN'] = get_execfn()

    except:
      pass

I receive a different set of errors:

$ gdb
Loaded 92 commands.  Type pwndbg for a list.
pwndbg> target remote 127.0.0.1:1234
Remote debugging using 127.0.0.1:1234
0x00000000 in ?? ()
Traceback (most recent call last):
  File "/home/int0x80/tools/pwndbg/pwndbg/events.py", line 107, in caller
    func()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/stack.py", line 76, in update
    page  = pwndbg.memory.Page(start, stop-start, 6 if not is_executable() else 7, 0, '[stack]')
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/stack.py", line 122, in is_executable
    ehdr         = pwndbg.elf.exe()
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 52, in exe
    return load(entry())
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 80, in entry
    return pwndbg.symbol.get(name)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/symbol.py", line 158, in get
    if address < pwndbg.memory.MMAP_MIN_ADDR or address >= ((1 << 64)-1):
TypeError: unorderable types: str() < int()
Python Exception <class 'TypeError'> unorderable types: str() < int(): 
Traceback (most recent call last):
  File "/home/int0x80/tools/pwndbg/pwndbg/events.py", line 107, in caller
    func()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/stack.py", line 122, in is_executable
    ehdr         = pwndbg.elf.exe()
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 52, in exe
    return load(entry())
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 80, in entry
    return pwndbg.symbol.get(name)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/symbol.py", line 158, in get
    if address < pwndbg.memory.MMAP_MIN_ADDR or address >= ((1 << 64)-1):
TypeError: unorderable types: str() < int()
Python Exception <class 'TypeError'> unorderable types: str() < int(): 
Traceback (most recent call last):
  File "/home/int0x80/tools/pwndbg/pwndbg/events.py", line 107, in caller
    func()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/symbol.py", line 215, in add_main_exe_to_symbols
    exe  = pwndbg.elf.exe()
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 52, in exe
    return load(entry())
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 80, in entry
    return pwndbg.symbol.get(name)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/symbol.py", line 158, in get
    if address < pwndbg.memory.MMAP_MIN_ADDR or address >= ((1 << 64)-1):
TypeError: unorderable types: str() < int()
Python Exception <class 'TypeError'> unorderable types: str() < int(): 
Traceback (most recent call last):
  File "/home/int0x80/tools/pwndbg/pwndbg/events.py", line 107, in caller
    func()
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/stack.py", line 76, in update
    page  = pwndbg.memory.Page(start, stop-start, 6 if not is_executable() else 7, 0, '[stack]')
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/stack.py", line 122, in is_executable
    ehdr         = pwndbg.elf.exe()
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 52, in exe
    return load(entry())
  File "/home/int0x80/tools/pwndbg/pwndbg/proc.py", line 60, in wrapper
    return func(*a, **kw)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/elf.py", line 80, in entry
    return pwndbg.symbol.get(name)
  File "/home/int0x80/tools/pwndbg/pwndbg/memoize.py", line 44, in __call__
    value = self.func(*args, **kwargs)
  File "/home/int0x80/tools/pwndbg/pwndbg/symbol.py", line 158, in get
    if address < pwndbg.memory.MMAP_MIN_ADDR or address >= ((1 << 64)-1):
TypeError: unorderable types: str() < int()
Python Exception <class 'TypeError'> unorderable types: str() < int(): 

Not sure whether it's helpful, but here is some diagnostic info about my VM.

$ python3 -V
Python 3.5.1+

$ python2 -V
Python 2.7.11+

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"

$ uname -r
4.4.0-24-generic

Please let me know how I can help further in debugging this issue.

IDA Port Selection

Currently, the IDA Pro integration relies on a static port, which means that only one IDB / binary can be interacted with at once.

We should be able to leverage GNU Build IDs in order to automate port selection, or at least do auto-discovery of the correct port via multiple attempts.

The XMLRPC server should start at well-known port N and attempt to listen on it. If it's unavailable, then N+1 and so-on.

Pwndbg already knows how to find various ELF things, and should be able to extract the Build ID both from memory, and from the IDA session. Thus, it can connect to well-known port N and verify that it's connected to the correct instance of IDA. If not, it moves on to N+1 and so-on.

Where this causes issues is if we have ports N through N+5 open and the IDB responsible for port N+2 closes, there will be a gap. Perhaps we should limit the total range to 10 ports [N..N+10) and try them all? If you have more than 10 IDBs open, WTF.

Feature parity with PEDA

These are the advertised features:

  • aslr -- Show/set ASLR setting of GDB
  • checksec -- Check for various security options of binary
  • dumpargs -- Display arguments passed to a function when stopped at a call instruction
  • dumprop -- Dump all ROP gadgets in specific memory range
    Won't implement, use ROPgadget
  • elfheader -- Get headers information from debugged ELF file
  • elfsymbol -- Get non-debugging symbol information from an ELF file
  • lookup -- Search for all addresses/references to addresses which belong to a memory range
  • patch -- Patch memory start at an address with string/hexstring/int
    Won't implement, is provided by the windbg commands
  • pattern -- Generate, search, or write a cyclic pattern to memory
    Won't implement, pwntools has it
  • procinfo -- Display various info from /proc/pid/
  • pshow -- Show various PEDA options and other settings
    Won't implement, just use regular show.
  • pset -- Set various PEDA options and other settings
    Won't implement, just use regular set.
  • readelf -- Get headers information from an ELF file (implemented as elfheader)
  • ropgadget -- Get common ROP gadgets of binary or library
    Implemented as ROPGadget and Ropper wrappers
  • ropsearch -- Search for ROP gadgets in memory
    Implemented as ROPGadget and Ropper wrappers
  • searchmem|find -- Search for a pattern in memory;
    • support regex search
  • shellcode -- Generate or download common shellcodes.
    Won't implement, pwntools has it and it's useless
  • skeleton -- Generate python exploit code template from pwn import *
  • vmmap -- Get virtual mapping address ranges of section(s) in debugged process
  • xormem -- XOR a memory region with a key

Additionally, there are a few useful aliases:

  • reg
  • stack
  • viewmem

These are additional commands which are not advertised:

  • hexprint (db, dd, etc)
  • hexdump
  • xprint
  • distance
  • session
    Won't implement, don't understand the use case.
  • getfile
  • getpid
  • pdisass
    alias for nearpc
  • nearpc
  • waitfor
    Won't implement, use pwntools's gdb.attach or gdb.debug
  • pltbreak
  • xrefs
    Won't implement, shells out to objdump
  • deactive
  • unptrace
  • dumpargs
  • xuntil
    Won't implement, use tbreak
  • goto
    Won't implement, use set $pc=
  • skip
  • start
  • stepuntil
  • nextcall
  • nextjmp
  • tracecall
  • traceinst
  • profile
  • dumpmem
    Won't implement, GDB provides this functionality via dump mem
  • loadmem
    Won't implement, GDB provides this functionality via restore
  • cmpmem
  • refsearch
  • lookup
  • telescope
  • eflags
    show-flags and color-flags options
  • xinfo
  • strings
  • sgrep
  • nxtest
  • asmsearch
  • jmpcall
  • pattern_create
    Won't implement
  • pattern_offset
    Won't implement
  • pattern_search
    Won't implement
  • pattern_patch
    Won't implement
  • pattern_arg
    Won't implement
  • pattern_env
    Won't implement
  • pattern
    Won't implement
  • gennop
  • snapshot
    Won't implement, just use gcore.
  • crashdump

pwndbg install issue on Arch Linux

Exception caught while booting Guile.
Error in function "open-file":
No such file or directory: "/usr/share/gdb/guile/gdb/boot.scm"
gdb: warning: Could not complete Guile gdb module initialization from:
/usr/share/gdb/guile/gdb/boot.scm.
Limited Guile support is available.
Suggest passing --data-directory=/path/to/gdb/data-directory.

Python Exception <type 'exceptions.ImportError'> No module named gdb: 
gdb: warning: 
Could not load the Python gdb module from `/usr/share/gdb/python'.
Limited Python support is available from the _gdb module.
Suggest passing --data-directory=/path/to/gdb/data-directory.

GNU gdb (GDB) 7.11.50.20160705-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from Documents/Projects/Education/BinaryExploitation/lab1/lab1...(no debugging symbols found)...done.
(gdb) 

Not sure what is causing this issue but would love some feedback. I also cannot seem to get rid of this error by deleting the .gdbinit file, any tips on how to also do this would be appreciated

Honor delay slots in disassembly splits

MIPS, SuperH, SPARC all have delay slots.

Wrong

    0x767cc014    ori    $t5, $a0, 0xfeff
    0x767cc018    b      0x767cc044

    0x767cc01c    ori    $t7, $a0, 0xff7d
    0x767cc020    addiu  $v1, $v1, 8

Correct

    0x767cc014    ori    $t5, $a0, 0xfeff
    0x767cc018    b      0x767cc044
    0x767cc01c    ori    $t7, $a0, 0xff7d

    0x767cc020    addiu  $v1, $v1, 8

Pwndbg raise exception with newest capstone engine

Excuse me but something went wrong with pwndbg which I installed recently, maybe something is wrong with /disasm/color.py(line 11), capstone has moved target_constant attribute, anyway thanks a lot to your wonderful work!

distance command does not work

Use distance command would get error:

%x format: an integer is required, not float

Because x / y will be float in Python3. Use %x to on float type variable will raise this error.

Code for reference,

    print("%#x->%#x is %#x bytes (%#x words)" % (a, b, distance, distance / _arch.ptrsize))

There are two ways to fix it. Use %f or use //. It depends on what to do if distance is not divisible by arch.ptrsize. Open this issue for discussing.

Pwndbg should mark pwndbg.regs.last['pc'] as executable

In the event we're executing under QEMU-user, we may not be able to detect executable pages.

However, we can certainly assume that whatever $PC was on the last instruction should be executable.

Unfortunately, this is arch-specific since pwndbg.regs.last is a dictionary of registers and does not support meta-registers like PC and SP e.g. on i386.

Sign not allowed in string format specifier

debugging radare2

pwn> p img_dbg_dir_entry 
$2 = (Pe32_image_debug_directory_entry *) 0x6e8ca0
Python Exception <class 'ValueError'> Sign not allowed in string format specifier:

on file #2 0x00007ffff70077c5 in Pe32_r_bin_pe_get_debug_data (bin=0x6e8ab0, res=0x7fffffffd280) at /home/jeff/ctf/tools/radare2/libr/..//libr/bin/p/../format/pe/pe.c:1911

ping me for more details for this.

Expose twiddly bits and arbitrary constants via properties

All of the random constants for defaults should be configurable.

We should implement a module object, pwndbg.config, which exposes configuration settings as recursive properties.

For example, print(pwndbg.config.assembly_lines) would print a configuration setting which the user has set via set pwndbg assembl-lines 3 or something similar.

We'd need to stub out all of operator properties (__add__, __radd__, etc.) and have a mechanism to set defaults.

Alternately, we can just have some basic wrapper defined in the pwndbg.config module to ease the process of setting these values.

start event is trigger 3 times when starting

I noticed that start event will be trigger 3 time. The first time is by _start_newobjfile on new_objfile event. The second and the third time is by pwndbg.events.after_reload() which is called by prompt_hook() in pwndbg/__init__.py.

pwndbg.events.after_reload() will call all the function that registered by start, new_objfile, stop events. It will call all start function directly for the second time.
However, _start_newobjfile is registered in new_objfile event and it will be called the second time and it will call StartEvent.on_new_objfile(). It will call all start function the third time.

Some condition handlingself.running in StartEvent does not work for avoiding the duplicate invoking because prompt_hook() will be called after stop event and stop event will set StartEvent.running to False.

   def after_reload():
      if gdb.selected_inferior().pid:
          for f in registered[gdb.events.start]:
              f()
          for f in registered[gdb.events.new_objfile]:
              f()
          for f in registered[gdb.events.stop]:
              f()

It seems that you have tried some ways to handle the reload and start event. But it is chaos now.
I don't know which functions depend on these events and what you want to do with this issue.
It is better that create an issue for discussing rather than directly give you a dirty patch.

Unicorn Engine

Need to add Unicorn Engine for emulation of the current basic block.

Feature parity with GEF

These can be enumerated easily via: gdb --nx --nh --command gef/gef.py --ex 'gef'

  • aslr -- View/modify GDB ASLR behavior.
  • capstone-disassemble -- Use capstone disassembly framework to disassemble code. (alias: cs-dis)
    • We always use Capstone
  • canary -- Shows the canary value of the current process. Apply the techique
  • capstone-disassemble -- Use capstone disassembly framework to disassemble code. (alias: cs-dis)
    • We always use capstone
  • checksec -- Checksec.sh (http://www.trapkit.de/tools/checksec.html) port.
  • context -- Display execution context. (alias: ctx)
  • ctf-exploit-templater -- Generates a ready-to-use exploit template for CTF.
    • Won't implement, use pwntools's pwn template.
  • dereference -- Dereference recursively an address and display information
  • dump-memory -- Dump chunks of memory into raw file on the filesystem. Dump file name template can be defined in GEF runtime config
    Won't implement, use the built-in dump command.
  • edit-flags -- Edit flags in a human friendly wait (alias: flags)
  • elf-info -- Display ELF header informations.
  • entry-break -- Tries to find best entry point and sets a temporary breakpoint on it.
    • Use entry
  • fd -- Enumerate file descriptors opened by process.
    • Use procinfo
  • format-string-helper -- Exploitable format-string helper: this command will set up specific breakpoints at well-known dangerous functions (printf, snprintf, etc.), and check if the - pointer [ ] holding the format string is writable, and therefore susceptible to format string attacks if an attacker can control its content. (alias: fmtstr-helper)
  • gef-alias -- GEF defined aliases
    • Not relevant.
  • gef-remote -- gef wrapper for the target remote command. This command will automatically download the target binary in the local temporary directory (defaut /tmp) and then source it. Additionally, it will fetch all the /proc/PID/maps and loads all its information.
    • Unnecessary for pwndbg, we do it better, and transparently.
  • heap -- Base command to get information about the Glibc heap structure.
  • hexdump -- Display arranged hexdump (according to architecture endianness) of memory range. (alias: xd)
  • hijack-fd -- ChangeFdCommand: redirect file descriptor during runtime.
    • Shouldn't be necessary, use pwntools to launch
  • ida-interact -- IDA Interact: set of commands to interact with IDA.
    This is provided by the $ida magic function, and the IDA module.
  • inspect-stack -- Exploiter-friendly top-down stack inspection command (peda-like)
    • Implemented with the telescope command, like PEDA.
  • ksymaddr -- Solve kernel symbols from kallsyms table.
  • nop -- Patch the instruction(s) pointed by parameters with NOP.
  • patch -- Patch the instruction pointed by parameters with NOP. If the return option is specified, it will set the return register to the specific value.
  • pattern -- Metasploit-like pattern generation/search
    • Won't implement, use pwndbg and the search functionality.
  • pid -- ProcessIdCommand: print the process id of the process being debugged.
  • process-search -- List and filter process. (alias: ps)
  • process-status -- Extends the info given by GDB info proc, by giving an exhaustive description of the
    • Implemented with procinfo
  • registers -- Display full details on one, many or all registers value from current architecture.
  • reset-cache -- Reset cache of all stored data.
    • Unnecessary, pwndbg's cache management is automagic.
  • search-pattern -- SearchPatternCommand: search a pattern in memory. (alias: grep)
    • Implemented as search.
  • shellcode -- ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to download shellcodes
    Won't implement, use binjitsu.
  • stub -- Stub out the specified function.
  • theme -- Customize GEF appearance.
  • system -- Invoke an external command and display result.
    • Won't implement, use GDB builtin shell.
  • trace-run -- Create a runtime trace of all instructions executed from $pc to LOCATION specified.
  • unicorn-emulate -- Unicorn emulate: Use Unicorn-Engine to emulate the behavior of the binary, without affecting the GDB runtime. By default the command will emulate only the next [ - ] instruction, but location and number of instruction can be changed via arguments to the command line. By default, it will emulate the next instruction from current PC. (alias: emulate)
    • Won't implement, we automatically instructions in a transparent manner when using nearpc.
  • vmmap -- Display virtual memory mapping
  • xfiles -- Shows all libraries (and sections) loaded by binary (Truth is out there).
    • Won't implement, use builtin info files or info sharedlibrary or vmmap.
  • xinfo -- Get virtual section information for specific address
    I- mplemented as vmmap.

Python Exception <class 'AttributeError'> 'str' object has no attribute 'decode'

While running a program with core file in gdb, I'm getting an error saying Python Exception <class 'AttributeError'> 'str' object has no attribute 'decode' which is coming from the line

    if pwndbg.compat.python3:
        data = data.decode()

if file vmmap.py. I checked the type of data but it turned out to be <class 'str'>. Also it gives error when I run vmmap inside the gdb session which was started with core file.

Python Exception <class 'AttributeError'> 'str' object has no attribute 'decode': 
Error occurred in Python command: 'str' object has no attribute 'decode'
Python Exception <class 'AttributeError'> 'str' object has no attribute 'decode':

On running vmmap while running a program without core file work fine.

Crash under Python2

When running pwndbg with a GDB that uses python2, you get the following crash:

$ gdb /bin/ls
GNU gdb (GDB) 7.8.2
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Traceback (most recent call last):
  File "/pwndbg/gdbinit.py", line 10, in <module>
    import pwndbg
  File "/pwndbg/pwndbg/__init__.py", line 6, in <module>
    import pwndbg.arguments
  File "/pwndbg/pwndbg/arguments.py", line 11, in <module>
    import pwndbg.disasm
  File "/pwndbg/pwndbg/disasm/__init__.py", line 17, in <module>
    import pwndbg.emu.emulator
  File "/pwndbg/pwndbg/emu/__init__.py", line 2, in <module>
    import pwndbg.emu.x86
  File "/pwndbg/pwndbg/emu/x86.py", line 2, in <module>
    import pwndbg.emu.emulator
  File "/pwndbg/pwndbg/emu/emulator.py", line 49
    if DEBUG: print(*a, **kw)
                    ^
SyntaxError: invalid syntax
Reading symbols from /bin/ls...(no debugging symbols found)...done.
(gdb) python import sys; print(sys.version)
2.7.6 (default, Jun 22 2015, 18:01:27) 
[GCC 4.8.2]

This is because in Python2, print is a statement, not a function.

This could be fixed by adding from __future__ import print_function at the top of emulator.py. However, I noticed that print is used often in the repo.

To provide co-compatibility to python2/3, you should add the following at the beginning of the imports of each *.py file:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

I wasn't sure how you wanted to handle the co-compatibility, so I decided to make this issue instead of a pull request.

source code section unavailable if current line is in the first chunk of the list command

when debugging through code and the current function is indeed one that it at the top of a .c file (that does not use tons of includes) the section is lost because of a too aggressive check:

https://github.com/pwndbg/pwndbg/blob/master/pwndbg/commands/context.py#L160

Which edge-case does that try to solve? As I'm hitting that in several cases, I think it does harm more then it maybe solves something? Would be cool to know which case it does try to fix so we could adjust that check to be less aggressive and preserve the section of the mentioned scenario.

broken on ubuntu vivid

minishwoods ~/pwndbg ‹master*› » gdb /bin/ls
GNU gdb (Ubuntu 7.9-1ubuntu1) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Traceback (most recent call last):
  File "~/pwndbg/gdbinit.py", line 10, in <module>
    import pwndbg
  File "/home/jeff/pwndbg/pwndbg/__init__.py", line 102
    print pwndbg.color.red(msg)
               ^
SyntaxError: invalid syntax
Reading symbols from /bin/ls...(no debugging symbols found)...done.
(gdb)

Some Errors...

Traceback (most recent call last):
  File "/home/lieanu/tools/pwndbg/gdbinit.py", line 10, in <module>
    import pwndbg
  File "/home/lieanu/tools/pwndbg/pwndbg/__init__.py", line 5, in <module>
    import pwndbg.arguments
  File "/home/lieanu/tools/pwndbg/pwndbg/arguments.py", line 11, in <module>
    import pwndbg.disasm
  File "/home/lieanu/tools/pwndbg/pwndbg/disasm/__init__.py", line 11, in <module>
    import pwndbg.disasm.arch
  File "/home/lieanu/tools/pwndbg/pwndbg/disasm/arch.py", line 225, in <module>
    generic_assistant = DisassemblyAssistant(None)
  File "/home/lieanu/tools/pwndbg/pwndbg/disasm/arch.py", line 27, in __init__
    CS_OP_IMM: self.immediate,
NameError: name 'CS_OP_IMM' is not defined
Traceback (most recent call last):
  File "/home/lieanu/tools/pwndbg/pwndbg/events.py", line 77, in caller
    func()
  File "/home/lieanu/tools/pwndbg/pwndbg/vmmap.py", line 90, in explore_registers
    find(pwndbg.regs[regname])
  File "/home/lieanu/tools/pwndbg/pwndbg/memoize.py", line 43, in __call__
    value = self.func(*args, **kwargs)
  File "/home/lieanu/tools/pwndbg/pwndbg/regs.py", line 273, in __getitem__
    if isinstance(item, (int,long)):
NameError: name 'long' is not defined
Python Exception <class 'NameError'> name 'long' is not defined: 

'dt' feature compiler issues

The current feature is not clean, and doesn't work well for anything but the OS-native architecture. This is because the current approach globs all of the header files form the OS-native architecture directory, and passes them to alternate-architecture compilers.

This has two issues:

  • Arch-specific headers may not get pulled in or use the wrong ones
  • Not all headers may exist for the alternate architecture (e.g. Python.h won't appear for ARM)

We should rework how this all works, perhaps with a whitelist of header files instead of a blacklist, and allowing the user to specify additional header files.

Add tests/CI

Not sure exactly what the best approach for testing is, but I'd at least like to make sure pwndbg loads in GDB fine on startup (this was broken for a while).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.