Exemplo n.º 1
0
void fixup_dynamic_rela(elfshobj_t *f, eresi_Addr rel, eresi_Addr sz)
{
  elfsh_Dyn *dyn;
  dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELA);
  elfsh_set_dynentry_val(dyn, rel);
  dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELASZ);
  elfsh_set_dynentry_val(dyn, sz);

}
Exemplo n.º 2
0
void fixup_dynamic_sym(elfshobj_t *f, eresi_Addr sym, eresi_Addr sz)
{
  elfsh_Dyn *dyn;
  dyn = elfsh_get_dynamic_entry_by_type(f, DT_SYMTAB);
  elfsh_set_dynentry_val(dyn, sym);
  //dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELASZ);
  //elfsh_set_dynentry_val(dyn, sz);

}
Exemplo n.º 3
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.º 4
0
void fix_dynamic_table(elf_bf_exec_t *env)
{
  elfsh_Dyn *dyn;
  elfshobj_t *f = env->ee_lm.lm_f;

  dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELA);
  env->ee_rela_orig = elfsh_get_dynentry_val(dyn);
  elfsh_set_dynentry_val(dyn, elfsh_get_section_addr(env->ee_lm.lm_reloc->shdr));
  dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELASZ);
  env->ee_relasz_orig = elfsh_get_dynentry_val(dyn);
  elfsh_set_dynentry_val(dyn, elfsh_get_section_size(env->ee_lm.lm_reloc->shdr));
  env->ee_dt_relasz_value = elfsh_get_section_size(env->ee_lm.lm_reloc->shdr);
  env->ee_reloc_end_value = elfsh_get_section_addr(env->ee_lm.lm_reloc->shdr) + env->ee_dt_relasz_value;
  dyn = elfsh_get_dynamic_entry_by_type(f, DT_GNU_HASH);
  env->ee_dt_gnu_hash = elfsh_get_dynentry_val(dyn);
  dyn = elfsh_get_dynamic_entry_by_type(f, DT_SYMTAB);
  env->ee_sym_orig = elfsh_get_dynentry_val(dyn);
  elfsh_set_dynentry_val(dyn, elfsh_get_section_addr(env->ee_lm.lm_sym->shdr));


  dyn = elfsh_get_dynamic_entry_by_type(f, DT_JMPREL);
  env->ee_dt_jmprel_value = elfsh_get_dynentry_val(dyn);
  elfsh_set_dynentry_val(dyn, 0);

  dyn = elfsh_get_dynamic_entry_by_type(f, DT_PLTRELSZ);
  env->ee_dt_pltrelsz_value = elfsh_get_dynentry_val(dyn);
  elfsh_set_dynentry_val(dyn, 0);

  //dyn = elfsh_get_dynamic_entry_by_type(f, DT_SYMENT);
  //env->ee_sym_orig = elfsh_get_dynentry_val(dyn);
}
Exemplo n.º 5
0
/**
 * FIXME: TEST?
 * Just a test 
 * @param robj
 * @param data
 * @param real_index
 * @return
 */
int		elfsh_get_dynent_by_type(elfshobj_t	*robj, 
					 elfsh_Dyn	*data,
					 elfsh_Word	real_index)
{
  elfsh_Dyn	*ent;
  int		idx;

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

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  elfsh_writememf(file, altgotprolog->shdr->sh_offset, opcode, sizeof(uint32_t) * 7);
  elfsh_writememf(file, padgot->shdr->sh_offset, opcode + 7, sizeof(uint32_t) * (2 + (varnbr * 2)));
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Exemplo n.º 7
0
//just cont number of symbols if lm_allocated is false
void init_tape_syms(elf_bf_exec_t *env)
{

  elf_bf_Sym *sym, *psym, *ifunc, *execmap, *ptrtapecpy, *stackaddr, *getchar, *putchar, *ldbase, *libcbase, *execmapvalue, *putcharextra;
  elf_bf_Sym top;
  if (env->ee_lm.lm_allocated){
    psym = calloc(1, sizeof(elf_bf_Sym));
    sym = calloc(1, sizeof(elf_bf_Sym));
    ptrtapecpy = calloc(1, sizeof(elf_bf_Sym));
    ifunc = calloc(1, sizeof(elf_bf_Sym));
    execmap = calloc(1, sizeof(elf_bf_Sym));
    stackaddr = calloc(1, sizeof(elf_bf_Sym));
    ldbase = calloc(1, sizeof(elf_bf_Sym));
    libcbase = calloc(1, sizeof(elf_bf_Sym));
    getchar = calloc(1, sizeof(elf_bf_Sym));
    putchar = calloc(1, sizeof(elf_bf_Sym));
    putcharextra = calloc(1, sizeof(elf_bf_Sym));
    execmapvalue = calloc(1, sizeof(elf_bf_Sym));
  }
  eresi_Addr index = env->ee_num_used_syms;
  //index++;
  //printf("index: %d\n", index);
  //symtab_get_sym(&(env->ee_lm), index++, nsym);
  symtab_get_sym(&(env->ee_lm), index++, psym);
  symtab_get_sym(&(env->ee_lm), index++, sym);
  symtab_get_sym(&(env->ee_lm), index++, ifunc);
  symtab_get_sym(&(env->ee_lm), index++, ptrtapecpy);
  symtab_get_sym(&(env->ee_lm), index++, execmap);
  symtab_get_sym(&(env->ee_lm), index++, stackaddr);
  symtab_get_sym(&(env->ee_lm), index++, ldbase);
  symtab_get_sym(&(env->ee_lm), index++, libcbase);
  symtab_get_sym(&(env->ee_lm), index++, getchar);
  symtab_get_sym(&(env->ee_lm), index++, putchar);
  symtab_get_sym(&(env->ee_lm), index++, putcharextra);
  symtab_get_sym(&(env->ee_lm), index, execmapvalue);

  

  if (env->ee_lm.lm_allocated){
    env->ee_num_used_syms = index;

    symtab_get_sym(&(env->ee_lm), index+1, &top);

    //keeps the tape head symbol number

    //address of where tape head is pointing's value
    symtab_set_sym(psym, 1, top.addr, STT_FUNC);

    //assume tape head value is zero
    symtab_set_sym(sym, 1, 0, STT_FUNC);
    symtab_set_sym(ifunc, 8, 0, STT_GNU_IFUNC);
    //elfsh_set_symbol_link(ifunc->sym, 1);
    symtab_set_sym(ptrtapecpy, 1, symtab_get_value_addr(sym), STT_FUNC);

    //start it up with address of PLTGOT
    elfsh_Dyn *dyn;
    eresi_Addr pltgot;
    dyn = elfsh_get_dynamic_entry_by_type(env->ee_lm.lm_f, DT_PLTGOT);
    pltgot = elfsh_get_dynentry_val(dyn);
    env->ee_dt_pltgot = pltgot+8;
    symtab_set_sym(execmap, 8, pltgot+8, STT_FUNC);


    symtab_set_sym(stackaddr, 8, 0, STT_FUNC);
    symtab_set_sym(ldbase, 8, 0, STT_FUNC);
    symtab_set_sym(libcbase, 8, 0, STT_FUNC);
    symtab_set_sym(getchar, 8, 0, STT_FUNC);
    symtab_set_sym(putchar, 8, 0, STT_FUNC);
    symtab_set_sym(putcharextra, 0, 0, STT_FUNC);  //we jsut want a readable address here
    //printf("ptr_tape_ptr %x, tape_ptr %x, copy %x\n", symtab_get_index(psym), symtab_get_index(sym), symtab_get_index(ptrtapecpy));
    symtab_set_sym(execmapvalue, 8, 0, STT_FUNC);

    //env->ee_tape_symnum = psym->index;
    env->ee_ptr_tape_ptr = psym;
    env->ee_tape_ptr = sym;
    env->ee_lm.lm_ifunc = ifunc;
    env->ee_ptr_tape_copy = ptrtapecpy;
    env->ee_exec_map = execmap;
    env->ee_stack_addr = stackaddr;
    env->ee_ld_base = ldbase;
    env->ee_libc_base = libcbase;
    env->ee_lm.lm_getchar = getchar;
    env->ee_lm.lm_putchar = putchar;
    env->ee_lm.lm_putcharextra = putcharextra;
    env->ee_exec_map_value = execmapvalue;
  }
  env->ee_num_new_syms = index - env->ee_num_used_syms;
}