关键词

vista和win7在windows服务中交互桌面权限问题解决方法:穿透Session 0 隔离

在Windows操作系统中,服务是一种常见的后台程序,它可以在系统启动时自动运行,并在后台执行某些任务。在本攻略中,我们将详细介绍如何在Windows服务中解决桌面权限问题,并提供两个示例来说明其用法。

以下是两个示例,介绍如何在Windows服务中解决桌面权限问题:

示例一:使用Win32 API穿透Session0隔离

  1. 首先,我们需要使用Win32 API来穿透Session0隔离:
#include <windows.h>
#include <userenv.h>

BOOL EnablePrivilege(LPCTSTR lpszPrivilege, BOOL bEnable) {
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    LUID luid;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
        return FALSE;
    }

    if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid)) {
        CloseHandle(hToken);
        return FALSE;
    }

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;

    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
        CloseHandle(hToken);
        return FALSE;
    }

    CloseHandle(hToken);
    return TRUE;
}

BOOL StartProcessInSession0(LPCTSTR lpszCommandLine) {
    DWORD dwSessionId = 0;
    HANDLE hToken = NULL;
    HANDLE hDupToken = NULL;
    PROCESS_INFORMATION pi = { 0 };
    STARTUPINFO si = { 0 };
    si.cb = sizeof(si);

    if (!WTSQueryUserToken(dwSessionId, &hToken)) {
        return FALSE;
    }

    if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hDupToken)) {
        CloseHandle(hToken);
        return FALSE;
    }

    if (!SetTokenInformation(hDupToken, TokenSessionId, &dwSessionId, sizeof(DWORD))) {
        CloseHandle(hDupToken);
        CloseHandle(hToken);
        return FALSE;
    }

    if (!EnablePrivilege(SE_TCB_NAME, TRUE)) {
        CloseHandle(hDupToken);
        CloseHandle(hToken);
        return FALSE;
    }

    if (!CreateProcessAsUser(hDupToken, NULL, (LPTSTR)lpszCommandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
        CloseHandle(hDupToken);
        CloseHandle(hToken);
        return FALSE;
    }

    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(hDupToken);
    CloseHandle(hToken);
    return TRUE;
}

在上面的示例中,我们首先定义了两个函数:EnablePrivilege和StartProcessInSession0。这些函数使用Win32 API来启动一个新进程,并穿透Session0隔离。

  1. 然后,我们可以在Windows服务中使用StartProcessInSession0函数来启动一个新进程:
void MyService::OnStart(DWORD dwArgc, LPTSTR* lpszArgv) {
    StartProcessInSession0(TEXT("C:\\Windows\\System32\\notepad.exe"));
}

在上面的示例中,我们首先定义了一个MyService类,并继承了CServiceBase类。然后,我们在OnStart方法中使用StartProcessInSession0函数来启动一个新进程。

示例二:使用PsExec穿透Session0隔离

  1. 首先,我们需要下载PsExec工具,并将其添加到系统路径中。

  2. 然后,我们可以在Windows服务中使用PsExec来启动一个新进程:

void MyService::OnStart(DWORD dwArgc, LPTSTR* lpszArgv) {
    system("psexec -i 0 -d C:\\Windows\\System32\\notepad.exe");
}

在上面的示例中,我们首先定义了一个MyService类,并继承了CServiceBase类。然后,我们在OnStart方法中使用system函数来调用PsExec工具,并使用-i和-d参数来穿透Session0隔离。

总之,在Windows服务中解决桌面权限问题是一种常见的需求,它可以帮助开发者在服务中启动一个新进程,并与桌面交互。开发者可以根据实际情况选择最适合自己的方法,并据需要其他自定义功能。使用Win32 API和PsExec可以大大简化Windows服务中解决桌面权限问题的过程,提高开发效率和可维护性。

本文链接:http://task.lmcjl.com/news/7324.html

展开阅读全文