svchost.exe是什么?
我的svchost.exe文件就在 C:\Windows\System32目錄下
svchost.exe工作過程
在系統(tǒng)啟動的時候,svchost.exe檢查注冊表中的位置來構(gòu)建需要加載的服務(wù)列表。這就會使多個svchost.exe在同一時間運行。一般地,通過在任務(wù)管理器,我們可以看到Windows系統(tǒng)中存在多個“svchost”進(jìn)程。
這些svchost進(jìn)程提供多種系統(tǒng)服務(wù),如:rpcss服務(wù)(remote procedure call)、dmserver服務(wù)(logical disk manager)、dhcp服務(wù)(dhcp client)等。 以常見的,讓人討厭的windows Update 服務(wù)為例子
其中,C:\Windows\System32\svchost.exe-k netsvcs -p 這個路徑當(dāng)然就是啟動服務(wù)的關(guān)鍵信息,但是,后邊的這個-k netsvcs參數(shù)并不是在告訴svchost.exe啟動哪個服務(wù),而是在告訴你wuauserv是屬于netsvcs這個組,正是由于采用了分組機制,系統(tǒng)中才會有多個svchost.exe進(jìn)程,每個進(jìn)程代表一個組,而這個服務(wù)的名稱叫wuauserv并不是顯示的Windows Update,哪個服務(wù)對應(yīng)哪個dll,都是保存在注冊表里的,路徑是計算機\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services
就拿上邊的wuauserv服務(wù)來說,在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services路徑下有一個wuauserv項,名字和服務(wù)名字一樣(也就是說,有多少個服務(wù),這個路徑下就有多少個項,和服務(wù)名稱相對應(yīng)),這個項里里邊又有一個Parameters子項,Parameters子項里有一個名字叫ServiceDll的鍵,它的值就是需要運行的動態(tài)鏈接庫文件(dll)的路徑。如圖:
啟動wuauserv服務(wù)的運行命令在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\wuauserv ,在項中找到類型為“reg_expand_sz”的鍵“Imagepath”的值為%systemroot%\system32\svchost.exe -k netsvcs -p,這就是wuauserv服務(wù)的運行命令,然后在重溫一遍 這個-k netsvcs參數(shù)并不是在告訴svchost.exe啟動哪個服務(wù),而而是告訴你wuauserv是屬于netsvcs這個組
這樣一來,svchost.exe根據(jù)服務(wù)名稱找到相應(yīng)的鍵值,就找到要啟動的dll了,然后在運行它
如果服務(wù)不通過svchost.exe啟動,那么就更簡單,直接在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services路徑下找到和服務(wù)名稱一樣的項,項中有一個叫ImagePath的鍵,這個鍵的值就是服務(wù)exe文件的路徑和啟動參數(shù)。如圖:
接著繼續(xù)分析svchost的分組要注意的是,并不是啟動一個相關(guān)服務(wù)就增加一個svchost進(jìn)程的,而是根據(jù)命令參數(shù)分組,一般是一組服務(wù)就有一個svchost進(jìn)程(上面提到過的)。也就是說,每個svchost.exe會話可以包含一組服務(wù),可以根據(jù)svchost.exe的啟動方式和位置的不同運行不同的服務(wù)。 svchost.exe組的鍵值是: HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\svchost 在其中,我們可以找到上面的例子,就是在netsvcs組下的
svchost原理總結(jié)
例如netsvcs(Windows Update) 在注冊表中的位置是: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\netsvcs,它的參數(shù)子鍵Parameters里有這樣一項: "ServiceDll"=REG_EXPAND_SZ:"%SystemRoot%\system32\wuaueng.dll" 當(dāng)啟動netsvcs服務(wù)時,svchost就會調(diào)用wuaueng.dll,并且執(zhí)行其ServiceMain()函數(shù)執(zhí)行具體服務(wù)。 既然這些服務(wù)是使用共享進(jìn)程方式由svchost啟動的,為什么系統(tǒng)中會有多個svchost進(jìn)程呢?微軟把這些服務(wù)分為幾組,同組服務(wù)共享一個svchost進(jìn)程,不同組服務(wù)使用多個svchost進(jìn)程,組的區(qū)別是由服務(wù)的可執(zhí)行程序后邊的參數(shù)決定的。就是這個
svchost的所有組和組內(nèi)的所有服務(wù)都在注冊表的如下位置: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\svchost,我的電腦上組內(nèi)服務(wù)最多的就是 netsvcs,在啟動一個svchost.exe負(fù)責(zé)的服務(wù)時,服務(wù)管理器如果遇到可執(zhí)行程序內(nèi)容ImagePath已經(jīng)存在于服務(wù)管理器的映象庫中,就不再啟動第2個進(jìn)程svchost,而是直接啟動服務(wù)。這樣就實現(xiàn)了多個服務(wù)共享一個svchost進(jìn)程。
要通過svchost調(diào)用來啟動的服務(wù),就一定要在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost下有該服務(wù)名,這可以通過如下方式來實現(xiàn):(1) 添加一個新的服務(wù)組,在組里添加服務(wù)名; (2) 在現(xiàn)有組里添加服務(wù)名; (3) 直接使用現(xiàn)有服務(wù)組里的一個服務(wù)名,但本機沒有安裝的該服務(wù); (4) 修改現(xiàn)有服務(wù)組里的現(xiàn)有服務(wù),把它的ServiceDll指向自己。 前兩種可以被正常服務(wù)使用,如使用第1種方式,啟動其服務(wù)要創(chuàng)建新的svchost進(jìn)程;第2種方式如果該組服務(wù)已經(jīng)運行,安裝后不能立刻啟動服務(wù),因為svchost啟動后已經(jīng)把該組信息保存在內(nèi)存里,并調(diào)用API StartServiceCtrlDispatcher() 為該組所有服務(wù)注冊了調(diào)度處理函數(shù),新增加的服務(wù)不能再注冊調(diào)度處理函數(shù),需要重啟計算機或者該組的svchost進(jìn)程。 后兩種可能被后門使用,尤其是最后一種,沒有添加服務(wù),只是改了注冊表里一項設(shè)置,從服務(wù)管理控制臺又看不出來,如果作為后門還是很隱蔽的。比如EventSystem服務(wù),缺省是指向es.dll,如果把ServiceDll改為EventSystem.dll就很難發(fā)現(xiàn)。 服務(wù)的安裝除了調(diào)用CreateService()創(chuàng)建服務(wù)之外,還需要設(shè)置服務(wù)的ServiceDll,如果使用前2種還要設(shè)置svchost的注冊表選項,在卸載時也最好刪除增加的部分。 |
|