Explorer進程被殺後會被Windows重新加載嗎

我很早就發現一個奇怪的現象了,如果你使用任務管理器殺死Explorer.EXE,Windows不會將Explorer.EXE自動喚起,但是如果你自己使用TerminateProcess() 函數結束Explorer.EXE進程,你會發現一個奇怪的現象:被殺死的Explorer.EXE又被Windows自動喚醒了。
在描述具體原因之前,簡單介紹一下Explorer.EXE。Explorer.EXE作爲Windows Shell的組件之一,主要的用途包括有:
  1. 顯示桌面、任務欄
  2. 提供圖形化的文件操作方式(例如大家熟知的資源管理器)
  3. ……
總而言之,沒有Explorer.EXE的Windows不是不能運作,而是操作很不方便。
作爲Windows Shell重要的一環,Explorer.EXE的啓動由註冊表鍵值(Windows 2000/XP/Server 2003):
鍵:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon
鍵名:Shell
默認鍵值:Explorer.EXE
或配置文件system.ini決定(Windows 98/ME):
[Boot]
Shell=Explorer.EXE
需要注意的是,Windows提供了更換Shell的功能,如果上述的配置點不同,那麼Windows會使用其它的Shell,例如把註冊表鍵值更換爲cmd.exe,那麼啓動以後你看到的不是圖形化的操作界面而是命令行提示符(很多軟件更換Shell就是這樣變出來的)。如果上述的配置點出現問題,那麼登陸以後你只能看到一個桌面,而桌面上沒有任何的圖標顯示(有部分計算機病毒會這樣操作)。
在回顧了Explorer.EXE的功能以後,下面進入正題,說說Explorer.EXE進程殺死的問題。
由於某些特殊原因,我們需要在某些時候殺死Explorer.EXE進程以達到某些效果,但是在使用中發現,很多程序,包括著名的IceSword在殺死Explorer.EXE以後,Explorer.EXE都會被Windows自動喚醒。但是如果使用任務管理器(Taskmgr.EXE)或Process Explorer([url]http://www.sysinternals.com[/url]),則沒有這樣的現象,爲什麼呢?
對這2個程序的導入表進行分析和動態跟蹤以後,發現這2個程序在結束進程的時候並沒有使用 Undocumented API,使用的還是已經公開的API函數TerminateProcess(),這就很奇怪了,爲什麼我們使用TerminateProcess()去結束Explorer.EXE會出現Explorer.EXE在結束以後被Windows自動喚醒的問題而任務管理器和Process Explorer不會呢?
先研究一下 TerminateProcess() 的調用方式:
  1. 以 PROCESS_TERMINATE 方式使用 OpenProcess() API或其他等同方法打開進程句柄
  2. 調用 TerminateProcess() API對被打開的句柄執行終止操作
  3. 使用 CloseHandel() API關閉句柄。
整個流程非常簡單,但是問題到底出在哪裏呢?仔細研究所涉及的API的參數,發現在Platform SDK裏面並沒有對TerminateProcess() API的參數有很相信的解釋,特別是第2個參數說的非常模糊。Platform SDK對TerminateProcess() API是這樣解釋的:
BOOL TerminateProcess(
HANDLE hProcess,
UINT uExitCode
);
Parameters
  hProcess 
    [in] Handle to the process to terminate. 
    The handle must have the PROCESS_TERMINATE access right. 
    For more information, see Process Security and Access Rights.
  uExitCode 
    [in] Exit code to be used by the process and threads terminated 
    as a result of this call. Use the GetExitCodeProcess function to 
    retrieve a process's exit value. Use the GetExitCodeThread function 
    to retrieve a thread's exit value. 
    
Return Values
  If the function succeeds, the return value is nonzero.
  If the function fails, the return value is zero. To get extended error 
  information, call GetLastError.
有什麼特殊的地方嗎?看不出來吧,我也看不出來。但是發現:無論任務管理器還是Process Explorer,在傳入第2個參數:uExitCode的時候,傳入的值總是1。1有什麼特殊的含義嗎?我不知道,因爲我沒法得知Windows是否對1有特殊的處理方式。但是從Platform SDK角度看,沒有什麼特殊的發現。
於是我試着創建一個了測試工程用於對TerminateProcess() 的參數進行測試,結果令人大吃一驚:如果我把uExitCode的值設置爲1,然後去結束Explorer.EXE,會發現Windows並沒有自動喚醒Explorer.EXE,但是如果我傳入的值是0,則Windows會在Explorer.EXE結束以後自動將Explorer.EXE喚醒
雖然到目前還是不知道Windows在執行TerminateProcess() 的時候的操作方式(有Windows源代碼就可以知道了),但是經過一些嘗試,關於TerminateProcess() API的一個隱藏點還是暴露了。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章