From beaa04604a7e2811446191e0b3f4c970b4e9d406 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 10 Oct 2022 20:01:25 +0200 Subject: [PATCH] proc/native: acquire debug programs privilege on Windows (#3162) On Windows we need to acquire the SeDebugPrivilege privilege to be able to debug programs owned by different users. See: https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debug-privilege This procedure will fail if the current user does not have this privilege so do not complain too much about it. Fixes #3136 --- pkg/proc/native/proc_windows.go | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/pkg/proc/native/proc_windows.go b/pkg/proc/native/proc_windows.go index 4d0c15a8e3..5c5ffcf25f 100644 --- a/pkg/proc/native/proc_windows.go +++ b/pkg/proc/native/proc_windows.go @@ -141,8 +141,20 @@ func findExePath(pid int) (string, error) { } } +var debugPrivilegeRequested = false + // Attach to an existing process with the given PID. func Attach(pid int, _ []string) (*proc.Target, error) { + var aperr error + if !debugPrivilegeRequested { + debugPrivilegeRequested = true + // The following call will only work if the user is an administrator + // has the "Debug Programs" privilege in Local security settings. + // Since this privilege is not needed to debug processes owned by the + // current user, do not complain about this unless attach actually fails. + aperr = acquireDebugPrivilege() + } + dbp := newProcess(pid) var err error dbp.execPtraceFunc(func() { @@ -150,6 +162,9 @@ func Attach(pid int, _ []string) (*proc.Target, error) { err = _DebugActiveProcess(uint32(pid)) }) if err != nil { + if aperr != nil { + return nil, fmt.Errorf("%v also %v", err, aperr) + } return nil, err } exepath, err := findExePath(pid) @@ -164,6 +179,40 @@ func Attach(pid int, _ []string) (*proc.Target, error) { return tgt, nil } +// acquireDebugPrivilege acquires the debug privilege which is needed to +// debug other user's processes. +// See: +// +// - https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debug-privilege +// - https://github.com/go-delve/delve/issues/3136 +func acquireDebugPrivilege() error { + var token sys.Token + err := sys.OpenProcessToken(sys.CurrentProcess(), sys.TOKEN_QUERY|sys.TOKEN_ADJUST_PRIVILEGES, &token) + if err != nil { + return fmt.Errorf("could not acquire debug privilege (OpenCurrentProcessToken): %v", err) + } + defer token.Close() + + privName, _ := sys.UTF16FromString("SeDebugPrivilege") + var luid sys.LUID + err = sys.LookupPrivilegeValue(nil, &privName[0], &luid) + if err != nil { + return fmt.Errorf("could not acquire debug privilege (LookupPrivilegeValue): %v", err) + } + + var tp sys.Tokenprivileges + tp.PrivilegeCount = 1 + tp.Privileges[0].Luid = luid + tp.Privileges[0].Attributes = sys.SE_PRIVILEGE_ENABLED + + err = sys.AdjustTokenPrivileges(token, false, &tp, 0, nil, nil) + if err != nil { + return fmt.Errorf("could not acquire debug privilege (AdjustTokenPrivileges): %v", err) + } + + return nil +} + // kill kills the process. func (dbp *nativeProcess) kill() error { if dbp.exited {