2013-02-25 09:36:07 +01:00
|
|
|
/* radare2 - LGPL - Copyright 2009-2013 - pancake */
|
2009-02-05 22:08:46 +01:00
|
|
|
|
|
|
|
#include "r_core.h"
|
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
R_API int r_core_setup_debugger (RCore *r, const char *debugbackend) {
|
|
|
|
int pid, *p = NULL;
|
|
|
|
ut8 is_gdb = (strcmp (debugbackend, "gdb") == 0);
|
|
|
|
|
|
|
|
RIODesc * fd = r->file ? r->file->fd : NULL;
|
|
|
|
p = fd ? fd->data : NULL;
|
|
|
|
r_config_set_i (r->config, "cfg.debug", 1);
|
|
|
|
if (!p) {
|
|
|
|
eprintf ("Invalid debug io\n");
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pid = *p; // 1st element in debugger's struct must be int
|
|
|
|
r_config_set (r->config, "io.ffio", "true");
|
|
|
|
if (is_gdb) r_core_cmd (r, "dh gdb", 0);
|
|
|
|
else r_core_cmdf (r, "dh %s", debugbackend);
|
|
|
|
r_core_cmdf (r, "dpa %d", pid);
|
|
|
|
r_core_cmdf (r, "dp=%d", pid);
|
|
|
|
r_core_cmd (r, ".dr*", 0);
|
|
|
|
/* honor dbg.bep */
|
|
|
|
{
|
|
|
|
const char *bep = r_config_get (r->config, "dbg.bep");
|
|
|
|
if (bep) {
|
|
|
|
if (!strcmp (bep, "loader")) {
|
|
|
|
/* do nothing here */
|
|
|
|
} else if (!strcmp (bep, "entry"))
|
|
|
|
r_core_cmd (r, "dcu entry0", 0);
|
|
|
|
else
|
|
|
|
r_core_cmdf (r, "dcu %s", bep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
r_core_cmd (r, "sr pc", 0);
|
|
|
|
r_config_set (r->config, "cmd.prompt", ".dr*");
|
|
|
|
r_config_set (r->config, "cmd.vprompt", ".dr*");
|
Fixed some issues in bin/dwarf.c and Fixed 1205194, 1205193, 1205192, 1205202, 1205203, 1205204, 1205205, 1205209, 1205208, 1205207, 1205206
2014-04-25 15:14:49 -05:00
|
|
|
return R_TRUE;
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_core_sync_view_by_fd (RCore *core, ut64 fd) {
|
|
|
|
int res = r_core_file_set_by_fd (core, fd);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
R_API int r_core_sync_view_by_file (RCore *core, RCoreFile *cf) {
|
|
|
|
int res = r_core_file_set_by_file (core, cf);
|
|
|
|
return res;
|
|
|
|
}
|
2013-09-12 01:55:45 +02:00
|
|
|
|
|
|
|
R_API int r_core_seek_base (RCore *core, const char *hex) {
|
|
|
|
int i;
|
|
|
|
ut64 n = 0;
|
|
|
|
ut64 addr = core->offset;
|
|
|
|
ut64 mask = 0LL;
|
|
|
|
char * p;
|
|
|
|
|
|
|
|
i = strlen (hex) * 4;
|
|
|
|
p = malloc (strlen (hex)+10);
|
|
|
|
if (p) {
|
|
|
|
strcpy (p, "0x");
|
|
|
|
strcpy (p+2, hex);
|
|
|
|
n = r_num_math (core->num, p);
|
|
|
|
free (p);
|
|
|
|
}
|
|
|
|
mask = UT64_MAX << i;
|
|
|
|
addr = (addr & mask) | n;
|
|
|
|
return r_core_seek (core, addr, 1);
|
|
|
|
}
|
|
|
|
|
2012-04-21 14:28:53 +02:00
|
|
|
R_API int r_core_dump(RCore *core, const char *file, ut64 addr, ut64 size) {
|
|
|
|
ut64 i;
|
|
|
|
ut8 *buf;
|
|
|
|
int bs = core->blocksize;
|
|
|
|
FILE *fd;
|
2012-08-10 11:35:38 +02:00
|
|
|
r_sys_truncate (file, 0);
|
2012-10-20 00:31:18 +02:00
|
|
|
fd = r_sandbox_fopen (file, "wb");
|
2012-04-21 14:28:53 +02:00
|
|
|
if (!fd) {
|
|
|
|
eprintf ("Cannot open '%s' for writing\n", file);
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
buf = malloc (bs);
|
|
|
|
r_cons_break (NULL, NULL);
|
2013-01-12 04:29:45 +01:00
|
|
|
for (i=0; i<size; i+=bs) {
|
2012-04-21 14:28:53 +02:00
|
|
|
if (r_cons_singleton ()->breaked)
|
|
|
|
break;
|
|
|
|
if ((i+bs)>size)
|
|
|
|
bs = size-i;
|
|
|
|
r_io_read_at (core->io, addr+i, buf, bs);
|
|
|
|
if (fwrite (buf, bs, 1, fd) <1) {
|
|
|
|
eprintf ("write error\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
eprintf ("dumped 0x%"PFMT64x" bytes\n", i);
|
|
|
|
r_cons_break_end ();
|
|
|
|
fclose (fd);
|
|
|
|
free (buf);
|
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
|
2010-03-08 12:45:22 +01:00
|
|
|
R_API int r_core_write_op(RCore *core, const char *arg, char op) {
|
2012-09-26 10:01:43 +02:00
|
|
|
int i, j, len, ret = R_FALSE;
|
2009-02-05 22:08:46 +01:00
|
|
|
char *str;
|
2009-07-08 13:49:55 +02:00
|
|
|
ut8 *buf;
|
2009-02-05 22:08:46 +01:00
|
|
|
|
|
|
|
// XXX we can work with config.block instead of dupping it
|
2010-02-01 11:55:56 +01:00
|
|
|
buf = (ut8 *)malloc (core->blocksize);
|
2013-12-03 00:14:59 +01:00
|
|
|
str = (char *)malloc (strlen (arg)+1);
|
2012-09-26 10:01:43 +02:00
|
|
|
if (buf == NULL || str == NULL)
|
|
|
|
goto beach;
|
2010-02-01 11:55:56 +01:00
|
|
|
memcpy (buf, core->block, core->blocksize);
|
2013-05-02 23:49:58 +02:00
|
|
|
if (op!='e') {
|
|
|
|
len = r_hex_str2bin (arg, (ut8 *)str);
|
|
|
|
if (len==-1) {
|
|
|
|
eprintf ("Invalid hexpair string\n");
|
|
|
|
goto beach;
|
|
|
|
}
|
|
|
|
} else len = 0;
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2013-05-02 23:49:58 +02:00
|
|
|
if (op=='e') {
|
|
|
|
char *p, *s = strdup (arg);
|
|
|
|
int n, from = 0, to = 0, dif = 0, step = 1;
|
|
|
|
n = from = to;
|
|
|
|
to = UT8_MAX;
|
|
|
|
//
|
|
|
|
p = strchr (s, ' ');
|
|
|
|
if (p) {
|
|
|
|
*p = 0;
|
|
|
|
step = atoi (p+1);
|
|
|
|
}
|
|
|
|
p = strchr (s, '-');
|
|
|
|
if (p) {
|
|
|
|
*p = 0;
|
|
|
|
to = atoi (p+1);
|
|
|
|
}
|
|
|
|
if (to<1 || to>UT8_MAX) to = UT8_MAX;
|
|
|
|
from = atoi (s);
|
|
|
|
free (s);
|
|
|
|
dif = (to<=from)? UT8_MAX: (to-from)+1;
|
|
|
|
from %= (UT8_MAX+1);
|
|
|
|
if (dif<1) dif = UT8_MAX+1;
|
|
|
|
if (step<1) step = 1;
|
|
|
|
for (i=n=0; i<core->blocksize; i++, n+= step)
|
|
|
|
buf[i] = (ut8)(n%dif)+from;
|
|
|
|
} else
|
2010-03-08 12:45:22 +01:00
|
|
|
if (op=='2' || op=='4') {
|
2010-02-01 11:55:56 +01:00
|
|
|
op -= '0';
|
2010-03-08 12:45:22 +01:00
|
|
|
for (i=0; i<core->blocksize; i+=op) {
|
2010-02-01 11:55:56 +01:00
|
|
|
/* endian swap */
|
|
|
|
ut8 tmp = buf[i];
|
|
|
|
buf[i] = buf[i+3];
|
|
|
|
buf[i+3] = tmp;
|
|
|
|
if (op==4) {
|
|
|
|
tmp = buf[i+1];
|
2010-04-06 18:21:41 +02:00
|
|
|
buf[i+1] = buf[i+2];
|
|
|
|
buf[i+2] = tmp;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
2010-02-01 11:55:56 +01:00
|
|
|
}
|
2010-03-08 12:45:22 +01:00
|
|
|
} else {
|
2010-02-03 18:15:31 +01:00
|
|
|
for (i=j=0; i<core->blocksize; i++) {
|
2010-02-01 11:55:56 +01:00
|
|
|
switch (op) {
|
2010-03-08 12:45:22 +01:00
|
|
|
case 'x': buf[i] ^= str[j]; break;
|
|
|
|
case 'a': buf[i] += str[j]; break;
|
|
|
|
case 's': buf[i] -= str[j]; break;
|
|
|
|
case 'm': buf[i] *= str[j]; break;
|
2012-11-07 04:25:42 +01:00
|
|
|
case 'w': buf[i] = str[j]; break;
|
2012-10-04 17:05:43 +02:00
|
|
|
case 'd': buf[i] = (str[j])? buf[i] / str[j]: 0; break;
|
2010-03-08 12:45:22 +01:00
|
|
|
case 'r': buf[i] >>= str[j]; break;
|
|
|
|
case 'l': buf[i] <<= str[j]; break;
|
|
|
|
case 'o': buf[i] |= str[j]; break;
|
|
|
|
case 'A': buf[i] &= str[j]; break;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
2010-02-01 11:55:56 +01:00
|
|
|
j++; if (j>=len) j=0; /* cyclic key */
|
|
|
|
}
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
|
2010-01-31 02:30:59 +01:00
|
|
|
ret = r_core_write_at (core, core->offset, buf, core->blocksize);
|
2012-09-26 10:01:43 +02:00
|
|
|
beach:
|
2010-01-31 14:22:27 +01:00
|
|
|
free (buf);
|
2012-09-26 10:01:43 +02:00
|
|
|
free (str);
|
2009-02-05 22:08:46 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-03-31 04:34:46 +02:00
|
|
|
R_API int r_core_seek_archbits (RCore *core, ut64 addr) {
|
|
|
|
static char *oldarch = NULL;
|
2013-04-01 01:45:28 +02:00
|
|
|
static int oldbits = 32;
|
2013-03-31 04:34:46 +02:00
|
|
|
int bits = 0;// = core->io->section->bits;
|
2013-04-01 01:45:28 +02:00
|
|
|
const char *arch = r_io_section_get_archbits (core->io, addr, &bits);
|
2013-03-31 04:34:46 +02:00
|
|
|
if (arch && bits) {
|
2013-04-01 01:45:28 +02:00
|
|
|
if (!oldarch) {
|
|
|
|
RBinInfo *info = r_bin_get_info (core->bin);
|
|
|
|
if (info) {
|
|
|
|
oldarch = strdup (info->arch);
|
|
|
|
oldbits = info->bits;
|
|
|
|
} else {
|
|
|
|
oldarch = strdup (r_config_get (core->config, "asm.arch"));
|
|
|
|
oldbits = 32;
|
|
|
|
}
|
|
|
|
}
|
2013-03-31 04:34:46 +02:00
|
|
|
r_config_set (core->config, "asm.arch", arch);
|
|
|
|
r_config_set_i (core->config, "asm.bits", bits);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (oldarch) {
|
|
|
|
r_config_set (core->config, "asm.arch", oldarch);
|
|
|
|
r_config_set_i (core->config, "asm.bits", oldbits);
|
|
|
|
free (oldarch);
|
|
|
|
oldarch = NULL;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-11-19 00:49:05 +01:00
|
|
|
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
|
2012-11-30 01:06:30 +01:00
|
|
|
RIOSection *newsection;
|
2010-01-31 02:30:59 +01:00
|
|
|
ut64 old = core->offset;
|
2011-01-20 23:28:20 +01:00
|
|
|
ut64 ret;
|
2010-02-21 11:35:49 +01:00
|
|
|
|
2010-01-31 02:30:59 +01:00
|
|
|
/* XXX unnecesary call */
|
2011-02-10 00:21:05 +01:00
|
|
|
//r_io_set_fd (core->io, core->file->fd);
|
2012-11-30 01:06:30 +01:00
|
|
|
core->io->section = core->section; // HACK
|
2010-06-28 14:12:34 +02:00
|
|
|
ret = r_io_seek (core->io, addr, R_IO_SEEK_SET);
|
2012-11-30 01:06:30 +01:00
|
|
|
newsection = core->io->section;
|
2012-12-06 00:55:22 +01:00
|
|
|
|
2011-01-20 23:28:20 +01:00
|
|
|
if (ret == UT64_MAX) {
|
2012-10-04 15:05:51 +02:00
|
|
|
//eprintf ("RET =%d %llx\n", ret, addr);
|
|
|
|
/*
|
|
|
|
XXX handle read errors correctly
|
|
|
|
if (core->ffio) {
|
|
|
|
core->offset = addr;
|
|
|
|
} else return R_FALSE;
|
|
|
|
*/
|
2011-01-20 23:28:20 +01:00
|
|
|
//core->offset = addr;
|
2011-04-19 00:59:16 +02:00
|
|
|
if (!core->io->va)
|
|
|
|
return R_FALSE;
|
2013-03-31 04:34:46 +02:00
|
|
|
//memset (core->block, 0xff, core->blocksize);
|
2010-06-28 14:12:34 +02:00
|
|
|
} else core->offset = addr;
|
2010-01-31 02:30:59 +01:00
|
|
|
if (rb) {
|
2010-04-08 14:04:34 +02:00
|
|
|
ret = r_core_block_read (core, 0);
|
2010-06-13 12:40:01 +02:00
|
|
|
if (core->ffio) {
|
|
|
|
if (ret<1 || ret > core->blocksize)
|
2010-01-31 14:22:27 +01:00
|
|
|
memset (core->block, 0xff, core->blocksize);
|
2010-06-13 12:40:01 +02:00
|
|
|
else memset (core->block+ret, 0xff, core->blocksize-ret);
|
2010-06-28 14:12:34 +02:00
|
|
|
ret = core->blocksize;
|
2010-06-13 12:40:01 +02:00
|
|
|
core->offset = addr;
|
|
|
|
} else {
|
|
|
|
if (ret<1) {
|
|
|
|
core->offset = old;
|
2010-06-28 02:12:35 +02:00
|
|
|
//eprintf ("Cannot read block at 0x%08"PFMT64x"\n", addr);
|
2010-06-13 12:40:01 +02:00
|
|
|
}
|
|
|
|
}
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
2012-11-30 01:06:30 +01:00
|
|
|
if (core->section != newsection) {//&& core->io->section->arch) {
|
2013-03-31 04:34:46 +02:00
|
|
|
r_core_seek_archbits (core, core->offset);
|
2012-11-30 01:06:30 +01:00
|
|
|
core->section = core->io->section;
|
|
|
|
}
|
2012-09-07 04:12:24 +02:00
|
|
|
return (ret==-1)? R_FALSE: R_TRUE;
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
|
|
|
|
2013-03-31 04:34:46 +02:00
|
|
|
R_API int r_core_seek_delta(RCore *core, st64 addr) {
|
|
|
|
ut64 tmp = core->offset;
|
|
|
|
int ret;
|
|
|
|
if (addr == 0)
|
|
|
|
return R_TRUE;
|
|
|
|
if (addr>0LL) {
|
|
|
|
/* check end of file */
|
|
|
|
if (0) addr = 0;
|
|
|
|
else addr += tmp;
|
|
|
|
} else {
|
|
|
|
/* check < 0 */
|
|
|
|
if (-addr > tmp) addr = 0;
|
|
|
|
else addr += tmp;
|
|
|
|
}
|
|
|
|
core->offset = addr;
|
|
|
|
ret = r_core_seek (core, addr, 1);
|
|
|
|
//ret = r_core_block_read (core, 0);
|
|
|
|
//if (ret == -1)
|
|
|
|
// memset (core->block, 0xff, core->blocksize);
|
|
|
|
// core->offset = tmp;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-03-08 12:45:22 +01:00
|
|
|
R_API int r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size) {
|
2010-11-22 01:27:20 +01:00
|
|
|
int ret;
|
|
|
|
if (!core->io || !core->file || size<1)
|
|
|
|
return R_FALSE;
|
|
|
|
ret = r_io_set_fd (core->io, core->file->fd);
|
2009-09-02 00:10:51 +00:00
|
|
|
if (ret != -1) {
|
2010-05-20 00:59:42 +02:00
|
|
|
ret = r_io_write_at (core->io, addr, buf, size);
|
2010-01-12 02:12:18 +01:00
|
|
|
if (addr >= core->offset && addr <= core->offset+core->blocksize)
|
2010-04-06 18:21:41 +02:00
|
|
|
r_core_block_read (core, 0);
|
2009-09-02 00:10:51 +00:00
|
|
|
}
|
2012-08-14 01:25:50 +02:00
|
|
|
core->file->size = r_io_size (core->io);
|
2012-02-09 01:38:16 +01:00
|
|
|
return (ret==-1)? R_FALSE: R_TRUE;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
|
2014-03-24 22:00:26 -05:00
|
|
|
R_API int r_core_extend_at(RCore *core, ut64 addr, int size) {
|
|
|
|
int ret;
|
|
|
|
if (!core->io || !core->file || size<1)
|
|
|
|
return R_FALSE;
|
|
|
|
ret = r_io_set_fd (core->io, core->file->fd);
|
|
|
|
if (ret != -1) {
|
|
|
|
ret = r_io_extend_at (core->io, addr, size);
|
|
|
|
if (addr >= core->offset && addr <= core->offset+core->blocksize)
|
|
|
|
r_core_block_read (core, 0);
|
|
|
|
}
|
|
|
|
core->file->size = r_io_size (core->io);
|
|
|
|
return (ret==-1)? R_FALSE: R_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-03-28 17:06:22 +01:00
|
|
|
R_API int r_core_shift_block(RCore *core, ut64 addr, ut64 b_size, st64 dist) {
|
2014-03-26 22:39:56 -05:00
|
|
|
// bstart - block start, fstart file start
|
|
|
|
ut64 fend = 0, fstart = 0, bstart = 0, file_sz = 0, cur_offset = core->offset;
|
|
|
|
ut8 * shift_buf = NULL;
|
|
|
|
int res = R_FALSE;
|
|
|
|
|
|
|
|
if (b_size == 0 || b_size == (ut64) -1) {
|
|
|
|
res = r_io_set_fd (core->io, core->file->fd);
|
|
|
|
file_sz = r_io_size (core->io);
|
|
|
|
bstart = r_io_seek (core->io, addr, R_IO_SEEK_SET);
|
|
|
|
fend = r_io_seek (core->io, 0, R_IO_SEEK_END);
|
2014-03-28 12:04:57 -05:00
|
|
|
fstart = file_sz - fend;
|
2014-03-26 22:39:56 -05:00
|
|
|
b_size = fend > bstart ? fend - bstart: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!core->io || !core->file || b_size<1)
|
|
|
|
return R_FALSE;
|
2014-03-28 12:04:57 -05:00
|
|
|
|
|
|
|
|
2014-03-26 22:39:56 -05:00
|
|
|
// XXX handling basic cases atm
|
|
|
|
shift_buf = malloc (b_size);
|
|
|
|
memset (shift_buf, 0, b_size);
|
|
|
|
|
2014-03-28 12:04:57 -05:00
|
|
|
// cases
|
2014-03-26 22:39:56 -05:00
|
|
|
// addr + b_size + dist > file_end
|
|
|
|
//if ( (addr+b_size) + dist > file_end ) {
|
|
|
|
// res = R_FALSE;
|
|
|
|
//}
|
|
|
|
// addr + b_size + dist < file_start (should work since dist is signed)
|
|
|
|
//else if ( (addr+b_size) + dist < 0 ) {
|
|
|
|
// res = R_FALSE;
|
|
|
|
//}
|
|
|
|
// addr + dist < file_start
|
|
|
|
if ( addr + dist < fstart ) {
|
|
|
|
res = R_FALSE;
|
|
|
|
}
|
|
|
|
// addr + dist > file_end
|
|
|
|
else if ( (addr) + dist > fend) {
|
|
|
|
res = R_FALSE;
|
|
|
|
} else {
|
|
|
|
res = r_io_set_fd (core->io, core->file->fd);
|
|
|
|
r_io_read_at (core->io, addr, shift_buf, b_size);
|
|
|
|
r_io_write_at (core->io, addr+dist, shift_buf, b_size);
|
|
|
|
res = R_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
r_core_seek (core, addr, 1);
|
2014-03-28 12:04:57 -05:00
|
|
|
free (shift_buf);
|
2014-03-26 22:39:56 -05:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-01-26 01:29:17 -06:00
|
|
|
static RCoreFile * r_core_file_set_first_valid(RCore *core) {
|
|
|
|
RListIter *iter;
|
2014-01-27 08:24:44 -06:00
|
|
|
RCoreFile *file = NULL;
|
2014-01-26 01:29:17 -06:00
|
|
|
|
|
|
|
r_list_foreach (core->files, iter, file) {
|
|
|
|
if (file && file->fd){
|
|
|
|
core->io->raised = file->fd->fd;
|
|
|
|
core->switch_file_view = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
2010-03-08 12:45:22 +01:00
|
|
|
R_API int r_core_block_read(RCore *core, int next) {
|
2011-04-19 00:59:16 +02:00
|
|
|
ut64 off;
|
2014-01-26 01:29:17 -06:00
|
|
|
if (core->file == NULL && r_core_file_set_first_valid(core) == NULL) {
|
2011-02-12 01:52:41 +01:00
|
|
|
memset (core->block, 0xff, core->blocksize);
|
2009-04-07 11:28:22 +00:00
|
|
|
return -1;
|
2011-02-12 01:52:41 +01:00
|
|
|
}
|
2014-01-18 09:26:09 -06:00
|
|
|
r_io_set_fdn (core->io, core->io->raised);
|
|
|
|
if (core->switch_file_view) {
|
2014-04-23 18:04:25 -05:00
|
|
|
r_core_sync_view_by_fd (core, core->io->raised);
|
2014-01-18 09:26:09 -06:00
|
|
|
core->switch_file_view = 0;
|
|
|
|
}
|
|
|
|
|
2013-06-04 23:49:28 +02:00
|
|
|
off = r_io_seek (core->io, core->offset+((next)?core->blocksize:0),
|
|
|
|
R_IO_SEEK_SET);
|
2011-04-19 00:59:16 +02:00
|
|
|
if (off == UT64_MAX) {
|
|
|
|
memset (core->block, 0xff, core->blocksize);
|
2013-03-18 00:38:04 +01:00
|
|
|
// TODO: do continuation in io
|
|
|
|
if (!core->io->va)
|
|
|
|
return -1;
|
2011-04-19 00:59:16 +02:00
|
|
|
}
|
2014-03-07 16:21:54 +04:00
|
|
|
core->io->off = off;
|
2011-04-19 00:59:16 +02:00
|
|
|
return (int)r_io_read (core->io, core->block, core->blocksize);
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
|
|
|
|
2010-03-08 12:45:22 +01:00
|
|
|
R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
|
2010-11-22 01:27:20 +01:00
|
|
|
int ret;
|
|
|
|
if (!core->io || !core->file || size<1)
|
|
|
|
return R_FALSE;
|
2012-08-13 04:33:01 +02:00
|
|
|
#if 0
|
2011-01-20 22:52:16 +01:00
|
|
|
r_io_set_fd (core->io, core->file->fd); // XXX ignore ret? -- ultra slow method.. inverse resolution of io plugin brbrb
|
2010-05-20 00:59:42 +02:00
|
|
|
ret = r_io_read_at (core->io, addr, buf, size);
|
2012-08-13 04:33:01 +02:00
|
|
|
if (addr>=core->offset && addr<=core->offset+core->blocksize)
|
|
|
|
r_core_block_read (core, 0);
|
|
|
|
#else
|
|
|
|
r_io_set_fd (core->io, core->file->fd); // XXX ignore ret? -- ultra slow method.. inverse resolution of io plugin brbrb
|
|
|
|
//ret = r_io_read_at (core->io, addr, buf, size);
|
|
|
|
r_io_seek (core->io, addr, R_IO_SEEK_SET);
|
|
|
|
ret = r_io_read (core->io, buf, size);
|
2011-04-25 20:09:09 +02:00
|
|
|
if (ret != size) {
|
2012-10-04 15:05:51 +02:00
|
|
|
if (ret>=size || ret<0) ret = 0;
|
|
|
|
memset (buf+ret, 0xff, size-ret);
|
2011-04-25 20:09:09 +02:00
|
|
|
}
|
2010-02-01 11:55:56 +01:00
|
|
|
if (addr>=core->offset && addr<=core->offset+core->blocksize)
|
|
|
|
r_core_block_read (core, 0);
|
2012-08-13 04:33:01 +02:00
|
|
|
#endif
|
2013-06-04 23:49:28 +02:00
|
|
|
return (ret==size);
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|