# 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.