10.6.2 radapy (remote api)

There are some extension APIs that uses r.cmd() as entrypoint in python radare, these are:

radapy   - client/server radare remote protocolo (rap://) implementation in pure python
ranal    - code analysis object-oriented api
radare   - commands aliased with userfriendly function names

As all those apis remains on r.cmd() to work (but radapy), you can use radapy to redefine the 'r' instance and make radare and ranal APIs work remotely or locally seamlessly.

The radapy API is used to implement radare servers or clients in python scripting. Here's a client example:

import sys
sys.path.append('.')
import radapy

c = radapy.RapClient('localhost', 9999)
fd = c.open("/bin/ls", 0)
print c.cmd("px")
c.close(fd)
c.disconnect()

Here's another example in python that hijacks the 'r' instance of radare api and proxies all the commands via network to a remote radare:

hijack=1

import radare
import ranal
import radapy

# r.cmd() hijacking
if hijack:
        class Food:
                def cmd(str):
                        global c
                        print "Command to run is (%s)"%str
                        return c.cmd(str)
                cmd = staticmethod(cmd)
        global r
        radare.r = Food


c = radapy.RapClient("localhost", 9999)

fd = c.open("/bin/ls", 0)
print c.cmd("px")
print radare.r.cmd("pd 20")
radare.seek(33)
print radare.disasm(0, 10)

c.close(fd)
c.disconnect()

The program expects to have radare server running at port 9999 in localhost. This is: 'radare rap://:9999' or 'radare listen://:9999'

The server-side is a bit more complicated to manage because it aims to implement a remote-io with support for remote commands and system execution thru the network. The following example shows implements a radare server that ignores any 'open' or 'close' operation but provides access to a local buffer (python string) as the remote file contents.

The seeking can be hooked, but by default radapy API implements a basic failover and tracks the value of current seek on a local variable of the radapy instance.

import radapy
from string import *

PORT = 8888

def fun_write(buf):
	print "WRITING %d bytes (%s)"%(len(buf),buf)
	return 6

def fun_read(len):
	global rs
	print "READ %d bytes from %d\n"% (len, rs.offset)
	str = "patata"
	str = str[rs.offset:]
	return str


# main

rs = radapy.RapServer()
rs.handle_cmd_read = fun_read
rs.handle_cmd_write = fun_write
rs.size = 10
rs.listen_tcp (PORT)

Using the radapy API you can easily make any python-based application interact with radare. This is for example: IDA, Inmunity Debugger, Bochs, etc..

The bochs-radare support is actually implement in a script that provides works as a bridge between the ero's python patch for bochs and radare. The details of this are described in the 'Debugging with bochs and python' chapter.

See 'scripts/radapy_bochs.py' for more information.