@ -1,5 +1,5 @@
"""
Displays gdb , python and pwndbg version s.
Implements version and bugreport command s.
"""
from __future__ import annotations
@ -14,8 +14,6 @@ from subprocess import check_output
from tempfile import NamedTemporaryFile
from urllib . parse import quote
import gdb
import pwndbg
import pwndbg . commands
import pwndbg . integration
@ -23,53 +21,81 @@ from pwndbg.color import message
from pwndbg . commands import CommandCategory
def _gdb_vers ion ( ) - > str :
return gdb . VERSION
def os _inf o( ) :
os_info = platform . system ( )
if os_info . lower ( ) == " linux " and os . path . isfile ( " /etc/os-release " ) :
with open ( " /etc/os-release " ) as os_release :
contents = os_release . read ( )
match = re . search ( ' PRETTY_NAME= " ?([^ " , \n ]+) ' , contents )
if match :
os_info = match . group ( 1 )
def _py_version ( ) :
return sys . version . replace ( " \n " , " " )
return os_info
def capstone_version ( ) :
def module_version( module ) :
try :
import capstone
return " . " . join ( map ( str , capstone . cs_version ( ) ) )
return __import__ ( module ) . __version__
except ImportError :
return " not found "
def unicorn _version( ) :
try :
import unicorn
def debugger _version( ) :
if pwndbg . dbg . is_gdblib_available ( ) :
import gdb
return unicorn . __version__
e xcept ImportError :
return " not found "
return f " GDB: { gdb . VERSION } "
e lse :
return f" LLDB: { ' . ' . join ( map ( str , pwndbg . dbg_mod . lldb . LLDB_VERSION ) ) } "
def all_versions ( ) :
gdb_str = f " Gdb: { _gdb_version ( ) } "
py_str = f " Python: { _py_version ( ) } "
pwndbg_str = f " Pwndbg: { pwndbg . __version__ } "
return (
f " Pwndbg: { pwndbg . __version__ } " ,
f " Python: { sys . version . replace ( ' \n ' , ' ' ) } " ,
debugger_version ( ) ,
f " Capstone: { module_version ( ' capstone ' ) } " ,
f " Unicorn: { module_version ( ' unicorn ' ) } " ,
f " Pwnlib: { module_version ( ' pwnlib ' ) } " ,
) + pwndbg . integration . provider . get_versions ( )
def get_target_arch ( ) :
arch_info = pwndbg . aglib . arch . current
target = f " Target Arch: { arch_info } \n "
if pwndbg . dbg . is_gdblib_available ( ) :
import gdb
capstone_str = f " Capstone: { capstone_version ( ) } "
unicorn_str = f " Unicorn: { unicorn_version ( ) } "
# Note: this are only available if given arch is supported by GDB
# (e.g., `gdb-multiarch` on Ubuntu)
if arch_info in ( " arm " , " armcm " , " aarch64 " ) :
arm_info = gdb . execute ( " show arm " , to_string = True )
target + = f " ARM: { arm_info } \n "
all_versions = ( gdb_str , py_str , pwndbg_str , capstone_str , unicorn_str )
elif arch_info in ( " mips " , " mips64 " ) :
mips_info = gdb . execute ( " show mips " , to_string = True )
target + = f " MIPS: { mips_info } \n "
all_versions + = pwndbg . integration . provider . get_versions ( )
return all_versions
return target
def get_terminal_size ( ) :
try :
width_info = os . get_terminal_size ( ) . columns
height_info = os . get_terminal_size ( ) . lines
except OSError :
# Terminal size may not be available in non-interactive environments (e.g., scripts, IDEs)
width_info = height_info = " <unavailable> "
return f " Terminal width: { width_info } , height: { height_info } \n "
@pwndbg.commands.ArgparsedCommand (
" Displays GDB, Python, and pwndbg versions. " , category = CommandCategory . PWNDBG
" Displays Pwndbg and its important deps versions." , category = CommandCategory . PWNDBG
)
def version ( ) - > None :
"""
Displays GDB , Python , and pwndbg versions .
"""
print ( " \n " . join ( map ( message . system , all_versions ( ) ) ) )
@ -87,20 +113,19 @@ bugreport_group.add_argument(
def bugreport ( run_browser = False , use_gh = False ) :
ISSUE_TEMPLATE = """
< ! - -
Before reporting a new issue , make sure that we do not have any duplicates already open .
If there is one it might be good to take part in the discussion there .
Please see if the bug isn ' t reported already on: https://github.com/pwndbg/pwndbg/issues
and take part in discussion if it was .
Please make sure you have checked that the issue persists on LATEST p wndbg version .
Before reporting a new issue , make sure it happens on latest P wndbg version .
Below is a template for BUG REPORTS .
Don ' t include it if this is a FEATURE REQUEST.
Use the template below .
- - >
### Description
< ! - -
Briefly d escribe the problem you are having in a few paragraphs .
D escribe the problem you are having in a few paragraphs .
- - >
### Steps to reproduce
@ -111,84 +136,73 @@ If this is connected to particular C/asm code or a binary,
please provide the binary or if possible , a smallest C code that reproduces the issue .
- - >
Gdb s ession history :
S ession history :
` ` `
{ gdb _history}
{ session _history}
` ` `
### My setup
< ! - -
Show us your gdb / python / pwndbg / OS / IDA Pro version ( depending on your case ) .
NOTE : We are currently testing Pwndbg only on Ubuntu installations but it should work fine on other distros as well .
This can be displayed in pwndbg through ` version ` command .
If it is somehow unavailable , use :
* ` show version ` - for gdb
* ` py import sys ; print ( sys . version ) ` - for python
* pwndbg version / git commit id
Show us your Pwndbg and any other relevant versions .
- - >
` ` `
{ setup }
` ` ` """
setup = " \n " . join ( all_versions ( ) ) + " \n "
setup + = f " OS: { os_info ( ) } ( { platform . platform ( ) } , { sys . byteorder } endian) \n "
setup + = f " OS ABI: { platform . uname ( ) . version } \n "
setup + = f " Charset: { sys . getdefaultencoding ( ) } \n "
setup + = get_terminal_size ( )
setup + = get_target_arch ( )
gdb_config = gdb . execute ( " show configuration " , to_string = True ) . split ( " \n " )
all_info = all_versions ( )
os_info = platform . system ( )
current_setup = f " Platform: { platform . platform ( ) } \n "
# Commented out for now: do we need this? It seems to be a bloat for GDB.
# People rarely build custom GDB with fancy options...?
# setup += get_debugger_configuration()
if os_info . lower ( ) == " linux " and os . path . isfile ( " /etc/os-release " ) :
with open ( " /etc/os-release " ) as os_release :
contents = os_release . read ( )
match = re . search ( ' PRETTY_NAME= " ?([^ " , \n ]+) ' , contents )
if match :
os_info = match . group ( 1 )
session_history = get_debugger_session_history ( )
current_setup + = f " OS: { os_info } \n "
# 1. showing osabi
osabi_info = platform . uname ( ) . version
current_setup + = f " OS ABI: { osabi_info } \n "
issue_bugreport = ISSUE_TEMPLATE . format ( setup = setup , session_history = session_history )
print ( issue_bugreport )
# 2. showing architecture
arch_info = platform . machine ( )
current_setup + = f " Architecture: { arch_info } \n "
please_please_submit = " Please submit the bugreport generated above at "
github_issue_url = " https://github.com/pwndbg/pwndbg/issues/new "
github_issue_body = " ?body= " + quote ( issue_bugreport )
# 3. showing endian
endian_info = sys . byteorder
current_setup + = f " Endian: { endian_info } \n "
if use_gh :
try :
with NamedTemporaryFile ( " w " , delete = True ) as f :
f . write ( issue_bugreport )
f . flush ( )
check_call ( [ os . environ . get ( " EDITOR " , " vi " ) , f . name ] )
check_call ( [ " gh " , " issue " , " create " , " --body-file " , f . name ] )
except Exception :
print ( please_please_submit + github_issue_url )
elif run_browser :
try :
check_output ( [ " xdg-open " , github_issue_url + github_issue_body ] )
except Exception :
print ( please_please_submit + github_issue_url )
else :
print ( please_please_submit + github_issue_url )
# 4. Depending on current arch -- note that those are only available if given arch is supported by current GDB, like gdb-multiarch
if arch_info in [ " armv7l " , " aarch64 " ] :
arm_info = gdb . execute ( " show arm " , to_string = True )
current_setup + = f " ARM: { arm_info } \n "
elif arch_info in [ " mips " , " mips64 " ] :
mips_info = gdb . execute ( " show mips " , to_string = True )
current_setup + = f " MIPS: { mips_info } \n "
def get_debugger_configuration ( ) :
if pwndbg . dbg . is_gdblib_available ( ) :
import gdb
# 7. showing charset
charset_info = sys . getdefaultencoding ( )
current_setup + = f " Charset: { charset_info } \n "
gdb_config = gdb . execute ( " show configuration " , to_string = True ) . split ( " \n " )
return " \n " + " \n " . join ( gdb_config )
# 8. showing width, height
try :
width_info = os . get_terminal_size ( ) . columns
height_info = os . get_terminal_size ( ) . lines
except OSError :
# Terminal size may not be available in non-interactive environments (e.g., scripts, IDEs)
width_info = " no terminal size "
height_info = " no terminal size "
# LLDB: TODO/FIXME: Do we need this?
else :
return " "
current_setup + = f " Width: { width_info } \n "
current_setup + = f " Height: { height_info } \n "
current_setup + = " \n " . join ( all_info )
current_setup + = " \n " + " \n " . join ( gdb_config )
def get_debugger_session_history ( ) :
if pwndbg . dbg . is_gdblib_available ( ) :
import gdb
# get saved history size (not including current gdb session)
gdb_history_file = gdb . execute ( " show history filename " , to_string = True )
@ -232,30 +246,8 @@ If it is somehow unavailable, use:
current_command_no + = 1
gdb_current_session_history = ( v for ( k , v ) in sorted ( gdb_current_session_history . items ( ) ) )
gdb_current_session_history = " \n " . join ( gdb_current_session_history )
issue_bugreport = ISSUE_TEMPLATE . format (
gdb_history = gdb_current_session_history , setup = current_setup
)
print ( issue_bugreport )
please_please_submit = " Please submit the bugreport generated above at "
github_issue_url = " https://github.com/pwndbg/pwndbg/issues/new "
github_issue_body = " ?body= " + quote ( issue_bugreport )
return " \n " . join ( gdb_current_session_history )
if use_gh :
try :
with NamedTemporaryFile ( " w " , delete = True ) as f :
f . write ( issue_bugreport )
f . flush ( )
check_call ( [ os . environ . get ( " EDITOR " , " vi " ) , f . name ] )
check_call ( [ " gh " , " issue " , " create " , " --body-file " , f . name ] )
except Exception :
print ( please_please_submit + github_issue_url )
elif run_browser :
try :
check_output ( [ " xdg-open " , github_issue_url + github_issue_body ] )
except Exception :
print ( please_please_submit + github_issue_url )
# LLDB: TODO/FIXME: Not yet supported
else :
print ( please_please_submit + github_issue_url )
return " <session history not supported on lldb yet> "