示例#1
0
文件: raw.c 项目: kejiewei/eresi
/**
 * @brief Get the buffered address from the real virtual address 
 */
void		*elfsh_get_raw_by_addr(elfshobj_t *current, eresi_Addr addr, void *buf, u_int size)
{
  elfshsect_t	*sect;
  elfsh_SAddr	offset;

  /* This happens when the object is a ERESI variable or when we request
   an address in runtime that is not part of any section */
  sect = elfsh_get_parent_section(current, (eresi_Addr) addr, &offset);
  if (!sect)
    return ((void *) addr);

  /* In debug mode, we return a pointer on the runtime data */
  if (elfsh_is_runtime_mode())
    {
      if (!elfsh_section_is_runtime(sect))
	return ((void *) sect->parent->rhdr.base + sect->shdr->sh_addr + offset);
      else if (!sect->shdr->sh_addr)
	return ((void *) sect->data + offset);
      else
	return ((void *) sect->shdr->sh_addr + offset);
    }

  /* Else we return a pointer on the cache data, doing a copy if requested */
  else
    {
      if (buf && size)
	memcpy(buf, (char *) sect->data + offset, size);
      return ((void *) sect->data + offset);
    }
  
}
示例#2
0
文件: raw.c 项目: kejiewei/eresi
/**
 * @brief Nice embedded debugging trick : return a pointer on the section data.
 * @brief This function makes the difference between static data and runtime data.
 * @param sect Section to return the data buffer from.
 */
void			*elfsh_get_raw(elfshsect_t *sect)
{
  void			*dataptr = 0;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);  
  if (elfsh_is_runtime_mode())
    {

      /* The address of the section */
      dataptr = (void *) sect->shdr->sh_addr;
      
      /* For runtime injected sections, do not add the base address of the object */
      if (!elfsh_section_is_runtime(sect))
	dataptr += sect->parent->rhdr.base;

      /* For unmapped sections */
      if (!dataptr)
	dataptr = sect->data;

      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, dataptr);
    }
  if (sect)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (sect->data));

  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid parameter", NULL);
}
示例#3
0
文件: stack.c 项目: kejiewei/eresi
/* Debugger stack display with symbols */
int		cmd_dbgstack()
{
  char		*param;
  eresi_Addr	  size;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Preliminary checks */
  if (!elfsh_is_runtime_mode())
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Command only available in e2dbg", (-1));
  param = world.curjob->curcmd->param[0];
  if (!param)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid argument", (-1));

  param = revm_lookup_string(param);

  /* Dump debugger stack */
  if (revm_isnbr(param))
    {
      if (sscanf(param, UFMT, &size) != 1)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Invalid argument", (-1));
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__,
			 e2dbg_stack_dump(size, (eresi_Addr) &param));
    }  
  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		    "Invalid parameter", -1);
}
示例#4
0
文件: runtime.c 项目: breed/elfsh
/**
 * @brief Restore original rights 
 * @param addr
 * @param sz
 * @param prot
 * @return
 */
int		elfsh_mprotect_userland(elfshobj_t *file, eresi_Addr addr, uint32_t sz, int prot)
{
  int		retval;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  if (!elfsh_is_runtime_mode())
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);

  retval = mprotect((void *) (long) addr - (long) addr % getpagesize(), 
		    getpagesize(), prot);
  if (retval != 0)
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			"Failed munprotect", -1);

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, retval);
}
示例#5
0
/* Do the switch */
int		revm_doswitch(int nbr)
{
  elfshobj_t	*actual; 

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  actual = (nbr ? revm_getfile(nbr) : 
	    hash_get(&file_hash, world.curjob->curcmd->param[0]));
					     
  if (actual == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Unknown requested object", (-1));
    
  world.curjob->curfile = actual;
  
  /* Switch to static mode if current file is not mapped */
  if (elfsh_is_runtime_mode() && !actual->linkmap)
    elfsh_set_static_mode();

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
示例#6
0
文件: runtime.c 项目: kejiewei/eresi
/**
 * @brief Put write capability on the zone 
 * @param file 
 * @param addr
 * @param sz
 * @return
 */
int		elfsh_munprotect_userland(elfshobj_t *file, eresi_Addr addr, uint32_t sz)
{
  elfshsect_t	*sect;
  elfsh_Phdr	*phdr;
  int		retval;
  int		prot;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  if (!elfsh_is_runtime_mode())
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);

  sect = elfsh_get_parent_section(file, addr, NULL);
  if (!sect)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			"Cannot find parent section", -1);

  phdr = elfsh_get_parent_segment(file, sect);
  prot = 0;

  if (elfsh_segment_is_readable(phdr))
    prot |= PROT_READ;
  if (elfsh_segment_is_writable(phdr))
    prot |= PROT_WRITE;
  if (elfsh_segment_is_executable(phdr))
    prot |= PROT_EXEC;

  retval = mprotect((void *) (addr - addr % getpagesize()), 
		    getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC);

  if (retval != 0)
    {
      perror("munprotect");
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			"Failed mprotect", -1);
    }

  /* Return the original rights */
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 
		     prot);
}
示例#7
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));
}
示例#8
0
文件: stack.c 项目: kejiewei/eresi
/* Stack display with symbols */
int		cmd_stack()
{
  char		*param;
  eresi_Addr	  size;
  revmobj_t	*ssp;
  revmexpr_t	*expr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Preliminary checks */
  if (!elfsh_is_runtime_mode())
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Command only available in e2dbg", (-1));
  param = world.curjob->curcmd->param[0];
  if (!param)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid argument", (-1));

  param = revm_lookup_string(param);
  expr = revm_expr_get(E2DBG_SSP_VAR);
  if (!expr || !expr->value)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "No saved SP", -1);
  ssp = expr->value;

  /* Dump debuggee stack */
  if (revm_isnbr(param))
    {
      if (sscanf(param, UFMT, &size) != 1)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Invalid argument", (-1));
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 
			 e2dbg_stack_dump(size, ssp->immed_val.ent));
    }  
  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		    "Invalid parameter", -1);
}
示例#9
0
/**
 * Get function addr list from call search basic
 * @param file target file
 * @param addr address list
 */
int			elfsh_addr_get_func_list(elfshobj_t *file, eresi_Addr **addr)
{
  int 			ret;
  int			index;
  asm_instr		instr;
  elfsh_SAddr		foffset;
  elfsh_Word		len;
  char			*base;
  asm_processor		proc;
  eresi_Addr		base_vaddr, caddr;
  u_char		found = 0;
  elfshsect_t		*text;
  eresi_Addr		*vaddr;
  const int		astep = 20;
  u_int			apos = 0;
  btree_t		*broot = NULL;
  u_int			diff;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

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

  /* Search entrypoint section, our address must be in this section */
  text = elfsh_get_parent_section(file, elfsh_get_entrypoint(file->hdr), &foffset);

  if (!text)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Cannot find parent section from entry point", -1);
  
  if (!elfsh_get_anonymous_section(file, text))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Unable to get an anonymous section", -1);
  
  base = elfsh_readmem(text);
  len = text->shdr->sh_size;

  /* Get the virtual address */
  base_vaddr = (elfsh_is_runtime_mode() && !elfsh_section_is_runtime(text) ?
		file->rhdr.base + elfsh_get_section_addr(text->shdr) :
		elfsh_get_section_addr(text->shdr));

  /* Setup asm_processor structure */
  if (etrace_setup_proc(file, &proc) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Failed during proc structure setup", -1);

  XALLOC(__FILE__, __FUNCTION__, __LINE__, vaddr, sizeof(eresi_Addr)*astep, -1);
  
  /* Despite the fact that we choose the right architecture to init asm,
     Our approach is totally architecture independant as we search using
     global type ASM_TYPE_CALLPROC and we know that op[0].imm will contain a
     relative value. */
  for (index = 0; index < len; index += ret)
    {
      /* Read an instruction */
      if ((ret = asm_read_instr(&instr, (u_char *) (base + index), len -  index, &proc)))
	{
	  /* Global assembler filter */
	  if ((instr.type & ASM_TYPE_CALLPROC)
	      && instr.op[0].imm != 0)
	    {
	      caddr = base_vaddr + index + instr.op[0].imm + instr.len;

	      /* Found a call check its local */
	      if (INTERVAL(base_vaddr, caddr, base_vaddr + len))
		{
		  found = 1;

		  diff = (u_int) caddr;

		  /* Avoid double entrie */
		  if (btree_get_elem(broot, diff) != NULL)
		    goto next;

		  btree_insert(&broot, diff, (void *)0x1);

		  /* Next will be the last of the current list
		     then realloc */
		  if ((apos+1) % astep == 0)
		    {
		      XREALLOC(__FILE__, __FUNCTION__, __LINE__, vaddr, vaddr,
			       sizeof(eresi_Addr)*(apos+1+astep), -1);

		      /* Blank new elements */
		      memset(&vaddr[apos], 0x00, astep*sizeof(eresi_Addr));
		    }

		  vaddr[apos++] = caddr;
		}
	    }
	}

    next:

      if (ret <= 0)
	ret = 1;
    }

  /* If nothing found we free allocated buffer and
     return an error */
  if (!found)
    {
      XFREE(__FILE__, __FUNCTION__, __LINE__, vaddr);
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		   "No call internal found", -3);
    }
  
  btree_free(broot, 0);

  *addr = vaddr;
  
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
示例#10
0
/**
 * Search a call for a given address
 * @param file target file
 * @param addr supose to be a function
 */
int			elfsh_addr_is_called(elfshobj_t *file, eresi_Addr addr)
{
  int 			ret;
  int			index;
  asm_instr		instr;
  elfsh_SAddr		foffset;
  elfsh_Word		len;
  char			*base;
  asm_processor		proc;
  eresi_Addr		base_vaddr;
  u_char		found = 0;
  elfshsect_t		*text;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (!file)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Invalid parameter", -1);

  /* Search entrypoint section, our address must be in this section */
  text = elfsh_get_parent_section(file, elfsh_get_entrypoint(file->hdr), &foffset);

  if (!text)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Cannot find parent section from entry point", -1);
  
  if (!elfsh_get_anonymous_section(file, text))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Unable to get an anonymous section", -1);
  
  base = elfsh_readmem(text);
  len = text->shdr->sh_size;

  /* Get the virtual address */
  base_vaddr = (elfsh_is_runtime_mode() && !elfsh_section_is_runtime(text) ?
		file->rhdr.base + elfsh_get_section_addr(text->shdr) :
		elfsh_get_section_addr(text->shdr));

  /* Our address is valid ? */
  if (!INTERVAL(base_vaddr, addr, (base_vaddr + len)))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Not in entrypoint section", -4);

  /* Setup asm_processor structure */
  if (etrace_setup_proc(file, &proc) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Failed during proc structure setup", -1);
  
  /* Despite the fact that we choose the right architecture to init asm,
     Our approach is totally architecture independant as we search using
     global type ASM_TYPE_CALLPROC and we know that op[0].imm will contain a
     relative value. */
  for (index = 0; index < len; index += ret)
    {
      /* Read an instruction */
      if ((ret = asm_read_instr(&instr, (u_char *) (base + index), len -  index, &proc)))
	{
	  /* Global assembler filter */
	  if ((instr.type & ASM_TYPE_CALLPROC)
	      && instr.op[0].imm != 0)
	    {
	      /* Found the correct call */
	      if (base_vaddr + index + instr.op[0].imm + instr.len == addr)
		{
		  found = 1;
		  break;
		}
	    }
	}

      if (ret <= 0)
	ret = 1;
    }

  if (!found)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "No call found", -3);

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
示例#11
0
/* Redirect a function on a OS independant manner */
int		cmd_hijack()
{
  elfsh_Sym	*dst;
  eresi_Addr	addr;
  int		err;
  char		*rev;
  char		logbuf[BUFSIZ];

  elfshredir_t	*redir;
  listent_t     *actual;
  int		idx;
  int		idx2;
  int		printed;
  eresi_Addr	hookedaddr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* If no parameter is given, print the redirection list */
  if (!world.curjob->curcmd->param[0])
    {
      printed = 0;

      /* Simple printing */
      for (idx2 = idx = 0; idx < world.curjob->curfile->redir_hash.size; idx++)
	for (actual = world.curjob->curfile->redir_hash.ent + idx;
	     actual != NULL && actual->key != NULL;
	     actual = actual->next)
	  {
	    redir = (elfshredir_t *) actual->data;
	    
	    if (!printed)
	      {
		revm_output("\t .::. ELFsh redirection list \n\n");
		printed = 1;
	      }
	    snprintf(logbuf, BUFSIZ, 
		     "\t [%02u] TYPE:%-6s [" AFMT "] <%s> redirected on [" AFMT "] <%s> \n",
		     idx2, (redir->type == ELFSH_REDIR_CFLOW  ? "CFLOW"  : 
			    redir->type == ELFSH_REDIR_ALTPLT ? "ALTPLT" : 
			    redir->type == ELFSH_REDIR_ALTGOT ? "ALTGOT" : "UNK"),
		     redir->addr[0], redir->name[0], redir->addr[1], redir->name[1]);
	    
	    revm_output(logbuf);
	    idx2++;
	  }

      /* End message */
      if (!printed)
	revm_output("\t .::. No redirection performed on current file \n\n");
      else
	revm_output("\n\n");

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

  /* Some sanity checks first */
  if (!world.curjob->curcmd->param[1])
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		      "Redirection destination needed", (-1));

  /* Resolve destination parameter */
  dst = elfsh_get_metasym_by_name(world.curjob->curfile, 
				  world.curjob->curcmd->param[1]);
  if (!dst && elfsh_is_runtime_mode())
    {
      elfsh_toggle_mode();
      dst = elfsh_get_metasym_by_name(world.curjob->curfile, 
				      world.curjob->curcmd->param[1]);
      elfsh_toggle_mode();
    }

  /* If not found */
  if (dst == NULL)
    {
      err = sscanf(world.curjob->curcmd->param[1], XFMT, 
		   (eresi_Addr *) &addr);
      
      /* If the hook function is not supplied as an address */
      if (err != 1 && elfsh_dynamic_file(world.curjob->curfile))
	{
	  elfsh_setup_hooks();

	  /* First bootstrap ALTPLT if not done */
	  err = elfsh_copy_plt(world.curjob->curfile, 
			       elfsh_get_pagesize(world.curjob->curfile));
	  if (err < 0)
	    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			      "Failed at copying PLT", (-1));		  
	  
	  /* Request a PLT entry since we have no symbol yet */
	  dst = elfsh_request_pltent(world.curjob->curfile, 
				     world.curjob->curcmd->param[1]);
	  if (dst)
	    addr = dst->st_value;
	  else
	    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			      "PLT entry request failed", (-1));		  
	}

      /* Insert a symbol on the requested address to avoid this */
      else	  
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Need a symbol to redirect", -1);
      
      rev = revm_reverse(world.curjob->curfile, addr);
    }

  /* The first resolution worked, we take the address */
  else
    {
      addr = dst->st_value;
      rev = NULL;
    }
  
#if	__DEBUG_HIJACK__
  printf("[cmd_hijack] Resolved %s as %08X \n", 
	 world.curjob->curcmd->param[1], addr);
#endif

  /* Hijack function */
  err = elfsh_hijack_function_by_name(world.curjob->curfile, 
				      ELFSH_HIJACK_TYPE_FLOW,
				      world.curjob->curcmd->param[0], 
				      addr, &hookedaddr);

  /* Last checks */
  if (err < 0)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Function redirection failed", (-1));
  
  /* Add it to redirection hash table */
  redir = revm_create_REDIR((u_char) err, world.curjob->curcmd->param[0], 
			  world.curjob->curcmd->param[1], hookedaddr, addr);
  hash_add(&world.curjob->curfile->redir_hash, 
	   world.curjob->curcmd->param[0], 
	   (void *) redir);

  /* Print final information */
  if (!world.state.revm_quiet)
    {
      snprintf(logbuf, BUFSIZ - 1,
	       "\n [*] Function %s redirected to addr " XFMT " <%s> \n\n", 
	       world.curjob->curcmd->param[0], (eresi_Addr) addr, 
	       (rev == NULL ? world.curjob->curcmd->param[1] : rev));
      revm_output(logbuf);
    }
  if (rev != NULL)
    XFREE(__FILE__, __FUNCTION__, __LINE__,rev);
  
  /* Everything is ok */
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
示例#12
0
/** 
 * List all the loaded objects 
 */
int		cmd_dolist()
{
  elfshobj_t	*actual;
  int		index;
  char		*time;
  char		*nl;
  char		c;
  char		c2;
  char		logbuf[BUFSIZ];
  char		optbuf[BUFSIZ];
  char		**keys;
  int		keynbr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  index = 1;

  /* Private descriptors */
  if (hash_size(&world.curjob->loaded))
    {
      revm_output(" .::. Static Working files .::. \n");
      keys = hash_get_keys(&world.curjob->loaded, &keynbr);
      for (index = 0; index < keynbr; index++)
	{
	  actual = hash_get(&world.curjob->loaded, keys[index]);
	  time = ctime(&actual->loadtime);
	  nl = strchr(time, '\n');
	  if (nl)
	    *nl = 0x00;
	  c = (world.curjob->curfile == actual ? '*' : ' ');
	  c2 = ((actual->linkmap || actual->rhdr.base) ? 'M' : ' ');
	  if (elfsh_is_runtime_mode())
	    snprintf(optbuf, BUFSIZ, "(" XFMT ")", actual->rhdr.base);
	  else
	    snprintf(optbuf, BUFSIZ, "%s", "");
	  
	  snprintf(logbuf, BUFSIZ - 1, " %s %c%c %s ID: %10u %s %-31s ", 
		   time, c, c2, optbuf, actual->id, 
		   elfsh_get_objtype(actual->hdr) == ET_REL  ? "ET_REL " : 
		   elfsh_get_objtype(actual->hdr) == ET_DYN  ? "ET_DYN " : 
		   elfsh_get_objtype(actual->hdr) == ET_EXEC ? "ET_EXEC" : 
		   elfsh_get_objtype(actual->hdr) == ET_CORE ? "ET_CORE" : 
		   "UNKNOWN", actual->name);
	  revm_output(logbuf);
	  revm_dolist_dep(actual);
	  revm_output("\n");

	  /* printf("-> Hashes for object : PAR[%u] ROOT[%u] CHILD[%u] \n",
	     hash_size(&actual->parent_hash),
	     hash_size(&actual->root_hash),
	     hash_size(&actual->child_hash));
	  */

	}
    }

  /* Shared descriptors */
  if (hash_size(&world.shared_hash))
    {
      revm_output("\n .::. Shared Working files .::. \n");
      keys = hash_get_keys(&world.shared_hash, &keynbr);
      for (index = 0; index < keynbr; index++)
	{
	  actual = hash_get(&world.shared_hash, keys[index]);
	  time = ctime(&actual->loadtime);
	  nl = strchr(time, '\n');
	  if (nl)
	    *nl = 0x00;
	  c = (world.curjob->curfile == actual ? '*' : ' ');
	  c2 = (actual->linkmap ? 'L' : ' ');
	  if (elfsh_is_runtime_mode())
	    snprintf(optbuf, BUFSIZ, "(" XFMT ")", actual->rhdr.base);
	  else
	    snprintf(optbuf, BUFSIZ, "%s", "");
	  
	  snprintf(logbuf, BUFSIZ - 1, " [%02u] %s %c%c %s ID: %02u %-31s \n", 
		   index + 1, time, c, c2, optbuf, actual->id, actual->name);
	  revm_output(logbuf);
	}
    }

  if (!hash_size(&world.curjob->loaded) && !hash_size(&world.shared_hash))
    revm_output(" [*] No loaded file\n");
  revm_output("\n");
  revm_modlist();
  revm_output("\n");
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
示例#13
0
文件: pht.c 项目: kejiewei/eresi
/** 
 * @brief Display a PHT 
 * @param phdr
 * @param num
 * @param base
 */
void	        revm_pht_print(elfsh_Phdr *phdr, uint16_t num, eresi_Addr base)
{
  elfsh_Shdr	*shdr;
  int		shtnum;
  int		index;
  int		index2;
  char		*type;
  u_int		typenum;
  elfshsect_t	*list;
  regex_t	*tmp;
  char		buff[512];
  char		warnmsg[256];
  char		logbuf[BUFSIZ];
  int		check;
  
  eresi_Addr	addr;
  eresi_Addr	addr_end;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  FIRSTREGX(tmp);
  
  /* Primary view (2 modes, depending on the quiet flag) */
  for (index = 0; index < num; index++)
    {
      
      typenum = elfsh_get_segment_type(phdr + index);
      type    = (char *) (typenum >= ELFSH_SEGTYPE_MAX ? 
			  revm_display_pdesc(typenum) : 
			  elfsh_seg_type[typenum].desc);

      addr = phdr[index].p_vaddr;
      addr_end = phdr[index].p_vaddr + phdr[index].p_memsz;
      if (elfsh_is_runtime_mode())
	{
	  addr_end += base;
	  addr += base;
	}

      /* We check if we have a correct alignment */
      check = (addr - phdr[index].p_offset) & (phdr[index].p_align - 1);

      if (check != 0)
	snprintf(warnmsg, 255, "Wrong alignment (%d)", check);

      if (!world.state.revm_quiet)
	snprintf(buff, sizeof(buff), 
		 " %s %s -> %s %c%c%c %s%s%s "
		 "%s%s%s %s%s%s %s%s%s => %s %s\n",
		 revm_colornumber("[%02u]", index), 
		 revm_coloraddress(XFMT, addr), 
		 revm_coloraddress(XFMT, addr_end),
		 (elfsh_segment_is_readable(&phdr[index])   ? 'r' : '-'),
		 (elfsh_segment_is_writable(&phdr[index])   ? 'w' : '-'),
		 (elfsh_segment_is_executable(&phdr[index]) ? 'x' : '-'),
		 revm_colorfieldstr("memsz("),
		 revm_colornumber(UFMT, phdr[index].p_memsz),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("foffset("),
		 revm_colornumber(UFMT, phdr[index].p_offset),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("filesz("),
		 revm_colornumber(UFMT, phdr[index].p_filesz),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("align("),
		 revm_colornumber(UFMT, phdr[index].p_align),
		 revm_colorfieldstr(")"),
		 revm_colortypestr(type),
		 check != 0 ? revm_colorwarn(warnmsg) : ""
		 );

      else
	snprintf(buff, sizeof(buff), 
		 " %s %s -> %s %c%c%c %s%s%s "
		 "%s%s%s %s%s%s\n",
		 revm_colornumber("[%02u]", index), 
		 revm_coloraddress(XFMT, addr), 
		 revm_coloraddress(XFMT, addr_end),
		 (elfsh_segment_is_readable(&phdr[index])   ? 'r' : '-'),
		 (elfsh_segment_is_writable(&phdr[index])   ? 'w' : '-'),
		 (elfsh_segment_is_executable(&phdr[index]) ? 'x' : '-'),
		 revm_colorfieldstr("memsz("),
		 revm_colornumber(UFMT, phdr[index].p_memsz),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("foffset("),
		 revm_colornumber(UFMT, phdr[index].p_offset),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("filesz("),
		 revm_colornumber(UFMT, phdr[index].p_filesz),
		 revm_colorfieldstr(")"));

      if (!tmp || (tmp && !regexec(tmp, buff, 0, 0, 0)))
	revm_output(buff);

      revm_endline();

    }

  snprintf(logbuf, BUFSIZ - 1, 
	   "\n [SHT correlation]"
	   "\n [Object %s]\n\n", world.curjob->curfile->name);
  revm_output(logbuf);

  /* Retreive the sht */
  if ((shdr = elfsh_get_sht(world.curjob->curfile, &shtnum)) == 0)
    PROFILER_OUT(__FILE__, __FUNCTION__, __LINE__);

  snprintf(logbuf, BUFSIZ - 1, " [*] SHT %s \n", 
	   (world.curjob->curfile->shtrb ? 
	    "has been rebuilt \n" :
	    "is not stripped \n"));
  revm_output(logbuf);
   
  /* Alternate View */
  for (index = 0; index < num; index++, index2 = 0)
    {
      typenum = elfsh_get_segment_type(phdr + index);
      type    = (char *) (typenum >= ELFSH_SEGTYPE_MAX ? 
			  revm_display_pname(typenum)    : 
			  elfsh_seg_type[typenum].name);

      snprintf(logbuf, BUFSIZ - 1, " %s %s \t", 
	       revm_colornumber("[%02u]", index), 
	       revm_colortypestr_fmt("%-10s", type));
      revm_output(logbuf);

      revm_endline();
      
      /* In SHT */
      for (index2 = 0, list = world.curjob->curfile->sectlist; 
	   list; list = list->next)
	if (elfsh_segment_is_parent(list, phdr + index))
	  {
	    index2++;
	    snprintf(logbuf, BUFSIZ - 1, "%s%s ", 
		     (list->shdr->sh_offset + list->shdr->sh_size > 
		      phdr[index].p_offset + phdr[index].p_filesz ? "|" : ""),
		     revm_colorstr(elfsh_get_section_name(world.curjob->curfile, list)));
	    revm_output(logbuf);

	    revm_endline();
	  }

      /* In RSHT */
      for (index2 = 0, list = world.curjob->curfile->rsectlist; 
	   list; list = list->next)
	if (elfsh_segment_is_parent(list, phdr + index))
	  {
	    index2++;
	    snprintf(logbuf, BUFSIZ - 1, "%s%s ", 
		     (list->shdr->sh_addr + list->shdr->sh_size > 
		      phdr[index].p_vaddr + phdr[index].p_memsz ? "|" : ""),
		     revm_colorstr(elfsh_get_section_name(world.curjob->curfile, list)));
	    revm_output(logbuf);

	    revm_endline();
	  }

      revm_output("\n");
    }
  
  PROFILER_OUT(__FILE__, __FUNCTION__, __LINE__);
}
示例#14
0
/**
 * Resolve symbol in one file or all (mapped) if we are in e2dbg
 * Runtime compatible.
 * @param file
 * @param addr
 * @param roffset
 * @return
*/
char		*revm_resolve(elfshobj_t *file, eresi_Addr addr, elfsh_SAddr *roffset)
{
    int		index;
    elfshobj_t	*actual;
    char		*name = NULL;
    char		*dname = NULL;
    elfsh_SAddr	offset = 0;
    elfsh_SAddr	doffset = 0;
    char		*bestname = NULL;
    elfsh_SAddr	bestoffset;
    elfshobj_t	*bestfile;
    char		buf[BUFSIZ];
    char		*str;
    char		**keys;
    int		keynbr;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
    if (!file)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Invalid NULL argument", NULL);

    actual = file;
    name = elfsh_reverse_symbol(actual, addr, &offset);
    dname = elfsh_reverse_dynsymbol(actual, addr, &doffset);

#if __DEBUG_RESOLVE__
    printf("[elfsh:resolve] First found file : %s name = %s:%d / dname = %s:%d ("XFMT") \n",
           actual->name, name, offset, dname, doffset, addr);
#endif

    if (!name || (dname && !strcmp(name, ELFSH_SECTION_NAME_PLT)) ||
            (offset < 0) || (dname && doffset < offset && doffset >= 0))
    {
        name = dname;
        offset = doffset;
    }
    else if (name && dname && doffset == offset)
        name = dname;

    bestname = name;
    bestoffset = offset;
    bestfile = actual;

    /* Find the best symbol by searching in all the objects of the process */
    if (e2dbg_presence_get())
    {
        keys = hash_get_keys(&world.curjob->loaded, &keynbr);
        for (index = 0; index < keynbr; index++)
        {
            actual = hash_get(&world.curjob->loaded, keys[index]);
            if (!actual->linkmap)
                continue;

            name = elfsh_reverse_symbol(actual, addr, &offset);
            dname = elfsh_reverse_dynsymbol(actual, addr, &doffset);

            if (!name || (offset < 0) ||
                    (dname && doffset < offset && doffset >= 0))
            {
                name = dname;
                offset = doffset;
            }

            if (!bestname ||
                    (bestoffset < 0) || (name && (offset < bestoffset) && offset >= 0))
            {
                bestname = name;
                bestoffset = offset;
                bestfile = actual;

#if __DEBUG_RESOLVE__
                fprintf(stderr, "[elfsh:resolve] Changed best : file %s name %s %d\n",
                        actual->name, name, offset);
#endif

            }

        }
    }

#if __DEBUG_RESOLVE__
    printf("[elfsh:resolve] BEST name %s %d\n", bestname, bestoffset);
#endif

    if (roffset)
        *roffset = bestoffset;

    if (bestname == NULL)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Unable to resolve best name", (NULL));

    if (elfsh_is_runtime_mode())
    {
        str = revm_basename(bestfile->name);
        snprintf(buf, BUFSIZ, "%s@%s",
                 bestname, (str ? str : "CORRUPTED"));
    }
    else
        snprintf(buf, BUFSIZ, "%s", bestname);

    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, strdup(buf));

}
示例#15
0
/**
 * Return the dynamic symbol name giving its value,
 * Fill 'offset' with the difference between sym->st_value and 'value'
 * @param file
 * @param value
 * @param offset
 * @return
 */
char		*elfsh_reverse_symbol(elfshobj_t	*file,
				      eresi_Addr       	value,
				      elfsh_SAddr      	*offset)
{
  elfshsect_t	*sect;
  elfsh_Sym	*sorted;
  int		num;
  int		index;
  char		*str;
  int		best;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sanity checks */
  if (!value || value == 0xFFFFFFFF)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid parameter", NULL);
  if (file == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid NULL parameter", NULL);

  /* handle dynamic case */
  if (elfsh_is_runtime_mode())
    value -= file->rhdr.base;

  /* If there is no symtab, resolve using SHT */
  if (elfsh_get_symtab(file, &num) == NULL)
    {
      sect = elfsh_get_parent_section(file, value, offset);
      if (sect == NULL)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "No parent section", NULL);

      *offset = (elfsh_SAddr) (sect->shdr->sh_addr - value);
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (elfsh_get_section_name(file, sect)));
    }

  /* Else use the sorted-by-address symbol table to match what we want */
  if (file->secthash[ELFSH_SECTION_SYMTAB]->altdata == NULL)
    elfsh_sync_sorted_symtab(file->secthash[ELFSH_SECTION_SYMTAB]);
  sorted = file->secthash[ELFSH_SECTION_SYMTAB]->altdata;

  /* Now find the best symbol -- type is more important than offset */
  for (str = NULL, best = index = 0; index < num; index++)
    if (sorted[index].st_value <= value && DUMPABLE(sorted + index))
      {
	if (best && !BESTYPE(sorted + index, sorted + best))
	  continue;

	*offset = (elfsh_SAddr) (value - sorted[index].st_value);
	best = index;
	str = elfsh_get_symbol_name(file, sorted + index);
	if (!*str)
	  str = NULL;
      }

  if (str)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, str);
  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		    "No valid symbol interval", NULL);
}
示例#16
0
/* Breakpoint command */
int		cmd_bp()
{
  char		*str;
  int		ret;
  eresi_Addr	addr;
  char		logbuf[BUFSIZ];
  int		idx;
  int		index;
  elfsh_SAddr	off = 0;
  char		*name;
  elfshbp_t	*cur;
  char		**keys;
  int		keynbr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* build argc */
  for (idx = 0; world.curjob->curcmd->param[idx] != NULL; idx++);
  str = revm_lookup_string(world.curjob->curcmd->param[0]);

  /* Select subcommand */
  switch (idx)
    {
      
      /* List breakpoints */
      case 0:
	e2dbg_output(" .:: Breakpoints ::.\n\n");	      
	keys = hash_get_keys(&e2dbgworld.bp, &keynbr);
	for (index = 0; index < keynbr; index++)
	  {
	    cur = hash_get(&e2dbgworld.bp, keys[index]);
	    name = revm_resolve(world.curjob->curfile, 
				(eresi_Addr) cur->addr, &off);
	    if (off)
	      snprintf(logbuf, BUFSIZ, " %c [%02u] " XFMT " <%s + " UFMT ">\n", 
		       (e2dbg_is_watchpoint(cur) ? 'W' : 'B'),
		       cur->id, cur->addr, name, off);
	    else
	      snprintf(logbuf, BUFSIZ, " %c [%02u] " XFMT " <%s>\n", 
		       (e2dbg_is_watchpoint(cur) ? 'W' : 'B'),
		       cur->id, cur->addr, name);
	    e2dbg_output(logbuf);
	  }
	hash_free_keys(keys);
	if (!index)
	  e2dbg_output(" [*] No breakpoints\n");
	e2dbg_output("\n");
	break;
      
	/* Supply a new breakpoint */
      case 1:
	if (!elfsh_is_runtime_mode())
	  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		       "Not in dynamic or debugger mode", -1);
	if (!str || !(*str))
	  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		       "Invalid argument", -1);
      
	/* Break on a supplied virtual address */
	if (IS_VADDR(str))
	  {
	    if (sscanf(str + 2, AFMT, &addr) != 1)
	      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			   "Invalid virtual address requested", (-1));
	  }
      
	/* Resolve first a function name */
	else
	  {
	    addr = e2dbg_breakpoint_find_addr(str);
	    if (addr == 0)
	      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			   "Requested symbol address unknown", -1);
	  }
      
	/* Add the breakpoint */
	ret = e2dbg_breakpoint_add(addr);
	if (ret < 0)
	  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		       "Breakpoint insertion failed\n", (-1));
	if (ret >= 0)
	  {
	    name = revm_resolve(world.curjob->curfile, addr, &off);
	    if (!off)
	      snprintf(logbuf, BUFSIZ - 1, 
		       " [*] Breakpoint added at <%s> (" XFMT ")\n\n", name, addr);
	    else
	      snprintf(logbuf, BUFSIZ - 1, 
		       " [*] Breakpoint added at <%s + " UFMT "> (" XFMT ")\n\n", 
		       name, off, addr);
	    e2dbg_output(logbuf);
	  }
	break;

	/* Wrong command syntax */
      default:
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		     "Wrong arg number", (-1));
    }

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