2012-08-10 09:35:38 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2012 - pancake */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
#include "r_core.h"
|
|
|
|
|
2012-04-21 12:28:53 +00: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 09:35:38 +00:00
|
|
|
r_sys_truncate (file, 0);
|
2012-04-21 12:28:53 +00:00
|
|
|
fd = fopen (file, "wb");
|
|
|
|
if (!fd) {
|
|
|
|
eprintf ("Cannot open '%s' for writing\n", file);
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
buf = malloc (bs);
|
|
|
|
r_cons_break (NULL, NULL);
|
|
|
|
for (i=0; i<size; ) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
i += bs;
|
|
|
|
}
|
|
|
|
eprintf ("dumped 0x%"PFMT64x" bytes\n", i);
|
|
|
|
r_cons_break_end ();
|
|
|
|
fclose (fd);
|
|
|
|
free (buf);
|
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
|
2010-03-08 11:45:22 +00:00
|
|
|
R_API int r_core_write_op(RCore *core, const char *arg, char op) {
|
2009-02-05 21:08:46 +00:00
|
|
|
char *str;
|
2009-07-08 11:49:55 +00:00
|
|
|
ut8 *buf;
|
2011-10-10 23:21:38 +00:00
|
|
|
int i, j, ret, len;
|
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);
|
|
|
|
str = (char *)malloc (strlen(arg));
|
2009-02-05 21:08:46 +00:00
|
|
|
if (buf == NULL || str == NULL) {
|
2010-02-03 17:15:31 +00:00
|
|
|
free (buf);
|
|
|
|
free (str);
|
2010-04-06 16:21:41 +00:00
|
|
|
return R_FALSE;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2010-02-01 10:55:56 +00:00
|
|
|
memcpy (buf, core->block, core->blocksize);
|
|
|
|
len = r_hex_str2bin (arg, (ut8 *)str);
|
2010-04-06 16:21:41 +00:00
|
|
|
if (len==-1) {
|
|
|
|
eprintf ("Invalid hexpair string\n");
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-03-08 11:45:22 +00:00
|
|
|
if (op=='2' || op=='4') {
|
2010-02-01 10:55:56 +00:00
|
|
|
op -= '0';
|
2010-03-08 11:45:22 +00:00
|
|
|
for (i=0; i<core->blocksize; i+=op) {
|
2010-02-01 10:55:56 +00: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 16:21:41 +00:00
|
|
|
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;
|
2010-04-06 16:21:41 +00:00
|
|
|
case 'd': if (str[j]) buf[i] /= str[j];
|
|
|
|
else buf[i] = 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);
|
2010-01-31 13:22:27 +00:00
|
|
|
free (buf);
|
2009-02-05 21:08:46 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-11-18 23:49:05 +00:00
|
|
|
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
|
2010-01-31 01:30:59 +00:00
|
|
|
ut64 old = core->offset;
|
2011-01-20 22:28:20 +00:00
|
|
|
ut64 ret;
|
2010-02-21 10:35:49 +00:00
|
|
|
|
2010-01-31 01:30:59 +00:00
|
|
|
/* XXX unnecesary call */
|
2011-02-09 23:21:05 +00:00
|
|
|
//r_io_set_fd (core->io, core->file->fd);
|
2010-06-28 12:12:34 +00:00
|
|
|
ret = r_io_seek (core->io, addr, R_IO_SEEK_SET);
|
2011-01-20 22:28:20 +00:00
|
|
|
if (ret == UT64_MAX) {
|
2010-06-29 23:13:09 +00:00
|
|
|
//eprintf ("RET =%d %llx\n", ret, addr);
|
2010-06-28 12:12:34 +00:00
|
|
|
/*
|
2010-07-12 23:00:36 +00:00
|
|
|
XXX handle read errors correctly
|
2010-06-28 12:12:34 +00:00
|
|
|
if (core->ffio) {
|
|
|
|
core->offset = addr;
|
|
|
|
} else return R_FALSE;
|
|
|
|
*/
|
2011-01-20 22:28:20 +00:00
|
|
|
//core->offset = addr;
|
2011-04-18 22:59:16 +00:00
|
|
|
if (!core->io->va)
|
|
|
|
return R_FALSE;
|
|
|
|
memset (core->block, 0xff, core->blocksize);
|
2010-06-28 12:12:34 +00:00
|
|
|
} else core->offset = addr;
|
2010-01-31 01:30:59 +00:00
|
|
|
if (rb) {
|
2010-04-08 12:04:34 +00:00
|
|
|
ret = r_core_block_read (core, 0);
|
2010-06-13 10:40:01 +00:00
|
|
|
if (core->ffio) {
|
|
|
|
if (ret<1 || ret > core->blocksize)
|
2010-01-31 13:22:27 +00:00
|
|
|
memset (core->block, 0xff, core->blocksize);
|
2010-06-13 10:40:01 +00:00
|
|
|
else memset (core->block+ret, 0xff, core->blocksize-ret);
|
2010-06-28 12:12:34 +00:00
|
|
|
ret = core->blocksize;
|
2010-06-13 10:40:01 +00:00
|
|
|
core->offset = addr;
|
|
|
|
} else {
|
|
|
|
if (ret<1) {
|
|
|
|
core->offset = old;
|
2010-06-28 00:12:35 +00:00
|
|
|
//eprintf ("Cannot read block at 0x%08"PFMT64x"\n", addr);
|
2010-06-13 10:40:01 +00:00
|
|
|
}
|
|
|
|
}
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
2010-04-08 12:04:34 +00:00
|
|
|
return (ret==-1)?R_FALSE:R_TRUE;
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
|
|
|
|
2010-03-08 11:45:22 +00:00
|
|
|
R_API int r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size) {
|
2010-11-22 00:27:20 +00: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-19 22:59:42 +00:00
|
|
|
ret = r_io_write_at (core->io, addr, buf, size);
|
2010-01-12 01:12:18 +00:00
|
|
|
if (addr >= core->offset && addr <= core->offset+core->blocksize)
|
2010-04-06 16:21:41 +00:00
|
|
|
r_core_block_read (core, 0);
|
2009-09-02 00:10:51 +00:00
|
|
|
}
|
2012-08-13 23:25:50 +00:00
|
|
|
core->file->size = r_io_size (core->io);
|
2012-02-09 00:38:16 +00:00
|
|
|
return (ret==-1)? R_FALSE: R_TRUE;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-03-08 11:45:22 +00:00
|
|
|
R_API int r_core_block_read(RCore *core, int next) {
|
2011-04-18 22:59:16 +00:00
|
|
|
ut64 off;
|
2011-02-12 00:52:41 +00:00
|
|
|
if (core->file == NULL) {
|
|
|
|
memset (core->block, 0xff, core->blocksize);
|
2009-04-07 11:28:22 +00:00
|
|
|
return -1;
|
2011-02-12 00:52:41 +00:00
|
|
|
}
|
2010-05-19 22:59:42 +00:00
|
|
|
r_io_set_fd (core->io, core->file->fd);
|
2011-04-18 22:59:16 +00:00
|
|
|
off = r_io_seek (core->io, core->offset+((next)?core->blocksize:0), R_IO_SEEK_SET);
|
|
|
|
if (off == UT64_MAX) {
|
|
|
|
memset (core->block, 0xff, core->blocksize);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return (int)r_io_read (core->io, core->block, core->blocksize);
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
|
|
|
|
2010-03-08 11:45:22 +00:00
|
|
|
R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
|
2010-11-22 00:27:20 +00:00
|
|
|
int ret;
|
|
|
|
if (!core->io || !core->file || size<1)
|
|
|
|
return R_FALSE;
|
2012-08-13 02:33:01 +00:00
|
|
|
#if 0
|
2011-01-20 21:52:16 +00:00
|
|
|
r_io_set_fd (core->io, core->file->fd); // XXX ignore ret? -- ultra slow method.. inverse resolution of io plugin brbrb
|
2010-05-19 22:59:42 +00:00
|
|
|
ret = r_io_read_at (core->io, addr, buf, size);
|
2012-08-13 02:33:01 +00: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 18:09:09 +00:00
|
|
|
if (ret != size) {
|
|
|
|
if (ret<size && ret>0)
|
|
|
|
memset (buf+ret, 0xff, size-ret);
|
|
|
|
else memset (buf, 0xff, size);
|
|
|
|
}
|
2010-02-01 10:55:56 +00:00
|
|
|
if (addr>=core->offset && addr<=core->offset+core->blocksize)
|
|
|
|
r_core_block_read (core, 0);
|
2012-08-13 02:33:01 +00:00
|
|
|
#endif
|
2011-04-18 22:59:16 +00:00
|
|
|
return (ret!=UT64_MAX);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|