Esempio n. 1
0
/**
 * SIGTRAP signal handler (The breakpoint routine). Save registers and callback. Multi-thread safe.
 * @param signum Received signal number.
 * @param info Signal info structure from breakpoint.
 * @param pcontext Context data pointer containing register values and more.
 * @return
*/
void			e2dbg_generic_breakpoint(int		signum, 
						 siginfo_t	*info, 
						 void		*pcontext)
{
  ucontext_t		*context;
  char			key[15];
  pthread_t		stopped;

  /* Do not allow processing of 2 breakpoint at the same time */
  /* We update the current thread information */
  e2dbg_presence_set();
  revm_proc_init();

  if (!e2dbgworld.curbp || e2dbgworld.curbp->tid != e2dbg_self())
    {
      e2dbg_mutex_lock(&e2dbgworld.dbgbp);

#if (__DEBUG_THREADS__ || __DEBUG_E2DBG__ || __DEBUG_MUTEX__ || __DEBUG_BP__)
      //e2dbg_output("-------------- ON-BREAK REGISTERS ----------------------->\n");
      //cmd_dumpregs();
      //e2dbg_output("<------------------------------------------------------\n");
      e2dbg_output("------------------------------------->\n");
      e2dbg_output(" [*] BP MUTEX LOCKED [e2dbg_generic_breakpoint] \n");
      //e2dbg_threads_print();
#endif
    }

  /* Get the current thread */
  stopped = (pthread_t) e2dbg_self();
  snprintf(key, sizeof(key), "%u", (unsigned int) stopped);
  e2dbgworld.curthread = hash_get(&e2dbgworld.threads, key);
  e2dbgworld.stoppedthread = e2dbgworld.curthread;
  
#if (__DEBUG_THREADS__ || __DEBUG_E2DBG__ || __DEBUG_MUTEX__ || __DEBUG_BP__)
  fprintf(stderr, "\n [*] Thread entering generic breakpoint (ID %u) \n",
	 (unsigned int) e2dbgworld.stoppedthread->tid);
  fflush(stdout);
#endif
  
  e2dbgworld.stoppedthread->state = E2DBG_THREAD_BREAKING;
  context = (ucontext_t *) pcontext;
  e2dbgworld.stoppedthread->context = context;

  /* We first get contexts for all other threads (except debugger) using SIGUSR2 */
  /* Then we stop all threads */
  /* We do this only at the first state (count = 0) of the breakpoint */
  if (!e2dbgworld.stoppedthread->count)
    {
      if (e2dbg_thread_stopall(SIGUSR2))
	usleep(100000);
    }
#if (__DEBUG_THREADS__ || __DEBUG_E2DBG__ || __DEBUG_MUTEX__ || __DEBUG_BP__)
  else
    fprintf(stderr, " NOT COLLECTING THREADS CONTEXTS (stopped thread %u state count = %u) \n", 
	    (u_int) e2dbgworld.stoppedthread->tid, e2dbgworld.stoppedthread->count);
#endif

  /* Call the real breakpoint code */
  e2dbg_breakpoint_process();

  /* Continue all threads */
  if (e2dbgworld.stoppedthread->count == E2DBG_BREAK_FINISHED || 
      e2dbgworld.curthread->step || e2dbgworld.curthread->was_step)
    {
      e2dbg_thread_contall();
      e2dbgworld.curthread->was_step = 0;
      e2dbgworld.stoppedthread->count = E2DBG_BREAK_NONE;
      e2dbgworld.curbp                = NULL;
  
      fprintf(stderr, " [D] Thread ID %lu now has Count = 0 (NONE) \n", e2dbgworld.curthread->tid);

      /* Allow another breakpoint to be processed */
      if (e2dbg_mutex_unlock(&e2dbgworld.dbgbp) != 0)
	e2dbg_output(" [*] Debuggee Cannot unlock breakpoint mutex ! \n");
#if (__DEBUG_THREADS__ || __DEBUG_E2DBG__ || __DEBUG_MUTEX__ || __DEBUG_BP__)
      else
	{
	  e2dbg_output(" [*] BP MUTEX UNLOCKED [e2dbg_generic_breakpoint] \n");
	  e2dbg_output("<-------------------------------------\n");
	}
#endif
    }

#if (__DEBUG_THREADS__ || __DEBUG_E2DBG__ || __DEBUG_MUTEX__ || __DEBUG_BP__)
  else
    fprintf(stderr, " [D] No SIGCONT as thread (%u) is stopped with state count = %u \n", 
	    (u_int) e2dbgworld.stoppedthread->tid, e2dbgworld.stoppedthread->count);
#endif

  e2dbgworld.stoppedthread->state = E2DBG_THREAD_RUNNING;
  e2dbg_presence_reset();
  SETSIG;

#if __DEBUG_BP__
  fprintf(stderr, " [D] Returning from generic signal handler\n");
#endif
}
Esempio n. 2
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