* Initial implementation of the rap:// IO plugin
- RMT packet descriptions are in r_io - io.rap plugin is now compiled by default. $ rm -f plugins.cfg $ ./configure-plugins * Some syntax fixes in r_vm * RCore.r_core_server() method uses r_io_is_listener() to wait for connections * Some minor fixes in r_socket - Add r_socket_read_block() fixes SIGPIPE and network issues
This commit is contained in:
parent
19f072f3f5
commit
4d50a86855
2
TODO
2
TODO
|
@ -69,8 +69,6 @@ TODO pancake
|
|||
| r_asm > r_vm |
|
||||
| r_debug > r_reg |
|
||||
`-----------------'
|
||||
* Implement visual function editor .. its done hacky in core/cmd.c .. maybe move to visual.c
|
||||
* Implement remote:// socket:// and listen://
|
||||
{
|
||||
* Implement RAnalCall (analyze function arguments, return values, propagate types..)
|
||||
- define number of arguments for given function
|
||||
|
|
|
@ -201,7 +201,8 @@ int main(int argc, char **argv) {
|
|||
r_cons_flush ();
|
||||
}
|
||||
|
||||
{ /* check if file.sha1 has changed */
|
||||
/* check if file.sha1 has changed */
|
||||
if (!strstr(r.file->filename,"://")) {
|
||||
char *path = strdup (r_config_get (r.config, "file.path"));
|
||||
const char *npath, *nsha1;
|
||||
char *sha1 = strdup (r_config_get (r.config, "file.sha1"));
|
||||
|
@ -229,6 +230,9 @@ int main(int argc, char **argv) {
|
|||
} else rabin_delegate (NULL);
|
||||
} else eprintf ("Metadata loaded from 'file.project'\n");
|
||||
|
||||
if (r_io_is_listener (r.io))
|
||||
r_core_serve (&r, r.io->fd);
|
||||
else
|
||||
for (;;) {
|
||||
do {
|
||||
if (r_core_prompt (&r, R_FALSE)<1)
|
||||
|
|
|
@ -211,20 +211,20 @@ R_API int r_anal_var_list_show(RAnal *anal, RAnalFcn *fcn, ut64 addr) {
|
|||
if (addr == 0 || (addr >= v->addr && addr <= v->eaddr)) {
|
||||
//ut32 value = r_var_dbg_read(v->delta);
|
||||
if (v->array>1)
|
||||
r_cons_printf("%s %s %s[%d] = ",
|
||||
eprintf ("%s %s %s[%d] = ",
|
||||
r_anal_var_type_to_str(anal, v->type), v->vartype,
|
||||
v->array, v->name);
|
||||
else r_cons_printf("%s %s %s = ", r_anal_var_type_to_str (anal, v->type),
|
||||
v->name, v->array);
|
||||
else eprintf ("%s %s %s = ", r_anal_var_type_to_str (anal, v->type),
|
||||
v->vartype, v->name);
|
||||
// TODO: implement r_var_dbg_read using r_vm or r_num maybe?? sounds dupped
|
||||
// XXX: not fully implemented
|
||||
r_cons_printf ("0x%"PFMT64x, 0LL);
|
||||
eprintf ("0x%"PFMT64x, 0LL);
|
||||
//r_var_print_value(anal, v);
|
||||
/* TODO: detect pointer to strings and so on */
|
||||
//if (string_flag_offset(NULL, buf, value, 0))
|
||||
// r_cons_printf(" ; %s\n", buf);
|
||||
//else
|
||||
r_cons_newline();
|
||||
eprintf ("\n"); //r_cons_newline();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,11 +243,11 @@ R_API int r_anal_var_list(RAnal *anal, RAnalFcn *fcn, ut64 addr, int delta) {
|
|||
}
|
||||
r_list_foreach (fcn->vars, iter, v) {
|
||||
if (addr == 0 || (addr >= v->addr && addr <= v->eaddr)) {
|
||||
r_cons_printf("0x%08llx - 0x%08llx type=%s type=%s name=%s delta=%d array=%d\n",
|
||||
eprintf ("0x%08llx - 0x%08llx type=%s type=%s name=%s delta=%d array=%d\n",
|
||||
v->addr, v->eaddr, r_anal_var_type_to_str(anal, v->type),
|
||||
v->vartype, v->name, v->delta, v->array);
|
||||
r_list_foreach (v->accesses, iter2, x) {
|
||||
r_cons_printf(" 0x%08llx %s\n", x->addr, x->set?"set":"get");
|
||||
eprintf (" 0x%08llx %s\n", x->addr, x->set?"set":"get");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ R_API int r_cmd_call(struct r_cmd_t *cmd, const char *input) {
|
|||
cmd->nullcallback (cmd->data);
|
||||
} else {
|
||||
c = cmd->cmds[(ut8)input[0]];
|
||||
if (c != NULL && c->callback!=NULL)
|
||||
if (c && c->callback)
|
||||
ret = c->callback (cmd->data, input+1);
|
||||
else ret = -1;
|
||||
}
|
||||
|
|
185
libr/core/core.c
185
libr/core/core.c
|
@ -1,8 +1,11 @@
|
|||
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
|
||||
|
||||
#include <r_core.h>
|
||||
#include <r_socket.h>
|
||||
#include "../config.h"
|
||||
|
||||
static int endian = 1; // XXX HACK
|
||||
|
||||
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
|
||||
RCore *core = (RCore *)userptr; // XXX ?
|
||||
RFlagItem *flag;
|
||||
|
@ -374,3 +377,185 @@ R_API RAnalOp *r_core_op_anal(RCore *core, ut64 addr) {
|
|||
r_anal_aop (core->anal, aop, addr, buf, sizeof (buf));
|
||||
return aop;
|
||||
}
|
||||
|
||||
/* XXX : this function needs more love */
|
||||
R_API int r_core_serve(RCore *core, int fd) {
|
||||
ut8 cmd, flg, *ptr, buf[1024];
|
||||
int i, c, pipefd;
|
||||
ut64 x;
|
||||
|
||||
if (fd == -1) {
|
||||
eprintf ("rap: cannot listen.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
eprintf ("RAP Server running\n");
|
||||
#if __UNIX__
|
||||
// XXX: ugly workaround
|
||||
signal (SIGINT, SIG_DFL);
|
||||
signal (SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
while ((c = r_socket_accept (fd))) {
|
||||
if (c == -1) {
|
||||
eprintf ("rap: cannot accept\n");
|
||||
r_socket_close (c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
eprintf ("Client connected\n");
|
||||
|
||||
for (;;) {
|
||||
i = r_socket_read_block (c, &cmd, 1);
|
||||
if (i==0) continue;
|
||||
|
||||
switch ((ut8)cmd) {
|
||||
case RMT_OPEN:
|
||||
r_socket_read_block (c, &flg, 1); // flags
|
||||
eprintf ("open (%d): ", cmd);
|
||||
r_socket_read_block (c, &cmd, 1); // len
|
||||
ptr = malloc(cmd);
|
||||
if (ptr == NULL) {
|
||||
eprintf("Cannot malloc in rmt-open len = %d\n", cmd);
|
||||
return -1;
|
||||
}
|
||||
r_socket_read_block (c, ptr, cmd); //filename
|
||||
ptr[cmd] = 0;
|
||||
r_core_file_open (core, (const char *)ptr, R_IO_READ); // XXX: mode write?
|
||||
//memcpy(config.file, ptr, cmd);
|
||||
//config.file[cmd]='\0';
|
||||
eprintf("(flags: %hhd) len: %hhd filename: '%s'\n",
|
||||
flg, cmd, ptr); //config.file);
|
||||
buf[0] = RMT_OPEN | RMT_REPLY;
|
||||
//config.fd = -1;
|
||||
//radare_open(0);
|
||||
r_mem_copyendian(buf+1, (ut8 *)&core->file->fd, 4, endian);
|
||||
write (c, buf, 5);
|
||||
free(ptr);
|
||||
break;
|
||||
case RMT_READ:
|
||||
r_socket_read_block (c, (ut8*)&buf, 4);
|
||||
r_mem_copyendian ((ut8*)&i, buf, 4, 1);
|
||||
ptr = (ut8 *)malloc (i+5);
|
||||
if (ptr==NULL) {
|
||||
eprintf ("Cannot read %d bytes\n", i);
|
||||
// TODO: reply error here
|
||||
return -1;
|
||||
} else {
|
||||
r_core_block_read (core, 0);
|
||||
ptr[0] = RMT_READ|RMT_REPLY;
|
||||
if (i>core->blocksize)
|
||||
r_core_block_size (core, i);
|
||||
r_mem_copyendian (ptr+1, (ut8 *)&i, 4, endian);
|
||||
memcpy (ptr+5, core->block, i); //core->blocksize);
|
||||
write (c, ptr, i+5);
|
||||
}
|
||||
break;
|
||||
case RMT_CMD:
|
||||
{
|
||||
char bufr[8], *bufw = NULL;
|
||||
char *cmd = NULL, *cmd_output = NULL;
|
||||
int i, cmd_len = 0;
|
||||
|
||||
/* read */
|
||||
r_socket_read_block (c, (ut8*)&bufr, 4);
|
||||
r_mem_copyendian ((ut8*)&i, (ut8 *)bufr, 4, endian);
|
||||
if (i <1) {
|
||||
eprintf ("Invalid length '%d'\n", i);
|
||||
} else {
|
||||
cmd = malloc(i);
|
||||
r_socket_read_block (c, (ut8*)cmd, i);
|
||||
cmd[i] = '\0';
|
||||
eprintf ("len: %d cmd: '%s'\n",
|
||||
i, cmd); fflush(stdout);
|
||||
cmd_output = r_core_cmd_str (core, cmd);
|
||||
if (cmd_output)
|
||||
cmd_len = strlen(cmd_output) + 1;
|
||||
free(cmd);
|
||||
/* write */
|
||||
bufw = malloc(cmd_len + 5);
|
||||
bufw[0] = RMT_CMD | RMT_REPLY;
|
||||
r_mem_copyendian((ut8*)bufw+1, (ut8 *)&cmd_len, 4, endian);
|
||||
memcpy(bufw+5, cmd_output, cmd_len);
|
||||
write(c, bufw, cmd_len+5);
|
||||
free(bufw);
|
||||
free(cmd_output);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RMT_WRITE:
|
||||
read (c, buf, 5);
|
||||
r_mem_copyendian((ut8 *)&x, buf+1, 4, endian);
|
||||
ptr = malloc (x);
|
||||
read (c, ptr, x);
|
||||
r_core_write_at (core, core->offset, ptr, x);
|
||||
free (ptr);
|
||||
break;
|
||||
case RMT_SEEK:
|
||||
r_socket_read_block (c, buf, 9);
|
||||
r_mem_copyendian((ut8 *)&x, buf+1, 8, endian);
|
||||
if (r_core_seek (core, x, R_TRUE)) {
|
||||
//core->offset = r__lseek(config.fd, x, buf[0]);
|
||||
x = (int)core->offset;
|
||||
} else x = (int)core->offset;
|
||||
buf[0] = RMT_SEEK | RMT_REPLY;
|
||||
r_mem_copyendian (buf+1, (ut8*)&x, 8, endian);
|
||||
write (c, buf, 9);
|
||||
break;
|
||||
case RMT_CLOSE:
|
||||
// XXX : proper shutdown
|
||||
r_socket_read_block (c, buf, 4);
|
||||
r_mem_copyendian ((ut8*)&i, buf, 4, endian);
|
||||
{
|
||||
int ret = r_socket_close (i);
|
||||
r_mem_copyendian (buf+1, (ut8*)&ret, 4, endian);
|
||||
buf[0] = RMT_CLOSE | RMT_REPLY;
|
||||
write(c, buf, 5);
|
||||
}
|
||||
break;
|
||||
case RMT_SYSTEM:
|
||||
// read
|
||||
r_socket_read_block (c, buf, 4);
|
||||
r_mem_copyendian((ut8*)&i, buf, 4, endian);
|
||||
ptr = (ut8 *) malloc(i+6);
|
||||
ptr[5]='!';
|
||||
r_socket_read_block (c, ptr+6, i);
|
||||
ptr[6+i]='\0';
|
||||
//env_update();
|
||||
//pipe_stdout_to_tmp_file((char*)&buf, (char*)ptr+5);
|
||||
pipefd = r_cons_pipe_open ((const char *)buf, 0);
|
||||
{
|
||||
FILE *fd = fopen((char*)buf, "r");
|
||||
free(ptr); i = 0;
|
||||
if (fd == NULL) {
|
||||
eprintf("Cannot open tmpfile\n");
|
||||
i = -1;
|
||||
} else {
|
||||
fseek(fd, 0, SEEK_END);
|
||||
i = ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
ptr = (ut8 *) malloc(i+5);
|
||||
fread(ptr+5, i, 1, fd);
|
||||
ptr[i+5]='\0';
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
r_cons_pipe_close (pipefd);
|
||||
unlink((char*)buf);
|
||||
|
||||
// send
|
||||
ptr[0] = (RMT_SYSTEM | RMT_REPLY);
|
||||
r_mem_copyendian ((ut8*)ptr+1, (ut8*)&i, 4, endian);
|
||||
if (i<0)i=0;
|
||||
write (c, ptr, i+5);
|
||||
eprintf ("REPLY SENT (%d) (%s)\n", i, ptr+5);
|
||||
free (ptr);
|
||||
break;
|
||||
default:
|
||||
eprintf ("unknown command 0x%02x\n", cmd);
|
||||
r_socket_close (c);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ typedef struct r_asm_plugin_t {
|
|||
int *bits;
|
||||
int (*init)(void *user);
|
||||
int (*fini)(void *user);
|
||||
const char *(*profile)();
|
||||
int (*disassemble)(RAsm *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len);
|
||||
int (*assemble)(RAsm *a, struct r_asm_aop_t *aop, const char *buf);
|
||||
RAsmModifyCallback modify;
|
||||
|
|
|
@ -102,6 +102,7 @@ R_API int r_core_read_at(struct r_core_t *core, ut64 addr, ut8 *buf, int size);
|
|||
R_API int r_core_visual(struct r_core_t *core, const char *input);
|
||||
R_API int r_core_visual_cmd(struct r_core_t *core, int ch);
|
||||
|
||||
R_API int r_core_serve(RCore *core, int fd);
|
||||
R_API struct r_core_file_t *r_core_file_open(struct r_core_t *r, const char *file, int mode);
|
||||
R_API struct r_core_file_t *r_core_file_get_fd(struct r_core_t *core, int fd);
|
||||
R_API int r_core_file_close(struct r_core_t *r, RCoreFile *fh);
|
||||
|
|
|
@ -15,6 +15,16 @@
|
|||
|
||||
#define R_IO_NFDS 32
|
||||
|
||||
#define RMT_OPEN 0x01
|
||||
#define RMT_READ 0x02
|
||||
#define RMT_WRITE 0x03
|
||||
#define RMT_SEEK 0x04
|
||||
#define RMT_CLOSE 0x05
|
||||
#define RMT_SYSTEM 0x06
|
||||
#define RMT_CMD 0x07
|
||||
#define RMT_REPLY 0x80
|
||||
|
||||
|
||||
#define IO_MAP_N 128
|
||||
typedef struct r_io_map_t {
|
||||
int fd;
|
||||
|
@ -83,6 +93,7 @@ typedef struct r_io_plugin_t {
|
|||
char *name;
|
||||
char *desc;
|
||||
void *widget;
|
||||
int (*listener)(RIO *io);
|
||||
int (*init)();
|
||||
struct r_io_undo_t undo;
|
||||
struct debug_t *debug; // ???
|
||||
|
@ -156,6 +167,7 @@ R_API int r_io_plugin_close(RIO *io, int fd, struct r_io_plugin_t *plugin);
|
|||
R_API int r_io_plugin_generate(RIO *io);
|
||||
R_API int r_io_plugin_add(RIO *io, struct r_io_plugin_t *plugin);
|
||||
R_API int r_io_plugin_list(RIO *io);
|
||||
R_API int r_io_is_listener(RIO *io);
|
||||
// TODO: _del ??
|
||||
R_API struct r_io_plugin_t *r_io_plugin_resolve(RIO *io, const char *filename);
|
||||
R_API struct r_io_plugin_t *r_io_plugin_resolve_fd(RIO *io, int fd);
|
||||
|
@ -253,6 +265,7 @@ extern struct r_io_plugin_t r_io_plugin_mach;
|
|||
extern struct r_io_plugin_t r_io_plugin_debug;
|
||||
extern struct r_io_plugin_t r_io_plugin_shm;
|
||||
extern struct r_io_plugin_t r_io_plugin_gdb;
|
||||
extern struct r_io_plugin_t r_io_plugin_rap;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -17,6 +17,7 @@ R_API int r_socket_flush(int fd);
|
|||
R_API void r_socket_block(int fd, int block);
|
||||
R_API int r_socket_ready(int fd, int secs, int usecs);
|
||||
R_API int r_socket_read(int fd, unsigned char *read, int len);
|
||||
R_API int r_socket_read_block(int fd, unsigned char *buf, int len);
|
||||
R_API int r_socket_puts(int fd, char *buf);
|
||||
R_API int r_socket_write(int fd, void *buf, int len);
|
||||
R_API int r_socket_connect(char *host, int port);
|
||||
|
@ -25,6 +26,7 @@ R_API int r_socket_accept(int fd);
|
|||
R_API int r_socket_gets(int fd, char *buf, int size);
|
||||
R_API void r_socket_printf(int fd, const char *fmt, ...);
|
||||
R_API char *r_socket_to_string(int fd);
|
||||
R_API int r_socket_close(int fd);
|
||||
|
||||
/* process */
|
||||
typedef struct r_socket_proc_t {
|
||||
|
|
|
@ -23,6 +23,12 @@ R_API struct r_io_t *r_io_new() {
|
|||
return io;
|
||||
}
|
||||
|
||||
R_API int r_io_is_listener(RIO *io) {
|
||||
if (io->plugin->listener)
|
||||
return io->plugin->listener (io);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API RBuffer *r_io_read_buf(struct r_io_t *io, ut64 addr, int len) {
|
||||
RBuffer *b = R_NEW (RBuffer);
|
||||
b->buf = malloc (len);
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
/* radare - LGPL - Copyright 2010 pancake<nopcode.org> */
|
||||
|
||||
// TODO: implement the rap API in r_socket ?
|
||||
#if __UNIX__
|
||||
|
||||
#include "r_io.h"
|
||||
#include "r_lib.h"
|
||||
#include "r_core.h"
|
||||
#include "r_socket.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
|
||||
static int rap_fd = -1;
|
||||
static int is_listener = 0;
|
||||
static int endian = 1;
|
||||
|
||||
static int rap__write(struct r_io_t *io, int fd, const ut8 *buf, int count) {
|
||||
int ret;
|
||||
unsigned int size = (int)count;
|
||||
ut8 *tmp = (ut8 *)malloc(count+5);
|
||||
|
||||
tmp[0] = RMT_WRITE;
|
||||
r_mem_copyendian((ut8 *)tmp+1, (ut8*)&size, 4, endian);
|
||||
memcpy(tmp+5, buf, size);
|
||||
|
||||
ret = write(rap_fd, tmp, size+5);
|
||||
|
||||
// recv
|
||||
read(rap_fd, tmp, 5);
|
||||
|
||||
free(tmp);
|
||||
// TODO: get reply
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rap__read(struct r_io_t *io, int fd, ut8 *buf, int count) {
|
||||
ut8 tmp[5];
|
||||
int i = (int)count;
|
||||
|
||||
// send
|
||||
tmp[0] = RMT_READ;
|
||||
r_mem_copyendian(tmp+1, (ut8*)&i, 4, endian);
|
||||
write(rap_fd, tmp, 5);
|
||||
|
||||
// recv
|
||||
read(rap_fd, tmp, 5);
|
||||
if (tmp[0] != (RMT_READ|RMT_REPLY)) {
|
||||
printf("Unexpected rap read reply (0x%02x)\n", tmp[0]);
|
||||
return -1;
|
||||
}
|
||||
r_mem_copyendian ((ut8*)&i, tmp+1, 4, endian);
|
||||
read (rap_fd, buf, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
static int rap__close(struct r_io_t *io, int fd) {
|
||||
int ret = -1;
|
||||
if (rap_fd != -1 && fd==rap_fd) {
|
||||
ret = close (fd);
|
||||
rap_fd = -1;
|
||||
}
|
||||
return ret; // return true/false here?
|
||||
}
|
||||
|
||||
static ut64 rap__lseek(struct r_io_t *io, int fildes, ut64 offset, int whence) {
|
||||
int ret;
|
||||
ut8 tmp[10];
|
||||
// query
|
||||
tmp[0] = RMT_SEEK;
|
||||
tmp[1] = (ut8)whence;
|
||||
r_mem_copyendian (tmp+2, (ut8*)&offset, 8, endian);
|
||||
write (rap_fd, &tmp, 10);
|
||||
|
||||
// get reply
|
||||
ret = read (fildes, &tmp, 9);
|
||||
if (ret!=9)
|
||||
return -1;
|
||||
if (tmp[0] != (RMT_SEEK | RMT_REPLY)) {
|
||||
eprintf ("Unexpected lseek reply\n");
|
||||
return -1;
|
||||
}
|
||||
r_mem_copyendian ((ut8 *)&offset, tmp+1, 8, endian);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int rap__plugin_open(struct r_io_t *io, const char *pathname) {
|
||||
return (!memcmp (pathname, "rap://", 6));
|
||||
}
|
||||
|
||||
static int rap__open(struct r_io_t *io, const char *pathname, int flags, int mode) {
|
||||
int i;
|
||||
char buf[1024];
|
||||
char *ptr = buf;
|
||||
|
||||
strncpy (buf, pathname, 1000);
|
||||
|
||||
if (!memcmp (ptr , "rap://", 6)) {
|
||||
ptr = ptr+6;
|
||||
if (strchr (ptr, '/')) {
|
||||
// connect
|
||||
char *file, *port = strchr(buf+6, ':');
|
||||
if (port == NULL) {
|
||||
eprintf("No port defined.\n");
|
||||
return -1;
|
||||
}
|
||||
port[0] = '\0';
|
||||
|
||||
// file
|
||||
file = strchr (pathname+6,'/');
|
||||
if (file == NULL) {
|
||||
eprintf ("No remote file specified.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rap_fd = r_socket_connect (ptr, atoi (port+1));
|
||||
if (rap_fd>=0)
|
||||
eprintf("Connected to: %s at port %d\n", ptr, atoi(port+1));
|
||||
else {
|
||||
eprintf("Cannot connect to '%s' (%d)\n", ptr, atoi(port+1));
|
||||
return -1;
|
||||
}
|
||||
// send
|
||||
buf[0] = RMT_OPEN;
|
||||
buf[1] = flags;
|
||||
buf[2] = (ut8)strlen(file)-1;
|
||||
memcpy (buf+3, file+1, buf[2]);
|
||||
write (rap_fd, buf, 3+buf[2]);
|
||||
//eprintf("OPENFILE(%s)\n", file+1);
|
||||
// read
|
||||
eprintf ("waiting... ");
|
||||
read (rap_fd, buf, 5);
|
||||
if (buf[0] != (char)(RMT_OPEN|RMT_REPLY))
|
||||
return -1;
|
||||
|
||||
r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, endian);
|
||||
if (i>0) eprintf ("ok\n");
|
||||
// ???
|
||||
//io->fd = rap_fd;
|
||||
is_listener = R_FALSE;
|
||||
return rap_fd;
|
||||
} else {
|
||||
// listen
|
||||
char *port = strchr (ptr, ':');
|
||||
int p;
|
||||
if (port == NULL) {
|
||||
eprintf ("No port defined.\n");
|
||||
return -1;
|
||||
}
|
||||
buf[0] = '\0';
|
||||
p = atoi (port+1);
|
||||
if (p<=0) {
|
||||
eprintf ("Cannot listen here. Try rap://:9999\n");
|
||||
return -1;
|
||||
}
|
||||
//TODO: Handle ^C signal (SIGINT, exit); // ???
|
||||
eprintf ("Listening at port %d\n", p);
|
||||
is_listener = R_TRUE;
|
||||
return r_socket_listen (p);
|
||||
}
|
||||
}
|
||||
return rap_fd;
|
||||
}
|
||||
|
||||
static int rap__init(struct r_io_t *io) {
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int rap__listener(struct r_io_t *io) {
|
||||
return is_listener;
|
||||
}
|
||||
|
||||
static int rap__system(RIO *io, int fd, const char *command) {
|
||||
ut8 buf[1024];
|
||||
char *ptr;
|
||||
int ret, i, j;
|
||||
|
||||
if (command[0] == '!')
|
||||
return system(command+1);
|
||||
|
||||
// send
|
||||
buf[0] = RMT_SYSTEM;
|
||||
i = strlen(command);
|
||||
r_mem_copyendian(buf+1, (ut8*)&i, 4, endian);
|
||||
memcpy(buf+5, command, i);
|
||||
write(rap_fd, buf, i+5);
|
||||
|
||||
// read
|
||||
ret = read(rap_fd, buf, 5);
|
||||
if (ret != 5) {
|
||||
return -1;
|
||||
}
|
||||
if (buf[0] != (RMT_SYSTEM | RMT_REPLY)) {
|
||||
eprintf("Unexpected system reply\n");
|
||||
return -1;
|
||||
}
|
||||
r_mem_copyendian ((ut8*)&i, buf+1, 4, endian);
|
||||
if (i == -1) //0xFFFFFFFF) {
|
||||
return -1;
|
||||
ptr = (char *)malloc (i);
|
||||
read (rap_fd, ptr, i);
|
||||
j = write (1, ptr, i);
|
||||
free (ptr);
|
||||
return i-j;
|
||||
}
|
||||
|
||||
struct r_io_plugin_t r_io_plugin_rap = {
|
||||
//void *plugin;
|
||||
.name = "rap",
|
||||
.desc = "radare protocol over tcp/ip (rap://:port rap://host:port/file)",
|
||||
.listener = rap__listener,
|
||||
.open = rap__open,
|
||||
.close = rap__close,
|
||||
.read = rap__read,
|
||||
.plugin_open = rap__plugin_open,
|
||||
.lseek = rap__lseek,
|
||||
.system = rap__system,
|
||||
.init = rap__init,
|
||||
.write = rap__write,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_IO,
|
||||
.data = &r_io_plugin_rap
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,12 @@
|
|||
OBJ_RAP=io_rap.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_RAP}
|
||||
TARGET_RAP=io_rap.${EXT_SO}
|
||||
ALL_TARGETS+=${TARGET_RAP}
|
||||
|
||||
${TARGET_RAP}: ${OBJ_RAP}
|
||||
${CC} -shared ${CFLAGS} -o ${TARGET_RAP} ${OBJ_RAP} \
|
||||
${LDFLAGS_LINKPATH}../../socket -L../../socket -lr_socket \
|
||||
${LDFLAGS_LINKPATH}../../util -L../../util -lr_util \
|
||||
${LDFLAGS_LINKPATH}../../cons -L../../cons -lr_cons \
|
||||
${LDFLAGS_LINKPATH}.. -L.. -L../../lib -lr_lib -lr_io \
|
|
@ -140,6 +140,7 @@ R_API int r_socket_unix_listen(const char *file) {
|
|||
|
||||
if (bind (sock, (struct sockaddr *) &unix_name, sizeof (unix_name)) < 0)
|
||||
return -1;
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/* change permissions */
|
||||
if (chmod (unix_name.sun_path, 0777) != 0)
|
||||
|
@ -225,6 +226,17 @@ R_API int r_socket_close(int fd) {
|
|||
#endif
|
||||
}
|
||||
|
||||
R_API int r_socket_read_block(int fd, unsigned char *buf, int len) {
|
||||
int ret = 0;
|
||||
for(ret=0;ret<len;) {
|
||||
int r= r_socket_read (fd, buf+ret, len-ret);
|
||||
if (r==-1)
|
||||
break;
|
||||
ret += r;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_socket_read(int fd, unsigned char *buf, int len) {
|
||||
#if __WINDOWS__
|
||||
return recv (fd, (void *)buf, len, 0);
|
||||
|
|
65
libr/vm/vm.c
65
libr/vm/vm.c
|
@ -334,28 +334,28 @@ R_API int r_vm_eval_eq(RVm *vm, const char *str, const char *val) {
|
|||
ut64 off = r_vm_get_math(vm, str+1);
|
||||
// XXX support 64 bits here
|
||||
ut32 v = (ut32)r_vm_get_math(vm, val); // TODO control endian
|
||||
p = strchr(str+1,':');
|
||||
p = strchr (str+1,':');
|
||||
if (vm->log)
|
||||
eprintf(" ; ==> [0x%08"PFMT64x"] = %x ((%s))\n", off, v, str+1);
|
||||
eprintf (" ; ==> [0x%08"PFMT64x"] = %x ((%s))\n", off, v, str+1);
|
||||
|
||||
if (p) {
|
||||
int size = atoi(val+1);
|
||||
off = r_vm_get_math(vm, p+1);
|
||||
int size = atoi (val+1);
|
||||
off = r_vm_get_math (vm, p+1);
|
||||
printf(" write size: %d\n", size);
|
||||
switch(size) {
|
||||
case 8: r_vm_mmu_write(vm, off, buf, 1);
|
||||
case 8: r_vm_mmu_write (vm, off, buf, 1);
|
||||
break;
|
||||
case 16: r_vm_mmu_write(vm, off, buf, 2);
|
||||
case 16: r_vm_mmu_write (vm, off, buf, 2);
|
||||
break;
|
||||
case 64: r_vm_mmu_write(vm, off, buf, 8);
|
||||
case 64: r_vm_mmu_write (vm, off, buf, 8);
|
||||
break;
|
||||
default:
|
||||
r_vm_mmu_write(vm, off, buf, 4);
|
||||
r_vm_mmu_write (vm, off, buf, 4);
|
||||
}
|
||||
} else {
|
||||
if (vm->log)
|
||||
eprintf(" ; write %x @ 0x%08"PFMT64x"\n", v, off);
|
||||
r_vm_mmu_write(vm, off, (ut8*)&v, 4);
|
||||
eprintf (" ; write %x @ 0x%08"PFMT64x"\n", v, off);
|
||||
r_vm_mmu_write (vm, off, (ut8*)&v, 4);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -453,30 +453,30 @@ R_API int r_vm_eval_single(RVm *vm, const char *str) {
|
|||
if (vm->log)
|
||||
eprintf("TODO: syscall interface not yet implemented\n");
|
||||
} else
|
||||
if((!memcmp(ptr, "call ", 4))
|
||||
|| (!memcmp(ptr, "jmp ", 4))){
|
||||
if((!memcmp (ptr, "call ", 4))
|
||||
|| (!memcmp (ptr, "jmp ", 4))){
|
||||
if (ptr[0]=='c')
|
||||
r_vm_stack_push(vm, r_vm_get_value(vm, vm->cpu.pc));
|
||||
printf("CALL(%s)\n", ptr+4);
|
||||
eprintf ("CALL(%s)\n", ptr+4);
|
||||
r_vm_reg_set(vm, vm->cpu.pc, r_vm_get_value(vm, ptr+4));
|
||||
} else
|
||||
if (!memcmp(ptr, "jz ", 3)){
|
||||
if (r_vm_reg_get(vm, ptr+3)==0)
|
||||
if (!memcmp (ptr, "jz ", 3)){
|
||||
if (r_vm_reg_get (vm, ptr+3)==0)
|
||||
r_vm_reg_set(vm, vm->cpu.pc, r_vm_get_value(vm, ptr+3));
|
||||
} else
|
||||
if (!memcmp(ptr, "jnz ", 4)){
|
||||
if (!memcmp (ptr, "jnz ", 4)){
|
||||
if (r_vm_reg_get(vm, ptr+4)==0)
|
||||
r_vm_reg_set(vm, vm->cpu.pc, r_vm_get_value(vm, ptr+4));
|
||||
r_vm_reg_set (vm, vm->cpu.pc, r_vm_get_value(vm, ptr+4));
|
||||
} else
|
||||
if (!memcmp(ptr, "push ", 5)) {
|
||||
r_vm_stack_push(vm, r_vm_get_value(vm, str+5));
|
||||
r_vm_stack_push (vm, r_vm_get_value(vm, str+5));
|
||||
} else
|
||||
if (!memcmp(str, "pop ", 4)) {
|
||||
r_vm_stack_pop(vm, str+5);
|
||||
r_vm_stack_pop (vm, str+5);
|
||||
} else
|
||||
if (!memcmp(ptr, "ret", 3)) {
|
||||
r_vm_stack_pop(vm, vm->cpu.pc);
|
||||
printf("RET (%x)\n", (ut32)vm->cpu.pc);
|
||||
if (vm->log) eprintf("RET (%x)\n", (ut32)vm->cpu.pc);
|
||||
} else if (vm->log) eprintf("r_vm: Unknown opcode\n");
|
||||
}
|
||||
return 0;
|
||||
|
@ -488,7 +488,6 @@ R_API int r_vm_eval(RVm *vm, const char *str) {
|
|||
|
||||
ptr = alloca (len);
|
||||
memcpy (ptr, str, len);
|
||||
|
||||
#if 0
|
||||
r_vm_mmu_real (vm, 0);
|
||||
r_vm_mmu_real(vm, config_get_i("vm.realio"));
|
||||
|
@ -507,8 +506,7 @@ R_API int r_vm_eval(RVm *vm, const char *str) {
|
|||
}
|
||||
} while (next);
|
||||
r_vm_eval_single (vm, ptr);
|
||||
|
||||
return 1;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_vm_eval_file(struct r_vm_t *vm, const char *str) {
|
||||
|
@ -521,16 +519,16 @@ R_API int r_vm_eval_file(struct r_vm_t *vm, const char *str) {
|
|||
if (*buf) {
|
||||
buf[strlen(buf)-1]='\0';
|
||||
//r_vm_eval(vm, buf);
|
||||
r_vm_op_eval(vm, buf);
|
||||
r_vm_op_eval (vm, buf);
|
||||
}
|
||||
}
|
||||
fclose(fd);
|
||||
return 1;
|
||||
fclose (fd);
|
||||
return R_TRUE;
|
||||
}
|
||||
return 0;
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
/* emulate n opcodes */
|
||||
/* XXX: this must go in core, not here! i.. or add&use RIOBind? emulate n opcodes */
|
||||
R_API int r_vm_emulate(struct r_vm_t *vm, int n) {
|
||||
#if 0
|
||||
ut64 pc;
|
||||
|
@ -544,9 +542,6 @@ R_API int r_vm_emulate(struct r_vm_t *vm, int n) {
|
|||
///vm_init(1);
|
||||
vm_mmu_real(config_get_i("vm.realio"));
|
||||
vm_import(0);
|
||||
config_set("asm.pseudo", "true");
|
||||
config_set("asm.syntax", "intel");
|
||||
config_set("asm.profile", "simple");
|
||||
while(n--) {
|
||||
pc = vm_reg_get(vm->cpu.pc);
|
||||
udis_init();
|
||||
|
@ -590,16 +585,16 @@ R_API void r_vm_reset(RVm *vm) {
|
|||
/* TODO : Allow to remove and so on */
|
||||
R_API int r_vm_cmd_op(RVm *vm, const char *op) {
|
||||
char *cmd, *ptr;
|
||||
int len = strlen(op)+1;
|
||||
int len = strlen (op)+1;
|
||||
if (*op==' ')
|
||||
op = op + 1;
|
||||
cmd = alloca(len);
|
||||
memcpy(cmd, op, len);
|
||||
cmd = alloca (len);
|
||||
memcpy (cmd, op, len);
|
||||
ptr = strchr (cmd, ' ');
|
||||
if (ptr) {
|
||||
ptr[0]='\0';
|
||||
eprintf ("vm: opcode '%s' added\n", cmd);
|
||||
r_vm_op_add (vm, cmd, ptr+1);
|
||||
} else r_vm_cmd_op_help();
|
||||
} else r_vm_cmd_op_help ();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ cmd.dummy
|
|||
crypto.aes
|
||||
debug.native
|
||||
io.debug
|
||||
io.rap
|
||||
io.gdb
|
||||
io.mach
|
||||
io.w32dbg
|
||||
|
|
Loading…
Reference in New Issue