Logo Search packages:      
Sourcecode: eresi version File versions  Download package

int revm_object_display ( elfshsect_t parent,
elfsh_Sym *  sym,
int  size,
u_int  off,
u_int  foffset,
eresi_Addr  vaddr,
char *  name,
char  otype 
)

Disassemble a function.

Parameters:
parent 
sym 
size 
off 
foffset 
vaddr 
name 
otype 
Returns:

Definition at line 328 of file disasm.c.

References s_rehdr::base, buf, s_sect::data, elfsh_get_parent_section(), elfsh_get_raw(), elfsh_get_symbol_type(), elfsh_is_debug_mode(), elfsh_is_pltentry(), elfsh_reverse_dynsymbol(), elfsh_reverse_symbol(), s_sect::name, s_sect::parent, revm_instr_display(), revm_output(), s_obj::rhdr, s_sect::shdr, strcat(), and strcmp().

Referenced by cmd_inspect(), e2dbg_do_breakpoint(), revm_match_special(), revm_match_symtab(), and revm_section_display().

{
  char            *buff;
  u_int           index;
  elfsh_SAddr   idx_bytes;
  char            buf[256];
  char            base[16] = "0123456789ABCDEF";
  eresi_Addr    loff;
  char            str[256];
  elfshsect_t     *targ;
  char            *s;
  u_int           ret;
  int       value;
  char            logbuf[BUFSIZ];
  char            tmp[BUFSIZ];
  char            c1[2], c2[2];
  char            *pStr;
  void            *tmpbuff;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (!parent)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                  "parent section is NULL", -1);

  /* Special case if the symbol is a plt entry */
  if (sym && elfsh_is_pltentry(parent->parent, sym) == 1 && 
      size > ELFSH_PLT_ENTRY_SIZE)
    size = ELFSH_PLT_ENTRY_SIZE;

#if __DEBUG_DISASM__
  snprintf(logbuf, BUFSIZ - 1, 
         "[debug:revm_object_display] %s off(%u) size(%u) vaddr(%08X) "
         "foffset(%u), parent(%p, %s) \n",
         name, off, size, vaddr, foffset, parent, 
         (parent ? parent->name : "UNK"));
  revm_output(logbuf);
#endif

  /* Get the pointer on relevant data */
  buff  = elfsh_get_raw(parent);
  index = off;
  buff += (vaddr - (parent->parent->rhdr.base + parent->shdr->sh_addr));

#if defined(KERNSH)  
  if (kernsh_is_mem_mode())
      parent->parent->rhdr.base = 0;
#endif  

  /* Filter requests on void sections (ex: bss when not inserted in file) */
  if (!parent || !parent->data)
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                  "No data at this address", -1);
  
  /* If the regex match a pointers array, print the pointed elements too */
  if (sym && 
      (elfsh_get_symbol_type(sym) == STT_OBJECT  ||
       elfsh_get_symbol_type(sym) == STT_COMMON) && 
      !(sym->st_size % sizeof(eresi_Addr)))
    {
      
      for (index = 0; index * sizeof(eresi_Addr) < sym->st_size; index++)
      {
        
        /* Do not print more than 250 entries at a time */
        /* Use an offset for more dumping */
        if (index >= 250)
          {
            revm_output("-- symbol size is bigger (use an offset) --\n");
            break;
          }
        
        /* For each entry of the array */
        /* Dont forget the section offset at the end */
        tmpbuff  = elfsh_get_raw(parent);
        tmpbuff += vaddr - (parent->parent->rhdr.base + parent->shdr->sh_addr);

#if defined(KERNSH)
        if (kernsh_is_mem_mode())
          parent->parent->rhdr.base = 0;
#endif

        tmpbuff += index * sizeof(eresi_Addr);
        loff     = * (eresi_Addr *) tmpbuff;
        
        snprintf(buf, sizeof(buf), " " AFMT " [foff: %u] \t %s[%0*u] = " XFMT, 
               elfsh_is_debug_mode() ? 
               parent->parent->rhdr.base + vaddr + index * sizeof(eresi_Addr) :
               vaddr   + index * sizeof(eresi_Addr), 
               foffset + index * sizeof(eresi_Addr), 
               name, 
               ((sym->st_size / sizeof(eresi_Addr)) < 100  ? 2 : 
                (sym->st_size / sizeof(eresi_Addr)) < 1000 ? 3 : 4),
               index,
               loff);

        /* If the target pointer is not valid */
        targ = elfsh_get_parent_section(parent->parent, loff, 
                                (elfsh_SAddr *) &off);
        if (targ == NULL || strcmp(targ->name, ELFSH_SECTION_NAME_RODATA))
          {
            s = elfsh_reverse_symbol(parent->parent, loff, &idx_bytes);
            if (NULL == s || idx_bytes > 1000)
            s = elfsh_reverse_dynsymbol(parent->parent, loff, &idx_bytes);
            if (NULL == s || idx_bytes > 1000)
            {
              if (targ != NULL)
                {
                  s = targ->name;
                  idx_bytes = off;
                }
              else
                idx_bytes = 0;
            }
            if (idx_bytes)
            snprintf(str, sizeof(str), "%s + %u", 
                   (s ? s : "<?>"), (u_int) idx_bytes);
            else
            snprintf(str, sizeof(str), "<IRREVELANT VADDR>");
            snprintf(logbuf, BUFSIZ, "%-75s %s \n", buf, str);
          }

        /* else if yes, print the pointed data too */
        else
          {
            s = elfsh_get_raw(targ);
            s += off;
            memcpy(str, s, 
                 (sizeof(str) > (targ->shdr->sh_size - off)) ?
                 targ->shdr->sh_size - off : sizeof(str));   
            snprintf(logbuf, BUFSIZ - 1, "%-75s \"%s\" \n", buf, str);
          }
        
        /* maybe the user asked to quit the display */
        revm_output(logbuf);
      }
    }
  
  
  
  /* We want asm + hexa output of the code */
  else if (otype == REVM_VIEW_DISASM)
    {
#if defined(KERNSH)
      if (!kernsh_is_present() && elfsh_is_debug_mode())
        vaddr += parent->parent->rhdr.base;
#else
      if (elfsh_is_debug_mode())
      vaddr += parent->parent->rhdr.base;
#endif

      idx_bytes = (sym ? vaddr + index - sym->st_value : index);
      
      while (index < size && size > 0)
      {
        value = revm_instr_display(-1, index, vaddr, 
                           foffset, size, name,
                           idx_bytes, buff);
        if (value <= 0)
          break;
        index += value;
        idx_bytes += value;
      }
    }

  /* We want hexa + ascii output of the data */
  else if (REVM_VIEW_HEX == otype)
    {
      if (name == NULL || !*name)
      name = ELFSH_NULL_STRING;

      while (index < size && size > 0)
      {
        /* Take care of quiet mode */
        if (world.state.revm_quiet)
          {
            sprintf(buf, " %s %s + %s", 
                  revm_coloraddress(AFMT, (eresi_Addr) vaddr + index), 
                  revm_colorstr(name), revm_colornumber("%u", index));
            snprintf(logbuf, BUFSIZ - 1, "%-40s ", buf);
            revm_output(logbuf);
          }
        else
          {
            sprintf(buf, " %s [%s %s] %s + %s", 
                  revm_coloraddress(AFMT, (eresi_Addr) vaddr + index), 
                  revm_colorfieldstr("foff:"),
                  revm_colornumber(DFMT, foffset + index), 
                  revm_colorstr(name), revm_colornumber("%u", index));
            snprintf(logbuf, BUFSIZ - 1, "%-*s", 60 + revm_color_size(buf), buf);
            revm_output(logbuf);
          }
        revm_endline();
        ret = (world.state.revm_quiet ? 8 : 16);
        tmp[0] = c1[1] = c2[1] = 0x00;

        /* Print hexa */
        for (loff = 0; loff < ret; loff++)
          {
            c1[0] = c2[0] = ' ';
            if (index + loff < size)
            {
              c1[0] = base[(buff[index + loff] >> 4) & 0x0F];
              c2[0] = base[(buff[index + loff] >> 0) & 0x0F];
            }
            snprintf(logbuf, BUFSIZ - 1, "%s%s ", c1, c2);
            if (strlen(tmp) + strlen(logbuf) < BUFSIZ)
            strcat(tmp, logbuf);
          }

        revm_output(revm_colorfieldstr(tmp));
        revm_endline();
        tmp[0] = 0x00;

        /* Print ascii */
        for (loff = 0; loff < ret; loff++)
          {
            c1[0] = buff[index + loff];
            pStr = (index + loff >= size ? " " : 
                  (PRINTABLE(buff[index + loff]) ? c1 : "."));
            if (strlen(tmp) + 1 < BUFSIZ)
            strcat(tmp, pStr);
          }

        revm_output(revm_colorstr(tmp));
        revm_endline();
        revm_output("\n");
        index += ret;
      }
  }

  revm_output("\n");
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}


Generated by  Doxygen 1.6.0   Back to index