/** * Symbol resolving handler for libasm. * Runtime compatible * @param data * @param vaddr * @param buf * @param maxlen */ void asm_do_resolve(void *data, eresi_Addr vaddr, char *buf, u_int maxlen) { elfshobj_t *file; elfshsect_t *parent; char *name; elfsh_SAddr off; int len; char *sep; uint32_t addr; /* Retreive the nearest symbol */ file = data; parent = elfsh_get_parent_section(file, vaddr, 0); if (NULL != parent && parent->shdr->sh_addr) name = revm_resolve(file, vaddr, &off); else name = NULL; /* Print the symbol name in 'buf' so that libasm can print it */ len = (NULL == name ? 10 : strlen(name) + 25); if (name != NULL && *name != 0x00) { sep = (off > 0 ? " + " : off < 0 ? " - " : ""); len = snprintf(buf, maxlen - 1, "%s%s%s%s", revm_colorfieldstr("<"), revm_colortypestr(name), (off ? revm_colorfieldstr(sep) : ""), (off ? "" : revm_colorfieldstr(">"))); if (off) snprintf(buf + len, maxlen - len - 1, "%s%s", revm_colornumber("%u", (u_int) off), revm_colorfieldstr(">")); } /* We currently only disassemble architecture with 32bits address space, even when 64b proc */ else { addr = (uint32_t) vaddr; snprintf(buf, maxlen, "0x%X", addr); } }
/** * Print a specific type * * @param type * @param mode * @return */ int revm_type_print(char *type, char mode) { aspectype_t *cur; aspectype_t *child; char buf[BUFSIZ]; char prefix[128]; int len; char *size; char offset[128]; int idx; int sz; char *pad; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); cur = hash_get(&types_hash, type); if (!cur) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unknown type", 0); /* Set up things */ revm_endline(); /* Setup first part of the line */ snprintf(prefix, sizeof(prefix), "%s%s%s", revm_colorfieldstr("{"), revm_colornumber("%u", cur->size), revm_colorfieldstr("}")); len = snprintf(buf, sizeof(buf), " %s %s %-20s %s %-10s", revm_colornumber("id:%-10u", cur->type), revm_colorfieldstr("Type"), revm_colortypestr_fmt("%-20s", type), revm_colorfieldstr("size"), prefix); size = alloca(20); /* If the type is a structure */ if (cur->childs) { len += snprintf(buf + len, sizeof(buf) - len, "%s", revm_colorfieldstr(" = {")); /* Prepare the padding after each field name */ sz = len - revm_color_size(buf) - 16; /* -16 is dirty: some bug in colors */ pad = alloca(sz + 1); memset(pad, ' ', sz); pad[sz] = 0x00; /* For each child field type */ for (child = cur->childs; child; child = child->next) { /* Compute the size field */ if (child->type == ASPECT_TYPE_RAW) snprintf(size, sizeof(size), "%s%s%s", revm_colorfieldstr("["), revm_colornumber("%u", child->size), revm_colorfieldstr("]")); else if (child->dimnbr && child->elemnbr) { for (sz = idx = 0; idx < child->dimnbr; idx++) sz += 20; size = alloca(sz); for (sz = idx = 0; idx < child->dimnbr; idx++) sz += snprintf(size + sz, sz, "%s%s%s", revm_colorfieldstr("["), revm_colornumber("%u", child->elemnbr[idx]), revm_colorfieldstr("]")); } else *size = 0x00; /* Format the whole thing */ if (mode) *offset = 0x00; else snprintf(offset, sizeof(offset), "%s%s", revm_colornumber("%u", child->off), revm_colorfieldstr(":")); len += snprintf(buf + len, sizeof(buf) - len, "%s%s%s%s%s%s%s", offset, revm_colorstr(child->fieldname), revm_colorfieldstr(":"), revm_colortypestr((child->isptr ? "*" : "")), revm_colortypestr(child->name), size, revm_colorfieldstr((child->next ? ",\n" : "}\n\n"))); /* Print field and next padding */ revm_output(buf); revm_endline(); if (child->next) revm_output(pad); *buf = 0x00; len = 0; } } /* Print non-structures types */ else { revm_output(buf); revm_output("\n"); } /* Return success */ PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 1); }
/** * @brief Display relocation entries */ int cmd_rel() { elfshsect_t *sect; elfsh_Rel *rel; regex_t *tmp; char *type; char *typeshort; char *name; u_int index; u_int index2; u_int typenum; char buff[256]; u_int size; revmconst_t *types; char addstr[32]; char logbuf[BUFSIZ]; void *data; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); /* Sanity checks */ sect = elfsh_get_reloc(world.curjob->curfile, 0, &size); if (sect == NULL) RET(-1); /* Choose between global or local regx */ FIRSTREGX(tmp); snprintf(logbuf, BUFSIZ - 1, " [RELOCATION TABLES]\n [Object %s]\n\n", world.curjob->curfile->name); revm_output(logbuf); /* We need to iterate as much as there is .rel* sections */ for (index2 = 0; sect; index2++) { snprintf(logbuf, BUFSIZ - 1, " {Section %s} \n", elfsh_get_section_name(world.curjob->curfile, sect)); revm_output(logbuf); /* Iterate on the .rel entries array for each .rel section */ data = elfsh_readmem(sect); for (index = 0; index < size; index++) { /* Get the current relocation entry */ if (sect->shdr->sh_type == SHT_RELA) { rel = (void *) ((elfsh_Rela *) data + index); snprintf(addstr, sizeof(addstr), "add[%s]", revm_colornumber("%08u", (unsigned int) ((elfsh_Rela *) rel)->r_addend)); } else { rel = (elfsh_Rel *) data + index; addstr[0] = 0x00; } /* Get linked symbol name */ name = elfsh_get_symname_from_reloc(world.curjob->curfile, rel); typenum = elfsh_get_reltype(rel); types = revm_getrelascii(world.curjob->curfile); type = (char *) (typenum > ELFSH_RELOC_MAX(world.curjob->curfile) ? NULL : types[typenum].desc); typeshort = (char *) (typenum > ELFSH_RELOC_MAX(world.curjob->curfile) ? NULL : types[typenum].name); /* Output is different depending on the quiet flag */ if (!world.state.revm_quiet) snprintf(buff, sizeof(buff), " [%s] %s %s %s%s%s : %s %s => %s\n", revm_colornumber("%03u", index), revm_colortypestr_fmt("%-15s", typeshort), revm_coloraddress(XFMT, elfsh_get_reloffset(rel)), revm_colorfieldstr("sym["), revm_colornumber("%03u", elfsh_get_relsym(rel)), revm_colorfieldstr("]"), (name != NULL ? revm_colorstr_fmt("%-30s", name) : revm_colorwarn_fmt("%-30s", "<?>")), addstr, revm_colortypestr(type)); else snprintf(buff, sizeof(buff), " [%s] %s %s %s%s%s : %s %s\n", revm_colornumber("%03u", index), revm_colortypestr_fmt("%-15s", typeshort), revm_coloraddress(XFMT, elfsh_get_reloffset(rel)), revm_colorfieldstr("sym["), revm_colornumber("%03u", elfsh_get_relsym(rel)), revm_colorfieldstr("]"), (name != NULL ? revm_colorstr_fmt("%-22s", name) : revm_colorwarn_fmt("%-22s", "<?>")), addstr); /* Print it if it matchs the regex */ if (NULL == tmp || (tmp != NULL && name != NULL && 0 == regexec(tmp, buff, 0, 0, 0))) switch (revm_output(buff)) { case -1: revm_endline(); revm_output("\n"); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); case -2: revm_endline(); goto next; } revm_endline(); } next: sect = elfsh_get_reloc(world.curjob->curfile, index2 + 1, &size); revm_output("\n"); } revm_output("\n"); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/** * @brief Display a PHT * @param phdr * @param num * @param base */ void revm_pht_print(elfsh_Phdr *phdr, uint16_t num, eresi_Addr base) { elfsh_Shdr *shdr; int shtnum; int index; int index2; char *type; u_int typenum; elfshsect_t *list; regex_t *tmp; char buff[512]; char warnmsg[256]; char logbuf[BUFSIZ]; int check; eresi_Addr addr; eresi_Addr addr_end; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); FIRSTREGX(tmp); /* Primary view (2 modes, depending on the quiet flag) */ for (index = 0; index < num; index++) { typenum = elfsh_get_segment_type(phdr + index); type = (char *) (typenum >= ELFSH_SEGTYPE_MAX ? revm_display_pdesc(typenum) : elfsh_seg_type[typenum].desc); addr = phdr[index].p_vaddr; addr_end = phdr[index].p_vaddr + phdr[index].p_memsz; if (elfsh_is_runtime_mode()) { addr_end += base; addr += base; } /* We check if we have a correct alignment */ check = (addr - phdr[index].p_offset) & (phdr[index].p_align - 1); if (check != 0) snprintf(warnmsg, 255, "Wrong alignment (%d)", check); if (!world.state.revm_quiet) snprintf(buff, sizeof(buff), " %s %s -> %s %c%c%c %s%s%s " "%s%s%s %s%s%s %s%s%s => %s %s\n", revm_colornumber("[%02u]", index), revm_coloraddress(XFMT, addr), revm_coloraddress(XFMT, addr_end), (elfsh_segment_is_readable(&phdr[index]) ? 'r' : '-'), (elfsh_segment_is_writable(&phdr[index]) ? 'w' : '-'), (elfsh_segment_is_executable(&phdr[index]) ? 'x' : '-'), revm_colorfieldstr("memsz("), revm_colornumber(UFMT, phdr[index].p_memsz), revm_colorfieldstr(")"), revm_colorfieldstr("foffset("), revm_colornumber(UFMT, phdr[index].p_offset), revm_colorfieldstr(")"), revm_colorfieldstr("filesz("), revm_colornumber(UFMT, phdr[index].p_filesz), revm_colorfieldstr(")"), revm_colorfieldstr("align("), revm_colornumber(UFMT, phdr[index].p_align), revm_colorfieldstr(")"), revm_colortypestr(type), check != 0 ? revm_colorwarn(warnmsg) : "" ); else snprintf(buff, sizeof(buff), " %s %s -> %s %c%c%c %s%s%s " "%s%s%s %s%s%s\n", revm_colornumber("[%02u]", index), revm_coloraddress(XFMT, addr), revm_coloraddress(XFMT, addr_end), (elfsh_segment_is_readable(&phdr[index]) ? 'r' : '-'), (elfsh_segment_is_writable(&phdr[index]) ? 'w' : '-'), (elfsh_segment_is_executable(&phdr[index]) ? 'x' : '-'), revm_colorfieldstr("memsz("), revm_colornumber(UFMT, phdr[index].p_memsz), revm_colorfieldstr(")"), revm_colorfieldstr("foffset("), revm_colornumber(UFMT, phdr[index].p_offset), revm_colorfieldstr(")"), revm_colorfieldstr("filesz("), revm_colornumber(UFMT, phdr[index].p_filesz), revm_colorfieldstr(")")); if (!tmp || (tmp && !regexec(tmp, buff, 0, 0, 0))) revm_output(buff); revm_endline(); } snprintf(logbuf, BUFSIZ - 1, "\n [SHT correlation]" "\n [Object %s]\n\n", world.curjob->curfile->name); revm_output(logbuf); /* Retreive the sht */ if ((shdr = elfsh_get_sht(world.curjob->curfile, &shtnum)) == 0) PROFILER_OUT(__FILE__, __FUNCTION__, __LINE__); snprintf(logbuf, BUFSIZ - 1, " [*] SHT %s \n", (world.curjob->curfile->shtrb ? "has been rebuilt \n" : "is not stripped \n")); revm_output(logbuf); /* Alternate View */ for (index = 0; index < num; index++, index2 = 0) { typenum = elfsh_get_segment_type(phdr + index); type = (char *) (typenum >= ELFSH_SEGTYPE_MAX ? revm_display_pname(typenum) : elfsh_seg_type[typenum].name); snprintf(logbuf, BUFSIZ - 1, " %s %s \t", revm_colornumber("[%02u]", index), revm_colortypestr_fmt("%-10s", type)); revm_output(logbuf); revm_endline(); /* In SHT */ for (index2 = 0, list = world.curjob->curfile->sectlist; list; list = list->next) if (elfsh_segment_is_parent(list, phdr + index)) { index2++; snprintf(logbuf, BUFSIZ - 1, "%s%s ", (list->shdr->sh_offset + list->shdr->sh_size > phdr[index].p_offset + phdr[index].p_filesz ? "|" : ""), revm_colorstr(elfsh_get_section_name(world.curjob->curfile, list))); revm_output(logbuf); revm_endline(); } /* In RSHT */ for (index2 = 0, list = world.curjob->curfile->rsectlist; list; list = list->next) if (elfsh_segment_is_parent(list, phdr + index)) { index2++; snprintf(logbuf, BUFSIZ - 1, "%s%s ", (list->shdr->sh_addr + list->shdr->sh_size > phdr[index].p_vaddr + phdr[index].p_memsz ? "|" : ""), revm_colorstr(elfsh_get_section_name(world.curjob->curfile, list))); revm_output(logbuf); revm_endline(); } revm_output("\n"); } PROFILER_OUT(__FILE__, __FUNCTION__, __LINE__); }