2017-10-09 54 views
-1

我正試圖在隱藏模式下創建一個進程(Internet Explorer「iexplore.exe」),但沒有成功。如何在隱藏模式下創建GUI進程?

我曾嘗試用下面的代碼:

#include "stdafx.h" 

BOOL WINAPI GetIePath(LPTSTR Buffer, DWORD Length) 
{ 
    HKEY hKey; 

    if(::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE"), 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) 
     return FALSE; 

    if(::RegQueryValueEx(hKey, NULL, 0, NULL, (LPBYTE)Buffer, &Length) != ERROR_SUCCESS) 
    { 
     ::RegCloseKey(hKey); 
     return FALSE; 
    } 

    ::RegCloseKey(hKey); 
    return TRUE; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    //::ShellExecute(NULL, /*_T("open")*/ NULL, _T("iexplore.exe"), _T("https://www.google.com"), NULL, SW_FORCEMINIMIZE); 

    PROCESS_INFORMATION PI = { 0 }; 
    STARTUPINFO SI = { 0 }; 
    SI.cb = sizeof(STARTUPINFO); 
    SI.dwFlags = STARTF_USESHOWWINDOW; 
    SI.wShowWindow = SW_FORCEMINIMIZE; 

    TCHAR lpsziepath[MAX_PATH] = { 0 }; 

    if (!GetIePath(lpsziepath, MAX_PATH - 1)) 
     return 1; 

    if(!::CreateProcess(lpsziepath, _T("iexplore.exe https://www.google.com") /*::GetCommandLine()*/, NULL, NULL, FALSE, /*CREATE_SUSPENDED*/ 0, NULL, NULL, &SI, &PI)) 
     return 1; 

    //::ResumeThread(PI.hThread); 

    //if ((hwnd = ::FindWindow(_T("IEFrame"), _T("https://www.google.com/ - Internet Explorer") /*NULL*/)) == NULL) 
    // return 1; 

    //::ShowWindow(hwnd, SW_HIDE); 

    return 0; 
} 

SW_HIDE標誌從來沒有爲我工作,而SW_FORCEMINIMIZE的作品,但它並不穩定(並不能保證總是迫使它處於隱藏狀態,它有時在正常狀態下顯示過程「顯示」)。

有沒有更好的方法來做到這一點?

謝謝您的理解。

編輯: 我發現只有第一進程也將被創建隱藏我的代碼,如果我試圖創建一個使用發射exe文件(代碼EXE)所有的IE實例將隨後產生的其它實例正常模式(如圖所示)。

+3

聽起來像[XY問題](http://xyproblem.info/)給我。你最終想要完成什麼? – IInspectable

+2

也許真正的解決方案涉及到根本不啓動IE瀏覽器 –

+1

還要注意'wShowWindow'標誌最好是* advisory *。啓動的應用程序不是*必需的*來履行它。大多數應用程序將會,但有些則不會。 –

回答

0

而不是嘗試在當前桌面上啓動IE,您可以嘗試一種替代方法。 Start IE in a hidden/virtual desktop

查找到CreateDesktopA/W和創建後,你可以以設置到此桌面所有後續調用使用SetThreadDesktop1

從這裏開始,您可以撥打CreateProcessA/W在該桌面上創建一個IE窗口,然後根據需要做任何事情。然後您可以再次撥打SetThreadDesktop將流程執行設置回原始用戶桌面。

在將當前線程上下文移動到新桌面之前,要獲得原始桌面,您可以使用GetThreadDesktopGetCurrentThreadId。然後在完成後使用SetThreadDesktop進行恢復。

CODE

INT WINAPI WinMain(HINSTANCE CurrBase, HINSTANCE PrevBase, LPSTR SomeArgs, INT ShowStatus) { 
    PROCESS_INFORMATION PI = { 0 }; 
    STARTUPINFOW SI = { 0 }; 
    SI.cb = sizeof(STARTUPINFOW); 
    SI.dwFlags = STARTF_USESHOWWINDOW; 
    SI.wShowWindow = SW_FORCEMINIMIZE; 

    WCHAR lpsziepath[MAX_PATH] = { 0 }; 

    if (!GetIePath(lpsziepath, MAX_PATH - 1)) 
     return 1; 
    lpsziepath[lstrlenW(lpsziepath)/* (* sizeof(WCHAR)) */] = UNICODE_NULL; 

    // create the hidden desktop 
    HDESK hiddenDesktop = CreateDesktopA("MyHiddenIEDesktop", NULL, NULL, 0, GENERIC_ALL, NULL); 
    if (hiddenDesktop) { 
     // get the thread for the current desktop 
     HDESK currDesktop = GetThreadDesktop(GetCurrentThreadId()); 
     // move to the hidden desktop 
     if (SetThreadDesktop(hiddenDesktop)) { 
      // Before calling CreateProcessW you need to tell it which desktop to open the process in 
      SI.lpDesktop = TEXT("MyHiddenIEDesktop"); 
      // here processes will with `SI` structure will be created in a hidden "window"/environment 
      CreateProcessW(lpsziepath, TEXT("iexplore.exe https://www.google.com"), NULL, NULL, FALSE, 0, NULL, NULL, &SI, &PI); 
      // Wait until CreateProcessW finishes execution, and then move on afterwards 
      WaitForSingleObject(PI.hProcess, INFINITE); 
      // move back to the original desktop after CreateProcessW is called 
      SetThreadDesktop(currDesktop); 
     } 
    } 
    return EXIT_SUCCESS; 
} 

注意

我剛纔寫的代碼從我的頭頂(因爲我從我的桌面我不在現在),但根據它的外觀對我來說,它會爲你工作!如果有的話,只是玩它。

+0

您的代碼除2個問題外都可以工作:1)** :: CreateProcess **和** :: Sleep(3000)**之後必須等一會兒;否則我會得到一個異常錯誤。 2)將在新桌面中創建** ctfmon.exe **的新實例進程。 – Tomay

+0

1)應該需要睡眠(3000),甚至可能更小,如睡眠(100或200),IE窗口需要在隱藏窗口中註冊自己,然後切換到新的上下文。您可以使用'WaitForSingleObject'來代替它,以便在IE註冊其窗口類並在隱藏桌面上初始化之前,它會等待一段適當的時間(儘可能最短)。 2)ctfmon.exe是在新的隱藏桌面註冊時創建的。這發生在任何給定的情況下。你需要一個rootkit來隱藏它。 3)我已經更新了我的答案,您可以通過給我關於問題的「對號」來接受它。 – 2017-10-13 03:13:06

+0

** WaitForSingleObject **僅在進程完成執行時返回,而不是在註冊其窗口時返回。 – Tomay