Example #1
0
/**
 * Write a breakpoint 0xCC in memory
 * One of the 2 breakpoint technique of e2dbg 
 */
int		e2dbg_break_amd64(elfshobj_t *f,
				 elfshbp_t  *bp)
{
  int		prot;
  
  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  
#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:amd64] bp->addr %08X \n", bp->addr);
#endif
  
  bp->savedinstr[0] = *(eresi_Addr *) bp->addr;
  prot = elfsh_munprotect(f, bp->addr, 4);
  if (prot == (-1))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Munprotect failed", (-1));
  
#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:amd64] after munprotect\n");
#endif
  *(u_char *) bp->addr = 0xCC;
#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:amd64] after write\n");
#endif
  elfsh_mprotect(f, bp->addr, 4, prot);
#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:amd64] after mprotect\n");
#endif
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (0));
}
Example #2
0
File: raw.c Project: 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));
}
Example #3
0
int                     e2dbg_break_sparc32(elfshobj_t *f, elfshbp_t *bp)
{
  int                   prot;
  unsigned long		addr;
  unsigned long long	addr64;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:sparc32] bp->addr %016x \n", bp->addr);
#endif

  memcpy(bp->savedinstr, (u_char *) bp->addr, 8);

  prot = elfsh_munprotect(f, bp->addr, 8);
  if (prot == (-1))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Munprotect failed", (-1));

#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:sparc32] after munprotect\n");
#endif

  //*(u_long *)  bp->addr      = 0x91d02001;		/* opcode for ta 1 */

  *((u_long *) bp->addr)     = 0x01000000;		/* put nop here */
  *((u_long *) bp->addr + 1) = 0x01000000;		/* put nop here */

  addr = (bp->addr & (~7));

#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:sparc32] Address to be flushed: %016lx \n", addr);
#endif
  
  /* FIXME: Testing .... nothing is working until now */
  __asm__ __volatile__("iflush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr), 
		       "r" (0));

  __asm__ __volatile__("iflush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr), 
		       "r" (8));

  __asm__ __volatile__("iflush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr), 
		       "r" (16));

  __asm__ __volatile__("flush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr), 
		       "r" (0));

  __asm__ __volatile__("flush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr), 
		       "r" (8));

  __asm__ __volatile__("flush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr), 
		       "r" (16));

  addr64 = 0xffffffff00000000 + addr;

#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:sparc32] Address64 to be flushed: %016llx \n", addr64);
#endif

  __asm__ __volatile__("iflush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr64), 
		       "r" (0));

  __asm__ __volatile__("iflush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr64), 
		       "r" (8));

  __asm__ __volatile__("iflush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr64), 
		       "r" (16));

  __asm__ __volatile__("flush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr64), 
		       "r" (0));

  __asm__ __volatile__("flush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr64), 
		       "r" (8));

  __asm__ __volatile__("flush %0 + %1 \n\t" ::
		       "r" ((unsigned long) addr64), 
		       "r" (16));


#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:sparc32] after sleep & write\n");
#endif

  elfsh_mprotect(f, bp->addr, 8, prot);

  sleep(2);

#if __DEBUG_BREAKPOINTS__
  fprintf(stderr, "[DEBUG_BREAKPOINTS:sparc32] after mprotect\n");
#endif

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (0));
}
Example #4
0
/**
 * 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
    }
}