如何解决Windows - 使用 CreateProcessWithTokenW 在会话 0 中创建进程
目的是从非 0 控制台会话中的进程在会话 0 中创建一个新进程。 我知道一些可以达到目的的方法,但我想知道为什么下面描述的方法不起作用,尽管 msdn 说它应该有效。
unsigned FindProcessInSession(unsigned SessionId,const wchar_t*ProcessName)
{
PWTS_PROCESS_INFOW pinfo;DWORD Count,Result=0;
if(WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE,1,&pinfo,&Count)){
for(unsigned i=0;i<Count;++i)if(pinfo[i].SessionId==SessionId&&_wcsicmp(pinfo[i].pProcessName,ProcessName)==0){
Result=pinfo[i].ProcessId;break;
}
WTSFreeMemory(pinfo);
}
return Result;
}
int main()
{
HANDLE hProcess=OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,FindProcessInSession(0,L"smss.exe")),ProcessToken,NewToken;
if(hProcess&&OpenProcessToken(hProcess,TOKEN_DUPLICATE,&ProcessToken)&&DuplicateTokenEx(ProcessToken,MAXIMUM_ALLOWED,SecurityImpersonation,TokenImpersonation,&NewToken)){
static STARTUPINFOW si={sizeof(STARTUPINFOW)};PROCESS_INFORMATION pi;DWORD SessionId,l;
printf("GetTokenInformation %d\n",GetTokenInformation(NewToken,TokenSessionId,&SessionId,sizeof SessionId,&l));
printf("SessionId %d\n",SessionId);
printf("CreateProcessWithTokenW %d\n",CreateProcessWithTokenW(NewToken,L"c:\\windows\\system32\\cmd.exe",&si,&pi));
}
}
在我的电脑上测试期间,GetTokenInformation 成功输出 SessionId=0 并且 CreateProcessWithTokenW 以 SYSTEM 用户名创建了一个新进程,所有权限都来自 smss.exe。但是新进程仍然在调用进程所在的任何会话中运行。 msdn 关于 CreateProcessWithTokenW 笔记
终端服务:进程在令牌中指定的会话中运行。默认情况下,这与调用 LogonUser 的会话相同。要更改会话,请使用 SetTokenInformation 函数。
显然依赖的辅助登录服务 CreateProcessWithTokenW 不遵循文档
解决方法
CreateProcessWithTokenW
获取调用者的 SessionId 并将此 SessionId 设置在令牌中(作为副作用 - 在 CreateProcessWithTokenW
之后修改了令牌。您可以调用在 GetTokenInformation
之后再次 CreateProcessWithTokenW
并查看现在这里已经不是 0。因此 - CreateProcessWithTokenW
不能用于另一个会话中的运行过程。需要使用 CreateProcessAsUserW
。更多研究{ {3}}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。