从服务调用时,带有JOB_OBJECT_UILIMIT_HANDLES的AssignProcessToJobObject失败

时间:2011-05-13 16:04:39

标签: windows security

我有一项服务,我想从中为当前登录的用户创建一个受限制的进程。 如果我尝试将进程分配给具有JOB_OBJECT_UILIMIT_HANDLES设置的作业对象,则调用将失败并显示ERROR_ACCESS_DENIED。如果我从作业设置中删除JOB_OBJECT_UILIMIT_HANDLES一切正常。如果我在用户的上下文中执行此代码,它也可以工作。

知道这是什么问题?

谢谢。

编辑:

这是一个重现问题的示例程序。程序启动一个与指定进程具有相同令牌的进程,并将该进程分配给作业对象。

如果以系统方式启动进程(可以创建服务,并将可执行文件路径设置为cmd.exe,然后可以切换到系统会话并从那里启动程序),请为任何用户进程指定源进程并将limit UI设置为true,对AssignProcessToJobObject的调用将失败,状态为ERROR_ACCESS_DENIED。如果将限制UI设置为false,则一切正常。

# define _CRT_SECURE_NO_WARNINGS

# include "stdafx.h"

# include <windows.h>

# include <stdio.h>
# include <assert.h>
# include <conio.h>

void main()
{   
    HANDLE job = NULL;
    STARTUPINFO startupInfo = { 0 };
    PROCESS_INFORMATION processInformation = { 0 };
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION eli = { 0 };
    JOBOBJECT_BASIC_UI_RESTRICTIONS bur = { 0 };
    HANDLE token = NULL;
    HANDLE process = NULL;
    BOOL limitUI = TRUE;

    DWORD sourcePid = 0;
    printf("Enter source pid: ");
    scanf("%u", &sourcePid);

   process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, sourcePid);
   if(process == NULL)
   {
        printf("OpenProcess failed\n");
        goto cleanup;
    }

    if(!OpenProcessToken(process, TOKEN_ALL_ACCESS, &token))   
    {
        printf("OpenProcessToken failed\n");
        goto cleanup;
    }

    job = CreateJobObject(NULL, NULL);
    if(job == NULL)    
    {
        printf("CreateJobObject failed\n");
        goto cleanup;
    }

    eli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    eli.BasicLimitInformation.PriorityClass = NORMAL_PRIORITY_CLASS;
    if(!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &eli, sizeof(eli)))   
    {
        printf("SetInformationJobObject failed\n");
        goto cleanup;
    }

    printf("Limit UI: ");
    scanf("%u", &limitUI);

    if(limitUI)
    {
        bur.UIRestrictionsClass = JOB_OBJECT_UILIMIT_HANDLES;
        if(!SetInformationJobObject(job, JobObjectBasicUIRestrictions, &bur, sizeof(bur)))   
        {
            printf("SetInformationJobObject failed\n");
            goto cleanup;
        }
    }

    if(!CreateProcessAsUser(token, L"c:\\windows\\system32\\notepad.exe", L"", NULL, NULL, FALSE,
        CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation))   
    {
        printf("CreateProcessAsUser failed\n");
        goto cleanup;
    }

    if(!AssignProcessToJobObject(job, processInformation.hProcess))   
    {
        printf("AssignProcessToJobObject failed\n");
        goto cleanup;
    }

    if(ResumeThread(processInformation.hThread) == (DWORD)-1)   
    {
        printf("ResumeThread failed\n");
        goto cleanup;
    }

    WaitForSingleObject(processInformation.hProcess, INFINITE);

cleanup:
    if(processInformation.hThread != NULL)
        CloseHandle(processInformation.hThread);
    if(processInformation.hProcess != NULL)
        CloseHandle(processInformation.hProcess);
    if(job != NULL)
        CloseHandle(job);
    if(token != NULL)
        CloseHandle(token);
    if(process != NULL)
        CloseHandle(process);

    printf("Last Error: %d\n", GetLastError());
}

0 个答案:

没有答案