windows服务创建带界面的窗口进程(穿透Session 0 隔离)

        Windows下服务直接启动窗口程序时,在任务管理器中可以看到窗口程序正在运行,但是桌面上并没有显示出窗口。

        这是因为在Windows XP、Windows Server 2003 或早期Windows 系统时代,当第一个用户登录系统后服务和应用程序是在同一个Session 中运行的,也就是Session 0。

        但是这种运行方式提高了系统安全风险,因为服务是通过提升了用户权限运行的,而应用程序往往是那些不具备管理员身份的普通用户运行的,其中的危险显而易见。

        所以从Vista 开始Session 0 中只包含系统服务,其他应用程序则通过分离的Session 运行,将服务与应用程序隔离提高系统的安全性。这样使得Session 0 与其他Session 之间无法进行交互,不能通过服务向桌面用户弹出信息窗口、UI 窗口等信息。

        这个时候如果想让我们的界面程序被服务启动就必须穿透Session 0 隔离。在实际开发过程中,可以通过Process Explorer检查服务或程序处于哪个Session,会不会遇到Session 0 隔离问题。

        下面就是穿透Session 0 隔离及服务启动窗口程序的步骤:

        1、使用OpenProcessToken函数来打开与服务进程相关联的访问令牌;

        2、使用DuplicateTokenEx函数创建一个新的访问令牌来复制一个已经存在的标记;

        3、使用SetTokenInformation函数把服务token的SessionId替换成当前活动的Session;

        4、使用CreateEnvironmentBlock函数创建进程环境块;

        5、使用CreateProcessAsUser函数在活动的Session下创建进程

        具体代码如下:

bool ServerRunWndProcess(LPWSTR lpExePath)
{
	HANDLE hToken = NULL;
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
	{
		return false;
	}

	HANDLE hTokenDup = NULL;
	bool bRet = DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
	if (!bRet || hTokenDup == NULL)
	{
		CloseHandle(hToken);
		return false;
	}

	DWORD dwSessionId = WTSGetActiveConsoleSessionId();
	//把服务hToken的SessionId替换成当前活动的Session(即替换到可与用户交互的winsta0下)
	if (!SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)))
	{
		DWORD nErr = GetLastError();
		CloseHandle(hTokenDup);
		CloseHandle(hToken);
		return false;
	}

	STARTUPINFO si;
	ZeroMemory(&si, sizeof(STARTUPINFO));

	si.cb = sizeof(STARTUPINFO);
	si.lpDesktop = _T("WinSta0\\Default");
	si.wShowWindow = SW_SHOW;
	si.dwFlags = STARTF_USESHOWWINDOW /*|STARTF_USESTDHANDLES*/;

	//创建进程环境块
	LPVOID pEnv = NULL;
	bRet = CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
	if (!bRet)
	{
		CloseHandle(hTokenDup);
		CloseHandle(hToken);
		return false;
	}

	if (pEnv == NULL)
	{
		CloseHandle(hTokenDup);
		CloseHandle(hToken);
		return false;
	}

	//在活动的Session下创建进程
	PROCESS_INFORMATION processInfo;
	ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
	DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;

	if (!CreateProcessAsUser(hTokenDup, NULL, lpExePath, NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &si, &processInfo))
	{
		DWORD nRet = GetLastError();
		CloseHandle(hTokenDup);
		CloseHandle(hToken);
		return false;
	}

	DestroyEnvironmentBlock(pEnv);
	CloseHandle(hTokenDup);
	CloseHandle(hToken);

	return true;
}

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Session0穿透安全桌面是指一种技术手段,可以通过远程桌面连接或者其他方式,在操作系统的Session0中执行代码或者运行程序。在Windows操作系统中,Session0是一个特殊的会话,用于运行服务和系统进程,通常不允许用户交互。 Session0穿透安全桌面具有以下特点和用途。首先,它可以实现安全远程管理和维护Windows服务和系统进程,提高系统的可靠性和稳定性。管理员可以通过远程桌面连接到Session0,查看和操作服务进程,方便进行故障排除和监控。 其次,Session0穿透安全桌面可以用于一些特定的应用场景,比如虚拟化技术和程序开发。在虚拟化环境中,可以通过Session0穿透安全桌面在宿主机上管理和控制虚拟机。在程序开发过程中,开发人员可以直接在Session0中调试和运行程序,以提高效率和减少开发周期。 此外,Session0穿透安全桌面也存在一些安全风险。由于Session0是一个特权会话,可以执行更高级别的操作,因此滥用Session0穿透可能导致系统的不稳定甚至崩溃。另外,远程连接Session0可能面临安全风险,如果黑客攻击成功获取Session0权限,可能导致系统被恶意控制或者敏感信息泄露。 综上所述,Session0穿透安全桌面是一种用于远程管理和控制Windows服务和系统进程的技术手段。它在提高系统可靠性和稳定性的同时,也来了一定的安全风险。因此,在使用Session0穿透安全桌面时,需要慎重考虑安全性和风险,并采取相应的措施来保护系统和数据的安全。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古道青阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值