// 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 registers(thread *Thread) (Registers, error) {
	var context C.CONTEXT

	context.ContextFlags = C.CONTEXT_ALL
	res := C.GetThreadContext(C.HANDLE(thread.os.hThread), &context)
	if res == C.FALSE {
		return nil, fmt.Errorf("failed to read ThreadContext")
	}

	var threadInfo C.THREAD_BASIC_INFORMATION
	res = C.thread_basic_information(C.HANDLE(thread.os.hThread), &threadInfo)
	if res == C.FALSE {
		return nil, fmt.Errorf("failed to get thread_basic_information")
	}
	tls := uintptr(threadInfo.TebBaseAddress)

	regs := &Regs{
		rax:    uint64(context.Rax),
		rbx:    uint64(context.Rbx),
		rcx:    uint64(context.Rcx),
		rdx:    uint64(context.Rdx),
		rdi:    uint64(context.Rdi),
		rsi:    uint64(context.Rsi),
		rbp:    uint64(context.Rbp),
		rsp:    uint64(context.Rsp),
		r8:     uint64(context.R8),
		r9:     uint64(context.R9),
		r10:    uint64(context.R10),
		r11:    uint64(context.R11),
		r12:    uint64(context.R12),
		r13:    uint64(context.R13),
		r14:    uint64(context.R14),
		r15:    uint64(context.R15),
		rip:    uint64(context.Rip),
		eflags: uint64(context.EFlags),
		cs:     uint64(context.SegCs),
		fs:     uint64(context.SegFs),
		gs:     uint64(context.SegGs),
		tls:    uint64(tls),
	}
	return regs, nil
}
func registers(thread *Thread) (Registers, error) {
	var context C.CONTEXT

	context.ContextFlags = C.CONTEXT_ALL
	res := C.GetThreadContext(C.HANDLE(thread.os.hThread), &context)
	if res == C.FALSE {
		return nil, fmt.Errorf("failed to read ThreadContext")
	}

	var threadInfo _THREAD_BASIC_INFORMATION
	status := _NtQueryInformationThread(syscall.Handle(thread.os.hThread), _ThreadBasicInformation, uintptr(unsafe.Pointer(&threadInfo)), uint32(unsafe.Sizeof(threadInfo)), nil)
	if !_NT_SUCCESS(status) {
		return nil, fmt.Errorf("failed to get thread_basic_information")
	}

	regs := &Regs{
		rax:    uint64(context.Rax),
		rbx:    uint64(context.Rbx),
		rcx:    uint64(context.Rcx),
		rdx:    uint64(context.Rdx),
		rdi:    uint64(context.Rdi),
		rsi:    uint64(context.Rsi),
		rbp:    uint64(context.Rbp),
		rsp:    uint64(context.Rsp),
		r8:     uint64(context.R8),
		r9:     uint64(context.R9),
		r10:    uint64(context.R10),
		r11:    uint64(context.R11),
		r12:    uint64(context.R12),
		r13:    uint64(context.R13),
		r14:    uint64(context.R14),
		r15:    uint64(context.R15),
		rip:    uint64(context.Rip),
		eflags: uint64(context.EFlags),
		cs:     uint64(context.SegCs),
		fs:     uint64(context.SegFs),
		gs:     uint64(context.SegGs),
		tls:    uint64(threadInfo.TebBaseAddress),
	}
	return regs, nil
}
Example #4
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
}