// SetPC sets the RIP register to the value specified by `pc`.
func (r *Regs) SetPC(thread *Thread, pc uint64) error {
	var context C.CONTEXT
	context.ContextFlags = C.CONTEXT_ALL

	res := C.GetThreadContext(C.HANDLE(thread.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not GetThreadContext")
	}

	context.Rip = C.DWORD64(pc)

	res = C.SetThreadContext(C.HANDLE(thread.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not SetThreadContext")
	}

	return nil
}
Example #2
0
func (t *Thread) singleStep() error {
	var context C.CONTEXT
	context.ContextFlags = C.CONTEXT_ALL

	// Set the processor TRAP flag
	res := C.GetThreadContext(C.HANDLE(t.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not GetThreadContext")
	}

	context.EFlags |= 0x100

	res = C.SetThreadContext(C.HANDLE(t.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not SetThreadContext")
	}

	// Suspend all threads except this one
	for _, thread := range t.dbp.Threads {
		if thread.ID == t.ID {
			continue
		}
		res := C.SuspendThread(C.HANDLE(thread.os.hThread))
		if res == C.DWORD(0xFFFFFFFF) {
			return fmt.Errorf("could not suspend thread: %d", thread.ID)
		}
	}

	// Continue and wait for the step to complete
	t.dbp.execPtraceFunc(func() {
		res = C.ContinueDebugEvent(C.DWORD(t.dbp.Pid), C.DWORD(t.ID), C.DBG_CONTINUE)
	})
	if res == C.FALSE {
		return fmt.Errorf("could not ContinueDebugEvent.")
	}
	_, err := t.dbp.trapWait(0)
	if err != nil {
		return err
	}

	// Resume all threads except this one
	for _, thread := range t.dbp.Threads {
		if thread.ID == t.ID {
			continue
		}
		res := C.ResumeThread(C.HANDLE(thread.os.hThread))
		if res == C.DWORD(0xFFFFFFFF) {
			return fmt.Errorf("ould not resume thread: %d", thread.ID)
		}
	}

	// Unset the processor TRAP flag
	res = C.GetThreadContext(C.HANDLE(t.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not GetThreadContext")
	}

	context.EFlags &= ^C.DWORD(0x100)

	res = C.SetThreadContext(C.HANDLE(t.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not SetThreadContext")
	}

	return nil
}