示例#1
0
/**
 * like revm_lookup_addr - Get address value 
 * @param file host file
 * @param param name to search
 * @return addresse found or 0
 */
eresi_Addr		edfmt_lookup_addr(elfshobj_t *file, char *param)
{
  elfsh_Sym		*sym;
  char			eol;
  int			ret;
  eresi_Addr	       	val;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Lookup .symtab */
  sym = elfsh_get_symbol_by_name(file, param);
  if (sym != NULL && sym->st_value > 0)
    {
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, sym->st_value);
    }

  /* Lookup .dynsym */
  sym = elfsh_get_dynsymbol_by_name(file, param);
  if (sym != NULL && sym->st_value > 0)
    {
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, sym->st_value);
    }

  /* Lookup hexadecimal numeric value */
  ret = sscanf(param, XFMT "%c", &val, &eol);
  if (ret == 1)
    {
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, val);
    }

  /* No match -- returns ERR */
  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		    "Unable to lookup address object", (eresi_Addr) 0);
}
示例#2
0
/**
 * Shift usual symbols (mandatory on solaris)
 * @param sect
 * @param sym
 */
void		elfsh_shift_usualsyms(elfshsect_t *sect, elfsh_Sym *sym)
{
  elfsh_Sym	*end;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  //fprintf(stderr, "Calling shift usual syms ! \n");

  /* Change _end in the symbol table */
  end = elfsh_get_symbol_by_name(sect->parent, "_end");
  if (end != NULL && sym->st_value + sym->st_size > end->st_value)
    {
      //printf("Shift _end! \n");
      end->st_value = sym->st_value + sym->st_size;
    }

  /* Change _end if necessary (solaris) */
  end = elfsh_get_dynsymbol_by_name(sect->parent, "_end");
  if (end != NULL && sym->st_value + sym->st_size > end->st_value)
    {
      //printf("Shift _end! \n");
      end->st_value = sym->st_value + sym->st_size;
    }

  /* Change _END_ if necessary (solaris) */
  end = elfsh_get_dynsymbol_by_name(sect->parent, "_END_");
  if (end != NULL && sym->st_value + sym->st_size > end->st_value)
    {
      //printf("Shift _END_! \n");
      end->st_value = sym->st_value + sym->st_size;
    }

  /* Change _edata if necessary (solaris) */
  if (elfsh_get_ostype(sect->parent) == ELFSH_OS_SOLARIS)
    {
      end = elfsh_get_dynsymbol_by_name(sect->parent, "_edata");
      if (end != NULL && sym->st_value + sym->st_size > end->st_value)
	{
	  //printf("Shift _edata! \n");
	  end->st_value = sym->st_value + sym->st_size;
	}
    }
  PROFILER_OUT(__FILE__, __FUNCTION__, __LINE__);
}
示例#3
0
/**
 * @brief Patch the first PLT entry (a special case which must handled by this function).
 * @param enew
 * @param off
 * @param symtab Section descriptor for the symbol table.
 * @param file Host file.
 * @param extplt Section descriptor for the previously injected .elfsh.extplt
 * @param plt Section descriptor for the .plt section.
 * @param diff
 * @return Success (0) or Error (-1).
 */
int		elfsh_altplt_firstent(elfshsect_t	*enew,
                              u_int		*off,
                              elfshsect_t	*symtab,
                              elfshobj_t	*file,
                              elfshsect_t	*extplt,
                              elfshsect_t	*plt,
                              uint32_t		diff)
{
    u_int		entsz;
    elfsh_Sym	newsym;
    elfsh_Sym	*sym;
    eresi_Addr	addr;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    /* Insert plt+0 symbol */
    entsz  = elfsh_get_pltentsz(file);
    newsym = elfsh_create_symbol(enew->shdr->sh_addr, entsz, STT_FUNC, 0, 0, 0);
    if (elfsh_insert_symbol(symtab, &newsym, "old_dlresolve") < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Unable to insert old_dlresolve symbol", -1);

    *off = *off - entsz + elfsh_get_first_pltentsz(file);

    /* On MIPS we have to callback __libc_start_main and not .plt+0 */
    if (FILE_IS_MIPS(plt->parent))
    {
        sym = elfsh_get_dynsymbol_by_name(file, "__libc_start_main");
        if (!sym)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Cannot find __libc_start_main",  -1);

#if __DEBUG_COPYPLT__
        printf("[DEBUG_COPYPLT] Found __libc_start_main MIPS at addr "
               XFMT "\n", sym->st_value);
#endif

        addr = sym->st_value;
    }
    else
        addr = plt->shdr->sh_addr;

    /* Call the libelfsh hook ALTPLT */
    if (elfsh_altplt(file, &newsym, addr) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "ALTPLT failed", -1);

    /* On IA32, reencode the PLT and EXTPLT entries to use the ALTGOT */
    /* The hook does nothing on other archs for now */
    if (FILE_IS_IA32(file))
        if (elfsh_encodeplt1(file, plt, extplt, diff) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Reencoding of (EXT)PLT+0 failed", -1);

    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
示例#4
0
/**
 * @brief Change the DT_PLTGOT entry in the .dynamic section to change 
 * the relocation base address.
 * @param file The host file.
 * @param altgot Section descriptor for the .elfsh.altgot section.
 * @param got Section descriptor for the .got section.
 * @param plt Section descriptor for the .plt section.
 * @param altplt Section descriptor for the .elfsh.altplt section.
 * @return Success (0) or Error (-1).
 */
int			elfsh_redirect_pltgot(elfshobj_t *file, 
					      elfshsect_t *altgot, 
					      elfshsect_t *got, 
					      elfshsect_t *plt, 
					      elfshsect_t *altplt)
{
  elfsh_Sym		*sym;
  elfsh_Dyn		*dyn;
  elfshsect_t		*relplt;
  char			*name;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Get the DT_PLTGOT entry in .dynamic */
  dyn = elfsh_get_dynamic_entry_by_type(file, DT_PLTGOT);
  if (!dyn)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Cannot find DT_PLTGOT", -1);

  /* Get the PLT related relocation table */
  name = IS_REL(plt) ? ELFSH_SECTION_NAME_RELPLT : ELFSH_SECTION_NAME_RELAPLT;
  relplt = elfsh_get_section_by_name(plt->parent, name, 0, 0, 0);
  if (!relplt)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Cannot find RELPLT section by name", -1);

  /* On MIPS we change it from .got to .alt.got : ALTGOT technique */
  if (FILE_IS_MIPS(file) || FILE_IS_IA32(file))
    {
      elfsh_set_dynentry_val(dyn, altgot->shdr->sh_addr);

      if (FILE_IS_MIPS(file))
	{
	  elfsh_set_gpvalue(file, altgot->shdr->sh_addr + 0x8000 - 0x10);
	  sym = elfsh_get_dynsymbol_by_name(file, "_gp_disp");
	  if (sym == NULL)
	        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			      "Could not find _gp_disp ",  -1);
	  sym->st_value = altgot->shdr->sh_addr + 0x8000 - 0x10;
	  elfsh_shift_mips_relocs(file, altgot->shdr->sh_addr - got->shdr->sh_addr);
	}
      else
	elfsh_shift_ia32_relocs(file, 
				altgot->shdr->sh_addr - got->shdr->sh_addr, relplt, 
				ELFSH_NOLIMIT);
    }
  
  /* On SPARC we change it from .plt to .alt.plt : ALTPLT technique */
  else if (FILE_IS_SPARC(file))
    {
      elfsh_set_dynentry_val(dyn, altplt->shdr->sh_addr);
      elfsh_shift_sparc_relocs(file, altplt->shdr->sh_addr - plt->shdr->sh_addr, relplt);
    }

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}