Rizin
unix-like reverse engineering framework and cli tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Friends Macros Modules Pages
RAP protocol

RAP stands for the Remote Access Protocol of Radare2, it is compatible with rizin1 and it simply defines a communication between a client and a server to simulate IO operations.

There are two different implementations, one in C and another in Python.

Usage example

Start in one terminal the following command to wait for incoming connections:

rizin rap://:9999

In another machine or terminal connect it:

rizin rap://localhost:9999//bin/ls

As you see, the path of the remote file to load must be specified, and this handled by the open() packet.

Known Bugs

  • Read/Write operations ignore the filedescriptor completely because it is supposed to be handled by the IO layer and it is redundant, but it introduces a bug that breaks support for multiple files.
  • This can be fixed with a new packet type RAP_SETFD.
  • Read lengths should be only 2 bytes, there's no sense in read > 64K of memory in a shot.
  • Seek does not returns anything
  • System vs Cmd - the first should have a return value as well as string result
  • Filedescriptors are assumed to be 32bit

Operations

The protocol is designed to be bidirectional, but right now, only one way is supported. The client sends a byte specifying the operation and the server will reply the same byte masked with the RMT_REPLY value (0x80 | op)

RAP_OPEN   = 1
RAP_READ   = 2
RAP_WRITE  = 3
RAP_SEEK   = 4
RAP_CLOSE  = 5
RAP_SYSTEM = 6
RAP_CMD    = 7
RAP_REPLY  = 0x80

This is how are constructed the packets:

RAP_OPEN
    struct packed RapOpen {
        ut8 op = 1;
        ut8 rw = 0; // 0 = read-only, 1 = read-write
        ut8 len = 15; // length of filename
    }
    >> 01 RW LN [....]
    << 81 FD=(.. .. .. ..)

RAP_READ
    >> 02 LN=(.. .. .. ..)
    << 82 LN=(.. .. .. ..) [..LN..]

RAP_WRITE
    >> 03 LN=(.. .. .. ..) [..LN..]
    << 83 LN=(.. .. .. ..)

RAP_SEEK
    >> 04 FLAG=(..) OFFSET=(.. 8 bytes ..)
    << 84

RAP_CLOSE
    >> 05 FD=(4 bytes) 
    << 85 RET=(4 bytes)

RAP_SYSTEM
    >> 06 LEN=(4 bytes) STR[LEN bytes]
    << 86 LN=(.. .. .. ..) STR[ LEN bytes]

RAP_CMD_
    >> 07 LEN=(4 bytes) STR[LEN bytes]
    << 87 LN=(.. .. .. ..) STR[ LEN bytes]

Examples

Python:

See rizin-bindings/python/remote.py and test-rap-*.py

C:

Server: librz/socket/rap_server.c
Client: librz/io/p/io_rap.c