Beispiel #1
0
EXPORT int CALL DebugBreakpointCommand(m64p_dbg_bkp_command command, unsigned int index, void *ptr)
{
#ifdef DBG
    switch (command)
    {
        case M64P_BKP_CMD_ADD_ADDR:
            return add_breakpoint(index);
        case M64P_BKP_CMD_ADD_STRUCT:
            return add_breakpoint_struct((breakpoint *) ptr);
        case M64P_BKP_CMD_REPLACE:
            replace_breakpoint_num(index, (breakpoint *) ptr);
            return 0;
        case M64P_BKP_CMD_REMOVE_ADDR:
            remove_breakpoint_by_address(index);
            return 0;
        case M64P_BKP_CMD_REMOVE_IDX:
            remove_breakpoint_by_num(index);
            return 0;
        case M64P_BKP_CMD_ENABLE:
            enable_breakpoint(index);
            return 0;
        case M64P_BKP_CMD_DISABLE:
            disable_breakpoint(index);
            return 0;
        case M64P_BKP_CMD_CHECK:
            return check_breakpoints(index);
        default:
            DebugMessage(M64MSG_ERROR, "Bug: DebugBreakpointCommand() called with invalid input m64p_dbg_bkp_command");
            return -1;
    }
#else
    DebugMessage(M64MSG_ERROR, "Bug: DebugBreakpointCommand() called, but Debugger not supported in Core library");
    return -1;
#endif
}
/* Python function to set the enabled state of a breakpoint.  */
static int
bppy_set_enabled (PyObject *self, PyObject *newvalue, void *closure)
{
  breakpoint_object *self_bp = (breakpoint_object *) self;
  int cmp;

  BPPY_SET_REQUIRE_VALID (self_bp);

  if (newvalue == NULL)
    {
      PyErr_SetString (PyExc_TypeError, 
		       _("Cannot delete `enabled' attribute."));

      return -1;
    }
  else if (! PyBool_Check (newvalue))
    {
      PyErr_SetString (PyExc_TypeError,
		       _("The value of `enabled' must be a boolean."));
      return -1;
    }

  cmp = PyObject_IsTrue (newvalue);
  if (cmp < 0)
    return -1;
  else if (cmp == 1)
    enable_breakpoint (self_bp->bp);
  else 
    disable_breakpoint (self_bp->bp);
  return 0;
}
Beispiel #3
0
static void
disable_bp_cb(void *addr, void *sbp, void *proc) {
	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid);
	if (((Breakpoint *)sbp)->enabled) {
		disable_breakpoint(((Process *)proc)->pid, sbp);
	}
}
Beispiel #4
0
int
breakpoint_turn_off(struct breakpoint *bp, struct process *proc)
{
	bp->enabled--;
	if (bp->enabled == 0)
		disable_breakpoint(proc, bp);
	assert(bp->enabled >= 0);
	return 0;
}
void
bpfinishpy_post_stop_hook (struct breakpoint_object *bp_obj)
{
  volatile struct gdb_exception except;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      /* Can't delete it here, but it will be removed at the next stop.  */
      disable_breakpoint (bp_obj->bp);
      gdb_assert (bp_obj->bp->disposition == disp_del);
    }
Beispiel #6
0
void
delete_breakpoint(Process *proc, void *addr) {
	Breakpoint *sbp;

	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);

	sbp = dict_find_entry(proc->breakpoints, addr);
	assert(sbp);		/* FIXME: remove after debugging has been done. */
	/* This should only happen on out-of-memory conditions. */
	if (sbp == NULL)
		return;

	sbp->enabled--;
	if (sbp->enabled == 0)
		disable_breakpoint(proc->pid, sbp);
	assert(sbp->enabled >= 0);
}
Beispiel #7
0
int resume_from_breakpoint(pid_t pid, debug_breakpoint* bp)
{
    struct user_regs_struct regs;
    int wait_status;

    ptrace(PTRACE_GETREGS, pid, 0, &regs);
    /* Make sure we indeed are stopped at bp */
    assert(regs.rip == (long) bp->addr + 1);

    /* Now disable the breakpoint, rewind EIP back to the original instruction
    ** and single-step the process. This executes the original instruction that
    ** was replaced by the breakpoint.
    */
    regs.rip = (long) bp->addr;
    ptrace(PTRACE_SETREGS, pid, 0, &regs);
    disable_breakpoint(pid, bp);
    if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0) < 0) {
        perror("ptrace");
        return -1;
    }
    wait(&wait_status);

    if (WIFEXITED(wait_status)) {
        return 0;
    }

    /* Re-enable the breakpoint and let the process run.
    */
    enable_breakpoint(pid, bp);

    if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) {
        perror("ptrace");
        return -1;
    }
    wait(&wait_status);

    if (WIFEXITED(wait_status))
        return 0;
    else if (WIFSTOPPED(wait_status)) {
        return 1;
    }
    else
        return -1;
}
/* Python function to set the enabled state of a breakpoint.  */
static int
bppy_set_enabled (PyObject *self, PyObject *newvalue, void *closure)
{
    gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
    int cmp;
    volatile struct gdb_exception except;

    BPPY_SET_REQUIRE_VALID (self_bp);

    if (newvalue == NULL)
    {
        PyErr_SetString (PyExc_TypeError,
                         _("Cannot delete `enabled' attribute."));

        return -1;
    }
    else if (! PyBool_Check (newvalue))
    {
        PyErr_SetString (PyExc_TypeError,
                         _("The value of `enabled' must be a boolean."));
        return -1;
    }

    cmp = PyObject_IsTrue (newvalue);
    if (cmp < 0)
        return -1;

    TRY_CATCH (except, RETURN_MASK_ALL)
    {
        if (cmp == 1)
            enable_breakpoint (self_bp->bp);
        else
            disable_breakpoint (self_bp->bp);
    }
    GDB_PY_SET_HANDLE_EXCEPTION (except);

    return 0;
}
Beispiel #9
0
void debugger_proc(pid_t child_proc, struct execute_context *ctx)
{
    /* about child process */
    int child_stat;
    kern_return_t kret;
    mach_port_t task;
    int wait_cnt = 0;
    char **args = ctx->passing_args;

    /* related analysys of target process binary. */
    int i;
    int nsym;
    int text_section;
    uint64_t text_section_offset;
    uint64_t text_section_size;
    uint64_t text_section_vmaddr;
    struct symbol_info *psymbol_table;
    int init = 0;
    struct breakpoint_entry top;

    int stack_depth = 0;

    /* error check */
    if (child_proc == 0 || child_proc == -1)	return;

    /* initialize */
    memset(&top, 0x00, sizeof(top));

    /* open the port (do as an administrator) */
    kret = task_for_pid(mach_task_self(), child_proc, &task);
    if (kret != KERN_SUCCESS) {
        fprintf(stderr, "task_for_pid() failed\n");
        fprintf(stderr, "%s\n", mach_error_string(kret));
        exit(0);
    }

    fprintf(stderr, "[Tracer] child_proc: %d\n", child_proc);
    /* main loop */
    while(waitpid(child_proc, &child_stat, WUNTRACED)) {    /* {{{ */
        char buffer[128];
        char w_buf[128];
        w_buf[0] = 0x90;	/* nop */

        if (WIFEXITED(child_stat)) {
            /* Child Process Terminated */
            fprintf(stderr, "[Tracer]  Process :%d Terminated\n", child_proc);
            return;
        }
        memset(buffer, 0x00, 128);
        if(wait_cnt == 0) {
            /* The First time trapped   {{{ */
            /* -- The debugee program has not been expanded.-- */
            /* -- 	lookup named symbol	-- */
            struct file_info bininfo;
            ud_t ud_obj;
            uint64_t previous_eip;
            uint64_t func_start_addr;
            uint64_t func_end_addr;

            nsym = get_func_table(args[0], &psymbol_table, &text_section, &text_section_offset, &text_section_size, &text_section_vmaddr);
            debug_printf("nsym: %d\n", nsym);
            debug_printf("text section = %d\n", text_section);
            debug_printf("text section offset: 0x%llx\n", text_section_offset);
            debug_printf("text section size: 0x%llx\n", text_section_size);
            debug_printf("text section vmaddr: 0x%llx\n", text_section_vmaddr);

            qsort(psymbol_table, nsym, sizeof(struct symbol_info), symbolinfo_comp);

            /* XXX for debugging  */
            /*display_symbol_table(psymbol_table, nsym);  */

            /* code analysys */
            map_binary(args[0], &bininfo);
            ud_init(&ud_obj);
            ud_set_input_buffer(&ud_obj, bininfo.top + text_section_offset, text_section_size);
            ud_set_mode(&ud_obj, 64);

            previous_eip = text_section_vmaddr;
            /* set breakpoint at the entry and exit points of functions */
            for(i = 0; i < nsym; i++) {
                /* Set breakpoints {{{ */
                if (is_exclude_func(psymbol_table + i) == 1) {
                    continue;
                }
                /* 1, specifying the region of the function */
                func_start_addr = psymbol_table[i].nlist64.n_value;
                if (i != nsym - 1) {
                    /* next section's entry point - 1 */
                    func_end_addr = psymbol_table[i + 1].nlist64.n_value;
                } else {
                    func_end_addr = text_section_vmaddr + text_section_size + 1;
                }
                printf("%s: 0x%llx --> 0x%llx\n", psymbol_table[i].name, func_start_addr, func_end_addr);
                /*
                if (strstr(psymbol_table[i].name, "main") != NULL) {
                    __asm__("int3");
                }
                */
                psymbol_table[i].ret_address_num = 0;

                previous_eip = ud_obj.pc + text_section_vmaddr;

                while(ud_disassemble(&ud_obj) && previous_eip < func_start_addr) {
                    previous_eip = ud_obj.pc + text_section_vmaddr;
                }
                while(ud_disassemble(&ud_obj) && previous_eip < func_end_addr) {
                    if (func_start_addr <= previous_eip && ud_obj.mnemonic == UD_Iret) {
                        set_breakpoint(task, previous_eip, &top);
                        psymbol_table[i].ret_inst_address[ psymbol_table[i].ret_address_num ] = previous_eip;
                        psymbol_table[i].ret_address_num++;
                    }
                    previous_eip = ud_obj.pc + text_section_vmaddr;
                }
                /*
                if (0 < psymbol_table[i].ret_address_num) {
                    set_breakpoint(task, psymbol_table[i].nlist64.n_value, &top);
                }
                */
                set_breakpoint(task, psymbol_table[i].nlist64.n_value, &top);
                /* }}} */
            }
            debug_printf("break point insert\n");
            unmap_binary(&bininfo);
            /* }}} */
        } else {
            /* {{{ */
            /* break point */
            /* 1, Get current address from RIP value.
            * 2, Find current function name by EIP, and Logging.
            * 3, Substitute original instruction code for current break point code(0x90).
            * 4, Decrement EIP value.
            * 5, Execute only one op-code.
            * 6, Substitute 0x90 for oroginal code (located in entrance of function).
            * */
            uint64_t rip;
            read_process_register_64(task, RIP, &rip);
            if (is_breakpoint(rip - 1, &top) == 1) {
                stack_depth = breakpoint_handler(task, rip - 1, psymbol_table, nsym, stack_depth);
                write_process_register_64(task, RIP, RELATIVE_VAL, -1);
                disable_breakpoint(task, rip - 1, &top);
                ptrace(PT_STEP, child_proc, (caddr_t)1, 0);
                set_breakpoint(task, rip - 1, &top);
            }
            /* }}} */
        }
        wait_cnt++;
        ptrace(PT_CONTINUE, child_proc, (caddr_t)1, 0);
    }   /* }}} */
}