@ -19,58 +19,52 @@ def decompile(func=None):
"""
"""
try :
try :
r2 = pwndbg . radare2 . r2pipe ( )
r2 = pwndbg . radare2 . r2pipe ( )
# LD list supported decompilers (e cmd.pdc=?)
except ImportError :
# Outputs for example:: pdc\npdg
raise Exception ( ' r2pipe not available, but required for r2->ghidra bridge ' )
if not " pdg " in r2 . cmd ( " LD " ) . split ( " \n " ) :
return [ " radare2 plugin r2ghidra-dec must be installed and available from r2 " ]
# LD -> list supported decompilers (e cmd.pdc=?)
except ImportError : # no r2pipe present
# Outputs for example: pdc\npdg
return [ " r2pipe not available, but required for r2->ghidra-bridge " ]
if " pdg " not in r2 . cmd ( " LD " ) . split ( " \n " ) :
if func is None :
raise Exception ( ' radare2 plugin r2ghidra must be installed and available from r2 ' )
try :
func = hex ( pwndbg . regs [ pwndbg . regs . current . pc ] )
if not func :
except :
func = hex ( pwndbg . regs [ pwndbg . regs . current . pc ] ) if pwndbg . proc . alive else ' main '
func = " main "
src = r2 . cmdj ( " pdgj @ " + func )
src = r2 . cmdj ( " pdgj @ " + func )
# Early exit if decompile command failed horribly, like unknown addr/func
if not src :
if not src :
r eturn [ ]
r aise Exception ( " Decompile command failed, check if ' {} ' is a valid target " . format ( func ) )
current_line_marker = ' /* %% PWNDBG_CODE_MARKER %% */ '
source = src . get ( " code " , " " )
source = src . get ( " code " , " " )
curline = None
try :
# If not running there is no current pc to mark
cur = pwndbg . regs [ pwndbg . regs . current . pc ]
if pwndbg . proc . alive :
except AttributeError :
pc = pwndbg . regs [ pwndbg . regs . current . pc ]
cur = None # If not running there is no current.pc
if cur is not None :
closest = 0
closest = 0
for off in ( a . get ( " offset " , 0 ) for a in src . get ( " annotations " , [ ] ) ) :
for off in ( a . get ( " offset " , 0 ) for a in src . get ( " annotations " , [ ] ) ) :
if abs ( cur - closest ) > abs ( cur - off ) :
if abs ( p c - closest ) > abs ( p c - off ) :
closest = off
closest = off
pos_annotations = sorted ( [ a for a in src . get ( " annotations " , [ ] ) if a . get ( " offset " ) == closest ] ,
pos_annotations = sorted ( [ a for a in src . get ( " annotations " , [ ] ) if a . get ( " offset " ) == closest ] , key = lambda a : a [ " start " ] )
key = lambda a : a [ " start " ] )
# Append code prefix marker for the current line and replace it later
if pos_annotations :
if pos_annotations :
curline = source . count ( " \n " , 0 , pos_annotations [ 0 ] [ " start " ] )
curline = source . count ( " \n " , 0 , pos_annotations [ 0 ] [ " start " ] )
source = source . split ( " \n " )
source = source . split ( " \n " )
# Append code prefix marker for the current line and replace it later
current_line_marker = ' /* %% PWNDBG_CODE_MARKER %% */ '
if curline is not None :
line = source [ curline ]
line = source [ curline ]
if line . startswith ( ' ' ) :
if line . startswith ( ' ' ) :
line = line [ min ( 4 , len ( pwndbg . config . code_prefix ) + 1 ) : ]
line = line [ min ( 4 , len ( pwndbg . config . code_prefix ) + 1 ) : ]
source [ curline ] = current_line_marker + ' ' + line
source [ curline ] = current_line_marker + ' ' + line
# Join the source for highlighting
source = " \n " . join ( source )
source = " \n " . join ( source )
if pwndbg . config . syntax_highlight :
if pwndbg . config . syntax_highlight :
# highlighting depends on the file extension to guess the language, so try to get one...
# highlighting depends on the file extension to guess the language, so try to get one...
try : # try to read the source filename from debug information
src_filename = pwndbg . symbol . selected_frame_source_absolute_filename ( )
src_filename = gdb . selected_frame ( ) . find_sal ( ) . symtab . fullname ( )
if not src_filename :
except : # if non, take the original filename and maybe append .c (just assuming is was c)
filename = gdb . current_progspace ( ) . filename
filename = gdb . current_progspace ( ) . filename
src_filename = filename + " .c " if os . path . basename ( filename ) . find ( " . " ) < 0 else filename
src_filename = filename + " .c " if os . path . basename ( filename ) . find ( " . " ) < 0 else filename
source = H . syntax_highlight ( source , src_filename )
source = H . syntax_highlight ( source , src_filename )
# Replace code prefix marker after syntax highlighting
# Replace code prefix marker after syntax highlighting
source = source . replace ( current_line_marker , C . prefix ( pwndbg . config . code_prefix ) , 1 )
source = source . replace ( current_line_marker , C . prefix ( pwndbg . config . code_prefix ) , 1 )
source = source . split ( " \n " )
return source
return source