2016-09-12 21:04:44 +00:00
|
|
|
/* radare2 - LGPL - Copyright 2009-2016 - pancake */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
#include "r_core.h"
|
|
|
|
|
2016-01-02 22:25:20 +00:00
|
|
|
R_API int r_core_setup_debugger (RCore *r, const char *debugbackend, bool attach) {
|
2014-04-23 23:04:25 +00:00
|
|
|
int pid, *p = NULL;
|
2016-09-13 01:25:15 +00:00
|
|
|
bool is_gdb = !strcmp (debugbackend, "gdb");
|
2017-08-22 07:42:16 +00:00
|
|
|
RIODesc * fd = r->file ? r_io_desc_get (r->io, r->file->fd) : NULL;
|
2016-05-18 08:01:39 +00:00
|
|
|
const char *prompt = NULL;
|
|
|
|
|
2014-04-23 23:04:25 +00:00
|
|
|
p = fd ? fd->data : NULL;
|
|
|
|
r_config_set_i (r->config, "cfg.debug", 1);
|
|
|
|
if (!p) {
|
|
|
|
eprintf ("Invalid debug io\n");
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2014-04-23 23:04:25 +00:00
|
|
|
}
|
|
|
|
|
2014-06-10 09:20:17 +00:00
|
|
|
r_config_set (r->config, "io.ff", "true");
|
2017-06-05 12:45:45 +00:00
|
|
|
r_core_cmdf (r, "dL %s", debugbackend);
|
2016-09-13 01:25:15 +00:00
|
|
|
if (!is_gdb) {
|
|
|
|
pid = *p; // 1st element in debugger's struct must be int
|
|
|
|
r_core_cmdf (r, "dp=%d", pid);
|
|
|
|
if (attach) {
|
|
|
|
r_core_cmdf (r, "dpa %d", pid);
|
|
|
|
}
|
2016-09-12 21:04:44 +00:00
|
|
|
}
|
2016-01-02 22:25:20 +00:00
|
|
|
//this makes to attach twice showing warnings in the output
|
|
|
|
//we get "resource busy" so it seems isn't an issue
|
2014-04-23 23:04:25 +00:00
|
|
|
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 */
|
2015-11-17 21:37:48 +00:00
|
|
|
} else if (!strcmp (bep, "entry")) {
|
2014-04-23 23:04:25 +00:00
|
|
|
r_core_cmd (r, "dcu entry0", 0);
|
2015-11-17 21:37:48 +00:00
|
|
|
} else {
|
|
|
|
r_core_cmdf (r, "dcu %s", bep);
|
|
|
|
}
|
2014-04-23 23:04:25 +00:00
|
|
|
}
|
|
|
|
}
|
2015-10-31 00:57:52 +00:00
|
|
|
r_core_cmd (r, "sr PC", 0);
|
2016-05-18 08:01:39 +00:00
|
|
|
|
|
|
|
/* set the prompt if it's not been set already by the callbacks */
|
|
|
|
prompt = r_config_get (r->config, "cmd.prompt");
|
|
|
|
if (prompt && !strcmp (prompt, "")) {
|
2016-09-12 21:04:44 +00:00
|
|
|
if (r_config_get_i (r->config, "dbg.status")) {
|
2016-05-18 08:01:39 +00:00
|
|
|
r_config_set (r->config, "cmd.prompt", ".dr*;drd;sr PC;pi 1;s-");
|
2016-09-12 21:04:44 +00:00
|
|
|
} else {
|
2016-05-18 08:01:39 +00:00
|
|
|
r_config_set (r->config, "cmd.prompt", ".dr*");
|
2016-09-12 21:04:44 +00:00
|
|
|
}
|
2016-05-18 08:01:39 +00:00
|
|
|
}
|
2014-04-23 23:04:25 +00:00
|
|
|
r_config_set (r->config, "cmd.vprompt", ".dr*");
|
2015-09-14 10:35:38 +00:00
|
|
|
return true;
|
2014-04-23 23:04:25 +00:00
|
|
|
}
|
|
|
|
|
2013-09-11 23:55:45 +00:00
|
|
|
R_API int r_core_seek_base (RCore *core, const char *hex) {
|
2015-11-17 21:37:48 +00:00
|
|
|
ut64 addr = r_num_tail (core->num, core->offset, hex);
|
2013-09-11 23:55:45 +00:00
|
|
|
return r_core_seek (core, addr, 1);
|
|
|
|
}
|
|
|
|
|
2015-04-03 02:04:46 +00:00
|
|
|
R_API int r_core_dump(RCore *core, const char *file, ut64 addr, ut64 size, int append) {
|
2012-04-21 12:28:53 +00:00
|
|
|
ut64 i;
|
|
|
|
ut8 *buf;
|
|
|
|
int bs = core->blocksize;
|
|
|
|
FILE *fd;
|
2015-04-03 02:04:46 +00:00
|
|
|
if (append) {
|
|
|
|
fd = r_sandbox_fopen (file, "ab");
|
|
|
|
} else {
|
|
|
|
r_sys_truncate (file, 0);
|
|
|
|
fd = r_sandbox_fopen (file, "wb");
|
|
|
|
}
|
2012-04-21 12:28:53 +00:00
|
|
|
if (!fd) {
|
|
|
|
eprintf ("Cannot open '%s' for writing\n", file);
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2012-04-21 12:28:53 +00:00
|
|
|
}
|
2015-08-18 23:58:27 +00:00
|
|
|
/* some io backends seems to be buggy in those cases */
|
|
|
|
if (bs > 4096)
|
|
|
|
bs = 4096;
|
2012-04-21 12:28:53 +00:00
|
|
|
buf = malloc (bs);
|
2015-08-18 23:58:27 +00:00
|
|
|
if (!buf) {
|
|
|
|
eprintf ("Cannot alloc %d bytes\n", bs);
|
2015-08-19 08:37:02 +00:00
|
|
|
fclose (fd);
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2015-08-18 23:58:27 +00:00
|
|
|
}
|
2016-11-20 18:20:14 +00:00
|
|
|
r_cons_break_push (NULL, NULL);
|
|
|
|
for (i = 0; i < size; i += bs) {
|
|
|
|
if (r_cons_is_breaked ()) {
|
2012-04-21 12:28:53 +00:00
|
|
|
break;
|
2016-11-20 18:20:14 +00:00
|
|
|
}
|
|
|
|
if ((i + bs) > size) {
|
2015-08-18 23:58:27 +00:00
|
|
|
bs = size - i;
|
2016-11-20 18:20:14 +00:00
|
|
|
}
|
2015-08-18 23:58:27 +00:00
|
|
|
r_io_read_at (core->io, addr + i, buf, bs);
|
|
|
|
if (fwrite (buf, bs, 1, fd) < 1) {
|
2012-04-21 12:28:53 +00:00
|
|
|
eprintf ("write error\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
eprintf ("dumped 0x%"PFMT64x" bytes\n", i);
|
2016-11-20 18:20:14 +00:00
|
|
|
r_cons_break_pop ();
|
2012-04-21 12:28:53 +00:00
|
|
|
fclose (fd);
|
|
|
|
free (buf);
|
2015-09-14 10:35:38 +00:00
|
|
|
return true;
|
2012-04-21 12:28:53 +00:00
|
|
|
}
|
|
|
|
|
2010-03-08 11:45:22 +00:00
|
|
|
R_API int r_core_write_op(RCore *core, const char *arg, char op) {
|
2015-09-14 10:35:38 +00:00
|
|
|
int i, j, len, ret = false;
|
2016-04-05 19:59:38 +00:00
|
|
|
char *str = NULL;
|
2009-07-08 11:49:55 +00:00
|
|
|
ut8 *buf;
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
// XXX we can work with config.block instead of dupping it
|
2010-02-01 10:55:56 +00:00
|
|
|
buf = (ut8 *)malloc (core->blocksize);
|
2016-04-05 19:59:38 +00:00
|
|
|
if (!buf)
|
2012-09-26 08:01:43 +00:00
|
|
|
goto beach;
|
2010-02-01 10:55:56 +00:00
|
|
|
memcpy (buf, core->block, core->blocksize);
|
2016-04-05 19:59:38 +00:00
|
|
|
|
2016-04-07 13:31:36 +00:00
|
|
|
if (op!='e') {
|
2016-04-05 19:59:38 +00:00
|
|
|
// fill key buffer either from arg or from clipboard
|
|
|
|
if (arg) { // parse arg for key
|
2016-04-07 13:45:59 +00:00
|
|
|
// r_hex_str2bin() is guaranteed to output maximum half the
|
|
|
|
// input size, or 1 byte if there is just a single nibble.
|
|
|
|
str = (char *)malloc (strlen (arg) / 2 + 1);
|
2016-04-05 19:59:38 +00:00
|
|
|
if (!str)
|
|
|
|
goto beach;
|
|
|
|
len = r_hex_str2bin (arg, (ut8 *)str);
|
2016-04-07 13:45:59 +00:00
|
|
|
// Output is invalid if there was just a single nibble,
|
|
|
|
// but in that case, len is negative (-1).
|
2016-04-05 19:59:38 +00:00
|
|
|
if (len <= 0) {
|
|
|
|
eprintf ("Invalid hexpair string\n");
|
|
|
|
goto beach;
|
|
|
|
}
|
|
|
|
} else { // use clipboard as key
|
|
|
|
len = core->yank_buf->length;
|
|
|
|
if (len <= 0) {
|
|
|
|
eprintf ("Clipboard is empty and no value argument(s) given\n");
|
|
|
|
goto beach;
|
|
|
|
}
|
|
|
|
str = r_mem_dup (core->yank_buf->buf, len);
|
|
|
|
if (!str)
|
|
|
|
goto beach;
|
2016-04-07 13:31:36 +00:00
|
|
|
}
|
|
|
|
} else len = 0;
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2016-04-05 19:59:38 +00:00
|
|
|
// execute the operand
|
2013-05-02 21:49:58 +00:00
|
|
|
if (op=='e') {
|
2015-09-07 21:36:57 +00:00
|
|
|
int wordsize = 1;
|
|
|
|
char *os, *p, *s = strdup (arg);
|
2013-05-02 21:49:58 +00:00
|
|
|
int n, from = 0, to = 0, dif = 0, step = 1;
|
|
|
|
n = from = to;
|
2015-09-07 21:36:57 +00:00
|
|
|
os = s;
|
2013-05-02 21:49:58 +00:00
|
|
|
to = UT8_MAX;
|
|
|
|
//
|
|
|
|
p = strchr (s, ' ');
|
|
|
|
if (p) {
|
|
|
|
*p = 0;
|
2015-09-07 21:36:57 +00:00
|
|
|
from = r_num_math (core->num, s);
|
|
|
|
s = p+1;
|
2013-05-02 21:49:58 +00:00
|
|
|
}
|
2015-09-07 21:36:57 +00:00
|
|
|
p = strchr (s, ' ');
|
|
|
|
if (p) {
|
|
|
|
*p = 0;
|
|
|
|
to = r_num_math (core->num, s);
|
|
|
|
s = p+1;
|
|
|
|
}
|
|
|
|
p = strchr (s, ' ');
|
2013-05-02 21:49:58 +00:00
|
|
|
if (p) {
|
|
|
|
*p = 0;
|
2015-09-07 21:36:57 +00:00
|
|
|
step = r_num_math (core->num, s);
|
|
|
|
s = p+1;
|
|
|
|
wordsize = r_num_math (core->num, s);
|
|
|
|
} else {
|
|
|
|
step = r_num_math (core->num, s);
|
2013-05-02 21:49:58 +00:00
|
|
|
}
|
2015-09-07 21:36:57 +00:00
|
|
|
free (os);
|
|
|
|
eprintf ("from %d to %d step %d size %d\n", from, to, step, wordsize);
|
2013-05-02 21:49:58 +00:00
|
|
|
dif = (to<=from)? UT8_MAX: (to-from)+1;
|
2015-09-07 21:36:57 +00:00
|
|
|
if (wordsize==1) {
|
|
|
|
if (to<1 || to>UT8_MAX) to = UT8_MAX;
|
|
|
|
from %= (UT8_MAX+1);
|
|
|
|
}
|
2013-05-02 21:49:58 +00:00
|
|
|
if (dif<1) dif = UT8_MAX+1;
|
|
|
|
if (step<1) step = 1;
|
2015-09-07 21:36:57 +00:00
|
|
|
if (wordsize<1) wordsize = 1;
|
|
|
|
if (wordsize == 1) {
|
|
|
|
for (i=n=0; i<core->blocksize; i++, n+= step)
|
2016-04-26 09:09:15 +00:00
|
|
|
buf[i] = (ut8)(n % dif) + from;
|
2015-09-07 21:36:57 +00:00
|
|
|
} else if (wordsize == 2) {
|
|
|
|
ut16 num16 = from;
|
2016-04-26 09:09:15 +00:00
|
|
|
for (i = 0; i < core->blocksize; i += wordsize, num16 += step) {
|
|
|
|
r_write_le16 (buf + i, num16);
|
2015-09-07 21:36:57 +00:00
|
|
|
}
|
|
|
|
} else if (wordsize == 4) {
|
|
|
|
ut32 num32 = from;
|
2016-04-26 09:09:15 +00:00
|
|
|
for (i = 0; i < core->blocksize; i += wordsize, num32 += step) {
|
|
|
|
r_write_le32 (buf + i, num32);
|
2015-09-07 21:36:57 +00:00
|
|
|
}
|
|
|
|
} else if (wordsize == 8) {
|
|
|
|
ut64 num64 = from;
|
2016-04-26 09:09:15 +00:00
|
|
|
for (i = 0; i < core->blocksize; i += wordsize, num64 += step) {
|
|
|
|
r_write_le64 (buf + i, num64);
|
2015-09-07 21:36:57 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
eprintf ("Invalid word size. Use 1, 2, 4 or 8\n");
|
|
|
|
}
|
2013-05-02 21:49:58 +00:00
|
|
|
} else
|
2010-03-08 11:45:22 +00:00
|
|
|
if (op=='2' || op=='4') {
|
2010-02-01 10:55:56 +00:00
|
|
|
op -= '0';
|
2015-07-12 18:48:11 +00:00
|
|
|
// if i < core->blocksize would pass the test but buf[i+3] goes beyond the buffer
|
2015-07-12 19:37:44 +00:00
|
|
|
if (core->blocksize > 3) {
|
|
|
|
for (i=0; i<core->blocksize-3; i+=op) {
|
|
|
|
/* endian swap */
|
|
|
|
ut8 tmp = buf[i];
|
|
|
|
buf[i] = buf[i+3];
|
|
|
|
buf[i+3] = tmp;
|
|
|
|
if (op==4) {
|
|
|
|
tmp = buf[i+1];
|
|
|
|
buf[i+1] = buf[i+2];
|
|
|
|
buf[i+2] = tmp;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2010-02-01 10:55:56 +00:00
|
|
|
}
|
2010-03-08 11:45:22 +00:00
|
|
|
} else {
|
2010-02-03 17:15:31 +00:00
|
|
|
for (i=j=0; i<core->blocksize; i++) {
|
2010-02-01 10:55:56 +00:00
|
|
|
switch (op) {
|
2010-03-08 11:45:22 +00: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 03:25:42 +00:00
|
|
|
case 'w': buf[i] = str[j]; break;
|
2012-10-04 15:05:43 +00:00
|
|
|
case 'd': buf[i] = (str[j])? buf[i] / str[j]: 0; break;
|
2010-03-08 11:45:22 +00: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 21:08:46 +00:00
|
|
|
}
|
2010-02-01 10:55:56 +00:00
|
|
|
j++; if (j>=len) j=0; /* cyclic key */
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-01-31 01:30:59 +00:00
|
|
|
ret = r_core_write_at (core, core->offset, buf, core->blocksize);
|
2012-09-26 08:01:43 +00:00
|
|
|
beach:
|
2010-01-31 13:22:27 +00:00
|
|
|
free (buf);
|
2012-09-26 08:01:43 +00:00
|
|
|
free (str);
|
2009-02-05 21:08:46 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-08-07 17:05:55 +00:00
|
|
|
|
2017-03-09 22:29:48 +00:00
|
|
|
static void choose_bits_anal_hints(RCore *core, ut64 addr, int *bits) {
|
2016-08-10 16:49:44 +00:00
|
|
|
RAnalRange *range;
|
2016-08-07 17:05:55 +00:00
|
|
|
RListIter *iter;
|
2016-08-10 16:49:44 +00:00
|
|
|
r_list_foreach (core->anal->bits_ranges, iter, range) {
|
|
|
|
if (addr >= range->from && addr < range->to) {
|
|
|
|
*bits = range->bits;
|
2016-08-07 17:05:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-07 22:51:44 +00:00
|
|
|
R_API void r_core_seek_archbits(RCore *core, ut64 addr) {
|
2016-08-07 16:00:40 +00:00
|
|
|
int bits = 0;
|
2017-03-09 22:29:48 +00:00
|
|
|
const char *arch = r_io_section_get_archbits (core->io, addr, &bits);
|
2016-08-07 15:37:33 +00:00
|
|
|
if (!bits) {
|
2017-03-09 22:29:48 +00:00
|
|
|
//if we found bits related with anal hints pick it up
|
|
|
|
choose_bits_anal_hints (core, addr, &bits);
|
2016-08-07 17:05:55 +00:00
|
|
|
}
|
2017-03-09 22:29:48 +00:00
|
|
|
if (bits) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", bits);
|
2013-03-31 02:34:46 +00:00
|
|
|
}
|
2017-03-09 22:29:48 +00:00
|
|
|
if (arch) {
|
|
|
|
r_config_set (core->config, "asm.arch", arch);
|
2016-08-07 17:05:55 +00:00
|
|
|
}
|
2013-03-31 02:34:46 +00:00
|
|
|
}
|
|
|
|
|
2016-01-03 01:05:13 +00:00
|
|
|
R_API bool r_core_seek(RCore *core, ut64 addr, bool rb) {
|
2017-08-22 22:21:28 +00:00
|
|
|
ut64 newoff = r_io_seek (core->io, addr, R_IO_SEEK_SET);
|
|
|
|
if (newoff == UT64_MAX) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
core->offset = newoff;
|
2010-01-31 01:30:59 +00:00
|
|
|
if (rb) {
|
2017-08-22 07:42:16 +00:00
|
|
|
r_core_block_read (core);
|
2012-11-30 00:06:30 +00:00
|
|
|
}
|
2017-08-22 22:21:28 +00:00
|
|
|
return (newoff != addr);
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
|
|
|
|
2013-03-31 02:34:46 +00:00
|
|
|
R_API int r_core_seek_delta(RCore *core, st64 addr) {
|
|
|
|
ut64 tmp = core->offset;
|
|
|
|
int ret;
|
2017-03-15 10:06:19 +00:00
|
|
|
if (addr == 0) {
|
2015-09-14 10:35:38 +00:00
|
|
|
return true;
|
2017-03-15 10:06:19 +00:00
|
|
|
}
|
|
|
|
if (addr > 0LL) {
|
|
|
|
/* TODO: check end of file */
|
|
|
|
addr += tmp;
|
2013-03-31 02:34:46 +00:00
|
|
|
} else {
|
|
|
|
/* check < 0 */
|
2017-03-15 10:06:19 +00:00
|
|
|
if (-addr > tmp) {
|
|
|
|
addr = 0;
|
|
|
|
} else {
|
|
|
|
addr += tmp;
|
|
|
|
}
|
2013-03-31 02:34:46 +00:00
|
|
|
}
|
|
|
|
core->offset = addr;
|
|
|
|
ret = r_core_seek (core, addr, 1);
|
2016-08-15 18:56:23 +00:00
|
|
|
//ret = r_core_block_read (core);
|
2013-03-31 02:34:46 +00:00
|
|
|
//if (ret == -1)
|
|
|
|
// memset (core->block, 0xff, core->blocksize);
|
|
|
|
// core->offset = tmp;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-08-22 14:52:40 +00:00
|
|
|
R_API bool r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size) {
|
|
|
|
bool ret;
|
2017-08-22 07:42:16 +00:00
|
|
|
if (!core) {
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2016-10-19 21:00:44 +00:00
|
|
|
}
|
2017-08-22 14:52:40 +00:00
|
|
|
ret = r_io_write_at (core->io, addr, buf, size);
|
|
|
|
if (addr >= core->offset && addr <= core->offset + core->blocksize) {
|
2017-08-22 07:42:16 +00:00
|
|
|
r_core_block_read (core);
|
2009-09-02 00:10:51 +00:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
return ret;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2014-03-25 03:00:26 +00:00
|
|
|
R_API int r_core_extend_at(RCore *core, ut64 addr, int size) {
|
|
|
|
int ret;
|
2017-08-22 07:42:16 +00:00
|
|
|
if (!core->io || !core->file || size < 1) {
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2017-03-15 10:06:19 +00:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ret = r_io_use_fd (core->io, core->file->fd);
|
2014-03-25 03:00:26 +00:00
|
|
|
if (ret != -1) {
|
|
|
|
ret = r_io_extend_at (core->io, addr, size);
|
2017-03-15 10:06:19 +00:00
|
|
|
if (addr >= core->offset && addr <= core->offset+core->blocksize) {
|
2016-08-15 18:56:23 +00:00
|
|
|
r_core_block_read (core);
|
2017-03-15 10:06:19 +00:00
|
|
|
}
|
2014-03-25 03:00:26 +00:00
|
|
|
}
|
2015-09-14 10:35:38 +00:00
|
|
|
return (ret==-1)? false: true;
|
2014-03-25 03:00:26 +00:00
|
|
|
}
|
|
|
|
|
2014-03-28 16:06:22 +00:00
|
|
|
R_API int r_core_shift_block(RCore *core, ut64 addr, ut64 b_size, st64 dist) {
|
2014-03-27 03:39:56 +00:00
|
|
|
// bstart - block start, fstart file start
|
2014-06-14 00:09:41 +00:00
|
|
|
ut64 fend = 0, fstart = 0, bstart = 0, file_sz = 0;
|
2014-03-27 03:39:56 +00:00
|
|
|
ut8 * shift_buf = NULL;
|
2015-09-14 10:35:38 +00:00
|
|
|
int res = false;
|
2014-03-27 03:39:56 +00:00
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
if (!core->io || !core->file) {
|
2017-03-15 10:06:19 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-27 03:39:56 +00:00
|
|
|
if (b_size == 0 || b_size == (ut64) -1) {
|
2017-08-22 07:42:16 +00:00
|
|
|
res = r_io_use_fd (core->io, core->file->fd);
|
2014-03-27 03:39:56 +00:00
|
|
|
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 17:04:57 +00:00
|
|
|
fstart = file_sz - fend;
|
2014-03-27 03:39:56 +00:00
|
|
|
b_size = fend > bstart ? fend - bstart: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX handling basic cases atm
|
2017-04-17 17:59:14 +00:00
|
|
|
if (b_size < 1) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-03-27 03:39:56 +00:00
|
|
|
shift_buf = malloc (b_size);
|
|
|
|
memset (shift_buf, 0, b_size);
|
|
|
|
|
2014-03-28 17:04:57 +00:00
|
|
|
// cases
|
2014-03-27 03:39:56 +00:00
|
|
|
// addr + b_size + dist > file_end
|
|
|
|
//if ( (addr+b_size) + dist > file_end ) {
|
2015-09-14 10:35:38 +00:00
|
|
|
// res = false;
|
2014-03-27 03:39:56 +00:00
|
|
|
//}
|
|
|
|
// addr + b_size + dist < file_start (should work since dist is signed)
|
|
|
|
//else if ( (addr+b_size) + dist < 0 ) {
|
2015-09-14 10:35:38 +00:00
|
|
|
// res = false;
|
2014-03-27 03:39:56 +00:00
|
|
|
//}
|
|
|
|
// addr + dist < file_start
|
2017-03-15 10:06:19 +00:00
|
|
|
if (addr + dist < fstart) {
|
2015-09-14 10:35:38 +00:00
|
|
|
res = false;
|
2014-03-27 03:39:56 +00:00
|
|
|
}
|
|
|
|
// addr + dist > file_end
|
|
|
|
else if ( (addr) + dist > fend) {
|
2015-09-14 10:35:38 +00:00
|
|
|
res = false;
|
2014-03-27 03:39:56 +00:00
|
|
|
} else {
|
2017-08-22 07:42:16 +00:00
|
|
|
r_io_use_fd (core->io, core->file->fd);
|
2014-03-27 03:39:56 +00:00
|
|
|
r_io_read_at (core->io, addr, shift_buf, b_size);
|
|
|
|
r_io_write_at (core->io, addr+dist, shift_buf, b_size);
|
2015-09-14 10:35:38 +00:00
|
|
|
res = true;
|
2014-03-27 03:39:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
r_core_seek (core, addr, 1);
|
2014-03-28 17:04:57 +00:00
|
|
|
free (shift_buf);
|
2014-03-27 03:39:56 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2016-08-15 18:56:23 +00:00
|
|
|
R_API int r_core_block_read(RCore *core) {
|
2017-08-22 07:42:16 +00:00
|
|
|
if (core && core->block) {
|
|
|
|
return r_io_read_at (core->io, core->offset, core->block, core->blocksize);
|
2011-02-12 00:52:41 +00:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
return -1;
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 14:52:40 +00:00
|
|
|
R_API bool r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
|
2017-08-22 07:42:16 +00:00
|
|
|
if (core) {
|
|
|
|
return r_io_read_at (core->io, addr, buf, size);
|
2017-01-16 11:15:59 +00:00
|
|
|
}
|
2017-08-22 14:52:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_core_is_valid_offset (RCore *core, ut64 offset) {
|
|
|
|
if (!core) {
|
|
|
|
eprintf ("r_core_is_valid_offset: core is NULL\n");
|
|
|
|
r_sys_backtrace ();
|
|
|
|
return R_FAIL;
|
|
|
|
}
|
|
|
|
return r_io_is_valid_real_offset (core->io, offset, 0);
|
2014-09-18 19:27:06 +00:00
|
|
|
}
|