Beispiel #1
0
/**
 * Retreive the file offset giving the virtual address
 * @param file
 * @param sym
 * @return
 */
int		elfsh_get_symbol_foffset(elfshobj_t *file, elfsh_Sym *sym)
{
  elfshsect_t	*sect;
  char		*name;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* If the symbol is a section, then look at the sht instead */
  if (elfsh_get_symbol_type(sym) == STT_SECTION)
    {
      name = elfsh_get_symbol_name(file, sym);
      sect = elfsh_get_section_by_name(file, name, NULL, NULL, NULL);
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 
			 (sect ? elfsh_get_section_foffset(sect->shdr) : 0));
    }

  /* get our parent section and compute the file offset */
  if (sym == NULL || file == NULL || NULL == sym->st_value)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
  sect = elfsh_get_parent_section(file, sym->st_value, NULL);
  if (sect == NULL)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 
		     (sect->shdr->sh_offset + 
		      (sym->st_value - sect->shdr->sh_addr)));
}
Beispiel #2
0
/**
 * Called from elfsh_fixup_symtab
 * When trying to inject part of the libc, some bss symbols have a wrong sctndx 
 * @param symtab
 * @return
 */
elfshsect_t   *elfsh_fixup_sctndx(elfshsect_t *symtab)
{
  int	        index;
  elfsh_Sym     *sym;
  elfsh_SAddr	offset;
  elfsh_Shdr	*shdr;
  elfshsect_t	*sct;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  //return (symtab); // XXX

  sym = symtab->data;
  shdr = symtab->parent->sht + symtab->index;

  for (index = 0; index < shdr->sh_size / sizeof(elfsh_Sym); index++)
  {
    if (elfsh_get_symbol_link(sym + index) != SHN_COMMON)
    {
      if (elfsh_get_symbol_type(sym + index) == STT_SECTION)
        continue;

      sct = elfsh_get_parent_section(symtab->parent, 
                                     elfsh_get_symbol_value(sym + index), 
                                     &offset);

      if (sct == NULL)
      {
        sct = elfsh_get_section_by_index(symtab->parent, 
                                         elfsh_get_symbol_link(sym + index), 
                                         NULL, 
                                         NULL);
        if (sct && elfsh_get_section_type(sct->shdr) == SHT_NOBITS)
        {

#if	__DEBUG_MAP__
          printf(" [*] Symbol [%s] sctndx changed from %u to SHN_COMMON\n", 
                 elfsh_get_symbol_name(symtab->parent, sym + index), 
                 elfsh_get_symbol_link(sym + index));
#endif

          elfsh_set_symbol_link(sym + index, SHN_COMMON);
          continue;
        }

      }

      if (sct && elfsh_get_section_type(sct->shdr) == SHT_NOBITS)
      {
        elfsh_set_symbol_link(sym + index, SHN_COMMON);
#if	__DEBUG_MAP__		  
        printf(" [*] Symbol [%s] sctndx changed to SHN_COMMON\n", 
               elfsh_get_symbol_name(symtab->parent, sym + index));
#endif
      }
    }
  }
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, symtab);
}
Beispiel #3
0
/**
 * Return the used offset in .strtab or -1 if failed 
 * @param file
 * @param s
 * @param name
 * @return
 */
int			elfsh_set_symbol_name(elfshobj_t	*file,
					      elfsh_Sym		*s,
					      char		*name)
{
  elfshsect_t		*sct;
  char			*str;
  u_int			len;
  u_int			new_len;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sanity checks */
  if (file == NULL || s == NULL || name == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		      "Invalid NULL parameter", -1);
  if (file->secthash[ELFSH_SECTION_SYMTAB] == NULL &&
      elfsh_get_symtab(file, NULL) == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Cannot retreive symbol table", -1);

  /* Also change the section name in .shstrtab if symbol is STT_SECTION */
  if (elfsh_get_symbol_type(s) == STT_SECTION)
    {
      sct = elfsh_get_section_from_sym(file, s);
      if (sct != NULL && elfsh_set_section_name(file, sct, name) < 0)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
			  "Unable to get section from its symbol", -1);
    }


  /* Else use the symbol string table */
  if (file->secthash[ELFSH_SECTION_STRTAB]       == NULL || 
      file->secthash[ELFSH_SECTION_STRTAB]->data == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "No STRTAB available", NULL);

  /* Change the name */
  str = file->secthash[ELFSH_SECTION_STRTAB]->data;
  str += s->st_name;
  len = strlen(str);
  new_len = strlen(name);

  /* Do not allocate new place if possible */
  if (len > new_len)
    strncpy(str, name, new_len + 1);
  /* Append the name to .strtab */
  else
    s->st_name = elfsh_insert_in_strtab(file, name);

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (s->st_name));
}
Beispiel #4
0
/**
 * The intermediate pass of theglobal algorithm for ET_REL injection
 * We fuze symbol tables from the ET_REL and the host binary
 *
 * @param file
 * @param rel
 * @return
 */
int		elfsh_fuse_etrel_symtab(elfshobj_t *file, elfshobj_t *rel)
{
    elfshsect_t	*sect;
    elfsh_Sym	newsym;
    elfsh_Half	type;
    u_int		index;
    char		sctname[BUFSIZ];
    elfsh_Sym	*sym;
    int		symnbr;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    sym = elfsh_get_symtab(rel, &symnbr);
    for (index = 0; index < symnbr; index++)
    {
        type = elfsh_get_symbol_type(sym + index);

        /* Avoid non-injectable symbols */
        if (type != STT_FUNC && type != STT_OBJECT)
            continue;

        if (sym[index].st_shndx >= rel->hdr->e_shnum)
            continue;

        /* Find target section in ET_REL */
        sect = elfsh_get_section_by_index(rel, sym[index].st_shndx, NULL, NULL);
        if (sect == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Cant find extracted section in ET_REL\n", -1);

        /* Filter symbols using source section */
        if (sect->shdr->sh_type != SHT_PROGBITS || !sect->shdr->sh_size ||
                !elfsh_get_section_allocflag(sect->shdr))
            continue;

        /* Find corresponding inserted section in ET_EXEC */
        snprintf(sctname, sizeof(sctname), "%s%s", rel->name, sect->name);
        sect = elfsh_get_section_by_name(file, sctname, NULL, NULL, NULL);
        if (sect == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Cant find inserted section in ET_EXEC\n", -1);

#if __DEBUG_RELADD__
        printf("[DEBUG_RELADD] Injected ET_REL symbol %-20s ["XFMT"] \n",
               elfsh_get_symbol_name(rel, sym + index),
               (eresi_Addr) (sect->shdr->sh_addr + sym[index].st_value));
#endif

        /* Add symbol in host file */
        newsym = elfsh_create_symbol(sect->shdr->sh_addr + sym[index].st_value,
                                     sym[index].st_size,
                                     elfsh_get_symbol_type(sym + index),
                                     elfsh_get_symbol_bind(sym + index),
                                     0, sect->index);

        if (elfsh_insert_symbol(file->secthash[ELFSH_SECTION_SYMTAB], &newsym,
                                elfsh_get_symbol_name(rel, sym + index)) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Unable to insert ET_REL symbol", -1);
    }

    /* Resynchronize sorted instances of symbol table */
    if (elfsh_sync_sorted_symtab(file->secthash[ELFSH_SECTION_SYMTAB]) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Unable to synchronize host symtab", -1);

    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Beispiel #5
0
/**
 * Relocate the just injected section
 * @param enew
 * @param reltab
 * @param stage
 * @return
 */
static int	elfsh_relocate_etrel_section(elfshsect_t	*enew,
        elfshsect_t	*reltab,
        u_char		stage)
{
    elfsh_Rel	*cur;
    volatile u_int		index;
    elfsh_Sym	*sym;
    volatile u_int		size;
    eresi_Addr	*dword;
    eresi_Addr   	addr;
    char		*name;
    char		tmpname[BUFSIZ];
    elfshsect_t	*sect;
    u_int		entsz;
    elfshsect_t   *plt;
    void		*data;
    elfsh_Half	symtype;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    /* ET_REL object is not mapped we use unconditionaly
       the ondisk relocation tables for such operation */
    data = reltab->data;

#if __DEBUG_RELADD__
    fprintf(stderr, "[DEBUG_RELADD] Using reloc table from %s [%s] data at %p \n",
            reltab->parent->name, reltab->name, data);
#endif

    /* Loop on the relocation table entries */
    size = (reltab->shdr->sh_type == SHT_RELA ?
            sizeof(elfsh_Rela) : sizeof(elfsh_Rel));
    size = reltab->shdr->sh_size / size;

    plt = elfsh_get_plt(enew->parent, NULL);
    if (NULL == plt && elfsh_dynamic_file(enew->parent))
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Unable to get plt", -1);

    entsz = elfsh_get_pltentsz(enew->parent);
    if (entsz < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Unable to get pltentsz", -1);

    for (index = 0; index < size; index++)
    {

#if __DEBUG_RELADD__
        fprintf(stderr, "[DEBUG_RELADD] relocation loop stage %u for section %s index %u \n",
                stage, enew->name, index);
#endif

        /* We try a enew relocation now that the ET_REL dependence is mapped */
retry:

        /* Get symbol value in ET_REL */
        cur = (reltab->shdr->sh_type == SHT_RELA ?
               (void *) (((elfsh_Rela *) data) + index) :
               (void *) (((elfsh_Rel  *) data) + index));
        sym  = elfsh_get_symbol_from_reloc(reltab->parent, cur);
        name = elfsh_get_symname_from_reloc(reltab->parent, cur);

        if (sym == NULL || name == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Unable to find symbol in ET_REL", -1);

        /* Grab a pointer on the dword that need to be relocated */
        dword = (eresi_Addr *) ((char *) elfsh_readmem(enew) + cur->r_offset);

        /*
        ** If symbol type is NOTYPE, we use ET_EXEC symtab, else if
        ** symbol link is COMMON, we use ET_REL symbol inserted in ET_EXEC
        ** during BSS sizescan in bss.c:elfsh_find_bsslen()
        */
        symtype = elfsh_get_symbol_type(sym);
        if (elfsh_get_symbol_bind(sym) != STB_LOCAL && /* patch BEOS */
                (symtype == STT_NOTYPE || elfsh_get_symbol_link(sym) == SHN_COMMON))
        {
            if (stage == ELFSH_RELOC_STAGE2 && !strstr(name, "old_"))
                continue;

            /* If the symbol is not found and we are still in
               the first stage relocation, just pass it */
            sym = elfsh_get_metasym_by_name(enew->parent, name);
            if (!sym)
            {
                switch (elfsh_find_relocsym(enew, reltab, &sym, name, stage, symtype))
                {
                case 2:
#if	__DEBUG_STATIC__
                    fprintf(stderr, "[DEBUG_STATIC] RETRY\n");
#endif
                    goto retry;
                    break;
                case 0:
                    continue;
                case 1:
                    break;
                case -1:
                default:
                    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                                 "Unable to satisfy symbol in ET_REL", -1);
                }
            }

            addr = sym->st_value;

#if	__DEBUG_RELADD__
            fprintf(stderr, "[DEBUG_RELADD] Relocate using existing symbol %-20s " AFMT "]\n",
                    name, (eresi_Addr) addr);
#endif

        }


        /* Compute addr giving the injected section's vaddr in ET_EXEC */
        else
        {

            /* All the following relocs are computed in stage 1 */
            if (stage == ELFSH_RELOC_STAGE2)
                continue;

            /* Find target section in ET_REL */
            sect = elfsh_get_section_by_index(reltab->parent, sym->st_shndx,
                                              NULL, NULL);
            if (sect == NULL)
                PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                             "Cant find extracted section in ET_REL", -1);

#if	__DEBUG_RELADD__
            fprintf(stderr, "[DEBUG_RELADD] Found -%s- section (idx = %u), now looking at "
                    "injected base address\n", sect->name, sect->index);
#endif

            /* Find corresponding inserted section in ET_EXEC */
            snprintf(tmpname, sizeof(tmpname), "%s%s", reltab->parent->name, sect->name);
            sect = elfsh_get_section_by_name(enew->parent, tmpname, NULL, NULL, NULL);

            if (sect == NULL)
            {

#if   	__DEBUG_RELADD__
                elfsh_print_sectlist(reltab->parent, "HEH");
                fprintf(stderr, "[DEBUG_RELADD] Did not found %s section (sym = %s) \n",
                        tmpname, name);
#endif

                PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                             "Cant find inserted section in ET_EXEC", -1);
            }

            /* Compute pointer value */
            addr = sect->shdr->sh_addr;
            addr += ((elfsh_get_symbol_type(sym) == STT_SECTION &&
                      !FILE_IS_SPARC(sect->parent) &&
                      !FILE_IS_ALPHA64(sect->parent) &&
                      !FILE_IS_MIPS(sect->parent)) ?
                     *dword : sym->st_value);

#if __DEBUG_RELADD__
            fprintf(stderr, "[DEBUG_RELADD] Relocate using section %-20s base [-> " AFMT "] \n",
                    sect->name, (eresi_Addr) addr);
#endif


        }

        /* Perform relocation */
        if (elfsh_relocate_entry(enew, cur, dword, addr, reltab) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Unable to relocate entry", -1);

    }
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Beispiel #6
0
/**
 * @brief Match a function in a symbol table.
 * @param sect Section pointer for symbol table.
 * @param num Element number.
 * @param preg Reguler expression to use.
 * @param func_list Function table.
 * @param count Counter pointer (from the table).
 * @param get_symname Function ptr to get symbol name.
 * @return Success (0) or Error (-1).
 */
static int		trace_match_symtab(elfshsect_t	*sect, 
					   int		num, 
					   regex_t	*preg,
					   char		***func_list, 
					   u_int	*count,
					   char		*(*get_symname)(elfshobj_t *f, 
									elfsh_Sym *s))
{
  u_int			index;
  elfsh_Sym		*table;
  char			*name;
  char			**f_list;
  u_int			cnum;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Check argument before anything */
  if (!sect || !preg || !func_list || !count || !get_symname)
     PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Invalid parameters", -1);

  f_list = *func_list;
  cnum = *count;
  table = (elfsh_Sym *) (sect->shdr->sh_addr ? elfsh_readmem(sect) : sect->data);

  /* Parse every function */
  for (index = 0; index < num; index++)
    {
      /* Only functions */
      if (elfsh_get_symbol_type(table + index) != STT_FUNC
	  || table[index].st_value == 0)
	continue;

      name = get_symname(sect->parent, table + index);

      /* Check if this name is valid */
      if (name == NULL || *name == 0)
	continue;

      /* We match a function */
      if (regexec(preg, name, 0, 0, 0) == 0)
	{
	  /* Do we need to realloc ? */
	  if (((cnum+1) % TRACE_MATCH_ALLOCSTEP) == 0)
	    {
	      XREALLOC(__FILE__, __FUNCTION__, __LINE__, f_list, f_list, 
		       sizeof(char*) * (cnum + 1 + TRACE_MATCH_ALLOCSTEP), -1);

	      /* Blank new elements */
	      memset(&f_list[cnum], 0x00, TRACE_MATCH_ALLOCSTEP*sizeof(char*));

	      /* Update the pointer, data can move during a reallocation */
	      *func_list = f_list;
	    }

	  /* Add the function in the table */
	  f_list[cnum] = name;

	  *count = ++cnum;
	}
    }
  
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); 
}
Beispiel #7
0
/**
 * ALTPLT hijacking on MIPS32
 *
 *  On MIPS we need to restore 2 words from .alt.got to .got 
 * and callback __libc_start_main. 
 *
 * Update: we also need to copy .got values for extern
 * variables. We put ld/st pairs in .pad.got so that we
 * fill those only one time, before calling __libc_start_main
 *  
 * The code works and is functional -mm
 *
 * @param file
 * @param symbol
 * @param addr
 * @return
 */
int		elfsh_hijack_altplt_mips32(elfshobj_t *file, 
					   elfsh_Sym *symbol,
					   eresi_Addr addr)
{
  elfshsect_t   *altgotprolog, *altgot, *padgot, *got, *start;
  elfshsect_t	*dynsym, *dynamic;
  elfsh_Sym	*sym;
  elfsh_Dyn	*dynent, *dynent2;
  uint32_t	gotno, gotsym;
  u_int		varnbr, gotnbr, symnbr;
  u_int		opcodendx, gotindex, index, varindex;
  uint32_t      *opcode;
  uint16_t	diff;
  uint16_t	gotdiff;
  uint32_t	*originstr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Regular checks */
  if (!FILE_IS_MIPS(file))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "File is not MIPS", -1);

  altgotprolog = file->secthash[ELFSH_SECTION_ALTGOTPROLOG];
  altgot       = file->secthash[ELFSH_SECTION_ALTGOT];
  padgot       = file->secthash[ELFSH_SECTION_PADGOT];
  got	       = file->secthash[ELFSH_SECTION_GOT];
  start        = file->secthash[ELFSH_SECTION_MIPSTART];
  dynsym       = file->secthash[ELFSH_SECTION_DYNSYM];
  dynamic      = file->secthash[ELFSH_SECTION_DYNAMIC];

  if (!altgotprolog || !altgot || !got || !padgot || !dynsym || !dynamic)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Cannot find GOT, ALTGOTPROLOG, ALTGOT"
		      " PADGOT, DYSYM, DYNAMIC or MIPSTART section", -1);

  /* Signed 16bits displacement from %gp to last word of .pad.got */
  diff = 0x800c;
  originstr = elfsh_readmem(padgot->data) + padgot->shdr->sh_size - 4;
  *originstr = altgotprolog->shdr->sh_addr; 
  gotdiff = (uint16_t) got->shdr->sh_addr - altgot->shdr->sh_addr;

  /* Valid _start signature on Linux, may you FIXME for other OS */
  /* lw      t9, __libc_start_main_off(gp) */
  originstr = ((uint32_t *) elfsh_readmem(start) + 19);	

  /* Grab infos on .got using .dynamic */
  dynent  = elfsh_get_dynamic_entry_by_type(file, DT_MIPS_GOTSYM);
  gotsym = (dynent  ? elfsh_get_dynentry_val(dynent)  : 0);
  symnbr = dynamic->shdr->sh_size / sizeof(elfsh_Sym);
  if (symnbr < gotsym)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "DYNSYM smaller than DT_MIPS_GOTSYM", -1);
  
  dynent2 = elfsh_get_dynamic_entry_by_type(file, DT_MIPS_LOCAL_GOTNO); 
  gotno  = (dynent2 ? elfsh_get_dynentry_val(dynent2) : 0);
  gotnbr = got->shdr->sh_size / sizeof(eresi_Addr);
  if (gotnbr < gotno)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "GOT smaller than DT_MIPS_GOTSYM", -1);

  sym   = elfsh_readmem(dynsym);
  sym  += gotsym;

  /* Find all .dynsym entries matching external variables
     (Assuming .got and .rel entries are in the same order)
     Copy their .alt.got entries value in .got 
  */
  for (varnbr = 0, gotindex = gotno, index = gotsym; 
       index < symnbr && gotno < gotnbr; index++, gotindex++)
    if (elfsh_get_symbol_type(sym + index) == STT_OBJECT && !sym[index].st_value)
      varnbr++;
  
  printf("[DEBUG_GOTPLT:mips] Found %u extern variables\n", varnbr);

  XALLOC(__FILE__, __FUNCTION__, __LINE__,opcode, (9 + (varnbr * 2)) * sizeof(uint32_t), -1);

  /*
    __asm__("addi $t0, $gp, 0x8010;");
    __asm__("addi $t1, $t0, gotdiff;"); 
    __asm__("lw   $t2, 0($t0);");     
    __asm__("lw   $t3, 4($t0);");     
    __asm__("sw   $t2, 0($t1);");     
    __asm__("sw   $t3, 4($t1);");     
    __asm__("lw   $t9, __libc_start_main_off($gp)");     <===
    __asm__("jr   $t9;");            
    __asm__("nop;");                 
  */
  opcode[0] = 0x23888010;		/* compute .alt.got addr */
  opcode[1] = 0x21090000 | gotdiff;	/* compute .got addr */
  opcode[2] = 0x8d0a0000;		/* load first   .alt.got word */
  opcode[3] = 0x8d0b0004;		/* load second  .alt.got word */
  opcode[4] = 0xad2a0000;		/* write first  .alt.got word into .got */
  opcode[5] = 0xad2b0004;		/* write second .alt.got word into .got */
  opcode[6] = *originstr;		/* reload __libc_start_main addr into $t9 */ 

  /* Compute the static __libc_start_main hijack in .start */
  *originstr = (*originstr & 0xFFFF0000) | diff;

  /* Now generate the ld/st pairs a la mano residing in .pad.got */
  printf("Using GOTNO = %u and GOTSYM = %u\n", gotno, gotsym);

  opcodendx = 7;
  for (index = varindex = 0, gotindex = gotno; varindex < varnbr; index++, gotindex++)
    if (elfsh_get_symbol_type(sym + index) == STT_OBJECT && !sym[index].st_value)
      {
	
	printf("Using GOT index %u \n", gotindex);
	
	opcode[opcodendx++] = 0x8d0a0000 | (uint16_t) gotindex * sizeof(eresi_Addr);
	opcode[opcodendx++] = 0xad2a0000 | (uint16_t) gotindex * sizeof(eresi_Addr);
	varindex++;
      }

  opcode[opcodendx++] = 0x0320f809;	 /* call restored $t9 */
  opcode[opcodendx++] = 0x00000000;	 /* nop delay slot    */

  if (padgot->shdr->sh_size < sizeof(uint32_t) * varnbr * 2)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      ".pad.got section too small", -1);

  elfsh_writememf(file, altgotprolog->shdr->sh_offset, opcode, sizeof(uint32_t) * 7);
  elfsh_writememf(file, padgot->shdr->sh_offset, opcode + 7, sizeof(uint32_t) * (2 + (varnbr * 2)));
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Beispiel #8
0
/** 
 * Print the chosen symbol table 
 * @param file
 * @param sect
 * @param tab
 * @param num
 * @param regx
 * @param get_symname
 * @return
 */
int		ds(elfshobj_t	*file,
		   elfshsect_t	*sect,
		   u_int        num,
		   regex_t	*regx,
		   char		*(*get_symname)(elfshobj_t *f, elfsh_Sym *s))
{
  elfsh_Sym	*table;
  char		*name;
  char		*type;
  char		*bind;
  u_int		typenum;
  u_int		bindnum;
  u_int		foff;
  u_int		index;
  char		*sect_name;
  char		buff[512];
  char		off[50];
  char		type_unk[ERESI_MEANING + 1];
  char		bind_unk[ERESI_MEANING + 1];

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sort the table if necessary */
  if (world.state.sort != NULL)
    switch (*world.state.sort)
      {
      case ELFSH_SORT_BY_ADDR:
	table = sect->altdata;
	break;
      case ELFSH_SORT_BY_SIZE:
	table = sect->terdata;
	break;
      default:
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Unknown sort mode", -1);
      }

  /* Avoid reading inexistant memory in the process for .symtab */
  else
    table = (elfsh_Sym *) (sect->shdr->sh_addr ? elfsh_readmem(sect) : sect->data);

  /* Browse symtab */
  for (index = 0; index < num; index++)
    {

      /* Retreive names */
      typenum = elfsh_get_symbol_type(table + index);
      bindnum = elfsh_get_symbol_bind(table + index);
      type = (char *) (typenum > ELFSH_SYMTYPE_MAX ? 
		       revm_build_unknown(type_unk, "type", typenum) : 
		       elfsh_sym_type[typenum].desc);
      bind = (char *) (bindnum >= ELFSH_SYMBIND_MAX ?
		       revm_build_unknown(bind_unk, "type", bindnum) : 
		       elfsh_sym_bind[bindnum].desc);
      name = get_symname(world.curjob->curfile, table + index);
      sect_name = NULL;
      sect = elfsh_get_parent_section(world.curjob->curfile, 
				      table[index].st_value, 
				      NULL);
      if (sect == NULL && table[index].st_shndx)
	sect = elfsh_get_section_by_index(world.curjob->curfile, 
					  table[index].st_shndx,
					  NULL, NULL);
      if (sect != NULL)
	sect_name = elfsh_get_section_name(world.curjob->curfile, sect);

      /* Fixup names */
      if (name == NULL || *name == 0)
	name = ELFSH_NULL_STRING;
      if (type == NULL || *type == 0)
	type = ELFSH_NULL_STRING;
      if (bind == NULL || *bind == 0)
	bind = ELFSH_NULL_STRING;
      if (sect_name == NULL)
	sect_name = ELFSH_NULL_STRING;
      foff = (!table[index].st_value ? 0 : 
	      elfsh_get_foffset_from_vaddr(world.curjob->curfile, 
					   table[index].st_value));
					
      if (sect && sect->shdr->sh_addr != table[index].st_value)
	snprintf(off, sizeof(off), " + %s", 
		 revm_colornumber("%u", (u_int) (table[index].st_value - sect->shdr->sh_addr)));
      else
	*off = '\0';



      /* Different output depending on the quiet flag */
      if (!world.state.revm_quiet)
	{
	  snprintf(buff, sizeof(buff), 
		   " %s %s %s %s %s%s "
		   "%s%s %s%s %s%s => %s%s\n",
		   revm_colornumber("[%03u]", index), 
		   revm_coloraddress(XFMT, (eresi_Addr) elfsh_get_symbol_value(table + index) + file->rhdr.base), 
		   revm_colortypestr_fmt("%-8s", type), 
		   revm_colorstr_fmt("%-40s", name),
		   revm_colorfieldstr("size:"),
		   revm_colornumber("%010u", elfsh_get_symbol_size(table + index)), 				  
		   revm_colorfieldstr("foffset:"),
		   revm_colornumber("%06u", foff),
		   revm_colorfieldstr("scope:"),
		   revm_colortypestr_fmt("%-6s", bind), 
		   revm_colorfieldstr("sctndx:"),
		   revm_colornumber("%02u", elfsh_get_symbol_link(table + index)),
		   revm_colorstr(sect_name), off);
	}

      else
	{
	  snprintf(buff, sizeof(buff), 
		   " %s %s %s %s %s%s %s%s %s%-6s\n",
		   revm_colornumber("[%03u]", index), 
		   revm_coloraddress(XFMT, (eresi_Addr) elfsh_get_symbol_value(table + index) + file->rhdr.base),
		   revm_colortypestr_fmt("%-8s", type), revm_colorstr_fmt("%-15s", name), 
		   revm_colorfieldstr("sz:"),
		   revm_colornumber("%06u", elfsh_get_symbol_size(table + index)),
		   revm_colorfieldstr("foff:"),
		   revm_colornumber("%06u", foff),
		   revm_colorfieldstr("scop:"),
		   revm_colortypestr_fmt("%-6s", bind));
	}
      
      if (regx == NULL || 
	  (regx != NULL && regexec(regx, buff, 0, 0, 0) == 0))
	{
	  /* If the user ask quit, we just break */
	  if (revm_output(buff) == -1)
	    break;
	}

      revm_endline();
    }

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