示例#1
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);
}
示例#2
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);
}
示例#3
0
/**
 * Reflect command disassemble the block cache of the parameter and create a list of instr exprs
 */
int		cmd_reflect()
{
  container_t	*container;
  container_t	*instrcontainer;
  mjrblock_t	*curblock;
  asm_instr	cur;
  elfsh_Half	machine;
  char		logbuf[BUFSIZ];
  char		logbuf2[BUFSIZ];
  eresi_Addr	addr;
  eresi_Addr	daddr;
  u_int		off;
  int		ret;
  aspectype_t	*curtype;
  void		*blocdata;
  int		fileoff;
  list_t	*instrlist;
  revmexpr_t	*expr;
  u_int		insnbr;
  u_int		reqnbr;
  u_int		readsize;
  revmexpr_t	*immed;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  curtype  = aspect_type_get_by_name("instr");
  if (!curtype)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                 "Failed reflection : unknown type : instr", -1);

  /* Validate parameters */
  if (world.curjob->curcmd->argc != 1 && world.curjob->curcmd->argc != 2)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                 "Command expect one or two parameters \n", -1);
  
  /* Init proc */
  if (!world.curjob->proc)
    {
      switch (machine = elfsh_get_arch(world.curjob->curfile->hdr))
        {
        case EM_386:
          world.curjob->proc = &world.proc_ia32;
          break;
        case EM_SPARC:
        case EM_SPARC32PLUS:
        case EM_SPARCV9:
          world.curjob->proc = &world.proc_sparc;
          break;
	case EM_ARM:
          world.curjob->proc = &world.proc_arm;
	  break;
	case EM_MIPS:
	case EM_MIPS_RS3_LE:
          world.curjob->proc = &world.proc_mips;
	  break;
        default:
          snprintf(logbuf, sizeof (logbuf),
                   "Architecture %s not supported. No disassembly available\n",
                   elfsh_get_machine_string(machine));
          revm_output(logbuf);
          PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
        }
    }

  /* Now lookup the block by its addr or symbol */
  immed = revm_lookup_param(world.curjob->curcmd->param[0], 1);
  if (!immed)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                 "Failed to lookup parameter address expr", -1);
  if (revm_convert_object(immed, ASPECT_TYPE_CADDR) < 0)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid address parameter", 0);
  addr = (immed->value->immed ? immed->value->immed_val.ent : 
	  immed->value->get_obj(immed->value->parent));

  /* Analyse the binary if not already done */
  /*
  if (!world.mjr_session.cur->analysed)
    {
      maxdepth = (int) config_get_data(CONFIG_CFGDEPTH);
      ret = mjr_analyse(&world.mjr_session,
                        world.curjob->curfile->hdr->e_entry,
                        maxdepth, 0);
      if (ret < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Failed analyzing current object", -1);
    }
  */

  /* One more param enables lightweight mode: lookup data from a binary file section - no CFG needed */
  if (world.curjob->curcmd->argc == 2)
    {
      immed = revm_lookup_param(world.curjob->curcmd->param[1], 1);
      if (revm_convert_object(immed, ASPECT_TYPE_INT) < 0)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid size parameter", 0);
      reqnbr = (immed->value->immed ? (u_int) immed->value->immed_val.ent : 
		(u_int) immed->value->get_obj(immed->value->parent));
      if (reqnbr <= 0)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		     "Invalid instruction number to reflect", -1);
      readsize = 16 * reqnbr;
      blocdata = alloca(readsize);
    }

  /* Only one param (an addr/symbol) --> Lookup data from a basic block on the CFG */
  else
    {
      container = mjr_block_get_by_vaddr(world.mjr_session.cur, addr, MJR_BLOCK_GET_STRICT);
      if (!container)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		     "Failed to find bloc at this virtual address", -1);
      curblock = (mjrblock_t *) container->data;
      readsize = curblock->size;
      blocdata = alloca(readsize);
      reqnbr = 0;
    }

  /* Read data -- could be imported from a remote process, so needs to copy buffer */
  fileoff = elfsh_get_foffset_from_vaddr(world.curjob->curfile, addr);
  if (elfsh_readmemf(world.curjob->curfile, fileoff, blocdata, readsize) != readsize)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Failed to read data to reflect", -1);

  /* Create the new list of instructions in expression form */
  XALLOC(__FILE__, __FUNCTION__, __LINE__, instrlist, sizeof(list_t), -1);
  snprintf(logbuf2, sizeof(logbuf2), AFMT, addr);
  elist_init(instrlist, strdup(logbuf2), ASPECT_TYPE_EXPR);

  /* Reflection all instructions of the basic bloc in the list */
  for (insnbr = off = 0; off < readsize; off += ret, insnbr++)      
    {

      /* If reached the number of requested instruction, stop now even without reaching buffer end */
      if (reqnbr && insnbr == reqnbr)			
	break;

      /* Fetch the current instruction */
      ret = asm_read_instr(&cur, (u_char *) blocdata + off,
                           readsize - off + 10, world.curjob->proc);
      if (ret < 0)
        {
          elist_destroy(instrlist);
          PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                       "Unable to fetch code for basic bloc", -1);
        }

      /* Also add the instruction to the current reflected list for this block */
      instrcontainer = container_create(curtype->type, (void *) &cur, NULL, NULL, 0);
      snprintf(logbuf, sizeof (logbuf), "$instr-"XFMT, addr + off);
      daddr = (eresi_Addr) instrcontainer;
      expr = revm_inform_type_addr(curtype->name, strdup(logbuf), daddr, NULL, 0, 1);
      elist_add(instrlist, strdup(logbuf), expr);
    }

  /* Reverse instrlist and add it to the hash of lists */
  instrlist = elist_reverse(instrlist);
  hash_add(&instrlists_hash, strdup(logbuf2), instrlist);

  /* Printing message if we are not in quiet mode */
  if (!world.state.revm_quiet)
    {
      snprintf(logbuf, sizeof(logbuf),
               " [*] Code at address " AFMT " reflected succesfully (%u instrs) \n\n",
               addr, insnbr);
      revm_output(logbuf);
    }

  /* Put the current bloc in the last result variable */
  /*
  revm_expr_destroy_by_name(REVM_VAR_RESULT);
  revm_expr_copy(expr, REVM_VAR_RESULT);
  */

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
示例#4
0
/**
 * @brief Search main function from binary entry point.
 *
 * This function inspect the code at entry point and inject the resolved
 * symbol for the main function. This is a separate function so that it
 * can be called from the tracer and benefit from the main symbol presence
 */
eresi_Addr	   mjr_find_main(elfshobj_t	*obj,
				 asm_processor	*proc,
				 u_char		*buf,
				 u_int		len,
				 eresi_Addr	vaddr,
				 u_int		*dis)
{
  int		   stop;
  elfsh_Sym	   *sym;
  u_int		   ilen,done;
  eresi_Addr	   init_addr;
  asm_instr	   ins;
  int		   arch_bin;
  int		   fetch_next = 0;
  eresi_Addr	   main_addr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  done = 0;

  for (*dis = stop = 0; !stop; *dis += ilen) 
    {
      ilen = asm_read_instr(&ins, (u_char *) buf + *dis, 
			    len - *dis, proc);

      if (!*dis)
	{
	  if (proc->type == ASM_PROC_IA32)
	    {
	      switch (ins.instr) 
		{
		case ASM_XOR:      
		  arch_bin = MJR_BIN_LINUX;
		  break;
		case ASM_PUSH:
		  arch_bin = MJR_BIN_FREEBSD;
		  sym = elfsh_get_metasym_by_name(obj, ELFSH_SECTION_NAME_INIT);
		  init_addr = sym->st_value;
		  fprintf(stderr, 
			  " [*] locating call to .init: %lx\n", 
			  (unsigned long) init_addr);
		  break;

		}
	    }
	  else if (proc->type == ASM_PROC_SPARC) 
	    {
	      switch (ins.instr)
		{
		case ASM_SP_MOV:
		  arch_bin = MJR_BIN_LINUX;
		  break;
		}
	    }
	  else if (proc->type == ASM_PROC_MIPS)
	    {
	      // FIXME: this should be expanded
	      arch_bin = MJR_BIN_LINUX;
	    }

	  else 
	    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
			 "Architecture not supported", -1);

	  // FIXME: This should go to librevm
	  fprintf(stderr, " [*] %s-like start\n", arch_bin ? "FreeBSD" : "Linux");  
	}

    /* Now fingerprint depending on the architecture */
    if (proc->type == ASM_PROC_IA32)
      {  
    	switch (ins.instr) 
  	  {
    	  case ASM_PUSH:
    	    if (*dis && (arch_bin == MJR_BIN_LINUX) && 
		ins.op[0].type == ASM_OTYPE_IMMEDIATE)
    	      asm_operand_get_immediate(&ins, 1, 0, &main_addr);
    	    break;
    	  case ASM_CALL:
    	    if (arch_bin == MJR_BIN_FREEBSD) 
	      {
		asm_operand_get_immediate(&ins, 1, 0, &main_addr);
		if (fetch_next)
		  stop = 1;
		
		main_addr += vaddr + *dis + ilen;
		if (main_addr == init_addr)
		  fetch_next = 1;
		
		break;	
  	      }
    	    else if ((arch_bin == MJR_BIN_LINUX)) 
  	      {
		stop = 1;
		break;
	      }
	  }
      }
    else if (proc->type == ASM_PROC_SPARC)
      {
	switch (ins.instr)
	  {
     	  case ASM_SP_SETHI:
     	    if (ins.op[0].baser == ASM_REG_O0)
     	      main_addr = ins.op[1].imm << 10;
     	    break;
     	  case ASM_SP_OR:
     	    if (ins.op[0].baser == ASM_REG_O0 &&
		ins.op[2].baser == ASM_REG_O0 &&
		ins.op[1].type == ASM_SP_OTYPE_IMMEDIATE)
     	      main_addr |= ins.op[1].imm;
     	    break;
     	  case ASM_SP_CALL:
	    stop = 1;
     	    break;      	
   	  }
      }
    else if (proc->type == ASM_PROC_MIPS)
      {
	// FIXME: this should be expanded (WIP)
	main_addr = vaddr;
	stop = 1;
      }
    else
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		   "Architecture not supported", -1);
 
    done += ilen;
    /* If we reached this point it probably means that we analyse 
       self made software, written in asm and compiled with nasm */
    if (done >= len)
      {
	main_addr = vaddr;
	stop = 1;
      }
    }
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, main_addr);
}
示例#5
0
文件: signal.c 项目: kejiewei/eresi
/**
 * The Real routine that handles each thread-specific breakpoint state machine.
 * 
 * breakpoint case:
 * 
 * 0-1: restore old instr, enable step, set bp addr in ->past, reset pc to orig bp addr
 * 1-2: do nothing (just executed instr)
 * 2-3: reinstall, resetstep, thread_contall, curthread->was_step = 0, 
 *     stoppedthread->count = NONE; e2dbgworld.curbp = NULL; stoppedthread = RUNNING
 *
 * stepping case:
 * 
 * 0-1: print current instr; reinstall
 *      stoppedthread->state = BREAKING; thread_contall; 
 *      was_step = 0; count = NONE; curbp = NULL; stoppedthread->state = RUNNING
 */
void			e2dbg_breakpoint_process()
{
  char			buf[32];
  elfshbp_t		*bp;
  int			prot;
  char			*name;
  elfsh_SAddr		off;
  int			ret;
  asm_instr		ptr;
  char			*s;
  eresi_Addr		*pc; 
  eresi_Addr		savedpc;
  u_int			bpsz;
  elfshsect_t		*sect;
  elfshobj_t		*parent;
  elfsh_Sym		*sym;

#if __DEBUG_BP__
  fprintf(stderr, " [D] Entering breakpoint handler\n");
#endif

  /* Set all registers as variables and get PC */
  e2dbg_user_hooks_install();
  e2dbg_getregs(); 
  pc = e2dbg_getpc();

  parent = e2dbg_get_parent_object((eresi_Addr) *pc);
  bpsz = elfsh_get_breaksize(parent);

  /* Print variables and registers on breakpoints */
  //if (!world.state.revm_quiet)
  //cmd_vlist();

  /* Try to find the breakpoint at current instruction pointer */
#if __DEBUG_BP__
  fprintf(stderr, " [D] At PC = %08X : Trying to find breakpoint at addr %08X (bpsize = %u)\n", 
	  *pc, *pc - bpsz, bpsz);
#endif

  snprintf(buf, sizeof(buf), XFMT, *pc - bpsz);
  bp = hash_get(&e2dbgworld.bp, buf);

#if __DEBUG_BP__
  if (bp)
    fprintf(stderr, " [D] Saved instruction BYTE = %02X and PC-BPSZ BYTE = %02X \n",
	    bp->savedinstr[0], *((u_char *) *pc - bpsz));
  else
    fprintf(stderr, " [D] No BP found at %08X ! \n", *pc);
#endif

  /* Case of processing breakpoint, or if we are single-stepping */
  if (!bp || (bp->savedinstr[0] == *((u_char *) *pc - bpsz)))
    {

      /* We are single-stepping, display the instruction at $pc */
      if (e2dbgworld.stoppedthread->step)
	{

#if __DEBUG_BP__
	  fprintf(stderr, " [D] Single-stepping -IS- enabled \n");
#endif

	  ret = asm_read_instr(&ptr, (u_char *) *pc, 16, world.curjob->proc);
	  if (!ret)
	    ret++;
	  sect   = elfsh_get_parent_section(parent, (eresi_Addr) *pc, NULL);
	  name   = revm_resolve(parent, (eresi_Addr) *pc, &off);
	  off = 0;
	  sym    = elfsh_get_metasym_by_value(parent, (eresi_Addr) *pc, 
					      &off, ELFSH_LOWSYM);

#if __DEBUG_BP__
	  fprintf(stderr, 
		  " [D] Found parent = %08X (%s) in step (name = %s, parentsect = %s) off = %u\n", 
		  (eresi_Addr) parent, parent->name, name, sect->name, off);
#endif

	  revm_instr_display(-1, *pc, 0, 20, name, off, (char *) *pc);
	  e2dbg_display(e2dbgworld.displaycmd, e2dbgworld.displaynbr);
	  if (!e2dbgworld.stoppedthread->trace)
	    e2dbg_entry(NULL);
	  else
	    e2dbg_watch();

	  e2dbg_breakpoint_reinstall();
	  return;
	}

#if __DEBUG_BP__
      fprintf(stderr, " [D] Single-stepping is -NOT- enabled \n");
#endif

      /* Here starts the real stuff 
      **
      ** count == E2DBG_BREAK_EXEC     -> execute restored instruction
      ** count == E2DBG_BREAK_FINISHED -> restore breakpoint
      ** count >  E2DBG_BREAK_MAX      -> e2dbg is getting debugged by a third party debugger
      */
      e2dbgworld.stoppedthread->count++;	
      
#if __DEBUG_BP__
      fprintf(stderr, " [C] Count %u -> %u for thread ID %u \n", 
	     e2dbgworld.stoppedthread->count - 1, 
	     e2dbgworld.stoppedthread->count, 
	     ((unsigned int) e2dbgworld.stoppedthread->tid));
#endif
      
      /* execute the previously restored instruction */
      if (e2dbgworld.stoppedthread->count == E2DBG_BREAK_EXEC)
	{
#if __DEBUG_BP__
	  printf(" [D] At PC = 0x%X : Debuggee executed restored instruction \n", *pc);
#endif
	  return;
	}
      
      /* Suggested by andrewg, useful when debugging valgrind */
      if (e2dbgworld.stoppedthread->count > E2DBG_BREAK_MAX)
	{
	  printf(".::- E2DBG WARNING -::.\n"
		 "Breakpoint triggered at location " AFMT " which we don't know about.\n\n"
		 "This may be an anti-debug trick or the program may be inside another\n"
		 "debugger. Exiting (DEBUG: count = " UFMT ", step is off)\n\n",
		 *pc - bpsz, e2dbgworld.stoppedthread->count);
	  return;
	}

      e2dbg_breakpoint_reinstall();
      
      /* remove trace flag */	  
#if __DEBUG_BP__
      fprintf(stderr, " [D] At PC = " AFMT " Resetting STEP mode\n", *pc);
#endif
      e2dbg_resetstep();
      return;
    }

  /* Case of newly hit breakpoint */
  else
    {
      name = revm_resolve(parent, (eresi_Addr) *pc - bpsz, &off);
      s    = (e2dbg_is_watchpoint(bp) ? "Watch" : "Break");

#if __DEBUG_BP__
      fprintf(stderr, " [C] Count set to 1 (HIT) for thread ID %u \n", 
		(unsigned int) e2dbgworld.stoppedthread->tid);
#endif      
      
      if (off)
	printf(" [*] %spoint found at " XFMT " <%s + " DFMT "> in thread %u \n\n", 
	       s, *pc - bpsz, name, off, (unsigned int) e2dbgworld.stoppedthread->tid);
      else 
	printf(" [*] %spoint found at " XFMT " <%s> in thread %u \n\n",   
	       s, *pc - bpsz, name, (unsigned int) e2dbgworld.stoppedthread->tid);

      revm_doswitch(parent->id);
      mjr_set_current_context(&world.mjr_session, parent->name);
      
      *pc -= bpsz;
      prot = elfsh_munprotect(bp->obj, *pc,  bpsz);
      memcpy((u_char *) *pc, bp->savedinstr, bpsz);
      elfsh_mprotect(bp->obj, *pc, bpsz, prot);

      e2dbg_setstep();

#if __DEBUG_BP__
      fprintf(stderr, " [D] Setting Step mode \n");
#endif

      e2dbgworld.stoppedthread->past  = *pc;
      e2dbgworld.stoppedthread->count = E2DBG_BREAK_HIT;
      e2dbgworld.curbp                = bp;
      bp->tid                         = (uint32_t) e2dbgworld.stoppedthread->tid;

#if __DEBUG_BP__
      fprintf(stderr, " [D] Reset break \n");
#endif

      if (bp->cmdnbr)
	e2dbg_display(bp->cmd, bp->cmdnbr);
      else
	e2dbg_display(e2dbgworld.displaycmd, e2dbgworld.displaynbr);

#if __DEBUG_BP__
      fprintf(stderr, " [D] After BP display \n");
#endif

#if __DEBUG_BP__
      fprintf(stderr, " [D] PC before entry is addr 0x%X \n", *pc);
#endif
      
      savedpc = *pc;
      e2dbg_entry(NULL);
      *pc = savedpc;

#if __DEBUG_BP__
      fprintf(stderr, " [D] At PC = 0x%X : returned from BP handler with step enabled\n",
	      *pc);
#endif
    }
}
示例#6
0
/**
 * Display An instruction.
 * Runtime compatible
 * @param fd
 * @param index
 * @param vaddr
 * @param foffset
 * @param size
 * @param name
 * @param nindex
 * @param buff
 */
int		revm_instr_display(int fd, eresi_Addr vaddr, u_int foffset, u_int size,
                           char *name, u_int symoff, char *buff)
{
    char		*s;
    char		buf[256];
    u_int		idx_bytes;
    int		ret;
    asm_instr	ptr;
    char		base[16] = "0123456789ABCDEF";
    char		logbuf[BUFSIZ];
    char		c1[2];
    char		c2[2];
    u_int		strsz;
    int		err;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
    if (!buff)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Invalid argument", (-1));
    revm_proc_init();
    err = 0;

    /* Print the instr. itself : vaddr and relative symbol resolution */
    ret = asm_read_instr(&ptr, (u_char *) buff, size, world.curjob->proc);
    if (ret == -1)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Failed to read instruction", ESTD_DISASM_FAILED);

    s = (!ret ? "(bad)" : asm_display_instr_att(&ptr, vaddr));

    /* Libasm test */
    if (fd == -1)
    {

        /* Are we in quiet mode ? */
        if (world.state.revm_quiet)
        {
            snprintf(buf, sizeof(buf), " %s %s + %s",
                     revm_coloraddress(XFMT, vaddr),
                     revm_colorstr(name),
                     revm_colornumber("%u", symoff));
            size = snprintf(logbuf, BUFSIZ, "%-40s %-30s ",
                            buf, revm_colorinstr(s));
        }
        else
        {
            size = snprintf(buf, sizeof(buf), " %s [%s %s] %s + %s",
                            revm_coloraddress(XFMT, vaddr),
                            revm_colorfieldstr("foff:"),
                            revm_colornumber("%u", foffset),
                            revm_colorstr(name),
                            revm_colornumber("%u", symoff));
            strsz = strlen(s);
            size = snprintf(logbuf, BUFSIZ, "%-*s %-*s ",
                            (size > 95 ? 125 :
                             size > 87 ? 100 :
                             size > 75 ? 108 :
                             size > 50 ? 88 : 55),
                            buf,
                            (strsz > 95 ? 125 :
                             strsz > 87 ? 100 :
                             strsz > 75 ? 108 :
                             strsz > 50 ? 88 : 55),
                            revm_colorinstr(s));
        }

        /* Print bytes in hexa for this instruction */
        ret = asm_instr_len(&ptr);
        if (!ret)
            ret++;

        if (!world.state.revm_quiet)
            for (idx_bytes = 0; idx_bytes < (u_int) ret; idx_bytes++)
            {
                c1[0] = base[(buff[idx_bytes] >> 4) & 0x0F];
                c2[0] = base[buff[idx_bytes] & 0x0F];
                c1[1] = c2[1] = 0x00;
                size += snprintf(logbuf + size, sizeof(logbuf) - size, "%s%s ",
                                 revm_colorfieldstr(c1),
                                 revm_colorfieldstr(c2));
            }

        if (!world.curjob->curcmd || !world.curjob->curcmd->use_regx[1] ||
                !regexec(&second->name, logbuf, 0, 0, 0))
        {
            snprintf(logbuf + size, sizeof(logbuf) - size, "\n");
            err = revm_output(logbuf);
        }
        revm_endline();
        if (err < 0)
            PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, err);
    }
    else