Example #1
0
/**
 * Inject a section from ET_REL object into ET_EXEC
 * @param file
 * @param sect
 * @param mod
 * @return
 */
static int	elfsh_inject_etrel_section(elfshobj_t *file, elfshsect_t *sect, u_int mod)
{
    elfsh_Shdr	hdr;
    elfshsect_t	*enew;
    char		*newname;
    char		writable;
    int		mode;
    char		*data;
    u_int		modulo;
    elfshsect_t	*plt;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

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

    /* else create a new section */
    hdr = elfsh_create_shdr(0, sect->shdr->sh_type, sect->shdr->sh_flags,
                            0, 0, sect->shdr->sh_size, 0, 0, 0, 0);
    XALLOC(__FILE__, __FUNCTION__, __LINE__,newname, strlen(sect->parent->name) + strlen(sect->name) + 2, -1);
    sprintf(newname, "%s%s", sect->parent->name, sect->name);
    enew = elfsh_create_section(newname);

    /* Copy the data */
    XALLOC(__FILE__, __FUNCTION__, __LINE__,data, sect->shdr->sh_size, -1);
    memcpy(data, sect->data, sect->shdr->sh_size);

    /* Inject new section by top or after bss depending on its type */
    writable = elfsh_get_section_writableflag(sect->shdr);

    /* FreeBSD is incompatible with pre-interp injection */
    ELFSH_SELECT_INJECTION(file,writable,mode);

    if (mode == ELFSH_DATA_INJECTION)
        modulo = sizeof(eresi_Addr);
    else
    {
        /* modulo = mod; (to be uncommented one day) */
        //modulo = elfsh_get_pagesize(file);
        modulo = sizeof(eresi_Addr);
    }

#if	__DEBUG_RELADD__
    printf("[DEBUG_RELADD] Mapping new section %s with data = %p \n", enew->name, data);
#endif

    if (elfsh_insert_mapped_section(file, enew, hdr, data, mode, modulo) < 0)
        goto bad;
    enew = elfsh_get_section_by_name(file, newname, NULL, NULL, NULL);
    if (enew == NULL)
        goto bad;

    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
bad:
    XFREE(__FILE__, __FUNCTION__, __LINE__,newname);
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                 "Unable to inject ET_REL section", -1);
}
Example #2
0
/**
 * @brief Copy the PLT of an ET_EXEC object for the ALTPLT technique.
 * and the GOT of an ET_EXEC object for the ALTGOT technique.
 * @param file Host file.
 * @param mod Always inject sections with size being a multiple of mod.
 * @return Success (0) or Error (-1).
 */
int		elfsh_relink_plt(elfshobj_t *file, u_int mod)
{
    elfshsect_t	*got;
    elfshsect_t   *plt;
    elfshsect_t	*symtab;
    elfshsect_t	*dynsym;
    elfshsect_t	*prolog;
    elfshsect_t	*extplt = NULL;
    elfshsect_t	*altgot = NULL; /* shut the nice talkative */
    elfshsect_t	*enew    = NULL; /* compiler also know as gcc */
    elfsh_Shdr	hdr;
    elfsh_Sym	*sym;
    elfsh_Sym	newsym;
    char		buf[BUFSIZ];
    u_int		off;
    u_int		entsz;
    int		mode;
    eresi_Addr	addr;
    char		*prologdata;
    u_int		sz;
    char		*name;
    u_char	ostype;
    eresi_Addr	diff;
    u_int		extplt_size;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    /* Get PLT */
    if (file->secthash[ELFSH_SECTION_ALTPLT] != NULL)
        PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
    plt = elfsh_get_plt(file, NULL);
    if (NULL == plt)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "PLT section not found", -1);
    entsz = elfsh_get_pltentsz(file);
    if (entsz < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Failed to get PLT entry size", -1);

    /* Get GOT (recent ld call it .got.plt) */
    got = elfsh_get_gotsct(file);
    if (NULL == got)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "GOT section not found", -1);

    /* Get symtabs */
    if (NULL == elfsh_get_dynsymtab(file, NULL))
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "DYNSYM not found", -1);
    if (NULL == elfsh_get_symtab(file, NULL))
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "SYMTAB not found", -1);

    /* Some fingerprint */
    ostype = elfsh_get_ostype(file);
    if (ostype == ELFSH_OS_ERROR)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Invalid OS target", -1);

    /* Insert alternative .plt */
    dynsym = file->secthash[ELFSH_SECTION_DYNSYM];
    symtab = file->secthash[ELFSH_SECTION_SYMTAB];

    /* FreeBSD and BeoS is incompatible with pre-interp injection */
    /* Solaris needs self-mutating code for ALTPLT technique */
    /* %gp offsets on ALPHA/MIPS requires data injection */
    ELFSH_SELECT_INJECTION(file,NULL,mode);

    /* Map .alt.plt.prolog on ALPHA, or .alt.got.prolog on MIPS */
    if (FILE_IS_MIPS(file) || FILE_IS_ALPHA64(file))
    {
        if (FILE_IS_MIPS(file))
        {
            name = ELFSH_SECTION_NAME_ALTGOTPROLOG;
            sz = 28;
        }
        else
        {
            name = ELFSH_SECTION_NAME_ALTPLTPROLOG;
            sz = 48;
        }
        prolog = elfsh_create_section(name);
        hdr = elfsh_create_shdr(0, SHT_PROGBITS, SHF_EXECINSTR | SHF_ALLOC,
                                0, 0, sz, 0, 0, 0, 0);

        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, sz, -1);

        if (elfsh_insert_mapped_section(file,
                                        prolog, hdr, prologdata,
                                        mode, mod) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".alt.{plt,got}.prolog insertion failed", -1);

        enew = elfsh_get_section_by_name(file, name, NULL, NULL, NULL);
        if (enew == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".alt.{plt,got}.prolog insertion failed", -1);
        file->secthash[ELFSH_SECTION_ALTPLTPROLOG] = enew;
    }

    /* Map .alt.plt (or .pad.got on MIPS)

       On MIPS we use .pad.got in order to align .alt.got on a 0x1000
       bound boundary.

       On ALPHA and SPARC, .alt.plt will be relocated instead of .plt
    */
    sz = plt->shdr->sh_size;
    if (FILE_IS_MIPS(file))
    {
        addr = enew->shdr->sh_addr + enew->shdr->sh_size;
        if ((addr - (got->shdr->sh_addr)) % 1024)
            sz = 1024 - ((addr - (got->shdr->sh_addr)) % 1024);
        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, sz, -1);
        memset(prologdata, 0x00, sz);
        name = ELFSH_SECTION_NAME_PADGOT;
    }
    else
    {
        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, sz, -1);
        memcpy(prologdata, elfsh_readmem(plt), sz);
        name = ELFSH_SECTION_NAME_ALTPLT;
    }
    enew = elfsh_create_section(name);
    hdr = elfsh_create_shdr(0, SHT_PROGBITS, SHF_EXECINSTR | SHF_ALLOC,
                            0, 0, sz, 0, 0, 0, 0);
    if (elfsh_insert_mapped_section(file, enew, hdr, prologdata, mode, mod) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     ".alt.plt|.pad.got insertion failed", -1);
    enew = elfsh_get_section_by_name(file, name, NULL, NULL, NULL);
    if (enew == NULL)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     ".alt.plt|.pad.got insertion failed", -1);
    file->secthash[ELFSH_SECTION_ALTPLT] = enew;


    /* Map .alt.got (all architectures except SPARC) */
    /* On IA32, remap GOT with a doubled size for non-present symbol resolving */
    if (FILE_IS_MIPS(file) || FILE_IS_ALPHA64(file) || FILE_IS_IA32(file))
    {
        sz = (FILE_IS_MIPS(file) ? got->shdr->sh_size     :
              FILE_IS_IA32(file) ? got->shdr->sh_size * 4 :
              plt->shdr->sh_size / elfsh_get_pltentsz(file) * sizeof(eresi_Addr));

        altgot = elfsh_create_section(ELFSH_SECTION_NAME_ALTGOT);
        hdr = elfsh_create_shdr(0, SHT_PROGBITS, SHF_ALLOC | SHF_WRITE,
                                0, 0, sz, 0, 0, 0, sizeof(eresi_Addr));

        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, sz, -1);
        memcpy(prologdata, elfsh_readmem(got), got->shdr->sh_size);

        if (elfsh_insert_mapped_section(file, altgot, hdr, prologdata,
                                        ELFSH_DATA_INJECTION, mod) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".alt.got insertion failed", -1);

        altgot = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_ALTGOT,
                                           NULL, NULL, NULL);
        if (altgot == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".alt.got insertion failed", -1);
        file->secthash[ELFSH_SECTION_ALTGOT] = altgot;
        altgot->curend = got->shdr->sh_size;
        memset(elfsh_readmem(altgot) + got->shdr->sh_size, 0x00, got->shdr->sh_size);
        altgot->shdr->sh_entsize = sizeof(eresi_Addr);
    }


    /* Insert EXTPLT in order to be able to resolve non present symbols */
    if (FILE_IS_IA32(file))
    {
        extplt_size = plt->shdr->sh_size * 2;
        extplt = elfsh_create_section(ELFSH_SECTION_NAME_EXTPLT);
        hdr = elfsh_create_shdr(0, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR,
                                0, 0, extplt_size, 0, 0, 0, 0);

        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, plt->shdr->sh_size, -1);
        memcpy(prologdata, elfsh_readmem(plt), plt->shdr->sh_size);

        if (elfsh_insert_mapped_section(file, extplt, hdr, prologdata,
                                        mode, mod) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".ext.plt insertion failed", -1);
        extplt = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_EXTPLT,
                                           NULL, NULL, NULL);
        if (extplt == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".ext.plt insertion failed", -1);
        file->secthash[ELFSH_SECTION_EXTPLT] = extplt;
        extplt->curend = elfsh_get_first_pltentsz(file);
    }



    /* Loop on .plt and inject 'old_symnam' symbols */
    for (off = 0; off < plt->shdr->sh_size; off += entsz)
    {

        /* SPARC does not have ALTGOT */
        if (FILE_IS_MIPS(file) || FILE_IS_ALPHA64(file) || FILE_IS_IA32(file))
            diff = (uint32_t) altgot->shdr->sh_addr - got->shdr->sh_addr;
        else
            diff = 0;

        /* Special case for the first plt entry */
        if (off == 0 && elfsh_altplt_firstent(enew, &off, symtab, file, extplt, plt, diff) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "ALTPLT on first entry failed", -1);
        else if (off == 0)
            continue;

        /* Get the existing symbol name for this plt entry ... */
        sym = elfsh_get_sym_by_value(elfsh_readmem(dynsym),
                                     dynsym->shdr->sh_size / sizeof(elfsh_Sym),
                                     plt->shdr->sh_addr + off,
                                     NULL, ELFSH_EXACTSYM);

        /* New versions of ld do not fill the vaddr of dynamic symbols,
        do it ourself. Do not insert old symbol in emergency cases */
        if (sym == NULL)
        {
            if ((sym = elfsh_restore_dynsym(file, plt, off, dynsym)) == NULL)
                continue;

            name = elfsh_get_dynsymbol_name(file, sym);

            /* __gmon_start__ should not be resolved
               if it was not already done by gcc */
            if (name && !strcmp(name, "__gmon_start__"))
                sym->st_value = 0x0;
        }

        /* ... and we inject the 'old' occurence symbol pointing in
        .alt.plt (.plt on MIPS) */
        if (!FILE_IS_MIPS(file))
            addr = enew->shdr->sh_addr + off;
        else
            addr = plt->shdr->sh_addr + off;

#if   __BYTE_ORDER == __BIG_ENDIAN
        if (file->hdr->e_ident[EI_DATA] == ELFDATA2LSB)
#elif __BYTE_ORDER == __LITTLE_ENDIAN
        if (file->hdr->e_ident[EI_DATA] == ELFDATA2MSB)
#else
#error Unexpected __BYTE_ORDER !
#endif
            addr = swaplong(addr);

        /* Injection */
        name = elfsh_get_dynsymbol_name(file, sym);
        newsym = elfsh_create_symbol(addr, entsz, STT_FUNC, 0, 0, 0);
        snprintf(buf, BUFSIZ, "old_%s", name);
        if (elfsh_insert_symbol(symtab, &newsym, buf) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "old_* symbol injection failed", -1);

#if __DEBUG_COPYPLT__
        printf("[DEBUG_COPYPLT] Symbol at .plt + %u injected"
               " succesfully (%s) \n", off, buf);
#endif

        /* On ALPHA, shift the relocation offset from .got to .alt.got to avoid
        hooks removing when calling back the original function. */
        if (FILE_IS_ALPHA64(file) &&
                elfsh_shift_alpha_relocs(file, name, altgot, off) < 0)
            continue;

        /* Reencode the PLT entry to use the alternative GOT */
        /* This condition is for compatibility with other archs where EXTPLT
        is not yet supported. For those we do not enter the hook */
        if (FILE_IS_IA32(file))
        {
            diff = (eresi_Addr) altgot->shdr->sh_addr - got->shdr->sh_addr;
            elfsh_encodeplt(file, plt, diff, off);
            if (file->hdr->e_type == ET_DYN)
                elfsh_encodeplt(file, file->secthash[ELFSH_SECTION_ALTPLT],
                                diff, off);
            diff = (eresi_Addr) altgot->shdr->sh_addr - got->shdr->sh_addr +
                   got->shdr->sh_size;
            elfsh_encodeplt(file, extplt, diff, off);
        }
    }

    /* Activate ALTGOT */
    if (elfsh_redirect_pltgot(file, altgot, got, plt, enew) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "PLTGOT redirection failed", -1);

    /* Activate EXTPLT */
    if (elfsh_extplt_mirror_sections(file) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Section mirroring failed", -1);

#if	__DEBUG_COPYPLT__
    printf("[DEBUG_COPYPLT] Section Mirrored Successfully ! \n");
#endif


    /* Everything is 0k4y */
    if (elfsh_sync_sorted_symtab(symtab) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "symtab synchronisation failed", -1);
    if (elfsh_sync_sorted_symtab(dynsym) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "dynsym synchronisation failed", -1);
    elfsh_sync_sectnames(file);
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Example #3
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);
}
Example #4
0
File: map.c Project: kejiewei/eresi
/**
 * Load all the part of the binary.
 * This function should not be used by e2dbg 
 * @param file
 * @return
 */
int		        elfsh_read_obj(elfshobj_t *file)
{
  elfshsect_t		*actual;
  int			index;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (file->read)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
  if (file->sht == NULL && NULL == elfsh_get_sht(file, NULL))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
                 "Unable to grab SHT", -1);
  if (NULL == elfsh_get_pht(file, NULL) && file->hdr->e_type != ET_REL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
                 "Unable to grab PHT", -1);

#if __DEBUG_MAP__
  puts("[DEBUG:read_obj] Loading all known typed sections\n");
#endif

  /* Fill multiple relocation sections */
  for (index = 0; NULL != 
       (actual = elfsh_get_reloc(file, index, NULL)); 
       index++);

  /*
  ** Load sections placed after symtab
  ** Added for Solaris
  */
  elfsh_get_comments(file);
  elfsh_get_dwarf(file);
  elfsh_get_stab(file, NULL);
  
  if (file->hdr->e_type == ET_CORE) 
    {
      elfsh_get_core_notes(file);
      goto out;
    }


  /*
   ** We cannot use simply elfsh_get_anonymous_section() here
   ** because the object's section hash ptrs would not be filled.
   */
  elfsh_get_symtab(file, NULL);

  /* Fixup stuffs in the SHT */
  elfsh_fixup(file);

  elfsh_get_dynsymtab(file, NULL);
  elfsh_get_stab(file, NULL);
  elfsh_get_dynamic(file, NULL);
  elfsh_get_ctors(file, NULL);
  elfsh_get_dtors(file, NULL);
  elfsh_get_got(file, NULL);
  elfsh_get_interp(file);

  elfsh_get_versymtab(file, NULL);
  elfsh_get_verneedtab(file, NULL);
  elfsh_get_verdeftab(file, NULL);
  elfsh_get_hashtable(file, NULL);

  //elfsh_get_comments(file);
  elfsh_get_plt(file, NULL);

  /* Fill the multiple notes sections */
  for (index = 0; NULL != elfsh_get_notes(file, index); index++);

  /* Loop on the section header table and load all unknown-typed sections */
  for (actual = file->sectlist; actual; actual = actual->next)
  {
    /* Fix first section size */
    if (actual->shdr->sh_size == 0 && actual->next &&
        actual->next->shdr->sh_offset != actual->shdr->sh_offset &&
	actual->next->shdr->sh_addr   != actual->shdr->sh_addr)
      actual->shdr->sh_size =
        actual->next->shdr->sh_offset - actual->shdr->sh_offset;

    /* If the section data has to be loaded, load it */
    /* In case of bss, only load if BSS data is inserted in the file */
    if (actual->data == NULL && actual->shdr->sh_size)
    {
      if ((actual->shdr->sh_type == SHT_NOBITS && 
           actual->shdr->sh_offset == actual->next->shdr->sh_offset) ||
          (actual->next != NULL && actual->next->shdr->sh_offset == actual->shdr->sh_offset))
        continue;

#if __DEBUG_MAP__
      printf("[LIBELFSH] Loading anonymous  section %15s \n",
             elfsh_get_section_name(file, actual));
#endif
      elfsh_get_anonymous_section(file, actual);
    }
  }

  /* Fixup various symbols like dynamic ones that are NULL */
  /* Non fatal error */
  if (file->secthash[ELFSH_SECTION_DYNSYM])
    elfsh_fixup_dynsymtab(file->secthash[ELFSH_SECTION_DYNSYM]);

out:
  /* We close the file descriptor after file mapping so we can open more files */
  if (file->fd >= 0) {
#if __DEBUG_MAP__
    printf("[LIBELFSH] Closing descriptor %d \n",
           file->fd);
#endif

    XCLOSE(file->fd, -1);
    /* neutralize file descriptor */
    file->fd = -1;
  }
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}