2017-03-30 00:20:22 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2017 - pancake */
|
2016-11-04 04:00:15 +00:00
|
|
|
|
2016-05-03 02:52:41 +00:00
|
|
|
#include "r_cons.h"
|
|
|
|
#include "r_core.h"
|
|
|
|
#include "r_types.h"
|
|
|
|
#include "r_io.h"
|
2012-10-25 23:33:57 +00:00
|
|
|
|
2017-07-26 13:46:38 +00:00
|
|
|
static const char *help_msg_S[] = {
|
|
|
|
"Usage:","S[?-.*=adlr] [...]","",
|
|
|
|
"S","","list sections",
|
2017-09-04 13:05:12 +00:00
|
|
|
"S"," paddr va sz [vsz] name rwx","add new section (if(!vsz)vsz=sz)",
|
2017-07-26 13:46:38 +00:00
|
|
|
"S.","","show current section name",
|
|
|
|
"S.-*","","remove all sections in current offset",
|
|
|
|
"S*","","list sections (in radare commands)",
|
|
|
|
"S-[id]","","remove section identified by id",
|
|
|
|
"S-.","","remove section at core->offset (can be changed with @)",
|
|
|
|
"S=","","list sections (ascii-art bars) (io.va to display paddr or vaddr)",
|
|
|
|
"Sa","[-] [A] [B] [[off]]","Specify arch and bits for given section",
|
|
|
|
"Sd[a]"," [file]","dump current (all) section to a file (see dmd)",
|
|
|
|
"Sf"," [baddr]","Alias for S 0 0 $s $s foo mrwx",
|
|
|
|
"Sj","","list sections in JSON (alias for iSj)",
|
|
|
|
"Sl"," [file]","load contents of file into current section (see dml)",
|
|
|
|
"Sr"," [name]","rename section on current seek",
|
2017-08-22 07:42:16 +00:00
|
|
|
"SR", "[?]", "Remap sections with different mode of operation",
|
2017-07-26 13:46:38 +00:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *help_msg_Sl[] = {
|
|
|
|
"Usage:", "Sl", "[file]",
|
2017-09-12 09:05:24 +00:00
|
|
|
NULL
|
2017-07-26 13:46:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const char *help_msg_Sr[] = {
|
|
|
|
"Usage:", "Sr", "[name] ([offset])",
|
2017-09-12 09:05:24 +00:00
|
|
|
NULL
|
2017-07-26 13:46:38 +00:00
|
|
|
};
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
static const char* help_msg_SR[] = {
|
|
|
|
"Usage:","SR[b|s][a|p|e] [id]","",
|
|
|
|
"SRb", "[a|p|e] binid", "Remap sections of binid for Analysis, Patch or Emulation",
|
|
|
|
"SRs","[a|p|e] secid","Remap section with sectid for Analysis, Patch or Emulation",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2017-07-27 12:52:17 +00:00
|
|
|
static void cmd_section_init(RCore *core) {
|
|
|
|
DEFINE_CMD_DESCRIPTOR (core, S);
|
|
|
|
DEFINE_CMD_DESCRIPTOR (core, Sl);
|
|
|
|
DEFINE_CMD_DESCRIPTOR (core, Sr);
|
2017-07-26 13:46:38 +00:00
|
|
|
}
|
|
|
|
|
2017-08-25 23:05:22 +00:00
|
|
|
#define PRINT_CURRENT_SEEK \
|
|
|
|
if (i > 0 && len != 0) { \
|
|
|
|
if (seek == UT64_MAX) seek = 0; \
|
|
|
|
io->cb_printf ("=> 0x%08"PFMT64x" |", seek); \
|
|
|
|
for (j = 0; j < width; j++) { \
|
|
|
|
io->cb_printf ( \
|
|
|
|
((j*mul) + min >= seek && \
|
|
|
|
(j*mul) + min <= seek + len) \
|
|
|
|
? "^" : "-"); \
|
|
|
|
} \
|
|
|
|
io->cb_printf ("| 0x%08"PFMT64x"\n", seek+len); \
|
|
|
|
}
|
|
|
|
|
|
|
|
static void list_section_visual(RIO *io, ut64 seek, ut64 len, int use_color, int cols) {
|
|
|
|
ut64 mul, min = -1, max = -1;
|
|
|
|
SdbListIter *iter;
|
|
|
|
RIOSection *s;
|
|
|
|
int j, i = 0;
|
|
|
|
int width = cols - 70;
|
|
|
|
if (width < 1) {
|
|
|
|
width = 30;
|
|
|
|
}
|
|
|
|
// seek = r_io_section_vaddr_to_maddr_try (io, seek);
|
|
|
|
// seek = r_io_section_vaddr_to_maddr_try (io, seek);
|
|
|
|
ls_foreach (io->sections, iter, s) {
|
|
|
|
if (min == -1 || s->paddr < min) {
|
|
|
|
min = s->paddr;
|
|
|
|
}
|
|
|
|
if (max == -1 || s->paddr+s->size > max) {
|
|
|
|
max = s->paddr + s->size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mul = (max-min) / width;
|
|
|
|
if (min != -1 && mul != 0) {
|
|
|
|
const char * color = "", *color_end = "";
|
|
|
|
char buf[128];
|
|
|
|
i = 0;
|
|
|
|
ls_foreach (io->sections, iter, s) {
|
|
|
|
r_num_units (buf, s->size);
|
|
|
|
if (use_color) {
|
|
|
|
color_end = Color_RESET;
|
|
|
|
if (s->flags & 1) { // exec bit
|
|
|
|
color = Color_GREEN;
|
|
|
|
} else if (s->flags & 2) { // write bit
|
|
|
|
color = Color_RED;
|
|
|
|
} else {
|
|
|
|
color = "";
|
|
|
|
color_end = "";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
color = "";
|
|
|
|
color_end = "";
|
|
|
|
}
|
|
|
|
if (io->va) {
|
|
|
|
io->cb_printf ("%02d%c %s0x%08"PFMT64x"%s |", s->id,
|
|
|
|
(seek >= s->vaddr && seek < s->vaddr + s->vsize) ? '*' : ' ',
|
|
|
|
color, s->vaddr, color_end);
|
|
|
|
} else {
|
|
|
|
io->cb_printf ("%02d%c %s0x%08"PFMT64x"%s |", s->id,
|
|
|
|
(seek >= s->paddr && seek < s->paddr + s->size) ? '*' : ' ',
|
|
|
|
color, s->paddr, color_end);
|
|
|
|
}
|
|
|
|
for (j = 0; j < width; j++) {
|
|
|
|
ut64 pos = min + (j * mul);
|
|
|
|
ut64 npos = min + ((j + 1) * mul);
|
|
|
|
if (s->paddr < npos && (s->paddr + s->size) > pos)
|
|
|
|
io->cb_printf ("#");
|
|
|
|
else io->cb_printf ("-");
|
|
|
|
}
|
|
|
|
if (io->va) {
|
|
|
|
io->cb_printf ("| %s0x%08"PFMT64x"%s %5s %s %04s\n",
|
|
|
|
color, s->vaddr + s->vsize, color_end, buf,
|
|
|
|
r_str_rwx_i (s->flags), s->name);
|
|
|
|
} else {
|
|
|
|
io->cb_printf ("| %s0x%08"PFMT64x"%s %5s %s %04s\n",
|
|
|
|
color, s->paddr+s->size, color_end, buf,
|
|
|
|
r_str_rwx_i (s->flags), s->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
PRINT_CURRENT_SEEK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
static void __section_list (RIO *io, ut64 offset, RPrint *print, int rad) {
|
|
|
|
SdbListIter *iter;
|
|
|
|
RIOSection *s;
|
|
|
|
|
|
|
|
if (!io || !io->sections || !print || !print->cb_printf) {
|
|
|
|
return;
|
|
|
|
}
|
2017-08-25 23:50:57 +00:00
|
|
|
if (rad == '=') { // "S="
|
2017-08-30 16:53:13 +00:00
|
|
|
int cols = r_cons_get_size (NULL);
|
2017-08-25 23:05:22 +00:00
|
|
|
list_section_visual (io, offset, -1, print->flags & R_PRINT_FLAGS_COLOR, cols);
|
|
|
|
} else if (rad) {
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (io->sections, iter, s) {
|
|
|
|
char *n = strdup (s->name);
|
|
|
|
r_name_filter (n, strlen (n));
|
2017-08-22 23:09:45 +00:00
|
|
|
print->cb_printf ("f section.%s %"PFMT64d" 0x%"PFMT64x"\n", n, s->size, s->vaddr);
|
2017-08-22 07:42:16 +00:00
|
|
|
print->cb_printf ("S 0x%08"PFMT64x" 0x%08"PFMT64x" 0x%08"
|
|
|
|
PFMT64x" 0x%08"PFMT64x" %s %s\n", s->paddr,
|
|
|
|
s->vaddr, s->size, s->vsize, n, r_str_rwx_i (s->flags));
|
|
|
|
free (n);
|
|
|
|
}
|
|
|
|
} else {
|
2017-08-23 10:20:33 +00:00
|
|
|
ls_foreach (io->sections, iter, s) {
|
2017-08-22 07:42:16 +00:00
|
|
|
print->cb_printf ("[%02d:%02d]", s->bin_id, s->id);
|
|
|
|
if (io->va) {
|
|
|
|
if ((s->vaddr <= offset) && ((offset - s->vaddr) < s->vsize)) {
|
|
|
|
print->cb_printf (" * ");
|
|
|
|
} else {
|
|
|
|
print->cb_printf (" . ");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((s->paddr <= offset) && ((offset - s->paddr) < s->size)) {
|
|
|
|
print->cb_printf (" * ");
|
|
|
|
} else {
|
|
|
|
print->cb_printf (" . ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
print->cb_printf ("pa=0x%08"PFMT64x" %s va=0x%08"PFMT64x
|
|
|
|
" sz=0x%04"PFMT64x" vsz=0x%04"PFMT64x" %s", s->paddr,
|
|
|
|
r_str_rwx_i (s->flags), s->vaddr, s->size, s->vsize, s->name);
|
|
|
|
if (s->arch && s->bits) {
|
|
|
|
print->cb_printf (" ; %s %d", r_sys_arch_str (s->arch),
|
|
|
|
s->bits);
|
|
|
|
}
|
|
|
|
print->cb_printf ("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-30 00:20:22 +00:00
|
|
|
static bool dumpSectionsToDisk(RCore *core) {
|
2017-03-15 01:22:54 +00:00
|
|
|
char file[512];
|
2017-08-22 07:42:16 +00:00
|
|
|
SdbListIter *iter;
|
2016-01-03 23:24:18 +00:00
|
|
|
RIOSection *s;
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (core->io->sections, iter, s) {
|
2016-01-03 23:24:18 +00:00
|
|
|
ut8 *buf = malloc (s->size);
|
2017-03-15 01:22:54 +00:00
|
|
|
r_io_read_at (core->io, s->paddr, buf, s->size);
|
|
|
|
snprintf (file, sizeof (file),
|
2016-01-03 23:24:18 +00:00
|
|
|
"0x%08"PFMT64x"-0x%08"PFMT64x"-%s.dmp",
|
|
|
|
s->vaddr, s->vaddr+s->size,
|
2017-03-15 01:22:54 +00:00
|
|
|
r_str_rwx_i (s->flags));
|
2016-01-03 23:24:18 +00:00
|
|
|
if (!r_file_dump (file, buf, s->size, 0)) {
|
|
|
|
eprintf ("Cannot write '%s'\n", file);
|
|
|
|
free (buf);
|
|
|
|
return false;
|
|
|
|
}
|
2017-12-27 17:33:58 +00:00
|
|
|
eprintf ("Dumped %d byte(s) into %s\n", (int)s->size, file);
|
2016-01-03 23:24:18 +00:00
|
|
|
free (buf);
|
|
|
|
}
|
2017-03-30 00:20:22 +00:00
|
|
|
return true;
|
2016-01-03 23:24:18 +00:00
|
|
|
}
|
|
|
|
|
2017-03-30 00:20:22 +00:00
|
|
|
static bool dumpSectionToDisk(RCore *core, char *file) {
|
2016-01-07 13:08:25 +00:00
|
|
|
char *heapfile = NULL;
|
2017-08-22 07:42:16 +00:00
|
|
|
SdbListIter *iter;
|
2016-01-03 23:24:18 +00:00
|
|
|
RIOSection *s;
|
|
|
|
int len = 128;
|
2017-04-17 20:02:04 +00:00
|
|
|
if (!core || !file) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
ut64 o = core->offset;
|
2016-10-06 22:54:24 +00:00
|
|
|
if (core->io->va || core->io->debug) {
|
2017-08-22 23:09:45 +00:00
|
|
|
s = r_io_section_vget (core->io, o);
|
2017-08-22 07:42:16 +00:00
|
|
|
o = s ? o - s->vaddr + s->paddr : o;
|
2016-10-06 22:54:24 +00:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (core->io->sections, iter, s) {
|
2017-03-15 01:22:54 +00:00
|
|
|
if (o >= s->paddr && o < s->paddr + s->size) {
|
2016-01-03 23:24:18 +00:00
|
|
|
ut8 *buf = malloc (s->size);
|
2017-03-15 01:22:54 +00:00
|
|
|
r_io_read_at (core->io, s->paddr, buf, s->size);
|
2016-01-03 23:24:18 +00:00
|
|
|
if (!file) {
|
2017-04-26 10:47:27 +00:00
|
|
|
heapfile = (char *)malloc (len);
|
2016-01-07 13:08:25 +00:00
|
|
|
if (!heapfile) {
|
2017-04-26 10:47:27 +00:00
|
|
|
free (buf);
|
2016-01-07 13:08:25 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
file = heapfile;
|
2016-01-03 23:24:18 +00:00
|
|
|
snprintf (file, len,
|
|
|
|
"0x%08"PFMT64x"-0x%08"PFMT64x"-%s.dmp",
|
2016-11-04 04:00:15 +00:00
|
|
|
s->vaddr, s->vaddr + s->size,
|
2017-03-15 01:22:54 +00:00
|
|
|
r_str_rwx_i (s->flags));
|
2016-01-03 23:24:18 +00:00
|
|
|
}
|
|
|
|
if (!r_file_dump (file, buf, s->size, 0)) {
|
|
|
|
eprintf ("Cannot write '%s'\n", file);
|
|
|
|
free (buf);
|
2016-01-07 13:08:25 +00:00
|
|
|
free (heapfile);
|
2016-01-03 23:24:18 +00:00
|
|
|
return false;
|
|
|
|
}
|
2017-12-27 17:33:58 +00:00
|
|
|
eprintf ("Dumped %d byte(s) into %s\n", (int)s->size, file);
|
2016-01-03 23:24:18 +00:00
|
|
|
free (buf);
|
2016-01-07 13:08:25 +00:00
|
|
|
free (heapfile);
|
2016-01-03 23:24:18 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-23 22:23:14 +00:00
|
|
|
static void update_section_flag_at_with_oldname(RIOSection *s, RFlag *flags, ut64 off, char *oldname) {
|
|
|
|
RFlagItem *item = NULL;
|
|
|
|
RListIter *iter;
|
|
|
|
const RList *list = NULL;
|
|
|
|
int len = 0;
|
|
|
|
char *secname = NULL;
|
|
|
|
list = r_flag_get_list (flags, s->vaddr);
|
|
|
|
secname = sdb_fmt (-1, "section.%s", oldname);
|
|
|
|
len = strlen (secname);
|
|
|
|
r_list_foreach (list, iter, item) {
|
|
|
|
if (!item->name) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!strncmp (item->name, secname, R_MIN (strlen (item->name), len))) {
|
|
|
|
free (item->realname);
|
|
|
|
item->name = strdup (sdb_fmt (-1, "section.%s", s->name));
|
2018-01-08 02:22:26 +00:00
|
|
|
r_str_trim (item->name);
|
2016-08-23 22:23:14 +00:00
|
|
|
r_name_filter (item->name, 0);
|
|
|
|
item->realname = item->name;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
list = r_flag_get_list (flags, s->vaddr + s->size);
|
|
|
|
secname = sdb_fmt (-1, "section_end.%s", oldname);
|
|
|
|
len = strlen (secname);
|
|
|
|
r_list_foreach (list, iter, item) {
|
|
|
|
if (!item->name) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!strncmp (item->name, secname, R_MIN (strlen (item->name), len))) {
|
|
|
|
free (item->realname);
|
|
|
|
item->name = strdup (sdb_fmt (-1, "section_end.%s", s->name));
|
2018-01-08 02:22:26 +00:00
|
|
|
r_str_trim (item->name);
|
2016-08-23 22:23:14 +00:00
|
|
|
r_name_filter (item->name, 0);
|
|
|
|
item->realname = item->name;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
static int cmd_section_reapply(RCore *core, const char *input) {
|
|
|
|
int mode = 0;
|
|
|
|
ut32 id;
|
|
|
|
switch (*input) {
|
|
|
|
case '?':
|
|
|
|
r_core_cmd_help (core, help_msg_SR);
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
case 's':
|
|
|
|
switch (input[1]) {
|
|
|
|
case 'e':
|
|
|
|
mode = R_IO_SECTION_APPLY_FOR_EMULATOR;
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
mode = R_IO_SECTION_APPLY_FOR_PATCH;
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
mode = R_IO_SECTION_APPLY_FOR_ANALYSIS;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r_core_cmd_help (core, help_msg_SR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (*input == 'b') {
|
|
|
|
id = (ut32)r_num_math (core->num, input + 2);
|
|
|
|
if (!r_io_section_reapply_bin (core->io, id, mode)) {
|
|
|
|
eprintf ("Cannot reapply section with binid %d\n", id);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
id = (ut32)r_num_math (core->num, input + 2);
|
|
|
|
if (!r_io_section_reapply (core->io, id, mode)) {
|
|
|
|
eprintf ("Cannot reapply section with secid %d\n", id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r_core_cmd_help (core, help_msg_SR);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-02-27 01:40:27 +00:00
|
|
|
static int cmd_section(void *data, const char *input) {
|
|
|
|
RCore *core = (RCore *)data;
|
|
|
|
switch (*input) {
|
2017-08-28 08:17:34 +00:00
|
|
|
case '?': // "S?"
|
2017-07-26 13:46:38 +00:00
|
|
|
r_core_cmd_help (core, help_msg_S);
|
2014-05-28 02:34:12 +00:00
|
|
|
// TODO: add command to resize current section
|
2012-11-30 00:06:30 +00:00
|
|
|
break;
|
2017-08-22 07:42:16 +00:00
|
|
|
case 'R' : // "SR"
|
|
|
|
return cmd_section_reapply (core, input + 1);
|
2016-11-08 13:27:37 +00:00
|
|
|
case 'f': // "Sf"
|
|
|
|
if (input[1] == ' ') {
|
|
|
|
ut64 n = r_num_math (core->num, input + 1);
|
|
|
|
r_core_cmdf (core, "S 0x%"PFMT64x" 0x%"PFMT64x" $s $s foo mrwx", n, n);
|
|
|
|
} else {
|
|
|
|
r_core_cmd0 (core, "S 0 0 $s $s foo mrwx");
|
|
|
|
}
|
2016-11-05 23:49:31 +00:00
|
|
|
break;
|
2016-11-08 13:27:37 +00:00
|
|
|
case 'j': // "Sj"
|
2014-11-01 03:13:50 +00:00
|
|
|
r_core_cmd0 (core, "iSj");
|
|
|
|
break;
|
2017-03-30 00:20:22 +00:00
|
|
|
case 'a': // "Sa"
|
2012-11-30 00:06:30 +00:00
|
|
|
switch (input[1]) {
|
|
|
|
case '\0':
|
|
|
|
{
|
|
|
|
int b = 0;
|
2016-08-23 22:23:14 +00:00
|
|
|
const char *n = r_io_section_get_archbits (core->io, core->offset, &b);
|
|
|
|
if (n) {
|
|
|
|
r_cons_printf ("%s %d\n", n, b);
|
|
|
|
}
|
2012-11-30 00:06:30 +00:00
|
|
|
}
|
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case '-': // "Sa-"
|
2012-11-30 00:06:30 +00:00
|
|
|
r_io_section_set_archbits (core->io, core->offset, NULL, 0);
|
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case '?': // "Sa?"
|
2012-11-30 00:06:30 +00:00
|
|
|
default:
|
|
|
|
eprintf ("Usage: Sa[-][arch] [bits] [[off]]\n");
|
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case ' ': // "Sa "
|
2012-11-30 00:06:30 +00:00
|
|
|
{
|
2013-06-26 07:52:32 +00:00
|
|
|
int i;
|
|
|
|
char *ptr = strdup (input+2);
|
|
|
|
const char *arch = NULL;
|
|
|
|
char bits = 0;
|
|
|
|
ut64 offset = core->offset;
|
|
|
|
i = r_str_word_set0 (ptr);
|
|
|
|
if (i < 2) {
|
|
|
|
eprintf ("Missing argument\n");
|
|
|
|
free (ptr);
|
|
|
|
break;
|
|
|
|
}
|
2016-08-23 22:23:14 +00:00
|
|
|
if (i == 3) {
|
|
|
|
offset = r_num_math (core->num, r_str_word_get0 (ptr, 2));
|
|
|
|
}
|
|
|
|
bits = r_num_math (core->num, r_str_word_get0 (ptr, 1));
|
2013-06-26 07:52:32 +00:00
|
|
|
arch = r_str_word_get0 (ptr, 0);
|
2016-08-23 22:23:14 +00:00
|
|
|
if (r_io_section_set_archbits (core->io, offset, arch, bits)) {
|
2012-12-05 23:55:22 +00:00
|
|
|
core->section = NULL;
|
2012-11-30 00:06:30 +00:00
|
|
|
r_core_seek (core, core->offset, 0);
|
2015-10-11 20:52:53 +00:00
|
|
|
} else {
|
2016-08-23 22:23:14 +00:00
|
|
|
eprintf ("Cannot set arch/bits at 0x%08"PFMT64x"\n",offset);
|
2015-10-11 20:52:53 +00:00
|
|
|
}
|
2013-06-26 07:52:32 +00:00
|
|
|
free (ptr);
|
|
|
|
break;
|
2012-11-30 00:06:30 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-27 01:40:27 +00:00
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case 'r': // "Sr"
|
2015-10-11 20:52:53 +00:00
|
|
|
if (input[1] == ' ') {
|
2012-06-14 08:01:16 +00:00
|
|
|
RIOSection *s;
|
2016-09-20 09:34:08 +00:00
|
|
|
// int len = 0;
|
2014-05-28 02:34:12 +00:00
|
|
|
ut64 vaddr;
|
2015-10-11 20:52:53 +00:00
|
|
|
char *p = strchr (input + 2, ' ');
|
2012-06-14 08:01:16 +00:00
|
|
|
if (p) {
|
2016-08-23 22:23:14 +00:00
|
|
|
*p = 0;
|
2015-10-11 20:52:53 +00:00
|
|
|
vaddr = r_num_math (core->num, p + 1);
|
2016-09-20 09:34:08 +00:00
|
|
|
// len = (int)(size_t)(p-input + 2);
|
2015-10-11 20:52:53 +00:00
|
|
|
} else {
|
|
|
|
vaddr = core->offset;
|
|
|
|
}
|
2014-05-28 02:34:12 +00:00
|
|
|
s = r_io_section_vget (core->io, vaddr);
|
2012-06-14 08:01:16 +00:00
|
|
|
if (s) {
|
2016-08-23 22:23:14 +00:00
|
|
|
char *oldname = s->name;
|
|
|
|
s->name = strdup (input + 2);
|
|
|
|
//update flag space for the given section
|
|
|
|
update_section_flag_at_with_oldname (s, core->flags, s->vaddr, oldname);
|
|
|
|
free (oldname);
|
2015-10-11 20:52:53 +00:00
|
|
|
} else {
|
2016-08-23 22:23:14 +00:00
|
|
|
eprintf ("No section found in 0x%08"PFMT64x"\n", core->offset);
|
2015-10-11 20:52:53 +00:00
|
|
|
}
|
|
|
|
} else {
|
2017-07-26 13:46:38 +00:00
|
|
|
r_core_cmd_help (core, help_msg_Sr);
|
2015-10-11 20:52:53 +00:00
|
|
|
}
|
2012-06-14 08:01:16 +00:00
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case 'd': // "Sd"
|
2012-02-27 01:40:27 +00:00
|
|
|
{
|
2016-01-03 23:24:18 +00:00
|
|
|
char *file = NULL;
|
|
|
|
int len = 128;
|
|
|
|
switch (input[1]) {
|
|
|
|
case 0:
|
2017-03-30 00:20:22 +00:00
|
|
|
(void) dumpSectionToDisk (core, NULL);
|
2016-01-03 23:24:18 +00:00
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case ' ': // "Sd "
|
2016-01-03 23:24:18 +00:00
|
|
|
if (input[2]) {
|
2017-04-17 20:02:04 +00:00
|
|
|
file = (char *)calloc (len, sizeof (char));
|
|
|
|
if (file) {
|
|
|
|
snprintf (file, len, "%s", input + 2);
|
|
|
|
}
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
2017-03-30 00:20:22 +00:00
|
|
|
(void) dumpSectionToDisk (core, file);
|
2016-01-07 13:08:25 +00:00
|
|
|
free (file);
|
2016-01-03 23:24:18 +00:00
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case 'a': // "Sda"
|
2017-03-30 00:20:22 +00:00
|
|
|
(void)dumpSectionsToDisk (core);
|
2016-01-03 23:24:18 +00:00
|
|
|
break;
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case 'l': // "Sl"
|
2012-02-27 01:40:27 +00:00
|
|
|
{
|
|
|
|
ut64 o = core->offset;
|
2017-08-22 07:42:16 +00:00
|
|
|
SdbListIter *iter;
|
2012-02-27 01:40:27 +00:00
|
|
|
RIOSection *s;
|
|
|
|
if (input[1] != ' ') {
|
2017-07-26 13:46:38 +00:00
|
|
|
r_core_cmd_help (core, help_msg_Sl);
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
2016-10-06 22:54:24 +00:00
|
|
|
if (core->io->va || core->io->debug) {
|
2017-08-22 07:42:16 +00:00
|
|
|
s = r_io_section_vget (core->io, core->offset);
|
|
|
|
o = s ? core->offset - s->vaddr + s->paddr : core->offset;
|
2016-10-06 22:54:24 +00:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (core->io->sections, iter, s) {
|
2017-03-15 01:22:54 +00:00
|
|
|
if (o >= s->paddr && o < s->paddr + s->size) {
|
2012-02-27 01:40:27 +00:00
|
|
|
int sz;
|
2015-10-11 20:52:53 +00:00
|
|
|
char *buf = r_file_slurp (input + 2, &sz);
|
2014-10-26 12:50:58 +00:00
|
|
|
// TODO: use mmap here. we need a portable implementation
|
2012-02-27 01:40:27 +00:00
|
|
|
if (!buf) {
|
2015-10-11 20:52:53 +00:00
|
|
|
eprintf ("Cannot allocate 0x%08"PFMT64x""
|
|
|
|
" bytes\n", s->size);
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
|
|
|
r_io_write_at (core->io, s->vaddr, (const ut8*)buf, sz);
|
2017-12-27 17:33:58 +00:00
|
|
|
eprintf ("Loaded %d byte(s) into the map region "
|
2015-10-11 20:52:53 +00:00
|
|
|
" at 0x%08"PFMT64x"\n", sz, s->vaddr);
|
2012-02-27 01:40:27 +00:00
|
|
|
free (buf);
|
2015-09-14 10:35:38 +00:00
|
|
|
return true;
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
eprintf ("No debug region found here\n");
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case '-': // "S-"
|
2015-10-11 20:52:53 +00:00
|
|
|
// remove all sections
|
2016-10-06 22:54:24 +00:00
|
|
|
if (input[1] == '*') {
|
|
|
|
r_io_section_init (core->io);
|
|
|
|
}
|
|
|
|
if (input[1] == '.') {
|
|
|
|
RIOSection *s = r_io_section_vget (core->io, core->offset);
|
|
|
|
if (!s) {
|
|
|
|
return 0;
|
|
|
|
}
|
2012-02-27 01:40:27 +00:00
|
|
|
// use offset
|
|
|
|
r_io_section_rm (core->io, s->id);
|
2016-10-06 22:54:24 +00:00
|
|
|
}
|
|
|
|
if (input[1]) {
|
|
|
|
r_io_section_rm (core->io, atoi (input + 1));
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case ' ': // "S "
|
2012-02-27 01:40:27 +00:00
|
|
|
switch (input[1]) {
|
2017-08-28 08:17:34 +00:00
|
|
|
case '-': // "S -" remove
|
2015-10-11 20:52:53 +00:00
|
|
|
if (input[2] == '?' || input[2] == '\0') {
|
|
|
|
eprintf ("Usage: S -N # where N is the "
|
|
|
|
" section index\n");
|
|
|
|
} else {
|
|
|
|
r_io_section_rm (core->io, atoi (input + 1));
|
|
|
|
}
|
2012-02-27 01:40:27 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
int i, rwx = 7;
|
2015-10-11 20:52:53 +00:00
|
|
|
char *ptr = strdup (input + 1);
|
2012-02-27 01:40:27 +00:00
|
|
|
const char *name = NULL;
|
2013-06-08 23:09:47 +00:00
|
|
|
char vname[64];
|
2012-02-27 01:40:27 +00:00
|
|
|
ut64 vaddr = 0LL;
|
2017-08-28 08:17:34 +00:00
|
|
|
ut64 paddr = 0LL;
|
2012-02-27 01:40:27 +00:00
|
|
|
ut64 size = 0LL;
|
|
|
|
ut64 vsize = 0LL;
|
2017-09-04 14:23:09 +00:00
|
|
|
int bin_id = -1;
|
2017-09-04 13:05:12 +00:00
|
|
|
int fd = r_core_file_cur_fd (core);
|
2012-02-27 01:40:27 +00:00
|
|
|
i = r_str_word_set0 (ptr);
|
|
|
|
switch (i) {
|
2017-09-04 14:23:09 +00:00
|
|
|
case 7: //get bin id
|
|
|
|
bin_id = r_num_math (core->num, r_str_word_get0 (ptr, 6));
|
2012-02-27 01:40:27 +00:00
|
|
|
case 6: // get rwx
|
|
|
|
rwx = r_str_rwx (r_str_word_get0 (ptr, 5));
|
|
|
|
case 5: // get name
|
|
|
|
name = r_str_word_get0 (ptr, 4);
|
|
|
|
case 4: // get vsize
|
2016-10-06 22:54:24 +00:00
|
|
|
vsize = r_num_math (core->num, r_str_word_get0 (ptr, 3));
|
2012-02-27 01:40:27 +00:00
|
|
|
case 3: // get size
|
2016-10-06 22:54:24 +00:00
|
|
|
size = r_num_math (core->num, r_str_word_get0 (ptr, 2));
|
2012-02-27 01:40:27 +00:00
|
|
|
case 2: // get vaddr
|
2016-10-06 22:54:24 +00:00
|
|
|
vaddr = r_num_math (core->num, r_str_word_get0 (ptr, 1));
|
2017-08-28 08:17:34 +00:00
|
|
|
case 1: // get paddr
|
|
|
|
paddr = r_num_math (core->num, r_str_word_get0 (ptr, 0));
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
2016-10-06 22:54:24 +00:00
|
|
|
if (!vsize) {
|
2013-06-08 23:09:47 +00:00
|
|
|
vsize = size;
|
2016-10-06 22:54:24 +00:00
|
|
|
if (i > 3) {
|
|
|
|
name = r_str_word_get0 (ptr, 3);
|
|
|
|
}
|
|
|
|
if (i > 4) {
|
|
|
|
rwx = r_str_rwx (r_str_word_get0 (ptr, 4));
|
|
|
|
}
|
2013-06-08 23:09:47 +00:00
|
|
|
}
|
|
|
|
if (!name || !*name) {
|
2017-08-22 07:42:16 +00:00
|
|
|
sprintf (vname, "area%d", (int)ls_length (core->io->sections));
|
2013-06-08 23:09:47 +00:00
|
|
|
name = vname;
|
|
|
|
}
|
2017-09-04 14:23:09 +00:00
|
|
|
RIOSection *sec = r_io_section_add (core->io, paddr, vaddr, size, vsize, rwx, name, bin_id, fd);
|
2017-09-04 13:05:12 +00:00
|
|
|
r_io_create_mem_for_section (core->io, sec);
|
2012-02-27 01:40:27 +00:00
|
|
|
free (ptr);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case '.': // "S."
|
|
|
|
if (input[1] == '-') { // "S.-"
|
2016-11-04 11:21:42 +00:00
|
|
|
ut64 o = core->offset;
|
2017-08-22 07:42:16 +00:00
|
|
|
SdbListIter *iter, *iter2;
|
2016-11-04 11:21:42 +00:00
|
|
|
RIOSection *s;
|
|
|
|
if (core->io->va || core->io->debug) {
|
2017-08-22 07:42:16 +00:00
|
|
|
s = r_io_section_vget (core->io, o);
|
|
|
|
o = s ? o - s->vaddr + s->paddr : o;
|
2016-11-04 11:21:42 +00:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach_safe (core->io->sections, iter, iter2, s) {
|
2017-03-15 01:22:54 +00:00
|
|
|
if (o >= s->paddr && o < s->paddr + s->size) {
|
2016-11-04 11:21:42 +00:00
|
|
|
r_io_section_rm (core->io, s->id);
|
|
|
|
if (input[2] != '*') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ut64 o = core->offset;
|
2017-08-22 07:42:16 +00:00
|
|
|
SdbListIter *iter;
|
2016-11-04 11:21:42 +00:00
|
|
|
RIOSection *s;
|
|
|
|
if (core->io->va || core->io->debug) {
|
2017-08-22 07:42:16 +00:00
|
|
|
s = r_io_section_vget (core->io, o);
|
|
|
|
o = s ? o - s->vaddr + s->paddr : o;
|
2016-11-04 11:21:42 +00:00
|
|
|
}
|
2017-05-14 21:16:35 +00:00
|
|
|
if (input[1] == 'j') { // "S.j"
|
|
|
|
r_cons_printf ("[");
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (core->io->sections, iter, s) {
|
2017-05-14 21:16:35 +00:00
|
|
|
if (o >= s->paddr && o < s->paddr + s->size) {
|
|
|
|
char *name = r_str_escape (s->name);
|
|
|
|
r_cons_printf ("{\"start\":%" PFMT64u ",\"end\":%" PFMT64u ",\"name\":\"%s\"}",
|
|
|
|
s->paddr + s->vaddr,
|
|
|
|
s->paddr + s->vaddr + s->size,
|
|
|
|
name);
|
|
|
|
free (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
r_cons_printf ("]");
|
|
|
|
} else {
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (core->io->sections, iter, s) {
|
2017-05-14 21:16:35 +00:00
|
|
|
if (o >= s->paddr && o < s->paddr + s->size) {
|
|
|
|
r_cons_printf ("0x%08"PFMT64x" 0x%08"PFMT64x" %s\n",
|
|
|
|
s->paddr + s->vaddr,
|
|
|
|
s->paddr + s->vaddr + s->size,
|
|
|
|
s->name);
|
|
|
|
break;
|
|
|
|
}
|
2016-11-04 11:21:42 +00:00
|
|
|
}
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-08-28 08:17:34 +00:00
|
|
|
case '\0': // "S"
|
|
|
|
case '=': // "S="
|
|
|
|
case '*': // "S*"
|
2017-08-25 23:05:22 +00:00
|
|
|
__section_list (core->io, core->offset, core->print, *input);
|
2012-02-27 01:40:27 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|