降权启动进程

需求:管理员启动了安装包并安装完后需要启动程序。此时希望是以当前登录用户来启动,而不是以管理员用户来启动(安装包是管理员权限,直接启动因为权限继承原因,程序也会是管理员权限)

思路:利用当前explorer.exe进程的token去创建目的进程

DWORD  GetExplorerToken(int nProcessId,OUT PHANDLE  phExplorerToken)
	{  
		DWORD       dwStatus = ERROR_FILE_NOT_FOUND ;   
		BOOL        bRet = FALSE ;  
		HANDLE      hProcess = NULL ;  
		HANDLE      hProcessSnap = NULL ;  
		TCHAR        szExplorerPath[MAX_PATH] = { 0 } ;  
		TCHAR        FileName[MAX_PATH] = { 0 } ;  
		PROCESSENTRY32 pe32 = { 0 } ;  
		__try  
		{  
			  
			hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 ) ;   
			if( hProcessSnap == INVALID_HANDLE_VALUE )    
			{  
				dwStatus = GetLastError() ;   
				__leave ;  
			}   
			pe32.dwSize = sizeof( PROCESSENTRY32 ) ;   
			if( !Process32First( hProcessSnap, &pe32 ))       
			{     
				dwStatus = GetLastError() ;   
				__leave ;   
			}   
			do {  
				
				


				if(nProcessId == pe32.th32ProcessID)
				{
					hProcess = OpenProcess(  
						PROCESS_QUERY_INFORMATION ,  
						FALSE ,  
						pe32.th32ProcessID ) ;  
					if( NULL != hProcess )          
					{   
						                               
								HANDLE  hToken ;  
								if( OpenProcessToken( hProcess , TOKEN_DUPLICATE  , &hToken ))  
								{       
									HANDLE hNewToken = NULL;
									DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken);
									* phExplorerToken = hNewToken ;  
									dwStatus = 0 ; 
									CloseHandle(hToken);
								}  
								break ;  
							 
						CloseHandle ( hProcess ) ;    
						hProcess = NULL ;  
					}
					else
					{
						int nLast = GetLastError();
						char pszbuffer[100]={0};
						sprintf(pszbuffer,"error:%d:%d:%d",nLast,nProcessId,pe32.th32ProcessID);
						MessageBox(0,pszbuffer,0,0);
					}
				}
				 


			} while( Process32Next( hProcessSnap, &pe32 )) ;  
		}  
		__finally   
		{  
			if( NULL != hProcess )  
			{  
				CloseHandle( hProcess ) ;  
			}  
			if( NULL != hProcessSnap )  
			{  
				CloseHandle ( hProcessSnap ) ;  
			}  
		}    
		return dwStatus ;   
	

 以下是调用    DWORD i;
		//考虑到多用户登录的时候explorer.exe有多个,故要特别处理一下
		HANDLE hPtoken = NULL ;  
		HWND hWnd = FindWindow("Shell_TrayWnd","");
		hWnd = FindWindowEx(hWnd,NULL,"ReBarWindow32","");

		hWnd = FindWindowEx(hWnd,NULL,"MSTaskSwWClass","运行应用程序");

		DWORD id = 0;  
		GetWindowThreadProcessId(hWnd,&id);

		
		GetExplorerToken(id,&hPtoken);

		PROCESS_INFORMATION pi;    
		STARTUPINFOW si = { sizeof(STARTUPINFO),NULL,L"",NULL,0,0,0,0,0,0,0,STARTF_USESHOWWINDOW,0,0,NULL,0,0,0};     
		si.wShowWindow = SW_SHOW;  
		si.lpDesktop = NULL;  
		ZeroMemory( &pi, sizeof(pi) );   


		char  infoBuf[MAX_PATH];
		DWORD  bufCharCount = MAX_PATH;
		popstring(infoBuf);
		int n= MultiByteToWideChar(CP_ACP,0,infoBuf,-1,NULL,0);
		wchar_t *m_pszHref =new wchar_t[n];
		memset(m_pszHref,0,n);
		MultiByteToWideChar(CP_ACP,0,infoBuf,-1,m_pszHref,n);


		CreateProcessWithTokenW(hPtoken, LOGON_WITH_PROFILE, NULL, m_pszHref, NULL, NULL, NULL, &si,&pi);
		

你可能感兴趣的:(windows)