// 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 }
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 }
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 }