예제 #1
0
파일: raw.c 프로젝트: kejiewei/eresi
/**
 * Retreive the virtual address given the file offset 
 * @param file
 * @param foffset
 * @return
 */
int		elfsh_get_vaddr_from_foffset(elfshobj_t *file, u_int foffset)
{
  elfshsect_t	*root;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  root = elfsh_get_parent_section_by_foffset(file, foffset, NULL);
  if (root)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 
		       (root->shdr->sh_addr + (foffset - root->shdr->sh_offset)));
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
예제 #2
0
파일: raw.c 프로젝트: kejiewei/eresi
/**
 * Perform a raw write on the object cache data 
 * @param file
 * @param foffset
 * @param src_buff
 * @param len
 * @return
 */
int		elfsh_raw_write(elfshobj_t	*file, 
				u_int		foffset, 
				void		*src_buff, 
				int		len)
{
  elfshsect_t	*sect;
  int		sect_off;
  void		*dst;
  int		prot;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  sect = elfsh_get_parent_section_by_foffset(file, foffset, NULL);
  if (sect == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid virtual address", -1);

  sect_off = foffset - sect->shdr->sh_offset;
  if (sect_off + len > sect->shdr->sh_size)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Section too short", -1);

  dst = elfsh_get_anonymous_section(file, sect);
  if (dst == NULL)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);

  if (elfsh_is_runtime_mode())
    {
      prot = elfsh_munprotect(file, (eresi_Addr) dst + sect_off, len);
      memcpy(dst + sect_off, src_buff, len);
      elfsh_mprotect(file, (eresi_Addr) dst + sect_off, len, prot);
    }
  else
    memcpy(dst + sect_off, src_buff, len);

  
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (len));
}
예제 #3
0
파일: raw.c 프로젝트: kejiewei/eresi
/**
 * Perform a raw read on the object cache data 
 * @param file
 * @param foffset
 * @param dest_buff
 * @param len
 * @return
 */
int		elfsh_raw_read(elfshobj_t *file, u_int foffset, void *dest_buff, int len)
{
  volatile elfshsect_t	*sect;
  volatile void	*src;
  volatile int	sect_off;
  
  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  sect = elfsh_get_parent_section_by_foffset(file, foffset, NULL);
  if (sect == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid virtual address", -1);

  sect_off = foffset - sect->shdr->sh_offset;
  if (sect_off + len > sect->shdr->sh_size)
    len -= (sect_off + len - sect->shdr->sh_size);
  
  src = elfsh_get_anonymous_section(file, sect);
  if (src == NULL)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);

  memcpy(dest_buff, src + sect_off, len);
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (len));
}
예제 #4
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);
}