You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PsExec与Go服务运行系统进程的Winlogon桌面权限差异排查

系统进程运行Electron应用的两种方式差异排查

我正在开发一款Electron应用,该应用的子Node.js进程通过ffmpeg工具捕获桌面流。为捕获winlogon流,子进程中使用setThreadDesktop API将线程桌面切换至winlogon。

使用PsExec工具执行命令 PsExec64.exe -sid <path-to-exe> 以系统进程运行该Electron应用时,一切正常。

但通过Go语言编写的Windows服务(依赖golang.org/x/sys/windows包)按以下程序步骤以系统进程运行应用时,无法正常工作:子进程中的ffmpeg工具退出并返回错误(5),即拒绝访问winlogon桌面。

获取token的代码

wlPid, e := processID("winlogon.exe", uint32(sessionId))
if e != nil {
    log.Printf("Error in getting winlogon pid: %s", e.Error())
    return 0xFFFFFFFF, e
}

hProcess, eo := windows.OpenProcess(windows.MAXIMUM_ALLOWED, true, wlPid)
if eo != nil {
    log.Printf("Error opening process: %s", eo.Error())
    return 0xFFFFFFFF, eo
}
token := windows.Token(impersonationToken)
ope := windows.OpenProcessToken(hProcess, windows.TOKEN_ALL_ACCESS, &token)
if ope != nil {
    log.Printf("OpenProcessToken failed %s", ope.Error())
    return 0xFFFFFFFF, ope
}

systemSid, err := windows.CreateWellKnownSid(windows.WinLocalSystemSid)

// Create the trustee to add to an ACE
trustee := windows.TRUSTEE{
    MultipleTrustee:          nil,
    MultipleTrusteeOperation: windows.NO_MULTIPLE_TRUSTEE,
    TrusteeForm:              windows.TRUSTEE_IS_SID,
    TrusteeType:              windows.TRUSTEE_IS_USER,
    TrusteeValue:             windows.TrusteeValueFromSID(systemSid),
}

ace := windows.EXPLICIT_ACCESS{
    // AccessPermissions: windows.ACCESS_MASK(windows.READ_CONTROL), // WINSTA_CREATEDESKTOP | WINSTA_READSCREEN | WINSTA_ACCESSCLIPBOARD | WINSTA_WRITEATTRIBUTES | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES |
    // AccessMode:        windows.SET_ACCESS,
    AccessPermissions: windows.STANDARD_RIGHTS_ALL,
    AccessMode:        windows.GRANT_ACCESS,
    Inheritance:       windows.INHERIT_ONLY,
    Trustee:           trustee,
}

// Add the new ACE for the token user to the existing security descriptor for the window station
sd, err := windows.BuildSecurityDescriptor(nil, nil, []windows.EXPLICIT_ACCESS{ace}, nil, nil)
if err != nil {
    return 0xFFFFFFFF, fmt.Errorf("there was an error calling windows.BuildSecurityDescriptor for the station: %s", err)
}

if returnCode, _, err := procDuplicateTokenEx.Call(uintptr(token), windows.MAXIMUM_ALLOWED, uintptr(unsafe.Pointer(&sd)), uintptr(SecurityImpersonation), uintptr(TokenPrimary), uintptr(unsafe.Pointer(&userToken))); returnCode == 0 {
    // log.Printf("Dup Error: %s", err.Error())
    return 0xFFFFFFFF, fmt.Errorf("call native DuplicateTokenEx: %s", err)
}

h := windows.Handle(token)
if err := windows.CloseHandle(h); err != nil {
    // log.Printf("Close Error: %s", err.Error())
    return 0xFFFFFFFF, fmt.Errorf("close windows handle used for token duplication: %s", err)
}

return userToken, nil

使用userToken创建进程的代码

if returnCode, _, err := procCreateEnvironmentBlock.Call(uintptr(unsafe.Pointer(&envInfo)), uintptr(userToken), 0); returnCode == 0 {
    return fmt.Errorf("create environment details for process: %s", err)
}

creationFlags := windows.CREATE_UNICODE_ENVIRONMENT | windows.CREATE_NEW_CONSOLE
startupInfo.ShowWindow = windows.SW_SHOW
startupInfo.Desktop = windows.StringToUTF16Ptr("winsta0\\default")

if len(cmdLine) > 0 {
    commandLine = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(cmdLine)))
}
if len(workDir) > 0 {
    workingDir = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(workDir)))
}
log.Printf("Calling Create Process as user")
log.Println(userToken)
if returnCode, _, err := procCreateProcessAsUser.Call(
    uintptr(userToken), uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(appPath))), commandLine, 0, 0, 0,
    uintptr(creationFlags), uintptr(envInfo), workingDir, uintptr(unsafe.Pointer(&startupInfo)), uintptr(unsafe.Pointer(&processInfo)),
); returnCode == 0 {
    return fmt.Errorf("create process as user: %s", err)
}

恳请Windows技术专家帮忙分析这两种以系统进程运行应用的方式存在哪些差异?


内容的提问来源于stack exchange,提问作者Hiren patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:44:54