-
- 主要代码如下:
- DWORD FindSessionPid(LPSTR lpProcessName, DWORD dwSessionId)
- {
- DWORD res = 0;
- PROCESSENTRY32 procEntry;
- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hSnap == INVALID_HANDLE_VALUE)
- {
- return res ;
- }
- procEntry.dwSize = sizeof(PROCESSENTRY32);
- if (!Process32First(hSnap, &procEntry))
- {
- goto _end;
- }
- do
- {
- if (_stricmp(procEntry.szExeFile, lpProcessName) == 0)
- {
- DWORD winlogonSessId = 0;
- if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId)
- {
- res = procEntry.th32ProcessID;
- break;
- }
- }
- } while (Process32Next(hSnap, &procEntry));
- _end:
- CloseHandle(hSnap);
- return res;
- }
- BOOL LaunchAppIntoDifferentSession(LPSTR lpCmdLine)
- {
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- BOOL bResult = FALSE;
- DWORD dwSessionId = 0, winlogonPid = 0;
- HANDLE hUserToken, hUserTokenDup, hPToken, hProcess;
- DWORD dwCreationFlags;
- // Log the client on to the local computer.
- typedef DWORD (WINAPI *__pfnWTSGetActiveConsoleSessionId)();
- typedef BOOL (WINAPI *__pfnWTSQueryUserToken)( ULONG SessionId, PHANDLE phToken );
- __pfnWTSGetActiveConsoleSessionId pfnWTSGetActiveConsoleSessionId =
- (__pfnWTSGetActiveConsoleSessionId)GetProcAddress(LoadLibraryA("kernel32.dll"), "WTSGetActiveConsoleSessionId");
- __pfnWTSQueryUserToken pfnWTSQueryUserToken =
- (__pfnWTSQueryUserToken)GetProcAddress(LoadLibraryA("Wtsapi32.dll"), "WTSQueryUserToken");
- if(pfnWTSGetActiveConsoleSessionId == NULL)
- {
- WriteLog("Not found api: WTSGetActiveConsoleSessionId\n");
- return 0;
- }
- if(pfnWTSQueryUserToken == NULL)
- {
- WriteLog("Not found api: WTSQueryUserToken\n");
- return 0;
- }
- dwSessionId = pfnWTSGetActiveConsoleSessionId();
- winlogonPid = FindSessionPid("explorer.exe", dwSessionId);
- if(winlogonPid == 0)
- {
- winlogonPid = FindSessionPid("winlogon.exe", dwSessionId);
- }
- if(winlogonPid == 0)
- {
- WriteLog("Can't Find Explorer\n");
- return 0;
- }
- ////////////////////////////////////////////////////////////////////////
- dwCreationFlags = NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE;
- ZeroMemory(&si, sizeof(STARTUPINFO));
- si.cb= sizeof(STARTUPINFO);
- si.lpDesktop = "winsta0\\default";
- ZeroMemory(&pi, sizeof(pi));
- TOKEN_PRIVILEGES tp;
- LUID luid;
- LPVOID TokenInformation;
- DWORD RetLen = 0;
- if( !pfnWTSQueryUserToken(dwSessionId, &hUserToken) )
- {
- hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, winlogonPid);
- if(!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P, &hPToken))
- {
- char pTemp[121];
- sprintf(pTemp, "Process token open Error: %u\n", GetLastError());
- WriteLog(pTemp);
- }
- if(hPToken == NULL)
- {
- WriteLog("Process tokenError: \n");
- }
- }
- else
- {
- hPToken = hUserToken;
- }
- if(GetTokenInformation(hPToken, TokenLinkedToken, &TokenInformation, 4, &RetLen))
- {
- hUserTokenDup = TokenInformation;
- }
- else
- {
- if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
- {
- char pTemp[121];
- sprintf(pTemp, "Lookup Privilege value Error: %u\n", GetLastError());
- WriteLog(pTemp);
- }
- if(!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hUserTokenDup))
- {
- char pTemp[121];
- sprintf(pTemp, "DuplicateTokenEx Error: %u\n", GetLastError());
- WriteLog(pTemp);
- }
- }
- LPVOID pEnv = NULL;
- if(CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE))
- {
- dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
- }
- else
- {
- WriteLog("CreateEnvironmentBlock Failed\n");
- pEnv = NULL;
- }
- // Launch the process in the client's logon session.
- bResult = CreateProcessAsUser(
- hUserTokenDup, // client's access token
- NULL, // file to execute
- lpCmdLine, // command line
- NULL, // pointer to process SECURITY_ATTRIBUTES
- NULL, // pointer to thread SECURITY_ATTRIBUTES
- FALSE, // handles are not inheritable
- dwCreationFlags, // creation flags
- pEnv, // pointer to new environment block
- NULL, // name of current directory
- &si, // pointer to STARTUPINFO structure
- &pi // receives information about new process
- );
- // End impersonation of client.
- //GetLastError Shud be 0
- int iResultOfCreateProcessAsUser = GetLastError();
- if(bResult == FALSE && iResultOfCreateProcessAsUser != 0)
- {
- char pTemp[121];
- sprintf(pTemp, "CreateProcessAsUser Error: %u\n", GetLastError());
- WriteLog(pTemp);
- }
- if(pi.hProcess)
- {
- CloseHandle(pi.hProcess);
- }
- if(pi.hThread)
- {
- CloseHandle(pi.hThread);
- }
- //Perform All the Close Handles task
- if(hProcess)
- {
- CloseHandle(hProcess);
- }
- if(hUserToken)
- {
- CloseHandle(hUserToken);
- }
- if(hUserTokenDup)
- {
- CloseHandle(hUserTokenDup);
- }
- if(hPToken)
- {
- CloseHandle(hPToken);
- }
- if(pEnv)
- {
- DestroyEnvironmentBlock(pEnv);
- }
- return bResult;
- }
- 调用方式:
- LaunchAppIntoDifferentSession("c:\\windows\\notepad.exe");
- 前提是有个服务进程已经启动,然后服务进程会以管理员模式(不需要用户点UAC的框)启动一个新的可以创建窗口的进程。
- 安装这个服务需要点UAC的框,所以不是什么不可公开的思路。好处就一点:每次自启动的进程,不需要再让用户点UAC框了
复制代码 |