Exemplo n.º 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)));
}
Exemplo n.º 2
0
elfshsect_t *insert_symtab_sec(elfshobj_t *f, eresi_Addr numsym, eresi_Addr strtab)
{
  char *syms;
  elfsh_Shdr *hdrsym;
  elfshsect_t *newsym;

  syms = (char *) calloc(numsym, sizeof(Elf64_Sym));
  hdrsym = (elfsh_Shdr *) calloc(1, sizeof(elfsh_Shdr));

  newsym = elfsh_create_section(".sym.p");
  if (!newsym) {
    elfsh_error();
    exit(-1);
  }

  /* Create a section header for the mapped section for a string table*/
  *hdrsym = elfsh_create_shdr(0, SHT_SYMTAB, SHF_WRITE | SHF_ALLOC, 0, 0, numsym*sizeof(Elf64_Sym), strtab, 2, 8, sizeof(Elf64_Sym));

  if (elfsh_insert_data_section(f, newsym, *hdrsym, syms) < 0) {
    elfsh_error();
    exit(-1);
  }


  /* Retreive it again since the file offset and the vaddr may have been updated during insertion */
  newsym = elfsh_get_section_by_name(f, ".sym.p", NULL, NULL, NULL);
  elfsh_set_section_type(newsym->shdr, SHT_DYNSYM);
  if (!newsym) {
    elfsh_error();
    exit(-1);
  }


  return newsym;
}
Exemplo n.º 3
0
eresi_Addr ret0_offset(char *lib) {
  //148dc:       31 c0                   xor    %eax,%eax
  //148de:       c3                      retq   
  // look at text segment, search for byte value c3
  elfshsect_t *text, *init, *plt;
  eresi_Addr offset;
  unsigned char *data;
  eresi_Addr sz, i;
  unsigned char seq[3] = {0x31,0xc0,0xc3};
  elfshobj_t *f;
  f = elfutils_read_elf_file(lib);
  if (NULL == f){
    return -1;
  }
  text =  elfsh_get_section_by_name(f,".text", NULL, NULL, NULL);
  if (NULL == text){
    return -1;
  }
  
  data = (char *) text->data;
  sz = elfsh_get_section_size(text->shdr);
  for (i = 0; i < (sz-2); i++) {
    if ((seq[0] == data[i]) && (seq[1] == data[i+1]) && (seq[2] == data[i+2])) {
      return i + text->shdr->sh_addr;
    }
  }
  return 0;

}
Exemplo n.º 4
0
eresi_Addr lookup_libc_offset(char *libc, char *function)
{
  elfshobj_t *f;
  elfsh_Rela *r;
  elfsh_Sym *s;
  int i;
  char *cmpname;
  f = elfutils_read_elf_file(libc);

  elfshsect_t *dynsym, *strtab;
  dynsym =  elfsh_get_section_by_name(f,".dynsym", NULL, NULL, NULL);

  // lookup strtab
  strtab = elfsh_get_section_by_index(f, elfsh_get_section_link(dynsym->shdr), NULL, NULL);

  // get symbol
  elfsh_Sym *table;
  table = (elfsh_Sym *) dynsym->data;
  eresi_Addr numsym = elfsh_get_section_size(dynsym->shdr)/sizeof(elfsh_Sym);

  char *strs = strtab->data;

  for (i = 0; i < numsym; i++) {
    //look at each entry
    s = &(table[i]);
    cmpname = strs + s->st_name;
    if(strcmp(function, cmpname) == 0){
      return s->st_value;
    }
  }
  return 0;  
}
Exemplo n.º 5
0
/**
 * Tell elfsh to strip all unmapped sections
 * @param file
 * @return
 */
int		elfsh_strip(elfshobj_t *file)
{
    elfshsect_t	*bss;
    elfshsect_t	*next;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    bss = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_BSS,
                                    NULL, NULL, NULL);
    if (file == NULL || file->sectlist == NULL || bss == NULL)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Invalid parameter", -1);

    while (bss->shdr->sh_addr)
        bss = bss->next;

    while (bss)
    {
        next = bss->next;
        if ((bss->index == 0) ||
                ((bss->index != file->hdr->e_shstrndx) &&
                 elfsh_remove_section(file, bss->name)))
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Unable to remove section", -1);

        bss = next;
    }

    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Exemplo n.º 6
0
/**
 * Get comment section 
 * @param file
 * @return
 */
elfshsect_t		*elfsh_get_comments(elfshobj_t *file)
{
  elfshsect_t		*enew;
  int			size;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (NULL == file)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid NULL paramater", NULL);

  enew = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_COMMENT, 
				  NULL, NULL, &size);
  if (NULL == enew)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Unable to get .comment by name", NULL);

  if (NULL == elfsh_readmem(enew))
    {
      enew->data = elfsh_load_section(file, enew->shdr);
      if (NULL == elfsh_readmem(enew))
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Unable to load .comment", NULL);
    }

  file->secthash[ELFSH_SECTION_COMMENT] = enew;
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (enew));
}
Exemplo n.º 7
0
/**
 * Return a pointer on ".reginfo" ri_gp_value 
 * @param file
 * @return
 */
elfsh_Sword	*elfsh_get_gpvalue_addr(elfshobj_t* file)
{
  elfshsect_t     *reginfo;
  
  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (file == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid NULL parameter", NULL);

  reginfo = elfsh_get_section_by_name(file,".reginfo", NULL, NULL, NULL);
  
  if (reginfo == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "No .reginfo section", NULL);

  if (reginfo->data == NULL) 
    reginfo->data = elfsh_load_section(file, reginfo->shdr);

  if (reginfo->data == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Can't read .reginfo section", NULL);

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 
		     (&((elfsh_RegInfo *) elfsh_readmem(reginfo))->ri_gp_value));
}
Exemplo n.º 8
0
/**
 * Relocate the object
 * @param file
 * @param rel
 * @param stage
 * @return
 */
int		elfsh_relocate_object(elfshobj_t *file, elfshobj_t *rel, u_char stage)
{
    elfshsect_t	*sect;
    elfshsect_t	*reltab;
    char		sctname[BUFSIZ];
    u_int		index;
    u_int		found;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    /* Last pass : relocate each inserted section */
    for (found = index = 0; index < rel->hdr->e_shnum; index++)
    {
        sect = elfsh_get_section_by_index(rel, index, NULL, NULL);
        if (sect == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "Cant get section in ET_REL",  -1);

        /* Check if the section is mapped */
        if (elfsh_get_section_allocflag(sect->shdr) && sect->shdr->sh_size &&
                sect->shdr->sh_type == SHT_PROGBITS)
        {

            /* Find the associate relocation section */
            snprintf(sctname, sizeof(sctname), "%s%s",
                     (IS_REL(sect) ? ".rel" : ".rela"), sect->name);
            reltab = elfsh_get_section_by_name(rel, sctname, NULL, NULL, NULL);
            if (reltab == NULL)
                continue;
            found++;

            /* Find the injected instance of this allocatable section in the ET_EXEC */
            snprintf(sctname, sizeof(sctname), "%s%s", sect->parent->name, sect->name);
            sect = elfsh_get_section_by_name(file, sctname, NULL, NULL, NULL);
            if (sect == NULL)
                PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                             "Cant get section in ET_EXEC",  -1);
            if (elfsh_relocate_etrel_section(sect, reltab, stage) < 0)
                PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                             "Unable to relocate section", -1);
        }
    }

    /* Note that we might have done no relocation if no table was available */
    /* This can happen on very simple .o files */
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
0
void insert_exec_secs(elf_bf_exec_t *env)
{
  elfshsect_t *sec, *str;
  sec = elfsh_get_section_by_name(env->ee_lm.lm_f, ".dynsym", NULL, NULL, NULL);

  //str = elfsh_get_section_by_name(env->ee_lm.lm_f, ".dynstr", NULL, NULL, NULL);
  env->ee_num_orig_syms = elfsh_get_section_size(sec->shdr)/sizeof(Elf64_Sym);
  env->ee_num_used_syms = env->ee_num_orig_syms;

  env->ee_lm.lm_sym = insert_symtab_sec(env->ee_lm.lm_f, env->ee_num_new_syms + env->ee_num_used_syms  + env->ee_tape_len, elfsh_get_section_link(sec->shdr));
  elfsh_set_section_type(sec->shdr, SHT_NULL);

  copy_dynsym(env);
  sec = elfsh_get_section_by_name(env->ee_lm.lm_f, ".rela.dyn", NULL, NULL, NULL);
  env->ee_lm.lm_reloc = insert_reloc_sec(env->ee_lm.lm_f, env->ee_num_reloc + (elfsh_get_section_size(sec->shdr)/sizeof(Elf64_Rela)), env->ee_lm.lm_sym);
  copy_dynrel(env);
  env->ee_lm.lm_allocated = 1;
}
Exemplo n.º 11
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);
}
Exemplo n.º 12
0
void copy_dynsym(elf_bf_exec_t *ee)
{
  //get original symbol table
  elfshsect_t *dynsym;
  dynsym = elfsh_get_section_by_name(ee->ee_lm.lm_f, ".dynsym", NULL, NULL, NULL);

 // copy in dynsym symbols
  ee->ee_lm.lm_sym->data = memcpy(ee->ee_lm.lm_sym->data, dynsym->data, elfsh_get_section_size(dynsym->shdr));

}
Exemplo n.º 13
0
void copy_dynrel(elf_bf_exec_t *ee)
{
  // get a copy of the current reladyn section so we can
  // copy data at end
  elfshsect_t *dynrel, *newrel;
  dynrel = elfsh_get_section_by_name(ee->ee_lm.lm_f, ".rela.dyn", NULL, NULL, NULL);
  newrel = ee->ee_lm.lm_reloc;
  // copy original relocation entries at end
  memcpy((void *) (newrel->data) + (ee->ee_num_reloc*sizeof(Elf64_Rela)), dynrel->data, elfsh_get_section_size(dynrel->shdr));
}
Exemplo n.º 14
0
void elfutils_setup_env(char *src,
			char *execf_in,
			char *execf_out,
			char *libc,
			int tape_len,
			eresi_Addr ifuncoffset,
			eresi_Addr dl_auxv, // offset of _dl_auxv (in ld.so's data)
			eresi_Addr endoffset, // offset of &end on stack from where auxv lives on stack (value of _dl_auxv)
			int debug,
			elf_bf_env_t *env)
{
  elfsh_Dyn *dyn;
  // open and load exec
  env->e_bf_source = read_source(src);
  env->e_bf_sourcepath = src;
  env->e_exec.ee_ifunc_offset = ifuncoffset;
  env->e_exec.ee_dl_auxv = dl_auxv;
  env->e_exec.ee_end_offset = endoffset;
  env->e_exec.ee_for_debug = debug;
  env->e_bf_libc = libc;
  env->e_exec.ee_libc = libc;
  env->e_exec.ee_exec_path = execf_in;
  init_elf_bf_linkmap(&(env->e_exec.ee_lm), execf_in, execf_out);
  elfshsect_t *bs; //we will pretend this section is our string table
  bs = elfsh_get_section_by_name(env->e_exec.ee_lm.lm_f, ".bss", NULL, NULL, NULL);
  env->e_exec.ee_lm.lm_bss_index = bs->index;
  env->e_exec.ee_tape_len = tape_len;
  //env->e_exec.ee_reloc_end = exec_reloc_end;
  env->e_exec.ee_dt_rela =  get_dynent_addr(env->e_exec.ee_lm.lm_f, DT_RELA);
  env->e_exec.ee_dt_relasz = get_dynent_addr(env->e_exec.ee_lm.lm_f, DT_RELASZ);
  env->e_exec.ee_dt_sym =  get_dynent_addr(env->e_exec.ee_lm.lm_f, DT_SYMTAB);
  env->e_exec.ee_dt_jmprel =  get_dynent_addr(env->e_exec.ee_lm.lm_f, DT_JMPREL);
  env->e_exec.ee_dt_pltrelsz = get_dynent_addr(env->e_exec.ee_lm.lm_f, DT_PLTRELSZ);

  env->e_exec.ee_ptr_tape_ptr = NULL;
  env->e_exec.ee_tape_ptr = NULL;
  env->e_exec.ee_ptr_tape_copy = NULL;
  env->e_exec.ee_lm.lm_ifunc = NULL;
  env->e_exec.ee_exec_map = NULL;
  env->e_exec.ee_ld_base = NULL;
  env->e_exec.ee_libc_base = NULL;
  env->e_exec.ee_stack_addr = NULL;
  env->e_exec.ee_lm.lm_getchar = NULL;
  env->e_exec.ee_lm.lm_putchar = NULL;
  env->e_exec.ee_lm.lm_putcharextra = NULL;
  env->e_exec.ee_exec_map_value = NULL;


  env->e_exec.ee_num_reloc = bf_rela_count(env);
  init_tape_syms(&(env->e_exec)); //first count number of new syms
  insert_exec_secs(&(env->e_exec));
  init_tape_syms(&(env->e_exec));
  fix_dynamic_table(&(env->e_exec));
}
Exemplo n.º 15
0
int		main(int argc, char **argv)
{
  elfshobj_t	*host;
  elfshobj_t	*rel;
  elfshsect_t	*txtsect;
  elfsh_Sym	*puts_troj;
  elfsh_Sym	*hook_func;
  int		idx;
  u_long	addr;

  /* Map host file and relocatable file */
  rel = elfsh_map_obj(RELOC_FILE);
  if (NULL == rel)
    goto err;
  host = elfsh_map_obj(TROJANED_FILE);
  if (NULL == host)
    goto err;

  /* Inject etrel */
  idx = elfsh_inject_etrel(host, rel);
  if (idx < 0)
    goto err;

  /* Get injected's section info */
  txtsect = elfsh_get_section_by_name(host, RELOC_FILE".text", NULL, NULL, NULL);
  if (txtsect == NULL)
    goto err;

  puts_troj = elfsh_get_symbol_by_name(host, "puts_troj");
  idx = elfsh_hijack_function_by_name(host, ELFSH_HIJACK_TYPE_PLT,
				      "puts", puts_troj->st_value, 
				      NULL);
  if (idx < 0)
    goto err;

  hook_func = elfsh_get_symbol_by_name(host, "hook_func");
  idx = elfsh_hijack_function_by_name(host, ELFSH_HIJACK_TYPE_FLOW,
				      "legit_func", hook_func->st_value, 
				      NULL);
  if (idx < 0)
    goto err;


  /* Save it */
  idx = elfsh_save_obj(host, OUTPUT_FILE);
  if (idx < 0)
    goto err;

  puts("[*] ET_REL injected");
  return (0);
 err:
  elfsh_error();
  return (-1);
}
Exemplo n.º 16
0
/**
 * Retreive strtab 
 * @param file
 * @param index
 * @return
 */
elfshsect_t	*elfsh_get_strtab(elfshobj_t *file, int index)
{
  elfshsect_t	*s;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sanity checks */
  if (file == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid NULL parameter", NULL);

  s = file->secthash[ELFSH_SECTION_STRTAB];
  if (s)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, s);
  
  /* Read the string table */
  if (index > 0)
    s = elfsh_get_section_by_index(file, index, NULL, NULL);
  else
    s = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_STRTAB,
				  NULL, NULL, NULL);
  
  /* Section is present */
  if (s != NULL)
    {
      file->secthash[ELFSH_SECTION_STRTAB] = s;
      s->shdr->sh_link = file->secthash[ELFSH_SECTION_SYMTAB]->index;
      if (s->data == NULL)
	{
	  s->data = elfsh_load_section(file, s->shdr);
	  if (s->data == NULL)
	    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			      "Unable to load STRTAB", NULL);
	} 
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (s));
    }

  /* Section is not present */
  s = elfsh_rebuild_strtab(file);
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (s));
}
Exemplo n.º 17
0
/**
 * Add a symbol name in .dynstr 
 * @param file
 * @param name
 * @return
 */
int		elfsh_insert_in_dynstr(elfshobj_t *file, char *name)
{
  elfshsect_t	*sect;
  int		ret;
  
  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (file == NULL || name == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid NULL parameter", -1);
  sect = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_DYNSTR, NULL, NULL, NULL);
  if (sect == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Unable to find DYNSTR by name", -1);
  ret = elfsh_append_data_to_section(sect, name, strlen(name) + 1);
  if (ret < 0)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                      "Failed to append data to dynstr", -1);
  else
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, ret);
}
Exemplo n.º 18
0
/**
 * Shift DTORS on ET_DYN 
 * @param file
 * @param size
 * @return
 */
int		elfsh_shift_dtors(elfshobj_t *file, u_int size)
{
  elfshsect_t	*dtors;
  int		nbr;
  u_int		idx;
  eresi_Addr	*addr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  dtors = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_DTORS, 
				  NULL, NULL, &nbr);
  if (!dtors)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                      "Cannot retreive DTORS in ET_DYN", -1);
  nbr = nbr / sizeof(eresi_Addr);
  for (idx = 0; idx < nbr; idx++)
    {
      addr = elfsh_get_dtors_entry_by_index(dtors->data, idx);
      if (*addr && *addr != ELFSH_END_DTORS)
	*addr += size;
    }
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (0));
}
Exemplo n.º 19
0
/**
 * Read the destructor array in .dtors 
 * @param file
 * @param num
 * @return
 */
eresi_Addr	*elfsh_get_dtors(elfshobj_t *file, int *num)
{
  elfshsect_t	*enew;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sanity checks */
  if (file == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid NULL parameter", NULL);

  /* Load dtors */
  enew = file->secthash[ELFSH_SECTION_DTORS];
  if (enew == NULL)
    {
      enew = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_DTORS, 
				      NULL, NULL, NULL);
      if (NULL == enew)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Unable to get DTORS by name", NULL);
    }
  
  /* Read dtors */
  if (NULL == enew->data)
    {
      enew->data = elfsh_load_section(file, enew->shdr);
      if (NULL == enew->data)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Unable to load DTORS", NULL);
      file->secthash[ELFSH_SECTION_DTORS] = enew;
    }

  /* Return data */
  if (num != NULL)
    *num = enew->shdr->sh_size / sizeof(eresi_Addr);
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (elfsh_readmem(enew)));
}
Exemplo n.º 20
0
/** 
 * Display the dynamic symbol table 
 */
int		cmd_dynsym()
{
  elfshsect_t	*sct;
  elfsh_Sym	*dynsym;
  regex_t	*tmp;
  int		num;
  char		logbuf[BUFSIZ];

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  dynsym = elfsh_get_dynsymtab(world.curjob->curfile, &num);
  if (dynsym == NULL)
    RET(-1);
  else
    {      
      sct = elfsh_get_section_by_name(world.curjob->curfile, 
				      ELFSH_SECTION_NAME_ALTDYNSYM, 
				      NULL, NULL, &num);
      if (!sct)
	sct = elfsh_get_section_by_type(world.curjob->curfile, SHT_DYNSYM, 0, 
					NULL, NULL, &num);
      
      if (!sct)
	RET(-1);
      num = num / sizeof(elfsh_Sym);
    }

  snprintf(logbuf, BUFSIZ - 1,
	   " [DYNAMIC SYMBOL TABLE]\n [Object %s]\n [Section %s]\n", 
	   world.curjob->curfile->name, sct->name);
  
  revm_output(logbuf);
  FIRSTREGX(tmp);
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 
		ds(world.curjob->curfile, sct,
		   num, tmp, elfsh_get_dynsymbol_name));
}
Exemplo n.º 21
0
elfshsect_t *insert_reloc_sec(elfshobj_t *f, eresi_Addr numrel, elfshsect_t *newsym)
{
  char *rels;
  elfsh_Shdr *hdrrel;
  elfshsect_t *newrel;


  //alloc space for new sections
  rels = (char *) calloc(numrel, sizeof(Elf64_Rela));
  hdrrel = (elfsh_Shdr *) calloc(1, sizeof(elfsh_Shdr));


  /* Create the section descriptor (ESD) */
  newrel = elfsh_create_section(".rela.p");
  if (!newrel) {
    elfsh_error();
    exit(-1);
  }

  /* Create a section header for the mapped section */
  *hdrrel = elfsh_create_shdr(0, SHT_RELA, SHF_WRITE | SHF_ALLOC, 0, 0, numrel*sizeof(Elf64_Rela), newsym->index, 0, 8, sizeof(Elf64_Rela));

  if (elfsh_insert_data_section(f, newrel, *hdrrel, rels) < 0) {
   elfsh_error();
   exit(-1);
  }

  /* Retreive it again since the file offset and the vaddr may have been updated during insertion */
  newrel = elfsh_get_section_by_name(f, ".rela.p", NULL, NULL, NULL);
  if (!newrel) {
    elfsh_error();
    exit(-1);
  }


  return newrel;
}
Exemplo n.º 22
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));
}
Exemplo n.º 23
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);
}
Exemplo n.º 24
0
elfshsect_t *reloc_get_reloc_shsect(elfshobj_t *f, char *name)
{
    return elfsh_get_section_by_name(f,name, NULL, NULL, NULL);
}
Exemplo n.º 25
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);
}
Exemplo n.º 26
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);
}
Exemplo n.º 27
0
/**
 * Match a list of function from symbol tables
 * @param funcreg Function regex (or not ?)
 * @param func_list the final function list
 */
int			trace_match_funcname(elfshobj_t *curfile, char *funcname, char ***func_list)
{
  regex_t		preg;
  char			**f_list;
  u_int			count = 0;
  elfshsect_t		*sect;
  int			num;
  elfsh_Sym		*symtab;
  elfsh_Sym		*sym;
  char			funcreg[256];
  char			addrname[256];
  size_t		len;
  eresi_Addr		addr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (!funcname || !func_list)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Invalid parameters", -1);

  len = strlen(funcname);

  /* We don't want to strip some part of the submited function
   but if you find a function/regex of this size (for this purpose) ... */
  if (len > 255)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Function name is too long", -1);

  /* An address ? */
  if (IS_VADDR(funcname))
    {
      /* Retrieve the address */
      sscanf(funcname + 2, AFMT, &addr);

      /* Prealloc the list */
      XALLOC(__FILE__, __FUNCTION__, __LINE__, f_list, sizeof(char*)*2, -1);

      sym = elfsh_get_symbol_by_value(curfile, addr, 0, ELFSH_EXACTSYM);
      
      /* We have a symbol for this address */
      if (sym)
	{
	  f_list[0] = elfsh_get_symbol_name(curfile, sym);
	  f_list[1] = NULL;
	}
      else
	{
	  sym = elfsh_get_dynsymbol_by_value(curfile, addr, 0, ELFSH_EXACTSYM);

	  /* We have a dynamic symbol for this address */
	  if (sym)
	    {
	      f_list[0] = elfsh_get_dynsymbol_name(curfile, sym);
	      f_list[1] = NULL;
	    }
	  else
	    {
	      TRACE_GET_FUNC_NAME(addrname, 255, funcname);
	      
	      f_list[0] = strdup(addrname);
	      f_list[1] = NULL;
	    }
	}

      goto end;
    }

  /* Add ^ and $ if needed, else we will check too many things
     For example, someone wanna add "main" function, if we don't
     add those symbols, it will match __libc_start_main which is very
     special function and that can create problems and make the tracer
     useless */
  snprintf(funcreg, 255, "%s%s%s", 
	   funcname[0] != '^' ? "^" : "",
	   funcname,
	   funcname[len-1] != '$' ? "$" : "");

  /* Do we have a regex ? */
  if (regcomp(&preg, funcreg, 0) != 0)
    {
      XALLOC(__FILE__, __FUNCTION__, __LINE__, f_list, sizeof(char*)*2, -1);
      f_list[0] = funcname;
      f_list[1] = NULL;

      goto end;
    }

  /* Preallocation */
  XALLOC(__FILE__, __FUNCTION__, __LINE__, f_list, 
	 sizeof(char*) * TRACE_MATCH_ALLOCSTEP, -1);


  /* Total match case */
  if (TRACE_MATCH_ALL(funcname))
    {
      /* Match everything we can, symbol or not ! */
      trace_match_addrtable(curfile, &f_list, &count);
    }

  /**
   * Match on symbol table
   */
  symtab = elfsh_get_symtab(curfile, &num);
  
  if (symtab != NULL)
    { 
      sect = elfsh_get_section_by_type(curfile, 
				       SHT_SYMTAB, 0, NULL, NULL, 0);
      
      /* Match function regex in the symbol table */
      trace_match_symtab(sect, num, &preg, &f_list, &count, elfsh_get_symbol_name);
    }
      
  /**
   * Match on dynamic symbol table
   */
  symtab = elfsh_get_dynsymtab(curfile, &num);

  if (symtab != NULL)
    { 

      sect = elfsh_get_section_by_name(curfile, 
				      ELFSH_SECTION_NAME_ALTDYNSYM, 
				      NULL, NULL, &num);
      if (!sect)
	sect = elfsh_get_section_by_type(curfile, SHT_DYNSYM, 0, 
					NULL, NULL, &num);

      num /= sizeof(elfsh_Sym);

      /* Match function regex in the dynamic symbol table */
      trace_match_symtab(sect, num, &preg, &f_list, &count, elfsh_get_dynsymbol_name);
    }

  /* Do we get something ? */
  if (count == 0)
    {
      XFREE(__FILE__, __FUNCTION__, __LINE__, f_list);
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		   "Can't match a single function", -1);
    }

 end:

  /* Set final pointer */
  *func_list = f_list;
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Exemplo n.º 28
0
/**
 * Static hooking for Mips32
 * Note : a new technique is beeing considered that
 * may invalidate this handler as it (at least 
 * change the way it should be implemented)
 *
 * Make sure to ask anything before deciding to implement it
 *
 * @param file
 * @param name
 * @param symbol
 * @param addr
 */
int			elfsh_cflow_mips32(elfshobj_t *file,
					   char	      *name,
					   elfsh_Sym  *symbol,
					   eresi_Addr  addr)
{
  elfshsect_t		*hooks;
  elfshsect_t		*source;
  uint32_t		buff[3];
  int			ret, len;
  int			off;
  char			*hookbuf;
  char			*hook;
  //elfsh_Sym		sym;
  char			bufname[BUFSIZ];
  void			*data;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /*
    func+0:	[addu t9, (hook-func)]
    func+4:	[jump hook]
    func+8:	[nop]
    func+c:	[???]

    hook:	...

    old_entry+0:	[addu t9, (func-old_entry)]
    old_entry+4:	[instr1]
    old_entry+8:	[instr2]
    old_entry+c:	[instr3]
    old_entry+10:	[jmp func+8]
    old_entry+14:	[nop]

   */

  /* Resolve parameters */
  off = elfsh_get_foffset_from_vaddr(file, symbol->st_value);
  if (!off) 
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid address to hijack", -1);

  ret = elfsh_readmemf(file, off, (void *) buff, 3*4);
  if (ret != 3*4)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Function too small to be hijacked", -1);

  /* If the hook section does not exist, create it */
  hooks = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_HOOKS, 0, 0, 0);
  if (!hooks)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                      "Cannot get .HOOKS", -1);  
  
  hook = (char *) (hooks->shdr->sh_addr + hooks->curend);
  
  if (((uint32_t)  symbol->st_value & 0xf0000000) != (addr & 0xf0000000))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "hook function too far from hijacked function", -1);
  
  if (((uint32_t) hook & 0xf0000000) != ((symbol->st_value + 0x8) & 0xf0000000)) 
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "hook section too far from hijacked function", -1);
  
  if ((addr - (uint32_t)  symbol->st_value) & (0xffffffff<<16))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "hook function too far from hijacked function", -1);

  if (((uint32_t)  symbol->st_value - (uint32_t) hook) & (0xffffffff<<16))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "hook section too far from hijacked function", -1);

  /* Determine the minimal aligned length */
  /* RISC's powa */
  /* 3 instructions : 1 add t9..., 1 jmp, 1 nop for delay slot */
  ret = 3 * 4; 

  /* Create the hook for this function */
  data = elfsh_readmem(hooks);
  memset(data + hooks->curend, 0x00, 40); // nop 

  /* addi $t, $s, imm : 0010 00ss ssst tttt iiii iiii iiii iiii */
  *((uint32_t *) ((char *) (data + hooks->curend) + 0x0)) = 0x23390000;
  *((uint32_t *) ((char *) (data + hooks->curend) + 0x0)) |= 
    (((uint32_t) symbol->st_value - (uint32_t)hook) & 0x0000ffff);

  /* first three hijacked function's instructions */
  *((uint32_t *) ((char *) (data + hooks->curend) + 0x4)) = buff[0];
  *((uint32_t *) ((char *) (data + hooks->curend) + 0x8)) = buff[1];
  *((uint32_t *) ((char *) (data + hooks->curend) + 0xc)) = buff[2];

  /* non-linked jump to func + 8 (where should be a NOP) */
  /* mips32 jump use the 4 MSB of PC reg and 26 bits from instruction left 
     shited by 2 */
  memcpy(data + hooks->curend + 0x10, "\x08\x00\x00\x00", 4);
  *((uint32_t *) ((char *) (data + hooks->curend) + 0x10)) |= ((symbol->st_value + 0x8) & (~ 0xe0000000 ))>>2;

  /* NOTE : there must be a NOP after this last jump */

  /* Insert the old symbol on the original saved bytes */
  //name = elfsh_get_symbol_name(file, symbo);
  snprintf(bufname, BUFSIZ, "old_%s", name); 
  elfsh_insert_funcsym(file, bufname, (eresi_Addr) hook,
		       ret + 0x10, hooks->index);

  /*  
      snprintf(bufname, BUFSIZ, "hook_%s", name);
      elfsh_insert_funcsym(file, bufname, addr,
      ret + 8, hooks->index);
  */

  /* We need to grab the parent section to compute the remaining offset */
  source = elfsh_get_parent_section_by_foffset(file, off, NULL);
  if (!source)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Cannot find parent section for hooked addr", -1);

  /* Install the hook */
  hookbuf = alloca(ret);

  /* patch t9 reg */
  *((uint32_t *) ((char *) (hookbuf) + 0x0)) = 0x23390000;
  *((uint32_t *) ((char *) (hookbuf) + 0x0)) |= ((addr - symbol->st_value) & 
						 0x0000ffff);  
  /* jump to hook func */
  *((uint32_t *) ((char *) (hookbuf) + 0x4)) = 0x08000000;
  *((uint32_t *) ((char *) (hookbuf) + 0x4)) |= ((uint32_t) (addr ) & 
						 (~0xe0000000))>>2;
  /* delay slot's NOP */
  *((uint32_t *) ((char *) (hookbuf) + 0x8)) = 0x00000000;

  len = elfsh_writememf(file, off, hookbuf, ret);
  if (len != ret)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Error during hook installation", -1);

  /* Everything OK, ret is always 3*4 on mips32 (RISC strike again) */
  hooks->curend += ret + 6; // (6 = 1 add, 3 instr, 1 jump, 1 nop)
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Exemplo n.º 29
0
/** 
 * Load linkmap 
 * @param name
 * @return
 */
int			e2dbg_linkmap_load(char *name)
{
  static int		done	= 0;
  elfshsect_t		*got;
  eresi_Addr		*linkmap_entry;
  void			*data;
#if defined(sun)
  Link_map		*actual;
#else
  elfshlinkmap_t	*actual;
#endif
  char			*gotname;
  char			*ename;
  elfsh_Ehdr		*hdr;
  u_int			elftypenum;
  elfsh_Sym		*endsym;
  char			buff[64];

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  if (done)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);    

#if __DEBUG_LINKMAP__
  fprintf(stderr, "[e2dbg] Starting Loading LINKMAP !! \n");
#endif

  e2dbg_user_hooks_install();
  revm_config(E2DBG_CONFIG);

  /* Load debugged file */
  if (name)
    {

      /* No need to fill ET_EXEC base addr */
      if (!revm_is_loaded(name) && revm_file_load(name, 0, NULL) < 0)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Cannot load file", -1);
      
#if __DEBUG_LINKMAP__
      fprintf(stderr, "[e2dbg_linkmap_load] file %s loaded\n", name);
#endif
      
      world.curjob->curfile->linkmap = E2DBG_DYNAMIC_LINKMAP;
      world.curjob->curfile->iotype  = ELFSH_IOTYPE_EMBEDDED;
      world.curjob->curfile->running = 0;
    }
  
#if __DEBUG_LINKMAP__
  fprintf(stderr, "[e2dbg_linkmap_load] Before switch\n");
#endif
  
  /* Switch to obj 1 */
  if (revm_doswitch(1) < 0)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Cannot switch on object 1", -1);    
  
#if __DEBUG_LINKMAP__
  fprintf(stderr, "[e2dbg_linkmap_load] After switch \n");
#endif
  
  /* Base address for PIE binaries have to be imported */
  if (world.curjob->curfile->hdr->e_type == ET_DYN &&
      !world.curjob->curfile->rhdr.base)
    {
#if __DEBUG_LINKMAP__
      fprintf(stderr, "[e2dbg_linkmap_load] Inside ET_DYN condition\n");
#endif

      endsym = elfsh_get_symbol_by_name(world.curjob->curfile, "_end");

      fprintf(stderr, "endsym = " AFMT " \n", (eresi_Addr) endsym);
      sleep(1);

#if __DEBUG_LINKMAP__
      fprintf(stderr, "[e2dbg_linkmap_load] Filling PIE base"
	      " (_end ondisk = " AFMT " / _end in memory = " AFMT ") ! \n",
	      endsym->st_value, e2dbgworld.syms.piebase);
#endif 

      world.curjob->curfile->rhdr.base = e2dbgworld.syms.piebase -
	endsym->st_value;
    }

  /* Get ALTGOT or GOT if we used LD_PRELOAD */
  if (!e2dbgworld.preloaded)
    {
      gotname = ELFSH_SECTION_NAME_ALTGOT;
      got = elfsh_get_section_by_name(world.curjob->curfile, 
				      gotname, NULL, NULL, NULL);
    }
  else
    got = elfsh_get_gotsct(world.curjob->curfile);

#if __DEBUG_LINKMAP__
  fprintf(stderr, "[e2dbg_linkmap_load] %s section at " XFMT "\n",
	  got->name, got->shdr->sh_addr);
  fprintf(stderr, "[e2dbg_linkmap_load] BASE = %08x\n", 
	  world.curjob->curfile->rhdr.base);
#endif
  
  
  /* Fix first file linkmap entry */
  if (world.curjob->curfile->linkmap == E2DBG_DYNAMIC_LINKMAP)
    {
      /* Fix first file linkmap entry */
      hdr = elfsh_get_hdr(world.curjob->curfile);
      if (!hdr)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Cannot get ELF header", -1);    
      elftypenum = elfsh_get_objtype(hdr);
      
      //fprintf(stderr, "[e2dbg_linkmap_load] after ELF header \n");

      /* Get ALTGOT entry */
      data          = elfsh_readmem(got);

      //fprintf(stderr, "[e2dbg_linkmap_load] after get_raw (data = %08X) \n", data);

      linkmap_entry = elfsh_get_got_entry_by_index(data, 1);
      
      //fprintf(stderr, "[e2dbg_linkmap_load] after entry_by_index (linkmap_entry = %08x)\n",
      //      linkmap_entry);

#if defined(__FreeBSD__) || defined(__NetBSD__)
      world.curjob->curfile->linkmap = (elfshlinkmap_t *)
	&((Obj_Entry *) elfsh_get_got_val(linkmap_entry))->linkmap;
#elif defined(sun)
      world.curjob->curfile->linkmap = e2dbgworld.syms.map;
#else
      world.curjob->curfile->linkmap = (elfshlinkmap_t *) elfsh_get_got_val(linkmap_entry);
#endif
      
    }
  
#if __DEBUG_LINKMAP__
  else
    fprintf(stderr, "[e2dbg_linkmap_load] Linkmap was -NOT- dynamic\n");

  fprintf(stderr, "[e2dbg_linkmap_load] LINKMAP Found at " XFMT "\n", 
	 world.curjob->curfile->linkmap);
#endif

  revm_doswitch(1);
  
  /* now load all linkmap's files */
  for (actual = elfsh_linkmap_get_lprev(world.curjob->curfile->linkmap);
       actual != NULL; 
       actual = elfsh_linkmap_get_lprev(actual))
    {
      
#if __DEBUG_LINKMAP__
      fprintf(stderr, "[e2dbg_linkmap_load] Running on LINKMAP PREV " XFMT "\n", 
	     actual);
#endif
      
      ename = elfsh_linkmap_get_lname(actual);
      if (ename && *ename && !revm_is_loaded(ename))
	{
	  if (revm_file_load(ename,
			     elfsh_linkmap_get_laddr(actual), 
			     world.curjob->curfile->linkmap) < 0)
	    e2dbg_output(" [EE] Loading failed");
	  world.curjob->curfile->iotype  = ELFSH_IOTYPE_EMBEDDED;
	}      
    }

#if __DEBUG_LINKMAP__
  fprintf(stderr, "[e2dbg_linkmap_load] Running on LINKMAP NEXT\n");
#endif
  
  for (actual = elfsh_linkmap_get_lnext(world.curjob->curfile->linkmap);
       actual != NULL; 
       actual = elfsh_linkmap_get_lnext(actual))
    {

      ename = elfsh_linkmap_get_lname(actual);
     
#if __DEBUG_LINKMAP__
      fprintf(stderr, "[e2dbg_linkmap_load] Running on LINKMAP NEXT " XFMT " (%s baseaddr %08X) \n", 
	      actual, ename, actual->laddr);
#endif

      if (ename && *ename && !revm_is_loaded(ename))
	{
	  if (revm_file_load(ename, elfsh_linkmap_get_laddr(actual), 
			     world.curjob->curfile->linkmap) < 0)
	    e2dbg_output(" [EE] Loading failed");
	  world.curjob->curfile->iotype  = ELFSH_IOTYPE_EMBEDDED;
	}      
    }

  /* Everything was OK */
  e2dbg_output("\n");
  //elfsh_set_runtime_mode();
  revm_doswitch(1);

  snprintf(buff, sizeof(buff), " [*] Target PID = %u \n", getpid());
  e2dbg_output(buff);

  done = 1;
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}