winapi - 为什么 CreateProcessWithTokenW 因 ERROR_ACCESS_DENIED 而失败

标签 winapi pinvoke createprocessasuser

我有一个调用 CreateProcessWithTokenW 失败,访问被拒绝。任何想法如何调试?

对 CreateProcessWithTokenW 的调用在这里:https://github.com/fschwiet/PShochu/blob/master/PShochu/PInvoke/NetWrappers/ProcessUtil.cs

现在我正在为当前进程使用访问 token ,最终我将使用来自另一个用户的 token 。现在我正在使用 https://github.com/fschwiet/PShochu/blob/master/PShochu/PInvoke/NetWrappers/AccessToken.cs获取访问 token 。

如果要调试,请拉下源代码并运行 build_and_test.ps1。错误堆栈是:

1) Test Error : PShochu.Tests.can_run_remote_interactive_tasks, given a psake script which writes the current process id to output, when that script is invoked interactively, then the script succeeds
   System.ComponentModel.Win32Exception : Access is denied
   at PShochu.PInvoke.NetWrappers.ProcessUtil.CreateProcessWithToken(IntPtr userPrincipalToken, String applicationName,
String applicationCommand, Boolean dontCreateWindow, Boolean createWithProfile, StreamReader& consoleOutput, StreamReader& errorOutput) in c:\src\PShochu\PShochu\PInvoke\NetWrappers\ProcessUtil.cs:line 52
   at PShochu.ProcessHandling.RunNoninteractiveConsoleProcessForStreams2(String command, String commandArguments, String& newLine) in c:\src\PShochu\PShochu\ProcessHandling.cs:line 36
   at PShochu.ProcessHandling.RunNoninteractiveConsoleProcess(String command, String commandArguments) in c:\src\PShochu\PShochu\ProcessHandling.cs:line 20
   at PShochu.Tests.can_run_remote_interactive_tasks.<>c__DisplayClass16.<>c__DisplayClass18.<Specify>b__2() in c:\src\PShochu\PShochu.Tests\can_run_remote_interactive_tasks.cs:line 27
   at NJasmine.Core.Execution.DescribeState.<>c__DisplayClass7`1.<visitBeforeEach>b__3() in c:\src\NJasmine\NJasmine\Core\Execution\DescribeState.cs:line 62

后来更新:我在一些文档中看到需要额外的权限( http://msdn.microsoft.com/en-us/library/aa374905%28v=vs.85%29.aspx )。我无法通过测试来验证我拥有这些个人证券(它们在 secpol.msc pre-reboot 中设置)
SE_ASSIGNPRIMARYTOKEN_NAME  "Replace a process level token"
SE_TCB_NAME "Act as part of the operatin system"
SE_INCREASE_QUOTA_NAME  "Adjust memory quotas for a process"

这些测试不断告诉我我没有在 UI 中设置的权限,https://github.com/fschwiet/PShochu/blob/master/PShochu.Tests/verify_privileges.cs

最佳答案

通过反复试验,我发现您传递给 CreateProcessWithTokenW() 的 token 需要以下访问标志(至少在 Windows 7 SP1 64 位上):

  • TOKEN_ASSIGN_PRIMARY
  • TOKEN_DUPLICATE
  • TOKEN_QUERY
  • TOKEN_ADJUST_DEFAULT
  • TOKEN_ADJUST_SESSIONID

  • CreateProcessWithTokenW() 的文档中根本没有提到粗体的最后两个非常有用。

    编辑 :以下代码对我来说很好用(运行提升时):
    HANDLE hToken = NULL;
    if(OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken))
    {
        HANDLE hDuplicate = NULL;
        if(DuplicateTokenEx(hToken, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID, NULL, SecurityImpersonation, TokenPrimary, &hDuplicate))
        {
            TCHAR szCommandLine[MAX_PATH];
            _tcscpy_s(szCommandLine, MAX_PATH, _T("C:\\Windows\\system32\\notepad.exe"));
            STARTUPINFO StartupInfo;
            ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
            StartupInfo.cb = sizeof(STARTUPINFO);
            PROCESS_INFORMATION ProcessInformation;
            ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
            if(CreateProcessWithTokenW(hDuplicate, LOGON_WITH_PROFILE, NULL, szCommandLine, 0, NULL, NULL, &StartupInfo, &ProcessInformation))
            {
                WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
                CloseHandle(ProcessInformation.hThread);
                ProcessInformation.hThread = NULL;
                CloseHandle(ProcessInformation.hProcess);
                ProcessInformation.hProcess = NULL;
            }
            CloseHandle(hDuplicate);
            hToken = hDuplicate;
        }
        CloseHandle(hToken);
        hToken = NULL;
    }
    

    关于winapi - 为什么 CreateProcessWithTokenW 因 ERROR_ACCESS_DENIED 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5447418/

    相关文章:

    c++ - 如何将 IStream 实例中的数据读入 char 指针?

    C# P/调用键盘事件

    c# - 将 C Union 转换为 C#(未正确对齐)

    windows - CreateProcessAsUser 错误代码 6

    c++ - 创建在新 Windows 桌面上运行 IE 的进程

    c++ - HttpAddUrl 因 ERROR_SHARING_VIOLATION (32L) 而失败

    winapi - 低级如何复制文件?

    c# - PInvoke - 如何表示来自 COM 接口(interface)的字段

    c# - 从 C# 调用 CreateProcessAsUser

    使用 getenv 调用 CreateProcessAsUser 的 C++ LPTSTR 问题