2009-02-05 21:08:46 +00:00
|
|
|
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
|
|
|
|
|
|
|
|
#include "r_core.h"
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
int r_core_shift()
|
|
|
|
{
|
|
|
|
/* like rsc move does .. but optimal :) */
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-04-02 10:23:32 +00:00
|
|
|
R_API int r_core_write_op(struct r_core_t *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;
|
2009-02-05 21:08:46 +00:00
|
|
|
int i,j;
|
|
|
|
int ret;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
// XXX we can work with config.block instead of dupping it
|
2009-07-08 11:49:55 +00:00
|
|
|
buf = (ut8 *)malloc(core->blocksize);
|
2009-02-05 21:08:46 +00:00
|
|
|
str = (char *)malloc(strlen(arg));
|
|
|
|
if (buf == NULL || str == NULL) {
|
|
|
|
free(buf);
|
|
|
|
free(str);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
memcpy(buf, core->block, core->blocksize);
|
2009-07-08 11:49:55 +00:00
|
|
|
len = r_hex_str2bin(arg, (ut8 *)str);
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
switch(op) {
|
|
|
|
case '2':
|
|
|
|
case '4':
|
|
|
|
op-='0';
|
|
|
|
for(i=0;i<core->blocksize;i+=op) {
|
|
|
|
/* endian swap */
|
2009-07-08 11:49:55 +00:00
|
|
|
ut8 tmp = buf[i];
|
2009-02-05 21:08:46 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
for(i=j=0;i<core->blocksize;i++) {
|
|
|
|
switch(op) {
|
|
|
|
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;
|
|
|
|
case 'd': buf[i] /= str[j]; break;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
j++; if (j>=len) j=0; /* cyclic key */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-12 01:12:18 +00:00
|
|
|
ret = r_core_write_at(core, core->offset, buf, core->blocksize);
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
free(buf);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-07-08 11:49:55 +00:00
|
|
|
R_API int r_core_seek(struct r_core_t *core, ut64 addr, int rb)
|
2009-04-07 11:28:22 +00:00
|
|
|
{
|
|
|
|
int ret;
|
2009-09-02 00:10:51 +00:00
|
|
|
r_io_set_fd(&core->io, core->file->fd);
|
2009-09-08 01:08:46 +00:00
|
|
|
ret = r_io_seek(&core->io, addr, R_IO_SEEK_SET);
|
2009-04-07 11:28:22 +00:00
|
|
|
if (ret) {
|
2010-01-12 01:12:18 +00:00
|
|
|
core->offset = addr;
|
2009-04-07 11:28:22 +00:00
|
|
|
if (rb) return r_core_block_read (core, 0);
|
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
R_API int r_core_write_at(struct r_core_t *core, ut64 addr, const ut8 *buf, int size)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-09-02 00:10:51 +00:00
|
|
|
int ret = r_io_set_fd(&core->io, core->file->fd);
|
|
|
|
if (ret != -1) {
|
|
|
|
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)
|
2009-09-02 00:10:51 +00:00
|
|
|
r_core_block_read(core, 0);
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
return (ret==-1)?R_FALSE:R_TRUE;
|
|
|
|
}
|
|
|
|
|
2009-04-07 11:28:22 +00:00
|
|
|
R_API int r_core_block_read(struct r_core_t *core, int next)
|
|
|
|
{
|
|
|
|
if (core->file == NULL)
|
|
|
|
return -1;
|
2009-09-02 00:10:51 +00:00
|
|
|
r_io_set_fd (&core->io, core->file->fd);
|
2010-01-12 01:12:18 +00:00
|
|
|
r_io_seek(&core->io, core->offset+((next)?core->blocksize:0), R_IO_SEEK_SET);
|
2009-09-02 00:10:51 +00:00
|
|
|
return r_io_read(&core->io, core->block, core->blocksize);
|
2009-04-07 11:28:22 +00:00
|
|
|
}
|
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
R_API int r_core_read_at(struct r_core_t *core, ut64 addr, ut8 *buf, int size)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-09-02 00:10:51 +00:00
|
|
|
int ret = r_io_set_fd (&core->io, core->file->fd);
|
|
|
|
ret = r_io_read_at(&core->io, addr, buf, size);
|
2010-01-12 01:12:18 +00:00
|
|
|
if (addr >= core->offset && addr <= core->offset+core->blocksize)
|
2009-02-05 21:08:46 +00:00
|
|
|
r_core_block_read(core, 0);
|
|
|
|
return (ret==-1)?R_FALSE:R_TRUE;
|
|
|
|
}
|