Windows-使用CreateProcessWithTokenW在会话0中创建进程

Windows-使用CreateProcessWithTokenW在会话0中创建进程,windows,winapi,windows-10-desktop,Windows,Winapi,Windows 10 Desktop,目的是从非0控制台会话中的进程创建会话0中的新进程。 我知道一些方法可以达到这个目的,但是我想知道为什么下面描述的方法不起作用,尽管msdn说它应该可以工作 unsigned FindProcessInSession(unsigned SessionId,const wchar_t*ProcessName) { PWTS_PROCESS_INFOW pinfo;DWORD Count,Result=0; if(WTSEnumerateProcessesW(WTS_CURRENT_

目的是从非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,0,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,0,FindProcessInSession(0,L"smss.exe")),ProcessToken,NewToken;
    if(hProcess&&OpenProcessToken(hProcess,TOKEN_DUPLICATE,&ProcessToken)&&DuplicateTokenEx(ProcessToken,MAXIMUM_ALLOWED,0,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,0,L"c:\\windows\\system32\\cmd.exe",0,0,0,0,&si,&pi));
    }
}
unsigned find进程会话(unsigned SessionId,const wchar\u t*ProcessName)
{
PWTS_PROCESS_INFOW pinfo;DWORD计数,结果=0;
if(WTSEnumerateProcessesW(WTS\u当前\u服务器\u句柄,0,1,&pinfo,&Count)){

对于(unsigned i=0;i
CreateProcessWithTokenW
获取调用方的SessionId并在token中设置此SessionId(作为副作用-令牌在
CreateProcessWithTokenW
之后被修改。您可以在
CreateProcessWithTokenW
之后再次调用
GetTokenInformation
,并在此处查看现在已经不是0的令牌。因此-
CreateProcessWithTokenW
不能用于另一个会话中的运行进程。需要使用
CreateProcessAsUserW
)>。更多研究

CreateProcessWithTokenW
获取调用者的SessionId并在token中设置此SessionId(作为副作用-令牌在
CreateProcessWithTokenW
之后被修改。您可以在
CreateProcessWithTokenW
之后再次调用
GetTokenInformation
,并在此处查看现在已经不是0的令牌。因此-
CreateProcessWithTokenW
不能用于另一个会话中的运行进程。需要使用
CreateProcessAsUserW
)>.更多研究

这是因为
CreateProcessWithTokenW
内部更改令牌的TokenSessionId。将其设置为caller SessionId。“从非0控制台会话中的进程在会话0中创建新进程”-为什么要这样做?这里的用例是什么?会话0是为服务保留的。如果希望进程在会话0中运行,它本身应该是服务,或者由服务启动。这是因为
CreateProcessWithTokenW
内部更改令牌的TokenSessionId。将其设置为调用者SessionId。“从非0控制台会话中的进程在会话0中创建新进程”-为什么要这样做?这里的用例是什么?会话0是为服务保留的。如果希望进程在会话0中运行,它本身应该是服务,或者由服务启动。