Radare2 Python scripting
r2pipe
- Sample scripts could be found here
-
Python: r2pipe
pip install r2pipe
Basic usage
- To run a python script inside the r2 shell, do not pass a file path. The file can then be called using
.
or#!pipe /path/to/script.py
r = r2pipe.open() # no file path
- Load a binary
import r2pipe
r = r2pipe.open('binary')
- Disable stderr messages
r = r2pipe.open('binary', flags=['-2']) # pass any options from radare2 as a list in the flags parameter. -2 signifies disable stderr
- Run multiple commands (effeciently)
r.cmd('doo; db main; dc') # multiple commands can be passed using a semicolon. In the example; doo (open in debug mode), db main (set breakpoint in main, dc (continue (will hit breakpoint))
- Run a command (any command that one runs in the r2 shell can be passed to the cmd method)
import r2pipe
r = r2pipe.open('binary')
print r.cmd('pdf') # disassamble funtion
- Run a command multiple times
r.cmd('3dc') # the 3 represents how many times dc will run. Can be any value
Json output
- Most commands in r2pipe supports json output by including a
j
at the end of the command
import r2pipe
r = r2pipe.open('binary')
json_out = r.cmd('iij') # get import table as json
- Instead of using python
json
module to parse the json data, usecmdj
instead which does the parsing of json objects for you
json = r.cmdj('iij') # parse json output as json objects
Working with registers
- Get values of all registers
r.cmd('drj') # dumps values of all registers in json format
- Get value of single register
r.cmd('dr eax') # gets the value of the eax register as a hex string
Open a binary in write mode
- To open a file in write mode, pass the
-w
switch to the flags
r = r2pipe.open('binary', flags=['-w', '-d']
# In this example, we are opening the binary in write and debug mode
User input via stdin (debugging mode)
- Method 1
import r2pipe
r = r2pipe.open(
filename='', flags=['-d', 'rarun2', 'program=binary', 'stdin="AAA"..."any rarun2 key/value pairs"'])
r.cmd('doo') # initially you are debuggign rarun2
- Method 2
import r2pipe
with open('profile.rr2', 'w+') as f:
f.write('#!/path/to/rarun2\nstdin="AAA"')
r = r2pipe.open('binary', flags=['-e', 'dbg.profile=profile.rr2'])
# This method is untested. Use method 1 or 3
- Method 3
import r2pipe
r = r2pipe.open('binary')
r.cmd('e dbg.profile=profile.rr2')
# Contents of profile.rr2
# #!/path/to/rarun2
# program=binary
# stdin="AAA"
User input as args (debugging mode)
r.cmd('doo arg') # could be any number of args
Other ways of user input with debugging
r.cmd('dor arg1=some_arg ...')
-
dor
will take any keypair that can be passed via rarun2
radare2-ctypes
-
pip install radare2-ctypes radare2 ctypes bindings
from r2.r_core import *
r = RCore()
r.cmd0("?V")
r.cons.flush()
Blogs
Scripting r2 with pipes - pancake - Medium