2010-02-17 48 views
4

我正在嘗試讓我的一個正在運行的進程被提升爲使用標準用戶令牌重新啓動資源管理器。模擬標準用戶

我在做什麼,首先我經營的主要過程作爲管理員,然後我在運行的快照:

if (Process32First(hSnapshot,&pe32)) 
    { 
     do 
     { 
      if (!wcsicmp(pe32.szExeFile, L"explorer.exe")) 
      { 
       DWORD dwExplorerSessId = 0; 
       if (ProcessIdToSessionId(pe32.th32ProcessID, &dwExplorerSessId) && dwExplorerSessId == dwSessionId) 
       { 
        dwExplorerLogonPid = pe32.th32ProcessID; 
        break; 
       } 
      } 

     } while (Process32Next(hSnapshot, &pe32)); 
    } 

    CloseHandle(hSnapshot); 

然後,一旦我得到它的標準下運行資源管理器的PID用戶帳戶,我呼籲:

OpenProcessToken(hProcess,TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_IMPERSONATE 
      ,&hPToken)) 

然後我打電話:

ImpersonateLoggedOnUser(hPToken); 

和國際泳聯lly我taskkill explorer.exe和shell再次執行它,但它的管理員權限下運行。

它彷彿impersonateLoggedonUser不起作用。雖然它返回true,GetLastError()返回0;

我也使用CreateProcessAsUser嘗試(),但這總是給人一種ERROR_FILE_NOT_FOUND:

STARTUPINFO si; 
    GetStartupInfo(&si);     
    PROCESS_INFORMATION pi; 
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); 

    TCHAR tchcmd[MAX_PATH]; 
    _tcscpy(tchcmd, _T("explorer.exe")); 
    PVOID penv; 
    CreateEnvironmentBlock(&penv, hToken, FALSE); 
HANDLE hNewToken; 
DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenImpersonation, &hNewToken); 
    CreateProcessAsUser(, NULL, tchcmd, 0, 0, 0, CREATE_DEFAULT_ERROR_MODE, penv, 0, &si, &pi); 

任何意見或建議。

+0

請記住,Process32First/Next函數是爲了向後兼容性而保留的,並不總是返回完美的結果。它們不能在64位機器上可靠地工作,並且它們通常返回的實際數量少於svchost.exes。鋤頭,幫助:) – 2010-02-17 16:00:52

+0

@BillyONeal:它會返回所有進程...如果你有權限SE_DEBUG – 2010-02-17 16:10:43

+0

即使使用'SeDebugPrivilege'它並不總是返回正確數量的svchosts。在Windows API初始化之前(在NT引導過程早些時候),啓動任何東西都會遇到問題。「EnumProcesses()」是唯一(記錄)的函數,它總是返回正確的答案。 – 2010-02-17 18:33:53

回答

3

在使用它之前是否在令牌上調用DuplicateTokenEx?你應該。

而不是ImpersonateLoggedOnUser,你可以更容易地調用CreateProcessAsUser

編輯以符合您:

  • 你CreateProcessAsUser的方式,應通過:CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENTdwCreationFlags

  • 你也應該錯誤檢查你的CreateEnvironmentBlock

  • 你也應該調整desktop和​​的Ace

  • 而不是直接在CreateProcessByUser中指定路徑,您應該首先使用ExpandEnvironmentStringsForUser擴展字符串中的任何環境變量。這將爲例如轉換:%windir%\explorer.exeC:\windows\explorer.exe

wchar_t szNewCommandLine[MAX_PATH]; 
if(!::ExpandEnvironmentStringsForUser(hNewToken, tchcmd, szNewCommandLine, MAX_PATH - 1)) 
{ 
    DWORD dwExpandEnvLastError = GetLastError(); 
    //error handling 
} 

For further reading please see this post on Session, Window Station, and Desktop management

+0

我也嘗試過,但它返回INVALID_PARAMETER_ERROR 我編輯了我正在使用的方法的問題。 – 2010-02-17 15:28:36

+0

什麼是返回INVALID_PARAMETER_ERROR?你打電話給DuplicateTokenEx嗎? – 2010-02-17 15:29:44

+0

添加了更多信息。 – 2010-02-17 15:49:01

0

我試圖以安裝程序作爲標準用戶以高級管理員權限啓動時運行程序時遇到類似問題。使用CreateProcessAsUser函數嘗試(並且失敗後)執行此操作後,我偶然發現了一個使用ShellExecute從IShellDispatch2接口的解決方案。

它可以用來當前交互式用戶啓動一個進程。爲完整的實施看看這裏: https://code.google.com/p/mulder/source/browse/trunk/Utils/nsis_stdutils/Contrib/StdUtils/ShellExecAsUser.cpp?r=327

希望這可以幫助!