/*
 * Initialize heaps and do first run for server programs.
 */
void
SOS_init()
{
	uint_t i, m;

	procs_init();
	/* enter SOS's debugger? */
	if (kern_args_cpy.debug == TRUE)
		set_single_step();

	main();
}
Esempio n. 2
0
void log_branch(_In_ PVOID address, _In_ DWORD pid, _In_ DWORD thread_id)
{
    if (!((DWORD_PTR)address >= k32_base && (DWORD_PTR)address < k32_max))
    {
        return;
    }


    // exception address read
    PDEBUGGEE dbge = NULL;
    for (int i = 0; i < sizeof(_debuggees) / sizeof(DEBUGGEE); ++i)
    {
        if (_debuggees[i]._pid == pid)
        {
            dbge = &_debuggees[i];
        }
    }
    if (NULL == dbge) return;

    SIZE_T bytes_read = 0;
    unsigned char buf[4] = { 0 };
    ReadProcessMemory(dbge->_proc_handle,
                      address,
                      buf,
                      sizeof(buf),
                      &bytes_read);

    if (0xE8 == buf[0])
    {
        log("call at 0x%08x", address);
    }

    // single step 을 활성화

    ch_param param = { 0 };
    param.hthread = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id);
    if (NULL != param.hthread)
    {
        param.context.ContextFlags = CONTEXT_ALL;
        if (TRUE != GetThreadContext(param.hthread, &param.context))
        {
            _ASSERTE(!"oops!");
            return;
        }
        set_single_step(&param);
    }
}
Esempio n. 3
0
int sys_ptrace(long request, long pid, long addr, long data)
{
	struct task_struct *child;
	int ret = -EPERM;

	lock_kernel();
	if (request == PTRACE_TRACEME) {
		/* are we already being traced? */
		if (current->ptrace & PT_PTRACED)
			goto out;
		ret = security_ptrace(current->parent, current);
		if (ret)
			goto out;
		/* set the ptrace bit in the process flags. */
		current->ptrace |= PT_PTRACED;
		ret = 0;
		goto out;
	}
	ret = -ESRCH;
	read_lock(&tasklist_lock);
	child = find_task_by_pid(pid);
	if (child)
		get_task_struct(child);
	read_unlock(&tasklist_lock);
	if (!child)
		goto out;

	ret = -EPERM;
	if (pid == 1)		/* you may not mess with init */
		goto out_tsk;

	if (request == PTRACE_ATTACH) {
		ret = ptrace_attach(child);
		goto out_tsk;
	}

	ret = ptrace_check_attach(child, request == PTRACE_KILL);
	if (ret < 0)
		goto out_tsk;

	switch (request) {
	/* when I and D space are separate, these will need to be fixed. */
	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
	case PTRACE_PEEKDATA: {
		unsigned long tmp;
		int copied;

		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
		ret = -EIO;
		if (copied != sizeof(tmp))
			break;
		ret = put_user(tmp,(unsigned long __user *) data);
		break;
	}

	/* read the word at location addr in the USER area. */
	case PTRACE_PEEKUSR: {
		unsigned long index;
		unsigned long tmp;

		ret = -EIO;
		/* convert to index and check */
		index = (unsigned long) addr >> 3;
		if ((addr & 7) || (index > PT_FPSCR))
			break;

		if (index < PT_FPR0) {
			tmp = get_reg(child, (int)index);
		} else {
			flush_fp_to_thread(child);
			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
		}
		ret = put_user(tmp,(unsigned long __user *) data);
		break;
	}

	/* If I and D space are separate, this will have to be fixed. */
	case PTRACE_POKETEXT: /* write the word at location addr. */
	case PTRACE_POKEDATA:
		ret = 0;
		if (access_process_vm(child, addr, &data, sizeof(data), 1)
				== sizeof(data))
			break;
		ret = -EIO;
		break;

	/* write the word at location addr in the USER area */
	case PTRACE_POKEUSR: {
		unsigned long index;

		ret = -EIO;
		/* convert to index and check */
		index = (unsigned long) addr >> 3;
		if ((addr & 7) || (index > PT_FPSCR))
			break;

		if (index == PT_ORIG_R3)
			break;
		if (index < PT_FPR0) {
			ret = put_reg(child, index, data);
		} else {
			flush_fp_to_thread(child);
			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
			ret = 0;
		}
		break;
	}

	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
	case PTRACE_CONT: { /* restart after signal. */
		ret = -EIO;
		if ((unsigned long) data > _NSIG)
			break;
		if (request == PTRACE_SYSCALL)
			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		else
			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		child->exit_code = data;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		ret = 0;
		break;
	}

	/*
	 * make the child exit.  Best I can do is send it a sigkill.
	 * perhaps it should be put in the status that it wants to
	 * exit.
	 */
	case PTRACE_KILL: {
		ret = 0;
		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
			break;
		child->exit_code = SIGKILL;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		break;
	}

	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
		ret = -EIO;
		if ((unsigned long) data > _NSIG)
			break;
		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		set_single_step(child);
		child->exit_code = data;
		/* give it a chance to run. */
		wake_up_process(child);
		ret = 0;
		break;
	}

	case PTRACE_DETACH:
		ret = ptrace_detach(child, data);
		break;

	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
		int i;
		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
		unsigned long __user *tmp = (unsigned long __user *)addr;

		for (i = 0; i < 32; i++) {
			ret = put_user(*reg, tmp);
			if (ret)
				break;
			reg++;
			tmp++;
		}
		break;
	}

	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
		int i;
		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
		unsigned long __user *tmp = (unsigned long __user *)addr;

		for (i = 0; i < 32; i++) {
			ret = get_user(*reg, tmp);
			if (ret)
				break;
			reg++;
			tmp++;
		}
		break;
	}

	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
		int i;
		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
		unsigned long __user *tmp = (unsigned long __user *)addr;

		flush_fp_to_thread(child);

		for (i = 0; i < 32; i++) {
			ret = put_user(*reg, tmp);
			if (ret)
				break;
			reg++;
			tmp++;
		}
		break;
	}

	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
		int i;
		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
		unsigned long __user *tmp = (unsigned long __user *)addr;

		flush_fp_to_thread(child);

		for (i = 0; i < 32; i++) {
			ret = get_user(*reg, tmp);
			if (ret)
				break;
			reg++;
			tmp++;
		}
		break;
	}

	default:
		ret = ptrace_request(child, request, addr, data);
		break;
	}
out_tsk:
	put_task_struct(child);
out:
	unlock_kernel();
	return ret;
}
Esempio n. 4
0
int sys_ptrace(long request, long pid, long addr, long data)
{
	struct task_struct *child;
	int ret = -EPERM;

	lock_kernel();
	if (request == PTRACE_TRACEME) {
		/* are we already being traced? */
		if (current->ptrace & PT_PTRACED)
			goto out;
		ret = security_ptrace(current->parent, current);
		if (ret)
			goto out;
		/* set the ptrace bit in the process flags. */
		current->ptrace |= PT_PTRACED;
		ret = 0;
		goto out;
	}
	ret = -ESRCH;
	read_lock(&tasklist_lock);
	child = find_task_by_pid(pid);
	if (child)
		get_task_struct(child);
	read_unlock(&tasklist_lock);
	if (!child)
		goto out;

	ret = -EPERM;
	if (pid == 1)		/* you may not mess with init */
		goto out_tsk;

	if (request == PTRACE_ATTACH) {
		ret = ptrace_attach(child);
		goto out_tsk;
	}

	ret = ptrace_check_attach(child, request == PTRACE_KILL);
	if (ret < 0)
		goto out_tsk;

	switch (request) {
	/* when I and D space are separate, these will need to be fixed. */
	case PTRACE_PEEKTEXT: /* read word at location addr. */
	case PTRACE_PEEKDATA: {
		unsigned long tmp;
		int copied;

		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
		ret = -EIO;
		if (copied != sizeof(tmp))
			break;
		ret = put_user(tmp,(unsigned long __user *) data);
		break;
	}

	/* read the word at location addr in the USER area. */
	/* XXX this will need fixing for 64-bit */
	case PTRACE_PEEKUSR: {
		unsigned long index, tmp;

		ret = -EIO;
		/* convert to index and check */
		index = (unsigned long) addr >> 2;
		if ((addr & 3) || index > PT_FPSCR
		    || child->thread.regs == NULL)
			break;

		CHECK_FULL_REGS(child->thread.regs);
		if (index < PT_FPR0) {
			tmp = get_reg(child, (int) index);
		} else {
			preempt_disable();
			if (child->thread.regs->msr & MSR_FP)
				giveup_fpu(child);
			preempt_enable();
			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
		}
		ret = put_user(tmp,(unsigned long __user *) data);
		break;
	}

	/* If I and D space are separate, this will have to be fixed. */
	case PTRACE_POKETEXT: /* write the word at location addr. */
	case PTRACE_POKEDATA:
		ret = 0;
		if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
			break;
		ret = -EIO;
		break;

	/* write the word at location addr in the USER area */
	case PTRACE_POKEUSR: {
		unsigned long index;

		ret = -EIO;
		/* convert to index and check */
		index = (unsigned long) addr >> 2;
		if ((addr & 3) || index > PT_FPSCR
		    || child->thread.regs == NULL)
			break;

		CHECK_FULL_REGS(child->thread.regs);
		if (index == PT_ORIG_R3)
			break;
		if (index < PT_FPR0) {
			ret = put_reg(child, index, data);
		} else {
			preempt_disable();
			if (child->thread.regs->msr & MSR_FP)
				giveup_fpu(child);
			preempt_enable();
			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
			ret = 0;
		}
		break;
	}

	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
	case PTRACE_CONT: { /* restart after signal. */
		ret = -EIO;
		if (!valid_signal(data))
			break;
		if (request == PTRACE_SYSCALL) {
			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		} else {
			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		}
		child->exit_code = data;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		ret = 0;
		break;
	}

/*
 * make the child exit.  Best I can do is send it a sigkill.
 * perhaps it should be put in the status that it wants to
 * exit.
 */
	case PTRACE_KILL: {
		ret = 0;
		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
			break;
		child->exit_code = SIGKILL;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		break;
	}

	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
		ret = -EIO;
		if (!valid_signal(data))
			break;
		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		set_single_step(child);
		child->exit_code = data;
		/* give it a chance to run. */
		wake_up_process(child);
		ret = 0;
		break;
	}

	case PTRACE_DETACH:
		ret = ptrace_detach(child, data);
		break;

#ifdef CONFIG_ALTIVEC
	case PTRACE_GETVRREGS:
		/* Get the child altivec register state. */
		preempt_disable();
		if (child->thread.regs->msr & MSR_VEC)
			giveup_altivec(child);
		preempt_enable();
		ret = get_vrregs((unsigned long __user *)data, child);
		break;

	case PTRACE_SETVRREGS:
		/* Set the child altivec register state. */
		/* this is to clear the MSR_VEC bit to force a reload
		 * of register state from memory */
		preempt_disable();
		if (child->thread.regs->msr & MSR_VEC)
			giveup_altivec(child);
		preempt_enable();
		ret = set_vrregs(child, (unsigned long __user *)data);
		break;
#endif
#ifdef CONFIG_SPE
	case PTRACE_GETEVRREGS:
		/* Get the child spe register state. */
		if (child->thread.regs->msr & MSR_SPE)
			giveup_spe(child);
		ret = get_evrregs((unsigned long __user *)data, child);
		break;

	case PTRACE_SETEVRREGS:
		/* Set the child spe register state. */
		/* this is to clear the MSR_SPE bit to force a reload
		 * of register state from memory */
		if (child->thread.regs->msr & MSR_SPE)
			giveup_spe(child);
		ret = set_evrregs(child, (unsigned long __user *)data);
		break;
#endif

	default:
		ret = ptrace_request(child, request, addr, data);
		break;
	}
out_tsk:
	put_task_struct(child);
out:
	unlock_kernel();
	return ret;
}
Esempio n. 5
0
asmlinkage int sys32_ptrace(long request, long pid, long addr, s32 data)
{
	struct task_struct *child;
	int ret = -EPERM;
	unsigned long flags;
	u32 tmp;
	int copied;
	ptrace_area   parea; 

	lock_kernel();
	if (request == PTRACE_TRACEME) 
	{
		/* are we already being traced? */
		if (current->ptrace & PT_PTRACED)
			goto out;
		/* set the ptrace bit in the process flags. */
		current->ptrace |= PT_PTRACED;
		ret = 0;
		goto out;
	}
	ret = -ESRCH;
	read_lock(&tasklist_lock);
	child = find_task_by_pid(pid);
	read_unlock(&tasklist_lock);
	if (!child)
		goto out;
	ret = -EPERM;
	if (pid == 1)		/* you may not mess with init */
		goto out;
	if (request == PTRACE_ATTACH) 
	{
		ret = ptrace_attach(child);
		goto out;
	}
	ret = -ESRCH;
	// printk("child=%lX child->flags=%lX",child,child->flags);
	/* I added child!=current line so we can get the */
	/* ieee_instruction_pointer from the user structure DJB */
	if(child!=current)
	{
		if (!(child->ptrace & PT_PTRACED))
			goto out;
		if (child->state != TASK_STOPPED) 
		{
			if (request != PTRACE_KILL)
				goto out;
		}
		if (child->p_pptr != current)
			goto out;
	}
	switch (request) 
	{
		/* If I and D space are separate, these will need to be fixed. */
	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
	case PTRACE_PEEKDATA: 
		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
		ret = -EIO;
		if (copied != sizeof(tmp))
			goto out;
		ret = put_user(tmp,(u32 *)(unsigned long)data);
		goto out;

		/* read the word at location addr in the USER area. */
	case PTRACE_PEEKUSR:
		ret=copy_user(child,addr,data,sizeof(u32),1,0);
		break;

		/* If I and D space are separate, this will have to be fixed. */
	case PTRACE_POKETEXT: /* write the word at location addr. */
	case PTRACE_POKEDATA:
		ret = 0;
		if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
			goto out;
		ret = -EIO;
		goto out;
		break;

	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
		ret=copy_user(child,addr,(addr_t)&data,sizeof(u32),0,1);
		break;

	case PTRACE_SYSCALL: 	/* continue and stop at next (return from) syscall */
	case PTRACE_CONT: 	 /* restart after signal. */
		ret = -EIO;
		if ((unsigned long) data >= _NSIG)
			break;
		if (request == PTRACE_SYSCALL)
			child->ptrace |= PT_TRACESYS;
		else
			child->ptrace &= ~PT_TRACESYS;
		child->exit_code = data;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		ret = 0;
		break;

/*
 * make the child exit.  Best I can do is send it a sigkill. 
 * perhaps it should be put in the status that it wants to 
 * exit.
 */
	case PTRACE_KILL:
		ret = 0;
		if (child->state == TASK_ZOMBIE) /* already dead */
			break;
		child->exit_code = SIGKILL;
		clear_single_step(child);
		wake_up_process(child);
		/* make sure the single step bit is not set. */
		break;

	case PTRACE_SINGLESTEP:  /* set the trap flag. */
		ret = -EIO;
		if ((unsigned long) data >= _NSIG)
			break;
		child->ptrace &= ~PT_TRACESYS;
		child->exit_code = data;
		set_single_step(child);
		/* give it a chance to run. */
		wake_up_process(child);
		ret = 0;
		break;

	case PTRACE_DETACH:  /* detach a process that was attached. */
		ret = -EIO;
		if ((unsigned long) data >= _NSIG)
			break;
		child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
		child->exit_code = data;
		write_lock_irqsave(&tasklist_lock, flags);
		REMOVE_LINKS(child);
		child->p_pptr = child->p_opptr;
		SET_LINKS(child);
		write_unlock_irqrestore(&tasklist_lock, flags);
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		ret = 0;
		break;
	case PTRACE_PEEKUSR_AREA:
	case PTRACE_POKEUSR_AREA:
		{
		ptrace_area_emu31 * parea31 = (void *)addr;
		if (!access_ok(VERIFY_READ, parea31, sizeof(*parea31)))
			return(-EFAULT);
		ret = __get_user(parea.len, &parea31->len);
		ret |= __get_user(parea.kernel_addr, &parea31->kernel_addr);
		ret |= __get_user(parea.process_addr, &parea31->process_addr);
		if(ret==0)  
		   ret=copy_user(child,parea.kernel_addr,parea.process_addr,
				 parea.len,1,(request==PTRACE_POKEUSR_AREA));
		break;
		}
	default:
		ret = -EIO;
		break;
	}
 out:
	unlock_kernel();
	return ret;
}
Esempio n. 6
0
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
	int ret = -EPERM;

	switch (request) {
	/* when I and D space are separate, these will need to be fixed. */
	case PTRACE_PEEKTEXT: /* read word at location addr. */
	case PTRACE_PEEKDATA: {
		unsigned long tmp;
		int copied;

		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
		ret = -EIO;
		if (copied != sizeof(tmp))
			break;
		ret = put_user(tmp,(unsigned long __user *) data);
		break;
	}

	/* read the word at location addr in the USER area. */
	case PTRACE_PEEKUSR: {
		unsigned long index, tmp;

		ret = -EIO;
		/* convert to index and check */
#ifdef CONFIG_PPC32
		index = (unsigned long) addr >> 2;
		if ((addr & 3) || (index > PT_FPSCR)
		    || (child->thread.regs == NULL))
#else
		index = (unsigned long) addr >> 3;
		if ((addr & 7) || (index > PT_FPSCR))
#endif
			break;

#ifdef CONFIG_PPC32
		CHECK_FULL_REGS(child->thread.regs);
#endif
		if (index < PT_FPR0) {
			tmp = get_reg(child, (int) index);
		} else {
			flush_fp_to_thread(child);
			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
		}
		ret = put_user(tmp,(unsigned long __user *) data);
		break;
	}

	/* If I and D space are separate, this will have to be fixed. */
	case PTRACE_POKETEXT: /* write the word at location addr. */
	case PTRACE_POKEDATA:
		ret = 0;
		if (access_process_vm(child, addr, &data, sizeof(data), 1)
				== sizeof(data))
			break;
		ret = -EIO;
		break;

	/* write the word at location addr in the USER area */
	case PTRACE_POKEUSR: {
		unsigned long index;

		ret = -EIO;
		/* convert to index and check */
#ifdef CONFIG_PPC32
		index = (unsigned long) addr >> 2;
		if ((addr & 3) || (index > PT_FPSCR)
		    || (child->thread.regs == NULL))
#else
		index = (unsigned long) addr >> 3;
		if ((addr & 7) || (index > PT_FPSCR))
#endif
			break;

#ifdef CONFIG_PPC32
		CHECK_FULL_REGS(child->thread.regs);
#endif
		if (index == PT_ORIG_R3)
			break;
		if (index < PT_FPR0) {
			ret = put_reg(child, index, data);
		} else {
			flush_fp_to_thread(child);
			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
			ret = 0;
		}
		break;
	}

	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
	case PTRACE_CONT: { /* restart after signal. */
		ret = -EIO;
		if (!valid_signal(data))
			break;
		if (request == PTRACE_SYSCALL)
			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		else
			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		child->exit_code = data;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		ret = 0;
		break;
	}

/*
 * make the child exit.  Best I can do is send it a sigkill.
 * perhaps it should be put in the status that it wants to
 * exit.
 */
	case PTRACE_KILL: {
		ret = 0;
		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
			break;
		child->exit_code = SIGKILL;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		break;
	}

	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
		ret = -EIO;
		if (!valid_signal(data))
			break;
		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		set_single_step(child);
		child->exit_code = data;
		/* give it a chance to run. */
		wake_up_process(child);
		ret = 0;
		break;
	}

#ifdef CONFIG_PPC64
	case PTRACE_GET_DEBUGREG: {
		ret = -EINVAL;
		/* We only support one DABR and no IABRS at the moment */
		if (addr > 0)
			break;
		ret = put_user(child->thread.dabr,
			       (unsigned long __user *)data);
		break;
	}

	case PTRACE_SET_DEBUGREG:
		ret = ptrace_set_debugreg(child, addr, data);
		break;
#endif

	case PTRACE_DETACH:
		ret = ptrace_detach(child, data);
		break;

	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
		int i;
		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
		unsigned long __user *tmp = (unsigned long __user *)addr;

		for (i = 0; i < 32; i++) {
			ret = put_user(*reg, tmp);
			if (ret)
				break;
			reg++;
			tmp++;
		}
		break;
	}

	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
		int i;
		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
		unsigned long __user *tmp = (unsigned long __user *)addr;

		for (i = 0; i < 32; i++) {
			ret = get_user(*reg, tmp);
			if (ret)
				break;
			reg++;
			tmp++;
		}
		break;
	}

	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
		int i;
		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
		unsigned long __user *tmp = (unsigned long __user *)addr;

		flush_fp_to_thread(child);

		for (i = 0; i < 32; i++) {
			ret = put_user(*reg, tmp);
			if (ret)
				break;
			reg++;
			tmp++;
		}
		break;
	}

	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
		int i;
		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
		unsigned long __user *tmp = (unsigned long __user *)addr;

		flush_fp_to_thread(child);

		for (i = 0; i < 32; i++) {
			ret = get_user(*reg, tmp);
			if (ret)
				break;
			reg++;
			tmp++;
		}
		break;
	}

#ifdef CONFIG_ALTIVEC
	case PTRACE_GETVRREGS:
		/* Get the child altivec register state. */
		flush_altivec_to_thread(child);
		ret = get_vrregs((unsigned long __user *)data, child);
		break;

	case PTRACE_SETVRREGS:
		/* Set the child altivec register state. */
		flush_altivec_to_thread(child);
		ret = set_vrregs(child, (unsigned long __user *)data);
		break;
#endif
#ifdef CONFIG_SPE
	case PTRACE_GETEVRREGS:
		/* Get the child spe register state. */
		if (child->thread.regs->msr & MSR_SPE)
			giveup_spe(child);
		ret = get_evrregs((unsigned long __user *)data, child);
		break;

	case PTRACE_SETEVRREGS:
		/* Set the child spe register state. */
		/* this is to clear the MSR_SPE bit to force a reload
		 * of register state from memory */
		if (child->thread.regs->msr & MSR_SPE)
			giveup_spe(child);
		ret = set_evrregs(child, (unsigned long __user *)data);
		break;
#endif

	default:
		ret = ptrace_request(child, request, addr, data);
		break;
	}

	return ret;
}
Esempio n. 7
0
int sys_ptrace(long request, long pid, long addr, long data)
{
	struct task_struct *child;
	int rval;

	lock_kernel();
	/* printk("sys_ptrace - PID:%u  ADDR:%08x  DATA:%08x\n",pid,addr,data); */

	if (request == PTRACE_TRACEME) {
		/* are we already being traced? */
		if (current->ptrace & PT_PTRACED) {
			rval = -EPERM;
			goto out;
		}
		/* set the ptrace bit in the process flags. */
		current->ptrace |= PT_PTRACED;
		rval = 0;
		goto out;
	}
	rval = -ESRCH;
	read_lock(&tasklist_lock);
	child = find_task_by_pid(pid);
	if (child)
		get_task_struct(child);
	read_unlock(&tasklist_lock);
	if (!child)
		goto out;

	rval = -EPERM;
	if (pid == 1)		/* you may not mess with init */
		goto out;

	if (request == PTRACE_ATTACH) {
		rval = ptrace_attach(child);
		goto out_tsk;
	}
	rval = -ESRCH;
	if (!(child->ptrace & PT_PTRACED))
		goto out_tsk;
	if (child->state != TASK_STOPPED) {
		if (request != PTRACE_KILL)
			goto out_tsk;
	}
	if (child->p_pptr != current)
		goto out_tsk;

	switch (request) {
		unsigned long val, copied;

	case PTRACE_PEEKTEXT: /* read word at location addr. */
	case PTRACE_PEEKDATA:
	/*	printk("PEEKTEXT/PEEKDATA at %08X\n",addr); */
		copied = access_process_vm(child, addr, &val, sizeof(val), 0);
		rval = -EIO;
		if (copied != sizeof(val))
			break;
		rval = put_user(val, (unsigned long *)data);
		goto out;

	case PTRACE_POKETEXT: /* write the word at location addr. */
	case PTRACE_POKEDATA:
		/* printk("POKETEXT/POKEDATA to %08X\n",addr); */
		rval = 0;
		if (access_process_vm(child, addr, &data, sizeof(data), 1)
		    == sizeof(data))
			break;
		rval = -EIO;
		goto out;

	/* Read/write the word at location ADDR in the registers.  */
	case PTRACE_PEEKUSR:
	case PTRACE_POKEUSR:
		rval = 0;
		if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
			/* Special requests that don't actually correspond
			   to offsets in struct pt_regs.  */
			if (addr == PT_TEXT_ADDR)
			{
				val = child->mm->start_code;
			}
			else if (addr == PT_DATA_ADDR)
			{
				val = child->mm->start_data;
			}
			else if (addr == PT_TEXT_LEN)
			{
				val = child->mm->end_code
					- child->mm->start_code;
			}
			else if (addr == PT_DATA_LEN)
			{
				val = child->mm->end_data
					- child->mm->start_data;
			}
			else
			{
				rval = -EIO;
			}
		} else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
			microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
			if (request == PTRACE_PEEKUSR)
			{
				val = *reg_addr;
			}
			else
			{
				*reg_addr = data;
			}
		} else
			rval = -EIO;

		if (rval == 0 && request == PTRACE_PEEKUSR)
		{
			rval = put_user (val, (unsigned long *)data);
		}
		goto out;

	/* Continue and stop at next (return from) syscall */
	case PTRACE_SYSCALL:
	/* Restart after a signal.  */
	case PTRACE_CONT:
		/* printk("PTRACE_CONT\n"); */
	/* Execute a single instruction. */
	case PTRACE_SINGLESTEP:
		/* printk("PTRACE_SINGLESTEP\n"); */
		rval = -EIO;
		if ((unsigned long) data > _NSIG)
			break;

		/* Turn CHILD's single-step flag on or off.  */
		/* printk("calling set_single_step\n"); */
		if (! set_single_step (child, request == PTRACE_SINGLESTEP))
			break;

		if (request == PTRACE_SYSCALL)
			child->ptrace |= PT_TRACESYS;
		else
			child->ptrace &= ~PT_TRACESYS;

		child->exit_code = data;
		/* printk("wakeup_process\n"); */
		wake_up_process(child);
		rval = 0;
		break;

	/*
	 * make the child exit.  Best I can do is send it a sigkill.
	 * perhaps it should be put in the status that it wants to
	 * exit.
	 */
	case PTRACE_KILL:
		/* printk("PTRACE_KILL\n"); */
		rval = 0;
		if (child->state == TASK_ZOMBIE)	/* already dead */
			break;
		child->exit_code = SIGKILL;
		wake_up_process(child);
		break;

	case PTRACE_DETACH: /* detach a process that was attached. */
		/* printk("PTRACE_DETACH\n"); */
		set_single_step (child, 0);  /* Clear single-step flag */
		rval = ptrace_detach(child, data);
		break;

	default:
		rval = -EIO;
		goto out;
	}

out_tsk:
	free_task_struct(child);
out:
	unlock_kernel();
	return rval;
}
Esempio n. 8
0
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
	int ret = -EPERM;

	switch (request) {
	/* when I and D space are separate, these will need to be fixed. */
	case PTRACE_PEEKTEXT: /* read word at location addr. */
	case PTRACE_PEEKDATA:
		ret = generic_ptrace_peekdata(child, addr, data);
		break;

	/* read the word at location addr in the USER area. */
	case PTRACE_PEEKUSR: {
		unsigned long index, tmp;

		ret = -EIO;
		/* convert to index and check */
#ifdef CONFIG_PPC32
		index = (unsigned long) addr >> 2;
		if ((addr & 3) || (index > PT_FPSCR)
		    || (child->thread.regs == NULL))
#else
		index = (unsigned long) addr >> 3;
		if ((addr & 7) || (index > PT_FPSCR))
#endif
			break;

		CHECK_FULL_REGS(child->thread.regs);
		if (index < PT_FPR0) {
			tmp = ptrace_get_reg(child, (int) index);
		} else {
			flush_fp_to_thread(child);
			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
		}
		ret = put_user(tmp,(unsigned long __user *) data);
		break;
	}

	/* If I and D space are separate, this will have to be fixed. */
	case PTRACE_POKETEXT: /* write the word at location addr. */
	case PTRACE_POKEDATA:
		ret = generic_ptrace_pokedata(child, addr, data);
		break;

	/* write the word at location addr in the USER area */
	case PTRACE_POKEUSR: {
		unsigned long index;

		ret = -EIO;
		/* convert to index and check */
#ifdef CONFIG_PPC32
		index = (unsigned long) addr >> 2;
		if ((addr & 3) || (index > PT_FPSCR)
		    || (child->thread.regs == NULL))
#else
		index = (unsigned long) addr >> 3;
		if ((addr & 7) || (index > PT_FPSCR))
#endif
			break;

		CHECK_FULL_REGS(child->thread.regs);
		if (index < PT_FPR0) {
			ret = ptrace_put_reg(child, index, data);
		} else {
			flush_fp_to_thread(child);
			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
			ret = 0;
		}
		break;
	}

	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
	case PTRACE_CONT: { /* restart after signal. */
		ret = -EIO;
		if (!valid_signal(data))
			break;
		if (request == PTRACE_SYSCALL)
			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		else
			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		child->exit_code = data;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		ret = 0;
		break;
	}

/*
 * make the child exit.  Best I can do is send it a sigkill.
 * perhaps it should be put in the status that it wants to
 * exit.
 */
	case PTRACE_KILL: {
		ret = 0;
		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
			break;
		child->exit_code = SIGKILL;
		/* make sure the single step bit is not set. */
		clear_single_step(child);
		wake_up_process(child);
		break;
	}

	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
		ret = -EIO;
		if (!valid_signal(data))
			break;
		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		set_single_step(child);
		child->exit_code = data;
		/* give it a chance to run. */
		wake_up_process(child);
		ret = 0;
		break;
	}

	case PTRACE_GET_DEBUGREG: {
		ret = -EINVAL;
		/* We only support one DABR and no IABRS at the moment */
		if (addr > 0)
			break;
		ret = put_user(child->thread.dabr,
			       (unsigned long __user *)data);
		break;
	}

	case PTRACE_SET_DEBUGREG:
		ret = ptrace_set_debugreg(child, addr, data);
		break;

#ifdef CONFIG_PPC64
	case PTRACE_GETREGS64:
#endif
	case PTRACE_GETREGS: { /* Get all pt_regs from the child. */
		int ui;
	  	if (!access_ok(VERIFY_WRITE, (void __user *)data,
			       sizeof(struct pt_regs))) {
			ret = -EIO;
			break;
		}
		CHECK_FULL_REGS(child->thread.regs);
		ret = 0;
		for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
			ret |= __put_user(ptrace_get_reg(child, ui),
					  (unsigned long __user *) data);
			data += sizeof(long);
		}
		break;
	}

#ifdef CONFIG_PPC64
	case PTRACE_SETREGS64:
#endif
	case PTRACE_SETREGS: { /* Set all gp regs in the child. */
		unsigned long tmp;
		int ui;
	  	if (!access_ok(VERIFY_READ, (void __user *)data,
			       sizeof(struct pt_regs))) {
			ret = -EIO;
			break;
		}
		CHECK_FULL_REGS(child->thread.regs);
		ret = 0;
		for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
			ret = __get_user(tmp, (unsigned long __user *) data);
			if (ret)
				break;
			ptrace_put_reg(child, ui, tmp);
			data += sizeof(long);
		}
		break;
	}

	case PTRACE_GETFPREGS: { /* Get the child FPU state (FPR0...31 + FPSCR) */
		flush_fp_to_thread(child);
		ret = get_fpregs((void __user *)data, child, 1);
		break;
	}

	case PTRACE_SETFPREGS: { /* Set the child FPU state (FPR0...31 + FPSCR) */
		flush_fp_to_thread(child);
		ret = set_fpregs((void __user *)data, child, 1);
		break;
	}

#ifdef CONFIG_ALTIVEC
	case PTRACE_GETVRREGS:
		/* Get the child altivec register state. */
		flush_altivec_to_thread(child);
		ret = get_vrregs((unsigned long __user *)data, child);
		break;

	case PTRACE_SETVRREGS:
		/* Set the child altivec register state. */
		flush_altivec_to_thread(child);
		ret = set_vrregs(child, (unsigned long __user *)data);
		break;
#endif
#ifdef CONFIG_SPE
	case PTRACE_GETEVRREGS:
		/* Get the child spe register state. */
		flush_spe_to_thread(child);
		ret = get_evrregs((unsigned long __user *)data, child);
		break;

	case PTRACE_SETEVRREGS:
		/* Set the child spe register state. */
		/* this is to clear the MSR_SPE bit to force a reload
		 * of register state from memory */
		flush_spe_to_thread(child);
		ret = set_evrregs(child, (unsigned long __user *)data);
		break;
#endif

	/* Old reverse args ptrace callss */
	case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
	case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
	case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
	case PPC_PTRACE_SETFPREGS: /* Get FPRs 0 - 31. */
		ret = arch_ptrace_old(child, request, addr, data);
		break;

	default:
		ret = ptrace_request(child, request, addr, data);
		break;
	}
	return ret;
}
Esempio n. 9
0
/// @brief
int main()
{
    // create process with /dbg
    STARTUPINFO			si = {0};
	PROCESS_INFORMATION pi = {0};
    wchar_t* target = L".\\debuggee.exe";

	if (TRUE != CreateProcessW(
					target, 
					NULL, 
					NULL, 
					NULL, 
					FALSE, 
					CREATE_NEW_CONSOLE | DEBUG_PROCESS,
					NULL, 
					NULL, 
					&si, 
					&pi))
	{
        log("CreateProcess() failed. gle = %u", GetLastError());
		return -1;
	}

    log("process created. pid = %u", pi.dwProcessId);

	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);

    DEBUG_EVENT debug_event = {0};	
	while (true)
	{
		if (TRUE != WaitForDebugEvent(&debug_event, 100)) continue;
        
        DWORD continue_status = DBG_CONTINUE;

		switch (debug_event.dwDebugEventCode)
        {
        case EXCEPTION_DEBUG_EVENT:
            {
                PDEBUGGEE dbge = NULL;
                for (int i = 0; i < sizeof(_debuggees) / sizeof(DEBUGGEE); ++i)
                {
                    if (_debuggees[i]._pid == debug_event.dwProcessId)
                    {
                        dbge = &_debuggees[i];
                    }
                }
                if (NULL == dbge) break;
                
                LPEXCEPTION_DEBUG_INFO edi = &debug_event.u.Exception;
                switch (edi->ExceptionRecord.ExceptionCode)
                {
                case EXCEPTION_BREAKPOINT:
                    if (true != dbge->_initial_bp_hit)
                    {
                        dbge->_initial_bp_hit = true;
                        log(
                            "\n"
                            "[EXCEPTION_DEBUG_EVENT] \n"\
                            "   img = %ws \n"\
                            "   pid = %u, tid = %u \n"\
                            "   + initial bp triggered at 0x%llx",
                            dbge->_image_name.c_str(),
                            debug_event.dwProcessId,
                            debug_event.dwThreadId,
                            edi->ExceptionRecord.ExceptionAddress);

                        // 
                        // install breakpoint at ep.
                        //

                        dbge->_bp_param = { 0 };
                        HANDLE thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, debug_event.dwThreadId);
                        if (NULL == thread_handle)
                        {
                            _ASSERTE(!"oops");
                            break;
                        }

                        dbge->_bp_param.hthread = thread_handle;
                        dbge->_bp_param.hproc = dbge->_proc_handle;
                        dbge->_bp_addr = dbge->_start_address;
                        bool bp_ret = set_break_point(
                            &dbge->_bp_param,
                            (DWORD_PTR)dbge->_bp_addr,
                            &dbge->_opcode);
                        if (true != bp_ret)
                        {
                            _ASSERTE(true == bp_ret);
                            break;
                        }

                        continue_status = DBG_EXCEPTION_HANDLED;
                        log("   + break point installed at 0x%llx", dbge->_bp_addr);
                        _pause;
                    }
                    else
                    {
                        log(
                            "\n"
                            "[EXCEPTION_DEBUG_EVENT] \n"\
                            "   img = %ws \n"\
                            "   pid = %u, tid = %u \n"\
                            "   + break point at 0x%llx",
                            dbge->_image_name.c_str(),
                            debug_event.dwProcessId,
                            debug_event.dwThreadId,
                            edi->ExceptionRecord.ExceptionAddress);

                        // 
                        // restore opcode and resume
                        //
                        if (edi->ExceptionRecord.ExceptionAddress != dbge->_bp_addr)
                        {
                            _ASSERTE(!"oops");
                            break;
                        }

                        dbge->_bp_param.context.ContextFlags = CONTEXT_ALL;
                        if (TRUE != GetThreadContext(
                            dbge->_bp_param.hthread,
                            &dbge->_bp_param.context))
                        {
                            _ASSERTE(!"oops!");
                            break;
                        }
                        if (true != clear_break_point(
                            &dbge->_bp_param,
                            (DWORD_PTR)dbge->_bp_addr,
                            dbge->_opcode, true))
                        {
                            _ASSERTE(!"oops");
                            break;
                        }

                        continue_status = DBG_EXCEPTION_HANDLED;
                        log("   + breakpoint un-installed at 0x%llx", dbge->_bp_addr);

                        // single step enable
                        ch_param param = { 0 };
                        param.hthread = OpenThread(THREAD_ALL_ACCESS, FALSE, debug_event.dwThreadId);
                        if (NULL != param.hthread)
                        {
                            param.context.ContextFlags = CONTEXT_ALL;
                            if (TRUE != GetThreadContext(param.hthread, &param.context))
                            {
                                _ASSERTE(!"oops!");
                                break;
                            }
                            set_single_step(&param);
                        }
                        _pause;
                    }
                    break;

                case EXCEPTION_SINGLE_STEP:
                    {
                    //log(
                    //    "\n"
                    //    "[EXCEPTION_DEBUG_EVENT] \n"\
                    //    "   pid = %u, tid = %u\n"\
                    //    "   + handle single step at 0x%llx", 
                    //    debug_event.dwProcessId,
                    //    debug_event.dwThreadId, 
                    //    edi->ExceptionRecord.ExceptionAddress);

                    
                    // call 명령이라면 log
                    log_branch(edi->ExceptionRecord.ExceptionAddress,
                               debug_event.dwProcessId,
                               debug_event.dwThreadId);

                    //continue_status = DBG_EXCEPTION_NOT_HANDLED;
                    continue_status = DBG_EXCEPTION_HANDLED;
                    break;
                    }
                default:
                    if (0 != edi->dwFirstChance)
                    {   
                        log("\n"
                            "[EXCEPTION_DEBUG_EVENT]\n"\
                            "   pid = %u, tid = %u\n"\
                            "   + %s (first chance) at 0x%llx",
                            debug_event.dwProcessId,
                            debug_event.dwThreadId, 
                            exception_code_str(edi->ExceptionRecord.ExceptionCode),
                            edi->ExceptionRecord.ExceptionAddress
                            );
                    }
                    else
                    {
                        log("\n"
                            "[EXCEPTION_DEBUG_EVENT]\n"\
                            "   + %s (second chance) at 0x%llx, can't handle anymore.",
                            exception_code_str(edi->ExceptionRecord.ExceptionCode),
                            edi->ExceptionRecord.ExceptionAddress
                            );
                    }

                    continue_status = DBG_EXCEPTION_NOT_HANDLED;
                    break;
                }
                break;
            }
        case CREATE_THREAD_DEBUG_EVENT:
            {
                //str = "CREATE_THREAD_DEBUG_EVENT";
                break;
            }
        case CREATE_PROCESS_DEBUG_EVENT:
            {
                LPCREATE_PROCESS_DEBUG_INFO cpi = &debug_event.u.CreateProcessInfo;
                std::wstring image;
                if (true != get_filepath_by_handle(cpi->hFile, image))
                {
                    image = L"unknown image path";
                }
                
                log("\n"\
                    "[CREATE_PROCESS_DEBUG_EVENT]\n"\
                    "   img = %ws\n"\
                    "   pid = %u, tid = %u, ep = 0x%llx",
                    image.c_str(), 
                    debug_event.dwProcessId,
                    debug_event.dwThreadId,
                    cpi->lpStartAddress
                    );
                
                for (int i = 0; i < sizeof(_debuggees) / sizeof(DEBUGGEE); ++i)
                {
                    if (_debuggees[i]._pid == 0)
                    {
                        _debuggees[i]._initial_bp_hit = 0;
                        _debuggees[i]._pid = debug_event.dwProcessId;

                        _debuggees[i]._file_handle = debug_event.u.CreateProcessInfo.hFile;
                        _debuggees[i]._proc_handle = debug_event.u.CreateProcessInfo.hProcess;
                        _debuggees[i]._thread_handle = debug_event.u.CreateProcessInfo.hThread;
                        _debuggees[i]._base_of_image = debug_event.u.CreateProcessInfo.lpBaseOfImage;
                        _debuggees[i]._thread_local_base = debug_event.u.CreateProcessInfo.lpThreadLocalBase;
                        _debuggees[i]._start_address = debug_event.u.CreateProcessInfo.lpStartAddress;
                        _debuggees[i]._image_name = image;

                        break;
                    }
                }
                break;
            }
        case EXIT_THREAD_DEBUG_EVENT:
            {
                //str = "EXIT_THREAD_DEBUG_EVENT";
                break;
            }
        //case EXIT_PROCESS_DEBUG_EVENT:
        //    {
        //        str = "EXIT_PROCESS_DEBUG_EVENT";
        //        break;
        //    }
        case LOAD_DLL_DEBUG_EVENT:
            {
                LPLOAD_DLL_DEBUG_INFO lddi = &debug_event.u.LoadDll;
                std::wstring dll_path;
                if (true != get_filepath_by_handle(lddi->hFile, dll_path))
                {
                    dll_path = L"Unknown dll path";
                }

                // get dll file size
                if (0 != k32_base)  break;

                HANDLE hFile = CreateFileW(dll_path.c_str(),
                                           GENERIC_READ,
                                           FILE_SHARE_READ,
                                           NULL,
                                           OPEN_ALWAYS,
                                           FILE_ATTRIBUTE_NORMAL,
                                           NULL);
                if (NULL == hFile) break;


                LARGE_INTEGER file_size = { 0 };
                if (TRUE != GetFileSizeEx(lddi->hFile, &file_size))
                {
                    return false;
                }

                if (std::wstring::npos != dll_path.rfind(L"ntdll.dll"))
                {
                    log("\n"
                        "gotcha!\n"\
                        "   pid = %u, tid = %u, img = %ws, addr ragne = 0x%08x ~ 0x%08x",
                        debug_event.dwProcessId,
                        debug_event.dwThreadId,
                        dll_path.c_str(),
                        lddi->lpBaseOfDll,
                        (DWORD_PTR)lddi->lpBaseOfDll + file_size.LowPart
                        );

                    k32_base = (DWORD_PTR)lddi->lpBaseOfDll;
                    k32_max = (DWORD_PTR)lddi->lpBaseOfDll + file_size.LowPart;

                }
                
                //log("\n"
                //    "[LOAD_DLL_DEBUG_EVENT]\n"\
                //    "   pid = %u, tid = %u, img = %ws",
                //    debug_event.dwProcessId,
                //    debug_event.dwThreadId,
                //    dll_path.c_str()
                //    );
                break;
            }
        case UNLOAD_DLL_DEBUG_EVENT:
            {
                LPUNLOAD_DLL_DEBUG_INFO uddi = &debug_event.u.UnloadDll;
                // todo 3
                break;
            }
        case OUTPUT_DEBUG_STRING_EVENT:
            {
                
                break;
            }
        case RIP_EVENT:
            {
                //str = "RIP_EVENT";
                break;
            }
        default:
            //str = "unknown";
            break;
        }

        


		//> continue_status 값이
		//>
		//>	DBG_CONTINUE
		//>		EXCEPTION_DEBUG_EVENT 인 경우
		//>			모든 exception processing 을 멈추고 스레드를 계속 실행
		//>		EXCEPTION_DEBUG_EVENT 이 아닌 경우 
		//>			스레드 계속 실행 
		//>
		//>	DBG_EXCEPTION_NOT_HANDLED
		//>		EXCEPTION_DEBUG_EVENT 인 경우
		//>			exception processing 을 계속 진행.
		//>			first-chance exception 인 경우 seh 핸들러의 search, dispatch 로직이 실행
		//>			first-chance exception 이 아니라면 프로세스는 종료 됨
		//>		EXCEPTION_DEBUG_EVENT 이 아닌 경우 
		//>			스레드 계속 실행 
        ContinueDebugEvent(debug_event.dwProcessId,debug_event.dwThreadId,continue_status);

		//> debuggee is terminating
		if (EXIT_PROCESS_DEBUG_EVENT == debug_event.dwDebugEventCode)
		{
            int i = 0;
            for (; i < sizeof(_debuggees) / sizeof(DEBUGGEE); ++i)
            {
                if (_debuggees[i]._pid == debug_event.dwProcessId)
                {
                    _debuggees[i]._initial_bp_hit = 0;
                    _debuggees[i]._pid = 0;
                    break;
                }
            }

            if (i == 0)
            {
                log("\n"\
                    "[EXIT_PROCESS_DEBUG_EVENT] \n"\
                    "   img = %ws\n"\
                    "   pid = %u, tid = %u\n"\
                    "   + debuggee is terminated.",
                    _debuggees[i]._image_name.c_str(),
                    debug_event.dwProcessId, debug_event.dwThreadId);
                _pause;
                break;
            }
            // do nothing...
		}
	}

    //log("press any key to terminate...");
    //getchar();

}
Esempio n. 10
0
/*
 * This function does all command procesing for interfacing to gdb.
 */
void
gdb_handle_exception (db_regs_t *raw_regs, int type, int code)
{
  int    sigval;
  long   addr, length;
  char * ptr;
  struct alpharegs {
    u_int64_t r[32];
    u_int64_t f[32];
    u_int64_t pc, vfp;
  };
  static struct alpharegs registers;
  int i;

  clear_single_step(raw_regs);

  bzero(&registers, sizeof registers);

  /*
   * Map trapframe to registers.
   * Ignore float regs for now.
   */
  for (i = 0; i < FRAME_SIZE; i++)
    if (tf2gdb[i] >= 0)
      registers.r[tf2gdb[i]] = raw_regs->tf_regs[i];
  registers.pc = raw_regs->tf_regs[FRAME_PC];

  /* reply to host that an exception has occurred */
  sigval = computeSignal (type, code);
  ptr = remcomOutBuffer;

  *ptr++ = 'T';
  *ptr++ = hexchars[sigval >> 4];
  *ptr++ = hexchars[sigval & 0xf];

  *ptr++ = hexchars[PC >> 4];
  *ptr++ = hexchars[PC & 0xf];
  *ptr++ = ':';
  ptr = mem2hex ((vm_offset_t)&registers.pc, ptr, 8);
  *ptr++ = ';';

  *ptr++ = hexchars[FP >> 4];
  *ptr++ = hexchars[FP & 0xf];
  *ptr++ = ':';
  ptr = mem2hex ((vm_offset_t)&registers.r[FP], ptr, 8);
  *ptr++ = ';';

  *ptr++ = hexchars[SP >> 4];
  *ptr++ = hexchars[SP & 0xf];
  *ptr++ = ':';
  ptr = mem2hex ((vm_offset_t)&registers.r[SP], ptr, 8);
  *ptr++ = ';';

  *ptr++ = 0;

  putpacket (remcomOutBuffer);

  while (1)
    {
      remcomOutBuffer[0] = 0;

      getpacket (remcomInBuffer);
      switch (remcomInBuffer[0]) 
	{
	case '?':
	  remcomOutBuffer[0] = 'S';
	  remcomOutBuffer[1] = hexchars[sigval >> 4];
	  remcomOutBuffer[2] = hexchars[sigval % 16];
	  remcomOutBuffer[3] = 0;
	  break;

	case 'D':		/* detach; say OK and turn off gdb */
	  putpacket(remcomOutBuffer);
	  boothowto &= ~RB_GDB;
	  return;

	case 'k':
	  prom_halt();
	  /*NOTREACHED*/
	  break;

	case 'g':		/* return the value of the CPU registers */
	  mem2hex ((vm_offset_t)&registers, remcomOutBuffer, NUMREGBYTES);
	  break;

	case 'G':		/* set the value of the CPU registers - return OK */
	  hex2mem (&remcomInBuffer[1], (vm_offset_t)&registers, NUMREGBYTES);
	  strcpy (remcomOutBuffer, "OK");
	  break;

	case 'P':		/* Set the value of one register */
	  {
	    long regno;

	    ptr = &remcomInBuffer[1];

	    if (hexToInt (&ptr, &regno)
		&& *ptr++ == '='
		&& regno < NUM_REGS)
	      {
		hex2mem (ptr, (vm_offset_t)&registers + regno * 8, 8);
		strcpy(remcomOutBuffer,"OK");
	      }
	    else
	      strcpy (remcomOutBuffer, "P01");
	    break;
	  }
	case 'm':	/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
	  /* Try to read %x,%x.  */

	  ptr = &remcomInBuffer[1];

	  if (hexToInt (&ptr, &addr)
	      && *(ptr++) == ','
	      && hexToInt (&ptr, &length))
	    {
	      if (mem2hex((vm_offset_t) addr, remcomOutBuffer, length) == NULL)
		strcpy (remcomOutBuffer, "E03");
	      break;
	    }
	  else
	    strcpy (remcomOutBuffer, "E01");
	  break;

	case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */

	  /* Try to read '%x,%x:'.  */

	  ptr = &remcomInBuffer[1];

	  if (hexToInt(&ptr,&addr)
	      && *(ptr++) == ','
	      && hexToInt(&ptr, &length)
	      && *(ptr++) == ':')
	    {
	      if (hex2mem(ptr, (vm_offset_t) addr, length) == NULL)
		strcpy (remcomOutBuffer, "E03");
	      else
		strcpy (remcomOutBuffer, "OK");
	    }
	  else
	    strcpy (remcomOutBuffer, "E02");
	  break;

	  /* cAA..AA    Continue at address AA..AA(optional) */
	  /* sAA..AA   Step one instruction from AA..AA(optional) */
	case 'c' :
	case 's' :
	  /* try to read optional parameter, pc unchanged if no parm */

	  ptr = &remcomInBuffer[1];
	  if (hexToInt(&ptr,&addr))
	    registers.pc = addr;

	  /*
	   * Map gdb registers back to trapframe (ignoring fp regs).
	   */
	  for (i = 0; i < NUM_REGS; i++)
	    if (gdb2tf[i] >= 0)
	      raw_regs->tf_regs[gdb2tf[i]] = registers.r[i];
	  raw_regs->tf_regs[FRAME_PC] = registers.pc;

	  if (remcomInBuffer[0] == 's')
	    if (!set_single_step(raw_regs))
	      printf("Can't set single step breakpoint\n");

	  return;

	} /* switch */

      /* reply to the request */
      putpacket (remcomOutBuffer);
    }
}