Fix #14647 - Add output of sections to segments mapping for ELFs (#16045)

Add output of sections to segments mapping for ELFs
This commit is contained in:
kuqadk3 2020-03-02 12:44:49 +07:00 committed by GitHub
parent 76c90e30ce
commit 53f21d9ae6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 2 deletions

View File

@ -2504,6 +2504,52 @@ struct io_bin_section_info_t {
int fd;
};
/* Map Sections to Segments https://github.com/radareorg/radare2/issues/14647 */
static int bin_map_sections_to_segments (RBin *bin, int mode) {
RListIter *iter, *iter2;
RBinSection *section = NULL, *segment = NULL;
RList *sections = r_list_new ();
RList *segments = r_list_new ();
RList *tmp = r_bin_get_sections (bin);
char *json_output = r_str_new ("");
RTable *table = r_table_new ();
RTableColumnType *typeString = r_table_type ("string");
r_table_add_column (table, typeString, "Segment", 0);
r_table_add_column (table, typeString, "Section", 0);
r_list_foreach (tmp, iter, section) {
RList *list = section->is_segment? segments: sections;
r_list_append (list, section);
}
char *tmp2 = NULL;
r_list_foreach (segments, iter, segment) {
RInterval segment_itv = (RInterval){segment->vaddr, segment->size};
tmp2 = r_str_new ("");
r_list_foreach (sections, iter2, section) {
RInterval section_itv = (RInterval){section->vaddr, section->size};
if (r_itv_begin (section_itv) >= r_itv_begin (segment_itv) && r_itv_end (section_itv) <= r_itv_end (segment_itv) && section->name[0]) {
tmp2 = r_str_appendf (tmp2, "%s ", section->name);
}
}
r_table_add_row (table, segment->name, tmp2, 0);
/*output to json*/
json_output = r_str_appendf (json_output, "\"%s\": \"%s\",", segment->name, tmp2);
}
// remove last ,
json_output [strlen (json_output) - 1] = 0;
json_output = r_str_newf ("[{%s}]", json_output);
if (IS_MODE_JSON (mode)){
r_cons_printf ("%s", json_output);
} else if (IS_MODE_NORMAL (mode)){
r_cons_printf ("Section to Segment mapping:\n");
r_cons_printf ("%s\n", r_table_tostring (table));
}
return true;
}
static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const char *name, const char *chksum, bool print_segments) {
char *str = NULL;
RBinSection *section;
@ -3917,6 +3963,9 @@ R_API int r_core_bin_info(RCore *core, int action, int mode, int va, RCoreBinFil
if ((action & R_CORE_BIN_ACC_SEGMENTS)) {
ret &= bin_sections (core, mode, loadaddr, va, at, name, chksum, true);
}
if ((action & R_CORE_BIN_ACC_SECTIONS_MAPPING)) {
ret &= bin_map_sections_to_segments (core->bin, mode);
}
if (r_config_get_i (core->config, "bin.relocs")) {
if ((action & R_CORE_BIN_ACC_RELOCS)) {
ret &= bin_relocs (core, mode, va);

View File

@ -66,6 +66,7 @@ R_LIB_VERSION_HEADER (r_bin);
#define R_BIN_REQ_HASHES 0x40000000
#define R_BIN_REQ_SIGNATURE 0x80000000
#define R_BIN_REQ_TRYCATCH 0x100000000
#define R_BIN_REQ_SECTIONS_MAPPING 0x200000000
/* RBinSymbol->method_flags : */
#define R_BIN_METH_CLASS 0x0000000000000001L

View File

@ -717,6 +717,7 @@ R_API void r_core_recover_vars(RCore *core, RAnalFunction *fcn, bool argonly);
#define R_CORE_BIN_ACC_SOURCE 0x800000
#define R_CORE_BIN_ACC_HASHES 0x10000000
#define R_CORE_BIN_ACC_TRYCATCH 0x20000000
#define R_CORE_BIN_ACC_SECTIONS_MAPPING 0x40000000
#define R_CORE_BIN_ACC_ALL 0x504FFF
#define R_CORE_PRJ_FLAGS 0x0001

View File

@ -29,7 +29,7 @@ static int rabin_show_help(int v) {
" -E globally exportable symbols\n"
" -f [str] select sub-bin named str\n"
" -F [binfmt] force to use that bin plugin (ignore header check)\n"
" -g same as -SMZIHVResizcld -SS -ee (show all info)\n"
" -g same as -SMZIHVResizcld -SS -SSS -ee (show all info)\n"
" -G [addr] load address . offset to header\n"
" -h this help message\n"
" -H header fields\n"
@ -57,6 +57,7 @@ static int rabin_show_help(int v) {
" -s symbols\n"
" -S sections\n"
" -SS segments\n"
" -SSS sections mapping to segments\n"
" -t display file hashes\n"
" -T display file signature\n"
" -u unfiltered (no rename duplicated symbols/sections)\n"
@ -649,6 +650,7 @@ R_API int r_main_rabin2(int argc, char **argv) {
set_action (R_BIN_REQ_SYMBOLS);
set_action (R_BIN_REQ_SECTIONS);
set_action (R_BIN_REQ_SEGMENTS);
set_action (R_BIN_REQ_SECTIONS_MAPPING);
set_action (R_BIN_REQ_STRINGS);
set_action (R_BIN_REQ_SIZE);
set_action (R_BIN_REQ_INFO);
@ -700,7 +702,10 @@ R_API int r_main_rabin2(int argc, char **argv) {
set_action (R_BIN_REQ_SYMBOLS);
break;
case 'S':
if (is_active (R_BIN_REQ_SECTIONS)) {
if (is_active (R_BIN_REQ_SEGMENTS)) {
action &= ~R_BIN_REQ_SEGMENTS;
action |= R_BIN_REQ_SECTIONS_MAPPING;
} else if (is_active (R_BIN_REQ_SECTIONS)) {
action &= ~R_BIN_REQ_SECTIONS;
action |= R_BIN_REQ_SEGMENTS;
} else {
@ -1150,6 +1155,7 @@ R_API int r_main_rabin2(int argc, char **argv) {
run_action ("versioninfo", R_BIN_REQ_VERSIONINFO, R_CORE_BIN_ACC_VERSIONINFO);
run_action ("sections", R_BIN_REQ_SIGNATURE, R_CORE_BIN_ACC_SIGNATURE);
run_action ("hashes", R_BIN_REQ_HASHES, R_CORE_BIN_ACC_HASHES);
run_action ("sections mapping", R_BIN_REQ_SECTIONS_MAPPING, R_CORE_BIN_ACC_SECTIONS_MAPPING);
if (action & R_BIN_REQ_SRCLINE) {
rabin_show_srcline (bin, at);
}

View File

@ -104,6 +104,16 @@ EXPECT=<<EOF
EOF
RUN
NAME=rabin2 -SSS
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=<<EOF
!rabin2 -SSS ${R2_FILE}|wc -l|awk "{print \$1}"
EOF
EXPECT=<<EOF
13
EOF
RUN
NAME=rabin2 -z pe
FILE=../bins/pe/a.exe
CMDS=!rabin2 -z ${R2_FILE}|wc -l|awk "{print \$1}"
@ -625,6 +635,19 @@ Version need section '.gnu.version_r' contains 1 entries:
Addr: 0x08048250 Offset: 0x00000250 Link to section: 6 (.dynstr)
0x00000000: Version: 1 File: libc.so.6 Cnt: 1
0x00000010: Name: GLIBC_2.0 Flags: none Version: 2
Section to Segment mapping:
Segment Section
--------------------
PHDR
INTERP .interp
LOAD0 .interp .note.ABI_tag .note.gnu.build_id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
LOAD1 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
DYNAMIC .dynamic
NOTE .note.ABI_tag .note.gnu.build_id
GNU_EH_FRAME .eh_frame_hdr
GNU_STACK
ehdr
EOF
RUN