Remove RAP protocol (#5046)

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
This commit is contained in:
NOT XVilka 2025-03-27 00:55:06 +08:00 committed by GitHub
parent 853629366f
commit 30ae60a759
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 9 additions and 1354 deletions

View file

@ -1,97 +0,0 @@
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

View file

@ -1203,7 +1203,6 @@ RZ_API RZ_BORROW RzCoreFile *rz_core_file_open(RZ_NONNULL RzCore *r, RZ_NONNULL
}
}
if (rz_io_is_listener(r->io)) {
rz_core_serve(r, fd);
rz_io_desc_free(fd);
goto beach;
}

View file

@ -117,24 +117,6 @@ RZ_IPI RzCmdStatus rz_remote_mode_disable_handler(RzCore *core, int argc, const
return RZ_CMD_STATUS_OK;
}
// "Rr"
RZ_IPI RzCmdStatus rz_remote_rap_handler(RzCore *core, int argc, const char **argv) {
char *args = rz_str_array_join(argv + 1, argc - 1, " ");
args = rz_str_prepend(args, ":");
rz_core_rtr_cmd(core, args);
free(args);
return RZ_CMD_STATUS_OK;
}
// "R&r"
RZ_IPI RzCmdStatus rz_remote_rap_bg_handler(RzCore *core, int argc, const char **argv) {
char *args = rz_str_array_join(argv + 1, argc - 1, " ");
args = rz_str_prepend(args, "&:");
rz_core_rtr_cmd(core, args);
free(args);
return RZ_CMD_STATUS_OK;
}
// "Rt"
RZ_IPI RzCmdStatus rz_remote_tcp_handler(RzCore *core, int argc, const char **argv) {
if (argc == 2) {

View file

@ -174,12 +174,10 @@ static const RzCmdDescArg remote_add_args[2];
static const RzCmdDescArg remote_del_args[2];
static const RzCmdDescArg remote_open_args[2];
static const RzCmdDescArg remote_mode_enable_args[2];
static const RzCmdDescArg remote_rap_args[3];
static const RzCmdDescArg remote_gdb_args[4];
static const RzCmdDescArg remote_gdb_debug_args[4];
static const RzCmdDescArg remote_webserver_start_fg_args[2];
static const RzCmdDescArg remote_tcp_args[3];
static const RzCmdDescArg remote_rap_bg_args[2];
static const RzCmdDescArg cmd_help_search_args[2];
static const RzCmdDescArg calculate_expr_args[2];
static const RzCmdDescArg list_rizin_vars_args[2];
@ -2643,26 +2641,6 @@ static const RzCmdDescHelp remote_mode_disable_help = {
.args = remote_mode_disable_args,
};
static const RzCmdDescArg remote_rap_args[] = {
{
.name = "[host:]port",
.type = RZ_CMD_ARG_TYPE_STRING,
},
{
.name = "cmd",
.type = RZ_CMD_ARG_TYPE_CMD,
.flags = RZ_CMD_ARG_FLAG_LAST,
.optional = true,
},
{ 0 },
};
static const RzCmdDescHelp remote_rap_help = {
.summary = "Start the rap server (o rap://9999) / Execute <cmd> on rap server",
.args = remote_rap_args,
};
static const RzCmdDescHelp Rg_help = {
.summary = "Start the gdbserver",
};
@ -2771,19 +2749,6 @@ static const RzCmdDescHelp remote_tcp_help = {
.args = remote_tcp_args,
};
static const RzCmdDescArg remote_rap_bg_args[] = {
{
.name = "port",
.type = RZ_CMD_ARG_TYPE_NUM,
},
{ 0 },
};
static const RzCmdDescHelp remote_rap_bg_help = {
.summary = "Start rap server in background (same as '& Rr')",
.args = remote_rap_bg_args,
};
static const RzCmdDescArg cmd_help_search_args[] = {
{
.name = "search_cmd",
@ -21298,9 +21263,6 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
RzCmdDesc *remote_mode_disable_cd = rz_cmd_desc_argv_new(core->rcmd, R_cd, "R=!", rz_remote_mode_disable_handler, &remote_mode_disable_help);
rz_warn_if_fail(remote_mode_disable_cd);
RzCmdDesc *remote_rap_cd = rz_cmd_desc_argv_new(core->rcmd, R_cd, "Rr", rz_remote_rap_handler, &remote_rap_help);
rz_warn_if_fail(remote_rap_cd);
RzCmdDesc *Rg_cd = rz_cmd_desc_group_new(core->rcmd, R_cd, "Rg", rz_remote_gdb_handler, &remote_gdb_help, &Rg_help);
rz_warn_if_fail(Rg_cd);
RzCmdDesc *remote_gdb_debug_cd = rz_cmd_desc_argv_new(core->rcmd, Rg_cd, "Rg!", rz_remote_gdb_debug_handler, &remote_gdb_debug_help);
@ -21317,9 +21279,6 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
RzCmdDesc *remote_tcp_cd = rz_cmd_desc_argv_new(core->rcmd, R_cd, "Rt", rz_remote_tcp_handler, &remote_tcp_help);
rz_warn_if_fail(remote_tcp_cd);
RzCmdDesc *remote_rap_bg_cd = rz_cmd_desc_argv_new(core->rcmd, R_cd, "R&r", rz_remote_rap_bg_handler, &remote_rap_bg_help);
rz_warn_if_fail(remote_rap_bg_cd);
RzCmdDesc *cmd_help_search_cd = rz_cmd_desc_argv_modes_new(core->rcmd, root_cd, "?*", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_help_search_handler, &cmd_help_search_help);
rz_warn_if_fail(cmd_help_search_cd);

View file

@ -193,8 +193,6 @@ RZ_IPI RzCmdStatus rz_remote_open_handler(RzCore *core, int argc, const char **a
RZ_IPI RzCmdStatus rz_remote_mode_enable_handler(RzCore *core, int argc, const char **argv);
// "R=!"
RZ_IPI RzCmdStatus rz_remote_mode_disable_handler(RzCore *core, int argc, const char **argv);
// "Rr"
RZ_IPI RzCmdStatus rz_remote_rap_handler(RzCore *core, int argc, const char **argv);
// "Rg"
RZ_IPI RzCmdStatus rz_remote_gdb_handler(RzCore *core, int argc, const char **argv);
// "Rg!"
@ -207,8 +205,6 @@ RZ_IPI RzCmdStatus rz_remote_webserver_restart_fg_handler(RzCore *core, int argc
RZ_IPI RzCmdStatus rz_remote_webserver_stop_fg_handler(RzCore *core, int argc, const char **argv);
// "Rt"
RZ_IPI RzCmdStatus rz_remote_tcp_handler(RzCore *core, int argc, const char **argv);
// "R&r"
RZ_IPI RzCmdStatus rz_remote_rap_bg_handler(RzCore *core, int argc, const char **argv);
// "?*"
RZ_IPI RzCmdStatus rz_cmd_help_search_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
// "%"

View file

@ -59,15 +59,6 @@ commands:
cname: remote_mode_disable
summary: Disable remote cmd mode
args: []
- name: "Rr"
cname: remote_rap
summary: Start the rap server (o rap://9999) / Execute <cmd> on rap server
args:
- name: "[host:]port"
type: RZ_CMD_ARG_TYPE_STRING
- name: cmd
type: RZ_CMD_ARG_TYPE_CMD
optional: true
- name: Rg
summary: Start the gdbserver
subcommands:
@ -123,9 +114,3 @@ commands:
- name: cmd
type: RZ_CMD_ARG_TYPE_CMD
optional: true
- name: "R&r"
cname: remote_rap_bg
summary: Start rap server in background (same as '& Rr')
args:
- name: port
type: RZ_CMD_ARG_TYPE_NUM

View file

@ -1980,272 +1980,6 @@ RZ_API RzAnalysisOp *rz_core_op_analysis(RzCore *core, ut64 addr, RzAnalysisOpMa
return op;
}
typedef struct {
RzSocket *fd;
RzSocket *client;
bool listener;
} RzIORap;
static void rap_break(void *u) {
RzIORap *rior = (RzIORap *)u;
if (u) {
rz_socket_close(rior->fd);
rior->fd = NULL;
}
}
// TODO: PLEASE move into core/io/rap? */
// TODO: use static buffer instead of mallocs all the time. it's network!
RZ_API bool rz_core_serve(RzCore *core, RzIODesc *file) {
// TODO: use rz_socket_rap_server API instead of duplicating the logic
ut8 cmd, flg, *ptr = NULL, buf[1024];
int i, pipefd = -1;
ut64 x;
RzIORap *rior = (RzIORap *)file->data;
if (!rior || !rior->fd) {
RZ_LOG_ERROR("core: rap: cannot listen.\n");
return false;
}
RzSocket *fd = rior->fd;
RZ_LOG_WARN("RAP Server started (rap.loop=%s)\n",
rz_config_get(core->config, "rap.loop"));
rz_cons_break_push(rap_break, rior);
reaccept:
while (!rz_cons_is_breaked()) {
RzSocket *c = rz_socket_accept(fd);
if (!c) {
break;
}
if (rz_cons_is_breaked()) {
goto out_of_function;
}
if (!c) {
RZ_LOG_ERROR("core: rap: cannot accept\n");
rz_socket_free(c);
goto out_of_function;
}
RZ_LOG_INFO("core: rap: client connected\n");
for (; !rz_cons_is_breaked();) {
if (!rz_socket_read_block(c, &cmd, 1)) {
RZ_LOG_ERROR("core: rap: connection closed\n");
if (rz_config_get_i(core->config, "rap.loop")) {
RZ_LOG_INFO("core: rap: waiting for new connection\n");
rz_socket_free(c);
goto reaccept;
}
goto out_of_function;
}
switch (cmd) {
case RAP_PACKET_OPEN:
rz_socket_read_block(c, &flg, 1); // flags
RZ_LOG_DEBUG("open (%d): \n", cmd);
rz_socket_read_block(c, &cmd, 1); // len
pipefd = -1;
if (UT8_ADD_OVFCHK(cmd, 1)) {
goto out_of_function;
}
ptr = malloc((size_t)cmd + 1);
if (!ptr) {
RZ_LOG_ERROR("core: rap: cannot malloc in rmt-open len = %d\n", cmd);
} else {
ut64 baddr = rz_config_get_i(core->config, "bin.laddr");
rz_socket_read_block(c, ptr, cmd);
ptr[cmd] = 0;
ut32 perm = RZ_PERM_R;
if (flg & RZ_PERM_W) {
perm |= RZ_PERM_W;
}
if (rz_core_file_open(core, (const char *)ptr, perm, 0)) {
int fd = rz_io_fd_get_current(core->io);
rz_core_bin_load(core, NULL, baddr);
rz_io_map_add(core->io, fd, perm, 0, 0, rz_io_fd_size(core->io, fd));
if (core->file) {
pipefd = fd;
} else {
pipefd = -1;
}
RZ_LOG_DEBUG("(flags: %d) len: %d filename: '%s'\n",
flg, cmd, ptr); // config.file);
} else {
RZ_LOG_ERROR("core: rap: cannot open file (%s)\n", ptr);
rz_socket_close(c);
if (rz_config_get_i(core->config, "rap.loop")) {
RZ_LOG_INFO("core: rap: waiting for new connection\n");
rz_socket_free(c);
goto reaccept;
}
goto out_of_function; // XXX: Close connection and goto accept
}
}
buf[0] = RAP_PACKET_OPEN | RAP_PACKET_REPLY;
rz_write_be32(buf + 1, pipefd);
rz_socket_write(c, buf, 5);
rz_socket_flush(c);
RZ_FREE(ptr);
break;
case RAP_PACKET_READ:
rz_socket_read_block(c, (ut8 *)&buf, 4);
i = rz_read_be32(buf);
ptr = (ut8 *)malloc(i + core->blocksize + 5);
if (ptr) {
rz_core_block_read(core);
ptr[0] = RAP_PACKET_READ | RAP_PACKET_REPLY;
if (i > RAP_PACKET_MAX) {
i = RAP_PACKET_MAX;
}
if (i > core->blocksize) {
rz_core_block_size(core, i);
}
if (i + 128 < core->blocksize) {
rz_core_block_size(core, i);
}
rz_write_be32(ptr + 1, i);
memcpy(ptr + 5, core->block, i); // core->blocksize);
rz_socket_write(c, ptr, i + 5);
rz_socket_flush(c);
RZ_FREE(ptr);
} else {
RZ_LOG_ERROR("core: rap: cannot read %d byte(s)\n", i);
rz_socket_free(c);
// TODO: reply error here
goto out_of_function;
}
break;
case RAP_PACKET_CMD: {
char *cmd = NULL, *cmd_output = NULL;
char bufr[8], *bufw = NULL;
ut32 cmd_len = 0;
int i;
/* read */
rz_socket_read_block(c, (ut8 *)&bufr, 4);
i = rz_read_be32(bufr);
if (i > 0 && i < RAP_PACKET_MAX) {
if ((cmd = malloc(i + 1))) {
rz_socket_read_block(c, (ut8 *)cmd, i);
cmd[i] = '\0';
int scr_interactive = rz_config_get_i(core->config, "scr.interactive");
rz_config_set_i(core->config, "scr.interactive", 0);
cmd_output = rz_core_cmd_str(core, cmd);
rz_config_set_i(core->config, "scr.interactive", scr_interactive);
free(cmd);
} else {
RZ_LOG_ERROR("core: rap: cannot allocate %u bytes\n", (i + 1));
}
} else {
RZ_LOG_ERROR("core: rap: invalid length '%u'\n", i);
}
/* write */
if (cmd_output) {
cmd_len = strlen(cmd_output) + 1;
} else {
cmd_output = rz_str_dup("");
cmd_len = 0;
}
bufw = malloc(cmd_len + 5);
bufw[0] = (ut8)(RAP_PACKET_CMD | RAP_PACKET_REPLY);
rz_write_be32(bufw + 1, cmd_len);
memcpy(bufw + 5, cmd_output, cmd_len);
rz_socket_write(c, bufw, cmd_len + 5);
rz_socket_flush(c);
free(bufw);
free(cmd_output);
break;
}
case RAP_PACKET_WRITE:
rz_socket_read_block(c, buf, 4);
x = rz_read_at_be32(buf, 0);
ptr = malloc(x);
rz_socket_read_block(c, ptr, x);
int ret = rz_core_write_at(core, core->offset, ptr, x);
buf[0] = RAP_PACKET_WRITE | RAP_PACKET_REPLY;
rz_write_be32(buf + 1, ret);
rz_socket_write(c, buf, 5);
rz_socket_flush(c);
RZ_FREE(ptr);
break;
case RAP_PACKET_SEEK:
rz_socket_read_block(c, buf, 9);
x = rz_read_at_be64(buf, 1);
if (buf[0] == 2) {
if (core->file) {
x = rz_io_fd_size(core->io, core->file->fd);
} else {
x = 0;
}
} else {
if (buf[0] == 0) {
rz_core_seek(core, x, true); // buf[0]);
}
x = core->offset;
}
buf[0] = RAP_PACKET_SEEK | RAP_PACKET_REPLY;
rz_write_be64(buf + 1, x);
rz_socket_write(c, buf, 9);
rz_socket_flush(c);
break;
case RAP_PACKET_CLOSE:
// XXX : proper shutdown
rz_socket_read_block(c, buf, 4);
i = rz_read_be32(buf);
{
// FIXME: Use rz_socket_close
int ret = close(i);
rz_write_be32(buf + 1, ret);
buf[0] = RAP_PACKET_CLOSE | RAP_PACKET_REPLY;
rz_socket_write(c, buf, 5);
rz_socket_flush(c);
}
break;
default:
if (cmd == 'G') {
// silly http emulation over rap://
char line[256] = { 0 };
rz_socket_read_block(c, (ut8 *)line, sizeof(line));
if (!strncmp(line, "ET /cmd/", 8)) {
char *cmd = line + 8;
char *http = strstr(cmd, "HTTP");
if (http) {
*http = 0;
http--;
if (*http == ' ') {
*http = 0;
}
}
rz_str_uri_decode(cmd);
char *res = rz_core_cmd_str(core, cmd);
if (res) {
rz_socket_printf(c, "HTTP/1.0 %d %s\r\n%s"
"Connection: close\r\nContent-Length: %d\r\n\r\n",
200, "OK", "", -1); // strlen (res));
rz_socket_write(c, res, strlen(res));
free(res);
}
rz_socket_flush(c);
rz_socket_close(c);
}
} else {
RZ_LOG_ERROR("core: rap: unknown command 0x%02x\n", cmd);
rz_socket_close(c);
RZ_FREE(ptr);
}
if (rz_config_get_i(core->config, "rap.loop")) {
RZ_LOG_INFO("core: rap: waiting for new connection\n");
rz_socket_free(c);
goto reaccept;
}
goto out_of_function;
}
}
RZ_LOG_INFO("core: rap: client disconnected\n");
rz_socket_free(c);
}
out_of_function:
rz_cons_break_pop();
return false;
}
RZ_API int rz_core_search_cb(RzCore *core, ut64 from, ut64 to, RzCoreSearchCallback cb) {
int ret, len = core->blocksize;
ut8 *buf = malloc(len);

View file

@ -519,9 +519,6 @@ RZ_API void rz_core_rtr_pushout(RzCore *core, const char *input) {
}
switch (rtr_host[rtr_n].proto) {
case RTR_PROTOCOL_RAP:
RZ_LOG_ERROR("core: Cannot use '=<' to a rap connection.\n");
break;
case RTR_PROTOCOL_UNIX:
rz_socket_write(rtr_host[rtr_n].fd, str, strlen(str));
break;
@ -545,12 +542,11 @@ RZ_API void rz_core_rtr_list(RzCore *core) {
if (!rtr_host[i].fd) {
continue;
}
const char *proto = "rap";
const char *proto = "http";
switch (rtr_host[i].proto) {
case RTR_PROTOCOL_HTTP: proto = "http"; break;
case RTR_PROTOCOL_TCP: proto = "tcp"; break;
case RTR_PROTOCOL_UDP: proto = "udp"; break;
case RTR_PROTOCOL_RAP: proto = "rap"; break;
case RTR_PROTOCOL_UNIX: proto = "unix"; break;
}
rz_cons_printf("%d fd:%i %s://%s:%i/%s\n",
@ -568,7 +564,7 @@ RZ_API void rz_core_rtr_add(RzCore *core, const char *_input) {
strncpy(input, _input, sizeof(input) - 4);
input[sizeof(input) - 4] = '\0';
int proto = RTR_PROTOCOL_RAP;
int proto = RTR_PROTOCOL_HTTP;
char *host = (char *)rz_str_trim_head_ro(input);
char *pikaboo = strstr(host, "://");
if (pikaboo) {
@ -578,8 +574,6 @@ RZ_API void rz_core_rtr_add(RzCore *core, const char *_input) {
} uris[7] = {
{ "tcp", RTR_PROTOCOL_TCP },
{ "udp", RTR_PROTOCOL_UDP },
{ "rap", RTR_PROTOCOL_RAP },
{ "r2p", RTR_PROTOCOL_RAP },
{ "http", RTR_PROTOCOL_HTTP },
{ "unix", RTR_PROTOCOL_UNIX },
{ NULL, 0 }
@ -639,16 +633,6 @@ RZ_API void rz_core_rtr_add(RzCore *core, const char *_input) {
// eprintf ("Connected to: 'http://%s:%s'\n", host, port);
free(str);
} break;
case RTR_PROTOCOL_RAP:
if (!rz_socket_connect_tcp(fd, host, port, timeout)) { // TODO: Use rap.ssl
RZ_LOG_ERROR("core: Cannot connect to '%s' (%s)\n", host, port);
rz_socket_free(fd);
return;
} else {
int n = rz_socket_rap_client_open(fd, file, 0);
RZ_LOG_INFO("core: opened as fd = %d\n", n);
}
break;
case RTR_PROTOCOL_UNIX:
if (!rz_socket_connect_unix(fd, host)) {
core->num->value = 1;
@ -659,7 +643,7 @@ RZ_API void rz_core_rtr_add(RzCore *core, const char *_input) {
RZ_LOG_INFO("core: Connected to: 'unix://%s'\n", host);
break;
case RTR_PROTOCOL_TCP:
if (!rz_socket_connect_tcp(fd, host, port, timeout)) { // TODO: Use rap.ssl
if (!rz_socket_connect_tcp(fd, host, port, timeout)) {
core->num->value = 1;
RZ_LOG_ERROR("core: Cannot connect to '%s' (%s)\n", host, port);
rz_socket_free(fd);
@ -669,7 +653,7 @@ RZ_API void rz_core_rtr_add(RzCore *core, const char *_input) {
RZ_LOG_INFO("core: Connected to: %s at port %s\n", host, port);
break;
case RTR_PROTOCOL_UDP:
if (!rz_socket_connect_udp(fd, host, port, timeout)) { // TODO: Use rap.ssl
if (!rz_socket_connect_udp(fd, host, port, timeout)) {
core->num->value = 1;
RZ_LOG_ERROR("core: Cannot connect to '%s' (%s)\n", host, port);
rz_socket_free(fd);
@ -725,38 +709,6 @@ RZ_API void rz_core_rtr_session(RzCore *core, const char *input) {
__rtr_shell(core, atoi(input));
}
static bool rz_core_rtr_rap_run(RzCore *core, const char *input) {
char *file = rz_str_newf("rap://%s", input);
int flags = RZ_PERM_RW;
RzIODesc *fd = rz_io_open_nomap(core->io, file, flags, 0644);
if (fd) {
if (rz_io_is_listener(core->io)) {
if (!rz_core_serve(core, fd)) {
rz_cons_singleton()->context->breaked = true;
}
rz_io_desc_close(fd);
// avoid double free, we are not the owners of this fd so we can't destroy it
// rz_io_desc_free (fd);
}
} else {
rz_cons_singleton()->context->breaked = true;
}
return !rz_cons_singleton()->context->breaked;
// rz_core_cmdf (core, "o rap://%s", input);
}
static void *rz_core_rtr_rap_thread(RapThread *rt) {
if (!rt || !rt->core) {
return false;
}
bool loop = true;
while (loop) {
loop = rz_atomic_bool_get(rt->loop) &&
rz_core_rtr_rap_run(rt->core, rt->input);
}
return NULL;
}
RZ_API void rz_core_rtr_cmd(RzCore *core, const char *input) {
unsigned int cmd_len = 0;
char tmpbuf[8];
@ -769,45 +721,6 @@ RZ_API void rz_core_rtr_cmd(RzCore *core, const char *input) {
cmd++;
cmd_len = strlen(cmd);
}
// "=:"
if (*input == ':' && !strchr(input + 1, ':')) {
void *bed = rz_cons_sleep_begin();
rz_core_rtr_rap_run(core, input);
rz_cons_sleep_end(bed);
return;
}
if (*input == '&') { // "Rh&" "R&:9090"
if (rapthread) {
RZ_LOG_ERROR("core: RAP thread is already running\n");
RZ_LOG_WARN("core: This is experimental and probably buggy. Use at your own risk\n");
} else {
// TODO: use tasks
RapThread *rap_th = RZ_NEW0(RapThread);
if (!rap_th) {
RZ_LOG_ERROR("cannot allocate RapThread\n");
return;
}
rap_th->core = core;
rap_th->input = rz_str_dup(input + 1);
rap_th->loop = rz_atomic_bool_new(true);
rapthread = rz_th_new((RzThreadFunction)rz_core_rtr_rap_thread, rap_th);
if (!rap_th) {
RZ_LOG_ERROR("cannot spawn the RzThread\n");
return;
}
int cpuaff = (int)rz_config_get_i(core->config, "cfg.cpuaffinity");
if (cpuaff) {
// modify the affinity only when the flag is actually set.
rz_th_set_affinity(rapthread, cpuaff);
}
rz_th_set_name(rapthread, "rapthread");
RZ_LOG_WARN("Background rap server started.\n");
}
return;
}
if (fd != -1) {
if (fd >= 0 && fd < RTR_MAX_HOSTS) {
rtr_n = fd;
@ -873,20 +786,6 @@ RZ_API void rz_core_rtr_cmd(RzCore *core, const char *input) {
return;
}
if (rtr_host[rtr_n].proto == RTR_PROTOCOL_RAP) {
core->num->value = 0; // that's fine
cmd = rz_str_trim_head_ro(cmd);
RzSocket *fh = rtr_host[rtr_n].fd;
if (!strlen(cmd)) {
// just check if we can connect
rz_socket_close(fh);
return;
}
char *cmd_output = rz_socket_rap_client_command(fh, cmd, &core->analysis->coreb);
rz_cons_println(cmd_output);
free(cmd_output);
return;
}
RZ_LOG_ERROR("core: unknown protocol\n");
}

View file

@ -5,7 +5,6 @@ debug_plugins_list = [
'gdb',
'io',
'null',
'rap',
'winkd',
]
@ -43,7 +42,6 @@ rz_debug_sources = [
'p/debug_gdb.c',
'p/debug_io.c',
'p/debug_null.c',
'p/debug_rap.c',
'p/debug_winkd.c',
#'p/native/arm.c',
#'p/native/bt/fuzzy-all.c',

View file

@ -1,96 +0,0 @@
// SPDX-FileCopyrightText: 2011-2019 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_cons.h>
#include <rz_debug.h>
static bool __rap_step(RzDebug *dbg) {
rz_io_system(dbg->iob.io, "ds");
return true;
}
static int __rap_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
rz_io_system(dbg->iob.io, "dr");
return 0;
}
static int __rap_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
return false; // XXX Error check
}
static int __rap_continue(RzDebug *dbg, int pid, int tid, int sig) {
rz_io_system(dbg->iob.io, "dc");
return true;
}
static RzDebugReasonType __rap_wait(RzDebug *dbg, int pid) {
/* do nothing */
return RZ_DEBUG_REASON_NONE;
}
static int __rap_attach(RzDebug *dbg, int pid) {
// XXX TODO PID must be a socket here !!1
RzIODesc *d = dbg->iob.io->desc;
if (d && d->plugin && d->plugin->name) {
if (!strcmp("rap", d->plugin->name)) {
eprintf("SUCCESS: rap attach with inferior rap rio worked\n");
} else {
eprintf("ERROR: Underlying IO descriptor is not a rap one..\n");
}
}
return true;
}
static int __rap_detach(RzDebug *dbg, int pid) {
// XXX TODO PID must be a socket here !!1
// close (pid);
// XXX Maybe we should continue here?
return true;
}
static char *__rap_reg_profile(RzDebug *dbg) {
char *out, *tf = rz_file_temp("rap.XXXXXX");
RzConsPipe *cpipe = rz_cons_pipe_open(tf, 1, 0);
if (!cpipe) {
rz_file_rm(tf);
return NULL;
}
rz_io_system(dbg->iob.io, "drp");
rz_cons_flush();
rz_cons_pipe_close(cpipe);
out = rz_file_slurp(tf, NULL);
rz_file_rm(tf);
free(tf);
return out;
}
static int __rap_breakpoint(RzBreakpoint *bp, RzBreakpointItem *b, bool set) {
// rz_io_system (dbg->iob.io, "db");
return false;
}
RzDebugPlugin rz_debug_plugin_rap = {
.name = "rap",
.license = "LGPL3",
.arch = "any",
.bits = RZ_SYS_BITS_32,
.step = __rap_step,
.cont = __rap_continue,
.attach = &__rap_attach,
.detach = &__rap_detach,
.wait = &__rap_wait,
.breakpoint = __rap_breakpoint,
.reg_read = &__rap_reg_read,
.reg_write = &__rap_reg_write,
.reg_profile = (void *)__rap_reg_profile,
//.bp_write = &__rap_bp_write,
//.bp_read = &__rap_bp_read,
};
#ifndef RZ_PLUGIN_INCORE
RZ_API RzLibStruct rizin_plugin = {
.type = RZ_LIB_TYPE_DBG,
.data = &rz_debug_plugin_rap,
.version = RZ_VERSION
};
#endif

View file

@ -515,7 +515,6 @@ RZ_API bool rz_core_analysis_esil_trace_start(RzCore *core);
RZ_API bool rz_core_analysis_esil_trace_stop(RzCore *core);
RZ_API int rz_core_search_cb(RzCore *core, ut64 from, ut64 to, RzCoreSearchCallback cb);
RZ_API bool rz_core_serve(RzCore *core, RzIODesc *fd);
RZ_API bool rz_core_file_reopen(RzCore *core, const char *args, int perm, int binload);
RZ_API void rz_core_file_reopen_in_malloc(RzCore *core);
RZ_API void rz_core_file_reopen_debug(RzCore *core, const char *args);

View file

@ -180,53 +180,6 @@ RZ_API void rz_socket_http_response(RzSocketHTTPRequest *rs, int code, const cha
RZ_API void rz_socket_http_close(RzSocketHTTPRequest *rs);
RZ_API ut8 *rz_socket_http_handle_upload(const ut8 *str, int len, int *olen);
typedef int (*rap_server_open)(void *user, const char *file, int flg, int mode);
typedef int (*rap_server_seek)(void *user, ut64 offset, int whence);
typedef int (*rap_server_read)(void *user, ut8 *buf, int len);
typedef int (*rap_server_write)(void *user, ut8 *buf, int len);
typedef char *(*rap_server_cmd)(void *user, const char *command);
typedef int (*rap_server_close)(void *user, int fd);
enum {
RAP_PACKET_OPEN = 1,
RAP_PACKET_READ = 2,
RAP_PACKET_WRITE = 3,
RAP_PACKET_SEEK = 4,
RAP_PACKET_CLOSE = 5,
// system was deprecated in slot 6,
RAP_PACKET_CMD = 7,
RAP_PACKET_REPLY = 0x80,
RAP_PACKET_MAX = 4096
};
typedef struct rz_socket_rap_server_t {
RzSocket *fd;
char *port;
ut8 buf[RAP_PACKET_MAX + 32]; // This should be used as a static buffer for everything done by the server
rap_server_open open;
rap_server_seek seek;
rap_server_read read;
rap_server_write write;
rap_server_cmd system;
rap_server_cmd cmd;
rap_server_close close;
void *user; // Always first arg for callbacks
} RzSocketRapServer;
RZ_API RzSocketRapServer *rz_socket_rap_server_new(bool is_ssl, const char *port);
RZ_API RzSocketRapServer *rz_socket_rap_server_create(const char *pathname);
RZ_API void rz_socket_rap_server_free(RzSocketRapServer *rap_s);
RZ_API bool rz_socket_rap_server_listen(RzSocketRapServer *rap_s, const char *certfile);
RZ_API RzSocket *rz_socket_rap_server_accept(RzSocketRapServer *rap_s);
RZ_API bool rz_socket_rap_server_continue(RzSocketRapServer *rap_s);
/* rap client */
RZ_API int rz_socket_rap_client_open(RzSocket *s, const char *file, int rw);
RZ_API char *rz_socket_rap_client_command(RzSocket *s, const char *cmd, RzCoreBind *c);
RZ_API int rz_socket_rap_client_write(RzSocket *s, const ut8 *buf, int count);
RZ_API int rz_socket_rap_client_read(RzSocket *s, ut8 *buf, int count);
RZ_API int rz_socket_rap_client_seek(RzSocket *s, ut64 offset, int whence);
/* run.c */
#define RZ_RUN_PROFILE_NARGS 512
typedef struct rz_run_profile_t {

View file

@ -18,7 +18,6 @@ io_plugins_list = [
'ptrace',
'rzpipe',
'rzweb',
'rap',
'self',
'shm',
'sparse',
@ -75,7 +74,6 @@ rz_io_sources = [
'p/io_ptrace.c',
'p/io_rzpipe.c',
'p/io_rzweb.c',
'p/io_rap.c',
'p/io_self.c',
'p/io_shm.c',
'p/io_sparse.c',

View file

@ -1,303 +0,0 @@
// SPDX-FileCopyrightText: 2011-2020 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: MIT
#include <rz_io.h>
#include <rz_lib.h>
#include <rz_core.h>
#include <rz_socket.h>
#include <sys/types.h>
#include "rz_io_plugins.h"
typedef struct {
RzSocket *fd;
RzSocket *client;
bool listener;
} RzIORap;
#define RzIORAP_FD(x) (((x)->data) ? (((RzIORap *)((x)->data))->client) : NULL)
#define RzIORAP_IS_LISTEN(x) (((RzIORap *)((x)->data))->listener)
#define RzIORAP_IS_VALID(x) ((x) && ((x)->data) && ((x)->plugin == &rz_io_plugin_rap))
static int __rap_write(RzIO *io, RzIODesc *fd, const ut8 *buf, size_t count) {
RzSocket *s = RzIORAP_FD(fd);
return rz_socket_rap_client_write(s, buf, count);
}
static bool __rap_accept(RzIO *io, RzIODesc *desc, int fd) {
RzIORap *rap = desc ? desc->data : NULL;
if (rap && fd != -1) {
rap->client = rz_socket_new_from_fd(fd);
return true;
}
return false;
}
static int __rap_read(RzIO *io, RzIODesc *fd, ut8 *buf, size_t count) {
RzSocket *s = RzIORAP_FD(fd);
return rz_socket_rap_client_read(s, buf, count);
}
static int __rap_close(RzIODesc *fd) {
int ret = -1;
if (RzIORAP_IS_VALID(fd)) {
if (RzIORAP_FD(fd) != NULL) {
RzIORap *r = fd->data;
if (r && fd->fd != -1) {
if (r->fd) {
(void)rz_socket_close(r->fd);
}
if (r->client) {
ret = rz_socket_close(r->client);
}
RZ_FREE(r);
}
}
} else {
eprintf("__rap_close: fdesc is not a rz_io_rap plugin\n");
}
return ret;
}
static ut64 __rap_lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
RzSocket *s = RzIORAP_FD(fd);
return rz_socket_rap_client_seek(s, offset, whence);
}
static bool __rap_plugin_open(RzIO *io, const char *pathname, bool many) {
return rz_str_startswith(pathname, "rap://") || rz_str_startswith(pathname, "raps://");
}
static RzIODesc *__rap_open(RzIO *io, const char *pathname, int rw, int mode) {
int i, p, listenmode;
char *file, *port;
if (!__rap_plugin_open(io, pathname, 0)) {
return NULL;
}
bool is_ssl = (!strncmp(pathname, "raps://", 7));
const char *host = pathname + (is_ssl ? 7 : 6);
if (!(port = strchr(host, ':'))) {
eprintf("rap: wrong uri\n");
return NULL;
}
listenmode = (*host == ':');
*port++ = 0;
if (!*port) {
return NULL;
}
p = atoi(port);
if ((file = strchr(port + 1, '/'))) {
*file = 0;
file++;
}
if (listenmode) {
if (p <= 0) {
eprintf("rap: cannot listen here. Try rap://:9999\n");
return NULL;
}
// TODO: Handle ^C signal (SIGINT, exit); // ???
eprintf("rap: listening at port %s ssl %s\n", port, (is_ssl) ? "on" : "off");
RzIORap *rior = RZ_NEW0(RzIORap);
rior->listener = true;
rior->client = rior->fd = rz_socket_new(is_ssl);
if (!rior->fd) {
free(rior);
return NULL;
}
if (is_ssl) {
if (file && *file) {
if (!rz_socket_listen(rior->fd, port, file)) {
rz_socket_free(rior->fd);
free(rior);
return NULL;
}
} else {
free(rior);
return NULL;
}
} else {
if (!rz_socket_listen(rior->fd, port, NULL)) {
rz_socket_free(rior->fd);
free(rior);
return NULL;
}
}
return rz_io_desc_new(io, &rz_io_plugin_rap,
pathname, rw, mode, rior);
}
RzSocket *s = rz_socket_new(is_ssl);
if (!s) {
eprintf("Cannot create new socket\n");
return NULL;
}
eprintf("Connecting to %s, port %s\n", host, port);
if (!rz_socket_connect(s, host, port, RZ_SOCKET_PROTO_TCP, 0)) {
eprintf("Cannot connect to '%s' (%d)\n", host, p);
rz_socket_free(s);
return NULL;
}
eprintf("Connected to: %s at port %s\n", host, port);
RzIORap *rior = RZ_NEW0(RzIORap);
if (!rior) {
rz_socket_free(s);
return NULL;
}
rior->listener = false;
rior->client = rior->fd = s;
if (file && *file) {
i = rz_socket_rap_client_open(s, file, rw);
if (i == -1) {
free(rior);
rz_socket_free(s);
return NULL;
}
if (i > 0) {
eprintf("rap connection was successful. open %d\n", i);
// io->corebind.cmd (io->corebind.core, "e io.va=0");
io->corebind.cmd(io->corebind.core, ".R!i*");
io->corebind.cmd(io->corebind.core, ".R!f*");
io->corebind.cmd(io->corebind.core, ".R!om*");
}
}
return rz_io_desc_new(io, &rz_io_plugin_rap,
pathname, rw, mode, rior);
}
static int __rap_listener(RzIODesc *fd) {
return (RzIORAP_IS_VALID(fd)) ? RzIORAP_IS_LISTEN(fd) : 0; // -1 ?
}
static char *__rap_system(RzIO *io, RzIODesc *fd, const char *command) {
RzSocket *s = RzIORAP_FD(fd);
// TODO: bind core into RzSocket instead of pass the one from io?
return rz_socket_rap_client_command(s, command, &io->corebind);
#if 0
int ret, reslen = 0, cmdlen = 0;
unsigned int i;
char *ptr, *res, *str;
ut8 buf[RMT_MAX];
buf[0] = RMT_CMD;
i = strlen (command) + 1;
if (i > RMT_MAX - 5) {
eprintf ("Command too long\n");
return NULL;
}
rz_write_be32 (buf + 1, i);
memcpy (buf + 5, command, i);
(void)rz_socket_write (s, buf, i+5);
rz_socket_flush (s);
/* read reverse cmds */
for (;;) {
ret = rz_socket_read_block (s, buf, 1);
if (ret != 1) {
return NULL;
}
/* system back in the middle */
/* TODO: all pkt handlers should check for reverse queries */
if (buf[0] != RMT_CMD) {
break;
}
// run io->cmdstr
// return back the string
buf[0] |= RMT_REPLY;
memset (buf + 1, 0, 4);
ret = rz_socket_read_block (s, buf + 1, 4);
if (ret != 4) {
return NULL;
}
cmdlen = rz_read_at_be32 (buf, 1);
if (cmdlen + 1 == 0) { // check overflow
cmdlen = 0;
}
str = calloc (1, cmdlen + 1);
ret = rz_socket_read_block (s, (ut8*)str, cmdlen);
eprintf ("RUN %d CMD(%s)\n", ret, str);
if (str && *str) {
res = io->cb_core_cmdstr (io->user, str);
} else {
res = rz_str_dup ("");
}
eprintf ("[%s]=>(%s)\n", str, res);
reslen = strlen (res);
free (str);
rz_write_be32 (buf + 1, reslen);
memcpy (buf + 5, res, reslen);
free (res);
(void)rz_socket_write (s, buf, reslen + 5);
rz_socket_flush (s);
}
// read
ret = rz_socket_read_block (s, buf + 1, 4);
if (ret != 4) {
return NULL;
}
if (buf[0] != (RMT_CMD | RMT_REPLY)) {
eprintf ("Unexpected rap cmd reply\n");
return NULL;
}
i = rz_read_at_be32 (buf, 1);
ret = 0;
if (i > ST32_MAX) {
eprintf ("Invalid length\n");
return NULL;
}
ptr = (char *)calloc (1, i + 1);
if (ptr) {
int ir, tr = 0;
do {
ir = rz_socket_read_block (s, (ut8*)ptr + tr, i - tr);
if (ir < 1) {
break;
}
tr += ir;
} while (tr < i);
// TODO: use io->cb_printf() with support for \x00
ptr[i] = 0;
if (io->cb_printf) {
io->cb_printf ("%s", ptr);
} else {
if (write (1, ptr, i) != i) {
eprintf ("Failed to write\n");
}
}
free (ptr);
}
#if DEAD_CODE
/* Clean */
if (ret > 0) {
ret -= rz_socket_read (s, (ut8*)buf, RMT_MAX);
}
#endif
#endif
return NULL;
}
RzIOPlugin rz_io_plugin_rap = {
.name = "rap",
.desc = "Remote binary protocol plugin",
.uris = "rap://,raps://",
.license = "MIT",
.listener = __rap_listener,
.open = __rap_open,
.close = __rap_close,
.read = __rap_read,
.check = __rap_plugin_open,
.lseek = __rap_lseek,
.system = __rap_system,
.write = __rap_write,
.accept = __rap_accept,
};
#ifndef RZ_PLUGIN_INCORE
RZ_API RzLibStruct rizin_plugin = {
.type = RZ_LIB_TYPE_IO,
.data = &rz_io_plugin_rap,
.version = RZ_VERSION
};
#endif

View file

@ -5,8 +5,6 @@ rz_socket_sources = [
'socket_serial.c',
'socket_proc.c',
'rzpipe.c',
'socket_rap_client.c',
'socket_rap_server.c',
'run.c',
]

View file

@ -1,200 +0,0 @@
// SPDX-FileCopyrightText: 2011-2020 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_socket.h>
#include <rz_util.h>
static ut8 *rz_rap_packet(ut8 type, ut32 len) {
ut8 *buf = malloc(len + 5);
if (buf) {
buf[0] = type;
rz_write_be32(buf + 1, len);
}
return buf;
}
static void rz_rap_packet_fill(ut8 *buf, const ut8 *src, int len) {
if (buf && src && len > 0) {
ut32 curlen = rz_read_be32(buf + 1);
memcpy(buf + 5, src, RZ_MIN(curlen, len));
}
}
RZ_API int rz_socket_rap_client_open(RzSocket *s, const char *file, int rw) {
rz_socket_block_time(s, true, 1, 0);
size_t file_len0 = strlen(file) + 1;
if (file_len0 > 255) {
eprintf("Filename too long\n");
return -1;
}
char *buf = malloc(file_len0 + 7);
if (!buf) {
return -1;
}
// >>
buf[0] = RAP_PACKET_OPEN;
buf[1] = rw;
buf[2] = (ut8)(file_len0 & 0xff);
memcpy(buf + 3, file, file_len0);
(void)rz_socket_write(s, buf, 3 + file_len0);
rz_socket_flush(s);
// <<
int fd = -1;
memset(buf, 0, 5);
int r = rz_socket_read_block(s, (ut8 *)buf, 5);
if (r == 5) {
if (buf[0] == (char)(RAP_PACKET_OPEN | RAP_PACKET_REPLY)) {
fd = rz_read_at_be32(buf + 1, 1);
} else {
eprintf("RapClientOpen: Bad packet 0x%02x\n", buf[0]);
}
} else {
eprintf("Cannot read 5 bytes from server\n");
}
free(buf);
return fd;
}
RZ_API char *rz_socket_rap_client_command(RzSocket *s, const char *cmd, RzCoreBind *c) {
char *buf = malloc(strlen(cmd) + 8);
if (!buf) {
return NULL;
}
/* send request */
buf[0] = RAP_PACKET_CMD;
size_t i = strlen(cmd) + 1;
rz_write_be32(buf + 1, i);
memcpy(buf + 5, cmd, i);
rz_socket_write(s, buf, 5 + i);
rz_socket_flush(s);
free(buf);
/* read response */
char bufr[8];
rz_socket_read_block(s, (ut8 *)bufr, 5);
while (bufr[0] == (char)(RAP_PACKET_CMD)) {
size_t cmd_len = rz_read_at_be32(bufr, 1);
char *rcmd = calloc(1, cmd_len + 1);
if (rcmd) {
rz_socket_read_block(s, (ut8 *)rcmd, cmd_len);
// char *res = rz_core_cmd_str (core, rcmd);
char *res = c->cmdstr(c->core, rcmd);
if (res) {
int res_len = strlen(res) + 1;
ut8 *pkt = rz_rap_packet((RAP_PACKET_CMD | RAP_PACKET_REPLY), res_len);
rz_rap_packet_fill(pkt, (const ut8 *)res, res_len);
rz_socket_write(s, pkt, 5 + res_len);
rz_socket_flush(s);
free(res);
free(pkt);
}
free(rcmd);
}
/* read response */
bufr[0] = -1;
(void)rz_socket_read_block(s, (ut8 *)bufr, 5);
}
if (bufr[0] != (char)(RAP_PACKET_CMD | RAP_PACKET_REPLY)) {
eprintf("Error: Wrong reply for command 0x%02x\n", bufr[0]);
return NULL;
}
size_t cmd_len = rz_read_at_be32(bufr, 1);
if (cmd_len < 1 || cmd_len > 16384) {
eprintf("Error: cmd_len is wrong\n");
return NULL;
}
char *cmd_output = calloc(1, cmd_len + 1);
if (!cmd_output) {
eprintf("Error: Allocating cmd output\n");
return NULL;
}
rz_socket_read_block(s, (ut8 *)cmd_output, cmd_len);
// ensure the termination
cmd_output[cmd_len] = 0;
return cmd_output;
}
RZ_API int rz_socket_rap_client_write(RzSocket *s, const ut8 *buf, int count) {
ut8 *tmp;
int ret;
if (count < 1) {
return count;
}
// TOOD: if count > RAP_PACKET_MAX iterate !
if (count > RAP_PACKET_MAX) {
count = RAP_PACKET_MAX;
}
if (!(tmp = (ut8 *)malloc(count + 5))) {
eprintf("__rap_write: malloc failed\n");
return -1;
}
tmp[0] = RAP_PACKET_WRITE;
rz_write_be32(tmp + 1, count);
memcpy(tmp + 5, buf, count);
(void)rz_socket_write(s, tmp, count + 5);
rz_socket_flush(s);
if (rz_socket_read_block(s, tmp, 5) != 5) { // TODO read_block?
eprintf("__rap_write: error\n");
ret = -1;
} else {
ret = rz_read_be32(tmp + 1);
if (!ret) {
ret = -1;
}
}
free(tmp);
return ret;
}
RZ_API int rz_socket_rap_client_read(RzSocket *s, ut8 *buf, int count) {
ut8 tmp[32];
if (count < 1) {
return count;
}
rz_socket_block_time(s, 1, 1, 0);
// XXX. if count is > RAP_PACKET_MAX, just perform multiple queries
if (count > RAP_PACKET_MAX) {
count = RAP_PACKET_MAX;
}
// send
tmp[0] = RAP_PACKET_READ;
rz_write_be32(tmp + 1, count);
(void)rz_socket_write(s, tmp, 5);
rz_socket_flush(s);
// recv
int ret = rz_socket_read_block(s, tmp, 5);
if (ret != 5 || tmp[0] != (RAP_PACKET_READ | RAP_PACKET_REPLY)) {
eprintf("__rap_read: Unexpected rap read reply "
"(%d=0x%02x) expected (%d=0x%02x)\n",
ret, tmp[0], 2, (RAP_PACKET_READ | RAP_PACKET_REPLY));
return -1;
}
int i = rz_read_at_be32(tmp, 1);
if (i > count) {
eprintf("__rap_read: Unexpected data size %d vs %d\n", i, count);
return -1;
}
rz_socket_read_block(s, buf, i);
return count;
}
RZ_API int rz_socket_rap_client_seek(RzSocket *s, ut64 offset, int whence) {
ut8 tmp[10];
tmp[0] = RAP_PACKET_SEEK;
tmp[1] = (ut8)whence;
rz_write_be64(tmp + 2, offset);
(void)rz_socket_write(s, &tmp, 10);
rz_socket_flush(s);
int ret = rz_socket_read_block(s, (ut8 *)&tmp, 9);
if (ret != 9) {
eprintf("Truncated socket read\n");
return -1;
}
if (tmp[0] != (RAP_PACKET_SEEK | RAP_PACKET_REPLY)) {
// eprintf ("%d %d - %02x %02x %02x %02x %02x %02x %02x\n",
// ret, whence, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6]);
eprintf("Unexpected seek reply (%02x -> %02x)\n", tmp[0], (RAP_PACKET_SEEK | RAP_PACKET_REPLY));
return -1;
}
return rz_read_at_be64(tmp, 1);
}

View file

@ -1,140 +0,0 @@
// SPDX-FileCopyrightText: 2014-2019 pancake <pancake@nopcode.org>
// SPDX-FileCopyrightText: 2014-2019 condret <condr3t@protonmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_socket.h>
#include <rz_util.h>
RZ_API RzSocketRapServer *rz_socket_rap_server_new(bool use_ssl, const char *port) {
rz_return_val_if_fail(port, NULL);
RzSocketRapServer *s = RZ_NEW0(RzSocketRapServer);
if (s) {
s->port = rz_str_dup(port);
s->fd = rz_socket_new(use_ssl);
if (s->fd) {
return s;
}
rz_socket_free(s->fd);
free(s);
}
return NULL;
}
RZ_API RzSocketRapServer *rz_socket_rap_server_create(const char *pathname) {
rz_return_val_if_fail(pathname, NULL);
if (strlen(pathname) < 11) {
return NULL;
}
if (strncmp(pathname, "rap", 3)) {
return NULL;
}
bool is_ssl = (pathname[3] == 's');
const char *port = &pathname[7 + is_ssl];
return rz_socket_rap_server_new(is_ssl, port);
}
RZ_API void rz_socket_rap_server_free(RzSocketRapServer *s) {
if (s) {
rz_socket_free(s->fd);
free(s);
}
}
RZ_API bool rz_socket_rap_server_listen(RzSocketRapServer *s, const char *certfile) {
rz_return_val_if_fail(s && s->port && *s->port, false);
return rz_socket_listen(s->fd, s->port, certfile);
}
RZ_API RzSocket *rz_socket_rap_server_accept(RzSocketRapServer *s) {
rz_return_val_if_fail(s && s->fd, NULL);
return rz_socket_accept(s->fd);
}
RZ_API bool rz_socket_rap_server_continue(RzSocketRapServer *s) {
rz_return_val_if_fail(s && s->fd, false);
int i;
char *ptr = NULL;
if (!rz_socket_is_connected(s->fd)) {
return false;
}
rz_socket_read_block(s->fd, s->buf, 1);
switch (s->buf[0]) {
case RAP_PACKET_OPEN:
rz_socket_read_block(s->fd, &s->buf[1], 2);
rz_socket_read_block(s->fd, &s->buf[3], (int)s->buf[2]);
{
int fd = s->open(s->user, (const char *)&s->buf[3], (int)s->buf[1], 0);
s->buf[0] = RAP_PACKET_OPEN | RAP_PACKET_REPLY;
eprintf("REPLY BACK %d\n", fd);
rz_write_be32(s->buf + 1, fd);
}
rz_socket_write(s->fd, s->buf, 5);
rz_socket_flush(s->fd);
break;
case RAP_PACKET_READ:
rz_socket_read_block(s->fd, &s->buf[1], 4);
i = rz_read_be32(&s->buf[1]);
if (i > RAP_PACKET_MAX || i < 0) {
i = RAP_PACKET_MAX;
}
s->read(s->user, &s->buf[5], i);
s->buf[0] = RAP_PACKET_READ | RAP_PACKET_REPLY;
rz_socket_write(s->fd, s->buf, i + 5);
rz_socket_flush(s->fd);
break;
case RAP_PACKET_WRITE:
rz_socket_read_block(s->fd, s->buf + 1, 4);
i = rz_read_be32(s->buf + 1);
if (i > RAP_PACKET_MAX || i < 0) {
i = RAP_PACKET_MAX;
}
rz_socket_read_block(s->fd, s->buf + 5, i);
rz_write_be32(s->buf + 1, s->write(s->user, s->buf + 5, i));
s->buf[0] = RAP_PACKET_WRITE | RAP_PACKET_REPLY;
rz_socket_write(s->fd, s->buf, 5);
rz_socket_flush(s->fd);
break;
case RAP_PACKET_SEEK: {
rz_socket_read_block(s->fd, &s->buf[1], 9);
int whence = s->buf[0];
ut64 offset = rz_read_be64(s->buf + 1);
offset = s->seek(s->user, offset, whence);
/* prepare reply */
s->buf[0] = RAP_PACKET_SEEK | RAP_PACKET_REPLY;
rz_write_be64(s->buf + 1, offset);
rz_socket_write(s->fd, s->buf, 9);
rz_socket_flush(s->fd);
} break;
case RAP_PACKET_CMD:
rz_socket_read_block(s->fd, &s->buf[1], 4);
i = rz_read_be32(&s->buf[1]);
if (rz_socket_read_block(s->fd, &s->buf[5], i) > 0) {
ptr = s->cmd(s->user, (const char *)s->buf + 5);
i = (ptr) ? strlen(ptr) + 1 : 0;
rz_write_be32(&s->buf[1], i);
s->buf[0] = RAP_PACKET_CMD | RAP_PACKET_REPLY;
rz_socket_write(s->fd, s->buf, 5);
if (i) {
rz_socket_write(s->fd, ptr, i);
}
rz_socket_flush(s->fd);
RZ_FREE(ptr);
}
break;
case RAP_PACKET_CLOSE:
rz_socket_read_block(s->fd, &s->buf[1], 4);
i = rz_read_be32(&s->buf[1]);
s->close(s->user, i);
s->buf[0] = RAP_PACKET_CLOSE | RAP_PACKET_REPLY;
rz_socket_write(s->fd, s->buf, 5);
rz_socket_flush(s->fd);
break;
default:
eprintf("unknown command 0x%02x\n", (ut8)(s->buf[0] & 0xff));
rz_socket_close(s->fd);
return false;
}
return true;
}

View file

@ -12,8 +12,7 @@ EXPECT=<<EOF
5 dbg native LGPL3
6 --- null MIT
7 --- qnx LGPL3
8 --- rap LGPL3
9 --- winkd LGPL3
8 --- winkd LGPL3
EOF
RUN
@ -28,9 +27,8 @@ Ldj~{[4]}
Ldj~{[5]}
Ldj~{[6]}
Ldj~{[7]}
Ldj~{[8]}
Ldj~{[9].name}
Ldj~{[9].license}
Ldj~{[8].name}
Ldj~{[8].license}
EOF
EXPECT=<<EOF
{"arch":"bf","name":"bf","license":"LGPL3"}
@ -41,7 +39,6 @@ EXPECT=<<EOF
{"arch":"x86","name":"native","license":"LGPL3"}
{"arch":"any","name":"null","license":"MIT"}
{"arch":"x86,arm","name":"qnx","license":"LGPL3"}
{"arch":"any","name":"rap","license":"LGPL3"}
winkd
LGPL3
EOF

View file

@ -10,7 +10,6 @@ EXPECT=<<EOF
5 dbg native LGPL3
6 --- null MIT
7 --- qnx LGPL3
8 --- rap LGPL3
9 --- winkd LGPL3
8 --- winkd LGPL3
EOF
RUN

View file

@ -68,7 +68,6 @@ rwd ptrace Ptrace and /proc/pid/mem (if available) io plugin (LGPL3) ptrace:/
rwd qnx Attach to QNX pdebug instance (LGPL3) qnx://
rw_ rzpipe rzpipe io plugin (MIT) rzpipe://
rw_ rzweb rzweb io client plugin (LGPL3) rzweb://
rw_ rap Remote binary protocol plugin (MIT) rap://,raps://
rw_ self Read memory from self (LGPL3) self://
rw_ shm Shared memory resources plugin (MIT) shm://
rw_ sparse Sparse buffer allocation plugin (LGPL3) sparse://
@ -84,7 +83,7 @@ FILE==
BROKEN=1
CMDS=Loj
EXPECT=<<EOF
[{"permissions":"rw_","name":"ar","description":"Open ar/lib files","license":"LGPL3","uris":["ar://","lib://"]},{"permissions":"rw_","name":"fd","description":"Local process filedescriptor IO","license":"MIT","uris":["fd://"]},{"permissions":"rw_","name":"bfdbg","description":"Attach to brainfuck Debugger instance","license":"LGPL3","uris":["bfdbg://"]},{"permissions":"rwd","name":"bochs","description":"Attach to a BOCHS debugger instance","license":"LGPL3","uris":["bochs://"]},{"permissions":"r_d","name":"debug","description":"Attach to native debugger instance","license":"LGPL3","uris":["dbg://","pidof://","waitfor://"],"version":"0.2.0","author":"pancake"},{"permissions":"rw_","name":"default","description":"Open local files","license":"LGPL3","uris":["file://","nocache://"]},{"permissions":"rwd","name":"gdb","description":"Attach to gdbserver instance","license":"LGPL3","uris":["gdb://"]},{"permissions":"rw_","name":"gzip","description":"Read/write gzipped files","license":"LGPL3","uris":["gzip://"]},{"permissions":"rw_","name":"http","description":"Make http get requests","license":"LGPL3","uris":["http://"]},{"permissions":"rw_","name":"ihex","description":"Open intel HEX file","license":"LGPL","uris":["ihex://"]},{"permissions":"r__","name":"mach","description":"mach debug io (unsupported in this platform)","license":"LGPL"},{"permissions":"rw_","name":"malloc","description":"Memory allocation plugin","license":"LGPL3","uris":["malloc://","hex://"]},{"permissions":"rw_","name":"null","description":"Null plugin","license":"LGPL3","uris":["null://"]},{"permissions":"rw_","name":"procpid","description":"Open /proc/[pid]/mem io","license":"LGPL3","uris":["procpid://"]},{"permissions":"rwd","name":"ptrace","description":"Ptrace and /proc/pid/mem (if available) io plugin","license":"LGPL3","uris":["ptrace://","attach://"]},{"permissions":"rwd","name":"qnx","description":"Attach to QNX pdebug instance","license":"LGPL3","uris":["qnx://"]},{"permissions":"rw_","name":"rzpipe","description":"rzpipe io plugin","license":"MIT","uris":["rzpipe://"]},{"permissions":"rw_","name":"rzweb","description":"rzweb io client plugin","license":"LGPL3","uris":["rzweb://"]},{"permissions":"rw_","name":"rap","description":"Remote binary protocol plugin","license":"MIT","uris":["rap://","raps://"]},{"permissions":"rw_","name":"self","description":"Read memory from self","license":"LGPL3","uris":["self://"]},{"permissions":"rw_","name":"shm","description":"Shared memory resources plugin","license":"MIT","uris":["shm://"]},{"permissions":"rw_","name":"sparse","description":"Sparse buffer allocation plugin","license":"LGPL3","uris":["sparse://"]},{"permissions":"rw_","name":"tcp","description":"Load files via TCP (listen or connect)","license":"LGPL3","uris":["tcp://"]},{"permissions":"rwd","name":"winkd","description":"Attach to a KD debugger","license":"LGPL3","uris":["winkd://"]},{"permissions":"rwd","name":"winedbg","description":"Wine-dbg io and debug.io plugin","license":"MIT","uris":["winedbg://"]},{"permissions":"rw_","name":"zip","description":"Open zip files","license":"BSD","uris":["zip://","apk://","ipa://","jar://","zipall://","apkall://","ipaall://","jarall://"]}]
[{"permissions":"rw_","name":"ar","description":"Open ar/lib files","license":"LGPL3","uris":["ar://","lib://"]},{"permissions":"rw_","name":"fd","description":"Local process filedescriptor IO","license":"MIT","uris":["fd://"]},{"permissions":"rw_","name":"bfdbg","description":"Attach to brainfuck Debugger instance","license":"LGPL3","uris":["bfdbg://"]},{"permissions":"rwd","name":"bochs","description":"Attach to a BOCHS debugger instance","license":"LGPL3","uris":["bochs://"]},{"permissions":"r_d","name":"debug","description":"Attach to native debugger instance","license":"LGPL3","uris":["dbg://","pidof://","waitfor://"],"version":"0.2.0","author":"pancake"},{"permissions":"rw_","name":"default","description":"Open local files","license":"LGPL3","uris":["file://","nocache://"]},{"permissions":"rwd","name":"gdb","description":"Attach to gdbserver instance","license":"LGPL3","uris":["gdb://"]},{"permissions":"rw_","name":"gzip","description":"Read/write gzipped files","license":"LGPL3","uris":["gzip://"]},{"permissions":"rw_","name":"http","description":"Make http get requests","license":"LGPL3","uris":["http://"]},{"permissions":"rw_","name":"ihex","description":"Open intel HEX file","license":"LGPL","uris":["ihex://"]},{"permissions":"r__","name":"mach","description":"mach debug io (unsupported in this platform)","license":"LGPL"},{"permissions":"rw_","name":"malloc","description":"Memory allocation plugin","license":"LGPL3","uris":["malloc://","hex://"]},{"permissions":"rw_","name":"null","description":"Null plugin","license":"LGPL3","uris":["null://"]},{"permissions":"rw_","name":"procpid","description":"Open /proc/[pid]/mem io","license":"LGPL3","uris":["procpid://"]},{"permissions":"rwd","name":"ptrace","description":"Ptrace and /proc/pid/mem (if available) io plugin","license":"LGPL3","uris":["ptrace://","attach://"]},{"permissions":"rwd","name":"qnx","description":"Attach to QNX pdebug instance","license":"LGPL3","uris":["qnx://"]},{"permissions":"rw_","name":"rzpipe","description":"rzpipe io plugin","license":"MIT","uris":["rzpipe://"]},{"permissions":"rw_","name":"rzweb","description":"rzweb io client plugin","license":"LGPL3","uris":["rzweb://"]},{"permissions":"rw_","name":"self","description":"Read memory from self","license":"LGPL3","uris":["self://"]},{"permissions":"rw_","name":"shm","description":"Shared memory resources plugin","license":"MIT","uris":["shm://"]},{"permissions":"rw_","name":"sparse","description":"Sparse buffer allocation plugin","license":"LGPL3","uris":["sparse://"]},{"permissions":"rw_","name":"tcp","description":"Load files via TCP (listen or connect)","license":"LGPL3","uris":["tcp://"]},{"permissions":"rwd","name":"winkd","description":"Attach to a KD debugger","license":"LGPL3","uris":["winkd://"]},{"permissions":"rwd","name":"winedbg","description":"Wine-dbg io and debug.io plugin","license":"MIT","uris":["winedbg://"]},{"permissions":"rw_","name":"zip","description":"Open zip files","license":"BSD","uris":["zip://","apk://","ipa://","jar://","zipall://","apkall://","ipaall://","jarall://"]}]
EOF
RUN
@ -330,7 +329,6 @@ EXPECT=<<EOF
--- io MIT
dbg null MIT
--- qnx LGPL3
--- rap LGPL3
--- winkd LGPL3
EOF
RUN
@ -346,7 +344,6 @@ EXPECT=<<EOF
--- io MIT
--- null MIT
--- qnx LGPL3
--- rap LGPL3
--- winkd LGPL3
EOF
RUN
@ -362,7 +359,6 @@ Ldj~{[4]}
# Ldj~{[5]} - Native plugin. The arch field changes in each test environment and breaks it.
Ldj~{[6]}
Ldj~{[7]}
Ldj~{[8]}
EOF
EXPECT=<<EOF
{"arch":"bf","name":"bf","license":"LGPL3"}
@ -372,7 +368,6 @@ EXPECT=<<EOF
{"arch":"any","name":"io","license":"MIT"}
{"arch":"any","name":"null","license":"MIT"}
{"arch":"x86,arm","name":"qnx","license":"LGPL3"}
{"arch":"any","name":"rap","license":"LGPL3"}
EOF
RUN