예제 #1
0
/**
 * @brief Main function performing ALTPLT, ALTGOT, and EXTPLT techniques.
 * @param file The host file.
 * @param modulo Always inject sections with a size being a multiple of mod.
 * @return Success (0) or Error (-1).
 */
int		elfsh_copy_plt(elfshobj_t *file, u_int modulo)
{
    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    /* Some sanity checks */
    if (elfsh_static_file(file))
        PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
    if (FILE_IS_MIPS(file) &&
            elfsh_dynamic_file(file) &&
            (elfsh_build_plt(file) < 0))
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Unable to build MIPS plt", -1);

    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__,
                  elfsh_relink_plt(file, modulo));
}
예제 #2
0
파일: map.c 프로젝트: kejiewei/eresi
/**
 * Fixup the binary, inject symbols and sort SHT 
 * @param file
 * @return
 */
void		      elfsh_fixup(elfshobj_t *file)
{
  elfsh_Shdr	*got;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (file->hdr->e_type == ET_REL || elfsh_static_file(file))
    elfsh_sort_sht(file);

  /* .got sht entsize fixup */
  got = elfsh_get_sht_entry_by_name(file, ELFSH_SECTION_NAME_GOT);
  if (got != NULL && got->sh_entsize == 0)
    got->sh_entsize = sizeof(eresi_Addr);

  PROFILER_OUT(__FILE__, __FUNCTION__, __LINE__);
}
예제 #3
0
/**
 * Inject a ET_REL object into a ET_EXEC object
 * @param file
 * @param rel
 * @return
 */
int		elfsh_inject_etrel(elfshobj_t *file, elfshobj_t *rel)
{
    u_int		mod;
    u_int		pgsize;
    u_int		index;
    elfshsect_t	*sect;
    elfshsect_t	*hooks;
    int		ret = 0;
    static int	depth = 0;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    /* Sanity checks */
    if (file == NULL || file->hdr == NULL || rel == NULL || rel->hdr == NULL)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Invalid NULL parameter", -1);
    if (rel->hdr->e_type != ET_REL ||
            (file->hdr->e_type != ET_EXEC && file->hdr->e_type != ET_DYN))
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Bad parameter types", -1);

#if	__DEBUG_RELADD__
    if (rel->pending)
    {
        printf("[DEBUG_RELADD] BUG BUG BUG \n");
        exit(0);
    }
    printf("[DEBUG_RELADD] INJECTING %s in %s (depth %d)\n",
           rel->name,
           file->name,
           depth++);
#endif


    /* Set pending injection flag */
    rel->pending = 1;

    /* If not already done */
    elfsh_setup_hooks();

    /* First physically insert all BSS in the file and fuse
    ** the module's BSS with the last one */
    if (elfsh_fuse_bss(file, rel) < 0)
    {
        rel->pending = 0;
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Cant fuze BSS sections", -1);
    }

    /* First pass : find and inject all allocatable sections */
    for (index = 0; index < rel->hdr->e_shnum; index++)
    {

        /* Get the current section */
        sect = elfsh_get_section_by_index(rel, index, NULL, NULL);
        if (sect == NULL)
        {
            rel->pending = 0;
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Cant read section in ET_REL",  -1);
        }

        /* Check if the current section need to be mapped */
        if (elfsh_get_section_allocflag(sect->shdr) &&
                sect->shdr->sh_size && sect->shdr->sh_type == SHT_PROGBITS)
        {
            mod = 0;

            if (elfsh_inject_etrel_section(file, sect, mod) < 0)
            {
                rel->pending = 0;
                PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                             "Unable to inject ET_REL section", -1);
            }
        }
    }

    /* compute the inject modulo */
    mod = elfsh_get_pagesize(file);
    //mod = sizeof(eresi_Addr);

    /* Do a copy of the procedure linkage table for eventual redirection */
    if (!elfsh_static_file(file) && elfsh_copy_plt(file, mod) < 0)
    {
        rel->pending = 0;
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Unable to copy PLT", -1);
    }

    /* Create an additional hook table for non-plt function redirection */
    hooks = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_HOOKS, 0, 0, 0);
    if (!hooks)
    {
        int mode;

        /* get injection mode */
        ELFSH_SELECT_INJECTION(file,NULL,mode);

        pgsize = elfsh_get_pagesize(file);
        pgsize *= 4; /* We need a lot more than a page to trace big binaries like ssh */
        hooks = elfsh_insert_section(file,
                                     ELFSH_SECTION_NAME_HOOKS,
                                     NULL,
                                     mode,
                                     pgsize - 1, pgsize);
        if (!hooks)
        {
            rel->pending = 0;
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Cannot inject .hooks", -1);
        }
        hooks->curend = 0;
    }

#if __DEBUG_RELADD__
    printf("[DEBUG_RELADD] Entering intermediate symbol injection loop\n");
#endif

    /* Intermediate pass 2 : Inject ET_REL symbol table into host file */
    if (elfsh_fuse_etrel_symtab(file, rel) < 0)
    {
        rel->pending = 0;
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Unable to fuze symbol tables", -1);
    }

#if __DEBUG_RELADD__
    printf("[DEBUG_RELADD] Entering final relocation loop\n");

    elfsh_print_sectlist(file, "before relocation");
#endif

    /* Now call the relocation on the object's sections */
    ret = elfsh_relocate_object(file, rel, ELFSH_RELOC_STAGE1);
    rel->pending = 0;
    depth--;
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (ret));
}
예제 #4
0
/**
 * Find the host symbol we rely on for performing the relocation
 * @param enew
 * @param reltab
 * @param sym
 * @param name
 * @param stage
 * @param symtype
 * @return
 */
static int	elfsh_find_relocsym(elfshsect_t *enew, elfshsect_t *reltab,
                                elfsh_Sym **sym, char *name, char stage,
                                elfsh_Half symtype)

{
    elfshobj_t	*dep;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    /* If this symbol is a old_ one, accept it to be relocated in 2nd stage */
    /* This is because function redirection may be done after ET_REL injection */
    if (strstr(name, "old_") && stage == ELFSH_RELOC_STAGE1)
    {
#if __DEBUG_RELADD__
        printf("[DEBUG_RELADD] %s symbol not found at RELOC_STAGE1, continue\n", name);
#endif
        if (enew->parent->nbrel < ELFSH_MAXREL)
        {
            if (enew->parent->listrel[enew->parent->nbrel] != reltab->parent)
            {

                enew->parent->listrel[enew->parent->nbrel++] = reltab->parent;
#if __DEBUG_RELADD__
                printf("[DEBUG_RELADD] %s object relocation will have a second stage\n",
                       reltab->parent->name);
#endif
            }

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


    /* We have a different behavior depending on the symbol type */
    switch (symtype)
    {
    /* The symbol is not found so we request a enew PLT entry for it */
    case STT_NOTYPE:
        if (!elfsh_static_file(enew->parent))
        {
            *sym = elfsh_request_pltent(enew->parent, name);
            if (*sym)
                PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (1));
        }
        else
        {
#if	__DEBUG_STATIC__
            printf("STT_NOTYPE in static file while relocating %s\n", reltab->parent->name);
#endif

            dep = elfsh_find_obj_by_symbol(name);

            /* no symbol found */
            if (dep == ((void *) -1))
                PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                             "Unable to inject ET_REL dependence", -1);

            /* Use stage 2 relocation as the best et_rel is beeing inserted */
            if (dep == NULL)
            {
#if	__DEBUG_STATIC__
                printf("[DEBUG_STATIC] Loop in dependency detected -> STAGE2 relocation\n");
#endif
                if (enew->parent->nbrel < ELFSH_MAXREL &&
                        enew->parent->listrel[enew->parent->nbrel] != reltab->parent)
                {
                    enew->parent->listrel[enew->parent->nbrel++] = reltab->parent;
#if	__DEBUG_STATIC__
                    printf("[DEBUG_STATIC] %s object relocation will have a second stage\n", reltab->parent->name);
#endif
                    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (0));
                }
                PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                             "Unable to add stage 2 relocation", -1);
            }

            /* symbol found, gonna try to inject et_rel */
            if (dep != NULL && dep != reltab->parent && elfsh_inject_etrel(enew->parent, dep) < 0)
            {
                PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                             "Unable to inject ET_REL dependence", -1);
            }

            PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (2));

        }
        break;
    case STT_SECTION:
        printf("STT_SECTION\n");
        break;
    case STT_FUNC:
        printf("STT_FUNC\n");
        break;
    case STT_OBJECT:
        printf("STT_OBJECT\n");
        break;
    case STT_COMMON:
        printf("STT_COMMON\n");
        break;
    case STT_BLOCK:
        printf("STT_BLOCK\n");
    }


#if __DEBUG_STATIC__
    printf("[DEBUG_STATIC] Not found after OLD check : sym = %s \n", name);
#endif

    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                 "Cant find requested symbol in ET_EXEC\n", -1);
}