新增SvcHost.exe 使用的服務原理與實踐
新增SvcHost.exe 使用的服務原理與實踐
1. 多個服務共享一個Svchost.exe行程利與弊 windows 系統服務分為獨立行程和共享行程兩種,在windows NT時只有伺服器管理器SCM(Services.exe)有多個共享服務,隨著系統內裝服務的增加,在windows 2000中ms又把很多服務做成共享方式,由svchost.exe啟動。windows 2000一般有2個svchost行程,一個是RPCSS(Remote Procedure Call)服務行程,另外一個則是由很多服務共享的一個svchost.exe。而在windows XP中,則一般有4個以上的svchost.exe服務行程,windows 2003 server中則更多,可以看出把更多的系統內裝服務以共享行程方式由svchost啟動是ms的一個趨勢。這樣做在一定程度上減少了系統資源的消耗,不過也帶來一定的不穩定因素,因為任何一個共享行程的服務因為錯誤結束行程就會導致整個行程中的所有服務都結束。另外就是有一點安全隱患,首先要介紹一下svchost.exe的實現機制。 2. Svchost原理 Svchost本身只是作為服務宿主,並不實現任何服務功能,需要Svchost啟動的服務以動態連接庫形式實現,在安裝這些服務時,把服務的可執行程序指向svchost,啟動這些服務時由svchost使用相應服務的動態連接庫來啟動服務。 那麼svchost如何知道某一服務是由哪個動態連接庫負責呢?這不是由服務的可執行程序路徑中的參數部分提供的,而是服務在註冊表中的參數設定的,註冊表中服務下邊有一個Parameters子鍵其中的ServiceDll表明該服務由哪個動態連接庫負責。並且所有這些服務動態連接庫都必須要匯出一個ServiceMain()函數,用來處理服務工作。 例如rpcss(Remote Procedure Call)在註冊表中的位置是HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcSs,它的參數子鍵Parameters裡有這樣一項: "ServiceDll"=REG_EXPAND_SZ:"%SystemRoot%\system32\rpcss.dll" 當啟動rpcss服務時,svchost就會使用rpcss.dll,並且執行其ServiceMain()函數執行具體服務。 既然這些服務是使用共享行程方式由svchost啟動的,為什麼系統中會有多個svchost行程呢?ms把這些服務分為幾組,同組服務共享一個svchost行程,不同組服務使用多個svchost行程,組的區別是由服務的可執行程序後邊的參數決定的。 例如rpcss在註冊表中 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcSs 有這樣一項: "ImagePath"=REG_EXPAND_SZ:"%SystemRoot%\system32\svchost -k rpcss" 因此rpcss就屬於rpcss組,這在服務管理控制台也可以看到。 svchost的所有組和組內的所有服務都在註冊表的如下位置: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost,例如windows 2000共有4組rpcss、netsvcs、wugroup、BITSgroup,其中最多的就是netsvcs=REG_MULTI_SZ:EventSystem.Ias.Iprip.Irmon.Netman.Nwsapagent.Rasauto.Rasman.Remoteaccess. SENS.Sharedaccess.Tapisrv.Ntmssvc.wzcsvc.. 在啟動一個svchost.exe負責的服務時,服務管理器如果遇到可執行程序內容ImagePath已經存在於服務管理器的映像庫中,就不在啟動第2個行程svchost,而是直接啟動服務。這樣就實現了多個服務共享一個svchost行程。 3. Svchost程式碼 現在我們基本清楚svchost的原理了,但是要自己寫一個DLL形式的服務,由svchost來啟動,僅有上邊的訊息還有些問題不是很清楚。比如我們在匯出的ServiceMain()函數中接收的參數是ANSI還是Unicode?我們是否需要使用RegisterServiceCtrlHandler和StartServiceCtrlDispatcher來註冊服務控制及調度函數? 這些問題要通過檢視svchost程式碼獲得。下邊的程式碼是windows 2000+ service pack 4 的svchost反彙編片段,可以看出svchost程序還是很簡單的。 函數首先使用ProcCommandLine()對指令行進行分析,獲得要啟動的服務組,然後使用SvcHostOptions()查詢該服務組的選項和服務組的所有服務,並使用一個資料結構 svcTable 來儲存這些服務及其服務的DLL,然後使用PrepareSvcTable() 函數新增SERVICE_TABLE_ENTRY 結構,把所有處理函數SERVICE_MAIN_FUNCTION 指向自己的一個函數FuncServiceMain(),最後使用API StartServiceCtrlDispatcher() 註冊這些服務的調度函數。 ; =============================== Main Funcion =========================================== .text:010010B8 public start .text:010010B8 start proc near .text:010010B8 pushesi .text:010010B9 pushedi .text:010010BA pushoffset sub_1001EBA ; lpTopLevelExceptionFilter .text:010010BF xor edi, edi .text:010010C1 callds:SetUnhandledExceptionFilter .text:010010C7 push1 ; uMode .text:010010C9 callds:SetErrorMode .text:010010CF callds:GetProcessHeap .text:010010D5 pusheax .text:010010D6 callsub_1001142 .text:010010DB mov eax, offset dword_1003018 .text:010010E0 pushoffset unk_1003000 ; lpCriticalSection .text:010010E5 mov dword_100301C, eax .text:010010EA mov dword_1003018, eax .text:010010EF callds:InitializeCriticalSection .text:010010F5 callds:GetCommandLineW .text:010010FB pusheax ; lpString .text:010010FC callProcCommandLine .text:01001101 mov esi, eax .text:01001103 testesi, esi .text:01001105 jzshort lab_doservice .text:01001107 pushesi .text:01001108 callSvcHostOptions .text:0100110D callPrepareSvcTable .text:01001112 mov edi, eax; SERVICE_TABLE_ENTRY returned .text:01001114 testedi, edi .text:01001116 jzshort loc_1001128 .text:01001118 mov eax, [esi+10h] .text:0100111B testeax, eax .text:0100111D jzshort loc_1001128 .text:0100111F pushdword ptr [esi+14h] ; dwCapabilities .text:01001122 pusheax ; int .text:01001123 callInitializeSecurity .text:01001128 .text:01001128 loc_1001128:; CODE XREF: start+5Ej .text:01001128 ; start+65j .text:01001128 pushesi ; lpMem .text:01001129 callHeapFreeMem .text:0100112E .text:0100112E lab_doservice:; CODE XREF: start+4Dj .text:0100112E testedi, edi .text:01001130 jzExitProgram .text:01001136 pushedi ; lpServiceStartTable .text:01001137 callds:StartServiceCtrlDispatcherW .text:0100113D jmp ExitProgram .text:0100113D start endp ; =============================== Main Funcion end =========================================== 由於svchost為該群組的所有服務都註冊了svchost中的一個處理函數,因此每次啟動任何一個服務時,服務管理器SCM都會使用FuncServiceMain() 這個函數。這個函數使用 svcTable 查詢要啟動的服務使用的DLL,使用DLL匯出的ServiceMain()函數來啟動服務,然後返回。 ; ============================== FuncServiceMain() =========================================== .text:01001504 FuncServiceMain proc near ; DATA XREF: PrepareSvcTable+44o .text:01001504 .text:01001504 arg_0 = dword ptr8 .text:01001504 arg_4 = dword ptr0Ch .text:01001504 .text:01001504 pushecx .text:01001505 mov eax, [esp+arg_4] .text:01001509 pushebx .text:0100150A pushebp .text:0100150B pushesi .text:0100150C mov ebx, offset unk_1003000 .text:01001511 pushedi .text:01001512 mov edi, [eax] .text:01001514 pushebx .text:01001515 xor ebp, ebp .text:01001517 callds:EnterCriticalSection .text:0100151D xor esi, esi .text:0100151F cmp dwGroupSize, esi .text:01001525 jbe short loc_1001566 .text:01001527 and [esp+10h], esi .text:0100152B .text:0100152B loc_100152B:; CODE XREF: FuncServiceMain+4Aj .text:0100152B mov eax, svcTable .text:01001530 mov ecx, [esp+10h] .text:01001534 pushdword ptr [eax+ecx] .text:01001537 pushedi .text:01001538 callds:lstrcmpiW .text:0100153E testeax, eax .text:01001540 jzshort StartThis .text:01001542 add dword ptr [esp+10h], 0Ch .text:01001547 inc esi .text:01001548 cmp esi, dwGroupSize .text:0100154E jbshort loc_100152B .text:01001550 jmp short loc_1001566 .text:01001552 ; ================================================= .text:01001552 .text:01001552 StartThis:; CODE XREF: FuncServiceMain+3Cj .text:01001552 mov ecx, svcTable .text:01001558 lea eax, [esi+esi*2] .text:0100155B lea eax, [ecx+eax*4] .text:0100155E pusheax .text:0100155F callGetDLLServiceMain .text:01001564 mov ebp, eax; dll ServiceMain Function address .text:01001566 .text:01001566 loc_1001566:; CODE XREF: FuncServiceMain+21j .text:01001566 ; FuncServiceMain+4Cj .text:01001566 pushebx .text:01001567 callds:LeaveCriticalSection .text:0100156D testebp, ebp .text:0100156F jzshort loc_100157B .text:01001571 push[esp+10h+arg_4] .text:01001575 push[esp+14h+arg_0] .text:01001579 callebp .text:0100157B .text:0100157B loc_100157B:; CODE XREF: FuncServiceMain+6Bj .text:0100157B pop edi .text:0100157C pop esi .text:0100157D pop ebp .text:0100157E pop ebx .text:0100157F pop ecx .text:01001580 retn8 .text:01001580 FuncServiceMain endp ; sp = -8 ; ============================== FuncServiceMain() end ======================================== |
由於svchost已經使用了StartServiceCtrlDispatcher來服務調度函數,因此我們在實現DLL實現時就不用了,這主要是因為一個行程只能使用一次StartServiceCtrlDispatcher API。但是需要用 RegisterServiceCtrlHandler 來註冊回應控制請求的函數。最後我們的DLL接收的都是unicode字元串。
由於這種服務啟動後由svchost載入,不增加新的行程,只是svchost的一個DLL,而且一般進行審計時都不會去HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost 檢查服務組是否變化,就算去檢查,也不一定能發現異常,因此如果增加一個這樣的DLL後門,偽裝的好,是比較隱蔽的。 4. 安裝服務與設定 要通過svchost使用來啟動的服務,就一定要在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost下有該服務名,這可以通過如下方式來實現: 1) 增加一個新的服務組,在組裡增加服務名 2) 在現有組裡增加服務名 3) 直接使用現有服務組裡的一個服務名,但本地機沒有安裝的服務 4) 修改現有服務組裡的現有服務,把它的ServiceDll指向自己 其中前兩種可以被正常服務使用,如使用第1種方式,啟動其服務要新增新的svchost行程;第2種方式如果該群組服務已經執行,安裝後不能立刻啟動服務,因為svchost啟動後已經把該群組訊息儲存在記憶體裡,並使用API StartServiceCtrlDispatcher() 為該群組所有服務註冊了調度處理函數,新增加的服務不能再註冊調度處理函數,需要重新啟動電腦或者該群組的svchost行程。而後兩種可能被後門使用,尤其是最後一種,沒有增加服務,只是改了註冊表裡一項設定,從服務管理控制台又看不出來,如果作為後門還是很隱蔽的。比如EventSystem服務,預設是指向es.dll,如果把ServiceDll改為EventSystem.dll就很難發現。 因此服務的安裝除了使用CreateService()新增服務之外,還需要設定服務的ServiceDll,如果使用前2種還要設定svchost的註冊表選項,在卸載時也最好移除增加的部分。 具體程式碼參見後邊的附例(使用的是方法3)。 註: ImagePath 和ServiceDll 是ExpandString不是普通字元串。因此如果使用.reg文件安裝時要注意。 5. DLL服務實現 DLL程序的編寫比較簡單,只要實現一個ServiceMain()函數和一個服務控制程序,在ServiceMain()函數里用RegisterServiceCtrlHandler()註冊服務控制程序,並設定服務的執行狀態就可以了。 另外,因為此種服務的安裝除了正常的CreateService()之外,還要進行其他設定,因此最好實現安裝和卸載函數。 為了方便安裝,實現的程式碼提供了InstallService()函數進行安裝,這個函數可以接收服務名作為參數(如果不提供參數,就使用預設的iprip),如果要安裝的服務不在svchost的netsvcs組裡安裝就會失敗;如果要安裝的服務已經存在,安裝也會失敗;安裝成功後程序會組態服務的ServiceDll為當前Dll。提供的UninstallService()函數,可以移除任何函數而沒有進行任何檢查。 為了方便使用rundll32.exe進行安裝,還提供了RundllInstallA()和RundllUninstallA()分別使用InstallService()及UninstallService()。因為rundll32.exe使用的函數原型是: void CALLBACK FunctionName( HWND hwnd,// handle to owner window HINSTANCE hinst,// instance handle for the DLL LPTSTR lpCmdLine, // string the DLL will parse int nCmdShow// show state ); 對應的指令行是rundll32 DllName,FunctionName [Arguments] DLL服務本身只是新增一個行程,該程序指令行就是啟動服務時提供的第一個參數,如果未指定就使用預設的svchostdll.exe。啟動服務時如果提供第二個參數,新增的行程就是和桌面交互的。 具體程式碼參見後邊的附例8,來源碼和DLL文件請到http://www.binglesite.net下載。 //main service process function void __stdcall ServiceMain( int argc, wchar_t* argv[] ); //report service stat to the service control manager int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress ); //service control handler, call back by service control manager void __stdcall ServiceHandler( DWORD dwCommand ); //RealService just create a process int RealService(char *cmd, int bInteract); //Install this dll as a Service host by svchost.exe, service name is given by caller int InstallService(char *name); //unInstall a Service, be CARE FOR call this to delete a service int UninstallService(char *name); //Install this dll as a Service host by svchost.exe, used by RUNDLL32.EXE to call void CALLBACK RundllInstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow); //unInstall a Service used by RUNDLL32.EXE to call, be CARE FOR call this to delete a service void CALLBACK RundllUninstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow); //output the debug infor into log file(or stderr if a console program call me) & DbgPrint void OutputString( char *lpFmt, ... ); 6. 程式碼使用 C:\>tlist -s 0 System Process 8 System 240 services.exeSvcs:Browser,Dhcp,dmserver,Dnscache,Eventlog,lanmanserver,lanmanworkstation, LmHosts,PlugPlay,ProtectedStorage,TrkWks,Wmi 504 svchost.exe Svcs:RpcSs 1360 svchost.exe Svcs:EventSystem,Netman,RasMan,SENS,TapiSrv C:\>rundll32 svchostdll.dll,RundllInstall abcd SvcHostDLL: DllMain called DLL_PROCESS_ATTACH you specify service name not in Svchost\netsvcs, must be one of following: - EventSystem - Ias - Iprip - Irmon - Netman - Nwsapagent - Rasauto - Rasman - Remoteaccess - SENS - Sharedaccess - Tapisrv - Ntmssvc - wzcsvc C:\>rundll32 svchostdll.dll,RundllInstall IPRIP SvcHostDLL: DllMain called DLL_PROCESS_ATTACH CreateService(IPRIP) SUCCESS. Config it Config service IPRIP ok. C:\>sc start iprip "cmd /k whoami" 1 NT AUTHORITY\SYSTEM SvcHostDLL: ServiceMain(3, IPRIP) called SvcHostDLL: RealService called 'cmd /k whoami' Interact SvcHostDLL: CreateProcess(cmd /k whoami) to 640 C:\>tlist -s 0 System Process 8 System 240 services.exeSvcs:Browser,Dhcp,dmserver,Dnscache,Eventlog,lanmanserver,lanmanworkstation, LmHosts,PlugPlay,ProtectedStorage,TrkWks,Wmi 504 svchost.exe Svcs:RpcSs 640 cmd.exe Title: C:\WINNT\System32\cmd.exe 1360 svchost.exe Svcs:EventSystem,Netman,RasMan,SENS,TapiSrv,IPRIP C:\>net stop iprip The IPRIP service was stopped successfully. C:\>rundll32 svchostdll.dll,RundllUninstall iprip DeleteService(IPRIP) SUCCESS. 7. 參考 Platform SDK: Tools - Rundll32 1) Inside Win32 Services, Part 2 by: Mark Russinovich, at: http://www.winnetmag.com/Articles/In...leID=8943&pg=3 2) Platform SDK: Tools - Rundll32, at: http://msdn.microsoft.com/library/en...s/rundll32.asp |
8. 程式碼
// SvcHostDLL.cpp : Demo for a service dll used by svchost.exe to host it. // // for detail comment see articles. // by bingle_at_email.com.cn //www.BingleSite.net // /* save following as a .def file to export function, only ServiceMain is needed. other used to install & uninstall service. or use /EXPORT: link option to export them. EXPORTS ServiceMain InstallService UninstallService RundllUninstallA RundllInstallA */ /* To compile & link: cl /MD /GX /LD svchostdll.cpp /link advapi32.lib /DLL /base:0x71000000 /export:ServiceMain EXPORT:RundllUninstallA /EXPORT:RundllInstallA /EXPORT:InstallService /EXPORT:UninstallService */ // //Articles: // 1. HOWTO Create a service dll used by svchost.exe by bingle, at: http://www.BingleSite.net/article/sv...l-service.html // 2. Inside Win32 Services, Part 2 by: Mark Russinovich, at: http://www.winnetmag.com/Articles/In...leID=8943&pg=3 // 3. Platform SDK: Tools - Rundll32, at: http://msdn.microsoft.com/library/en...s/rundll32.asp #include <stdio.h> #include <time.h> #include <assert.h> #include <windows.h> #define DEFAULT_SERVICE "IPRIP" #define MY_EXECUTE_NAME "SvcHostDLL.exe" //main service process function void __stdcall ServiceMain( int argc, wchar_t* argv[] ); //report service stat to the service control manager int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress ); //service control handler, call back by service control manager void __stdcall ServiceHandler( DWORD dwCommand ); //RealService just create a process int RealService(char *cmd, int bInteract); //Install this dll as a Service host by svchost.exe, service name is given by caller int InstallService(char *name); //unInstall a Service, be CARE FOR call this to delete a service int UninstallService(char *name); //Install this dll as a Service host by svchost.exe, used by RUNDLL32.EXE to call void CALLBACK RundllInstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow); //unInstall a Service used by RUNDLL32.EXE to call, be CARE FOR call this to delete a service void CALLBACK RundllUninstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow); //output the debug infor into log file(or stderr if a console program call me) & DbgPrint void OutputString( char *lpFmt, ... ); //dll module handle used to get dll path in InstallService HANDLE hDll = NULL; //Service HANDLE & STATUS used to get service state SERVICE_STATUS_HANDLE hSrv; DWORD dwCurrState; BOOL APIENTRY DllMain( HANDLE hModule, DWORDul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: hDll = hModule; #ifdef _DEBUG AllocConsole(); OutputString("SvcHostDLL: DllMain called DLL_PROCESS_ATTACH"); break; case DLL_THREAD_ATTACH: OutputString("SvcHostDLL: DllMain called DLL_THREAD_ATTACH"); case DLL_THREAD_DETACH: OutputString("SvcHostDLL: DllMain called DLL_THREAD_DETACH"); case DLL_PROCESS_DETACH: TellSCM( SERVICE_STOP_PENDING, 0, 0 ); Sleep(1500); TellSCM( SERVICE_STOPPED, 0, 0 ); OutputString("SvcHostDLL: DllMain called DLL_PROCESS_DETACH"); #endif break; } return TRUE; } void __stdcall ServiceMain( int argc, wchar_t* argv[] ) { //DebugBreak(); char svcname[256]; strncpy(svcname, (char*)argv[0], sizeof svcname); //it's should be unicode, but if it's ansi we do it well wcstombs(svcname, argv[0], sizeof svcname); OutputString("SvcHostDLL: ServiceMain(%d, %s) called", argc, svcname); hSrv = RegisterServiceCtrlHandler( svcname, (LPHANDLER_FUNCTION)ServiceHandler ); if( hSrv == NULL ) { OutputString("SvcHostDLL: RegisterServiceCtrlHandler %S failed", argv[0]); return; }else FreeConsole(); TellSCM( SERVICE_START_PENDING, 0, 1 ); TellSCM( SERVICE_RUNNING, 0, 0 ); // call Real Service function noew if(argc > 1) strncpy(svcname, (char*)argv[1], sizeof svcname), wcstombs(svcname, argv[1], sizeof svcname); RealService(argc > 1 ? svcname : MY_EXECUTE_NAME, argc > 2 ? 1 : 0); do{ Sleep(10);//not quit until receive stop command, otherwise the service will stop }while(dwCurrState != SERVICE_STOP_PENDING && dwCurrState != SERVICE_STOPPED); OutputString("SvcHostDLL: ServiceMain done"); return; } int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress ) { SERVICE_STATUS srvStatus; srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; srvStatus.dwCurrentState = dwCurrState = dwState; srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN; srvStatus.dwWin32ExitCode = dwExitCode; srvStatus.dwServiceSpecificExitCode = 0; srvStatus.dwCheckPoint = dwProgress; srvStatus.dwWaitHint = 3000; return SetServiceStatus( hSrv, &srvStatus ); } void __stdcall ServiceHandler( DWORD dwCommand ) { // not really necessary because the service stops quickly switch( dwCommand ) { case SERVICE_CONTROL_STOP: TellSCM( SERVICE_STOP_PENDING, 0, 1 ); OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_STOP"); Sleep(10); TellSCM( SERVICE_STOPPED, 0, 0 ); break; case SERVICE_CONTROL_PAUSE: TellSCM( SERVICE_PAUSE_PENDING, 0, 1 ); OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_PAUSE"); TellSCM( SERVICE_PAUSED, 0, 0 ); break; case SERVICE_CONTROL_CONTINUE: TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 ); OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_CONTINUE"); TellSCM( SERVICE_RUNNING, 0, 0 ); break; case SERVICE_CONTROL_INTERROGATE: OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_INTERROGATE"); TellSCM( dwCurrState, 0, 0 ); break; case SERVICE_CONTROL_SHUTDOWN: OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_SHUTDOWN"); TellSCM( SERVICE_STOPPED, 0, 0 ); break; } } //RealService just create a process int RealService(char *cmd, int bInteract) { OutputString("SvcHostDLL: RealService called '%s' %s", cmd, bInteract ? "Interact" : ""); STARTUPINFO si = {0}; PROCESS_INFORMATION pi; si.cb = sizeof si; if(bInteract) si.lpDesktop = "WinSta0\\Default"; if(!CreateProcess(NULL, cmd, NULL, NULL, false, 0, NULL, NULL, &si, &pi)) OutputString("SvcHostDLL: CreateProcess(%s) error:%d", cmd, GetLastError()); else OutputString("SvcHostDLL: CreateProcess(%s) to %d", cmd, pi.dwProcessId); return 0; } |
int InstallService(char *name)
{ // Open a handle to the SC Manager database. int rc = 0; HKEY hkRoot = HKEY_LOCAL_MACHINE, hkParam = 0; SC_HANDLE hscm = NULL, schService = NULL; try{ char buff[500]; char *svcname = DEFAULT_SERVICE; if(name && name[0]) svcname = name; //query svchost setting char *ptr, *pSvchost = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"; rc = RegOpenKeyEx(hkRoot, pSvchost, 0, KEY_QUERY_value, &hkRoot); if(ERROR_SUCCESS != rc) { OutputString("RegOpenKeyEx(%s) KEY_QUERY_value error %d.", pSvchost, rc); throw ""; } DWORD type, size = sizeof buff; rc = RegQueryvalueEx(hkRoot, "netsvcs", 0, &type, (unsigned char*)buff, &size); RegCloseKey(hkRoot); SetLastError(rc); if(ERROR_SUCCESS != rc) throw "RegQueryvalueEx(Svchost\\netsvcs)"; for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1) if(stricmp(ptr, svcname) == 0) break; if(*ptr == 0) { OutputString("you specify service name not in Svchost\\netsvcs, must be one of following:"); for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1) OutputString(" - %s", ptr); throw ""; } //install service hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hscm == NULL) throw "OpenSCManager()"; char *bin = "%SystemRoot%\\System32\\svchost.exe -k netsvcs"; schService = CreateService( hscm,// SCManager database svcname,// name of service NULL, // service name to display SERVICE_ALL_ACCESS,// desired access SERVICE_WIN32_SHARE_PROCESS, // service type SERVICE_AUTO_START,// start type SERVICE_ERROR_NORMAL,// error control type bin,// service's binary NULL,// no load ordering group NULL,// no tag identifier NULL,// no dependencies NULL,// LocalSystem account NULL); // no password if (schService == NULL) { OutputString("CreateService(%s) error %d", svcname, rc = GetLastError()); throw ""; } OutputString("CreateService(%s) SUCCESS. Config it", svcname); CloseServiceHandle(schService); CloseServiceHandle(hscm); //config service hkRoot = HKEY_LOCAL_MACHINE; strncpy(buff, "SYSTEM\\CurrentControlSet\\Services\\", sizeof buff); strncat(buff, svcname, 100); rc = RegOpenKeyEx(hkRoot, buff, 0, KEY_ALL_ACCESS, &hkRoot); if(ERROR_SUCCESS != rc) { OutputString("RegOpenKeyEx(%s) KEY_SET_value error %d.", svcname, rc); throw ""; } rc = RegCreateKey(hkRoot, "Parameters", &hkParam); SetLastError(rc); if(ERROR_SUCCESS != rc) throw "RegCreateKey(Parameters)"; if(!GetModuleFileName(HMODULE(hDll), buff, sizeof buff)) throw "GetModuleFileName() get dll path"; rc = RegSetvalueEx(hkParam, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)buff, strlen(buff)+1); SetLastError(rc); if(ERROR_SUCCESS != rc) throw "RegSetvalueEx(ServiceDll)"; OutputString("Config service %s ok.", svcname); }catch(char *str) { if(str && str[0]) { rc = GetLastError(); OutputString("%s error %d", str, rc); } } RegCloseKey(hkRoot); RegCloseKey(hkParam); CloseServiceHandle(schService); CloseServiceHandle(hscm); return rc; } /* used to install by rundll32.exe Platform SDK: Tools - Rundll32 The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax: */ void CALLBACK RundllInstallA( HWND hwnd,// handle to owner window HINSTANCE hinst,// instance handle for the DLL char *param,// string the DLL will parse int nCmdShow// show state ) { InstallService(param); } int UninstallService(char *name) { int rc = 0; SC_HANDLE schService; SC_HANDLE hscm; __try{ hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hscm == NULL) { OutputString("OpenSCManager() error %d", rc = GetLastError() ); return rc; } char *svcname = DEFAULT_SERVICE; if(name && name[0]) svcname = name; schService = OpenService(hscm, svcname, DELETE); if (schService == NULL) { OutputString("OpenService(%s) error %d", svcname, rc = GetLastError() ); return rc; } if (!DeleteService(schService) ) { OutputString("OpenService(%s) error %d", svcname, rc = GetLastError() ); return rc; } OutputString("DeleteService(%s) SUCCESS.", svcname); }__except(1) { OutputString("Exception Catched 0x%X", GetExceptionCode()); } CloseServiceHandle(schService); CloseServiceHandle(hscm); return rc; } /* used to uninstall by rundll32.exe Platform SDK: Tools - Rundll32 The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax: */ void CALLBACK RundllUninstallA( HWND hwnd,// handle to owner window HINSTANCE hinst,// instance handle for the DLL char *param,// string the DLL will parse int nCmdShow// show state ) { UninstallService(param); } //output the debug infor into log file & DbgPrint void OutputString( char *lpFmt, ... ) { char buff[1024]; va_listarglist; va_start( arglist, lpFmt ); _vsnprintf( buff, sizeof buff, lpFmt, arglist ); va_end( arglist ); DWORD len; HANDLE herr = GetStdHandle(STD_OUTPUT_HANDLE); if(herr != INVALID_HANDLE_value) { WriteFile(herr, buff, strlen(buff), &len, NULL); WriteFile(herr, "\r\n", 2, &len, NULL); }else { FILE *fp = fopen("SvcHost.DLL.log", "a"); if(fp) { char date[20], time[20]; fprintf(fp, "%s %s - %s\n", _strdate(date), _strtime(time), buff); if(!stderr) fclose(fp); } } OutputDebugString(buff); } |
淺析svchost.exe工作,辨明真假svchost.exe
微軟是這樣描述svchost.exe的:svchost.exe 是從動態連接庫 (DLL) 中執行的服務通用主機工作名稱。那麼........ 為什麼有svchost.exe是病毒這種說法呢? 因為svchost.exe可以作為服務的宿主來啟動服務,所以病毒、木馬的編寫者也挖空心思的要利用svchost.exe的這個特性來迷惑用戶達到入侵、破壞電腦的目的。 svchost.exe是一個系統的核心工作,並不是病毒工作。但由於svchost.exe工作的特殊性,所以病毒也會千方百計的入侵svchost.exe。通過察看svchost.exe工作的執行路徑可以驗證是否中毒。如何才能辨別哪些是正常的svchost.exe工作,而哪些是病毒工作呢? 1、svchost.exe的鍵值是在HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrentVersionSvchost」,每個鍵值表示一個獨立的svchost.exe組。 2、通過搜尋svchost.exe文件就可以發現異常情況。一般只會找到一個在:「C:WindowsSystem32」目錄下的svchost.exe程序。如果你在其它目錄下發現svchost.exe程序的話,那很可能就是中毒了。 3、在工作管理器中察看工作的執行路徑。但是由於在Windows系統原有的的工作管理器不能察看工作路徑,所以要使用第三方的工作察看工具。 svchost.exe到底是做什麼用的呢? 首先我們要瞭解一點那就是Windows系統的中的工作分為:獨立工作和共享工作這兩種。由於Windows系統中的服務越來越多,為了節約有限的系統資源微軟把很多的系統服務做成了共享模式。那svchost.exe在這中間是擔任怎樣一個角色呢? svchost.exe的工作就是作為這些服務的宿主,即由svchost.exe來啟動這些服務。svchost.exe只是負責為這些服務提供啟動的條件,其自身並不能實現任何服務的功能,也不能為用戶提供任何服務。svchost.exe通過為這些系統服務使用動態連接庫(DLL)的方式來啟動系統服務。 svchost.exe Windows中的系統服務是以動態連接庫(DLL)的形式實現的,其中一些會把可執行程序指向svchost.exe,由它使用相應服務的動態連接庫並加上相應參數來啟動服務。正是因為它的特殊性和重要性,使它更容易成為了一些病毒木馬的宿主。 其實svchost.exe是Windows XP系統的一個核心工作。svchost.exe不單單只出現在Windows XP中,在使用NT內核的Windows系統中都會有svchost.exe的存在。一般在Windows 2000中svchost.exe工作的數目為2個,而在Windows XP中svchost.exe工作的數目就上升到了4個及4個以上。所以看到系統的工作列表中有幾個svchost.exe不用那麼擔心。 |
svchost.exe是nt核心系統的非常重要的工作行程,對於2000、xp來說,不可或缺。很多病毒、木馬也會調用它。所以,深入瞭解這個程式,是玩電腦的必修課之一。
大家對windows操作系統一定不陌生,但你是否注意到系統中「svchost.exe」這個文件呢?細心的朋友會發現windows中存在多個 「svchost」工作行程(通過「ctrl+alt+del」鍵打開任務管理器,這裡的「工作行程」標籤中就可看到了),為什麼會這樣呢?下面就來揭開它神秘的面紗。 發現 在基於nt內核的windows操作系統家族中,不同版本的windows系統,存在不同數量的「svchost」工作行程,用戶使用「任務管理器」可檢視其工作行程數目。一般來說,win2000有兩個svchost工作行程,winxp中則有四個或四個以上的sv chost工作行程(以後看到系統中有多個這種工作行程,千萬別立即判定系統有病毒了喲),而win2003 server中則更多。這些svchost工作行程提供很多系統服務,如:rpcss服務(remote procedure call)、dmserver服務(logical disk manager)、dhcp服務(dhcp client)等。 如果要瞭解每個svchost工作行程到底提供了多少系統服務,可以在win2000的命令提示字元視窗中輸入「tlist -s」命令來檢視,該命令是win2000 support tools提供的。在winxp則使用「tasklist /svc」命令。 svchost中可以包含多個服務 深入 windows系統工作行程分為獨立工作行程和共享工作行程兩種,「svchost.exe」文件存在於「%systemroot% system32」目錄下,它屬於共享工作行程。隨著windows系統服務不斷增多,為了節省系統資源,微軟把很多服務做成共享方式,交由 svchost.exe工作行程來啟動。但svchost工作行程只作為服務宿主,並不能實現任何服務功能,即它只能提供條件讓其他服務在這裡被啟動,而它自己卻不能給用戶提供任何服務。那這些服務是如何實現的呢? 原來這些系統服務是以動態鏈接庫(dll)形式實現的,它們把可執行程式指向 svchost,由svchost調用相應服務的動態鏈接庫來啟動服務。那svchost又怎麼知道某個系統服務該調用哪個動態鏈接庫呢?這是通過系統服務在註冊表中設置的參數來實現。下面就以rpcss(remote procedure call)服務為例,進行講解。 從啟動參數中可見服務是靠svchost來啟動的。 實例 以windows xp為例,點擊「開始」/「執行」,輸入「services.msc」命令,彈出服務對話框,然後打開「remote procedure call」內容對話框,可以看到rpcss服務的可執行文件的路徑為「c:\windows\system32\svchost -k rpcss」,這說明rpcss服務是依靠svchost調用「rpcss」參數來實現的,而參數的內容則是存放在系統註冊表中的。 在執行對話框中輸入「regedit.exe」後Enter鍵,打開註冊表編輯器,找到[hkey_local_machine systemcurrentcontrolsetservicesrpcss]項,找到類型為「reg_expand_sz」的鍵「magepath」,其鍵值為「%systemroot%system32svchost -k rpcss」(這就是在服務視窗中看到的服務啟動命令),另外在「parameters」子項中有個名為「servicedll」的鍵,其值為「% systemroot%system32rpcss.dll」,其中「rpcss.dll」就是rpcss服務要使用的動態鏈接庫文件。這樣 svchost工作行程通過讀取「rpcss」服務註冊表訊息,就能啟動該服務了。 |
電腦高手必修 SVCHOST.exe工作行程
svchost.exe是nt核心系統的非常重要的工作行程,對於2000、xp來 說,不可或缺。很多病毒、木馬也會呼叫它。所以,深入瞭解 這個程式,是玩電腦的必修課之一。 大家對windows操作系統一定不陌生,但你是否注意到系 統中「svchost.exe」這個文件呢?細心的朋友會發現windows 中存在多個 「svchost」工作行程(通過「ctrl+alt+del」鍵打開任務管理器, 這裡的「工作行程」標籤中就可看到了),為什麼會這樣呢?下面 就來揭開它神秘的面紗。 發現 在基於nt內核的windows操作系統家族中,不同版本的 windows系統,存在不同數量的「svchost」工作行程,用戶使用「 任務管理器」可檢視其工作行程數目。一般來說,win2000有兩個 svchost工作行程,winxp中則有四個或四個以上的svchost工作行程,而 win2003 server中則更多。這些svchost工作行程提供很多系統服務,如: rpcss服務(remote procedure call)、dmserver服務(logical disk manager)、dhcp服務 (dhcp client)等。 如果要瞭解每個svchost工作行程到底提供了多少系統服務, 可以在win2000的命令提示字元視窗中輸入「tlist -s」命令來查 看,該命令是win2000 support tools提供的。在winxp則使用「tasklist /svc」命令 。 svchost中可以包含多個服務 深入 windows系統工作行程分為獨立工作行程和共享工作行程兩種, 「svchost.exe」文件存在於「%systemroot% system32」目錄下,它屬於共享工作行程。隨著windows系統服務不 斷增多,為了節省系統資源,微軟把很多服務做成共享方式, 交由 svchost.exe工作行程來啟動。但svchost工作行程只作為服務宿主,並 不能實現任何服務功能,那這些服務是如何實現的呢? 原來這些系統服務是以動態鏈接庫(dll)形式實現的 ,它們把可執行程式指向 svchost,由svchost呼叫相應服務的動態鏈接庫來啟動服務。 那svchost又怎麼知道某個系統服務該呼叫哪個動態鏈接庫呢? 這是通過系統服務在註冊表中設置的參數來實現。下面來說說 rpcss(remote procedure call)服務的例子吧。 從啟動參數中可見服務是靠svchost來啟動的。 實例 以windows xp為例,點擊「開始」/「執行」,輸入 「services.msc」命令,彈出服務交談視窗,然後打開「remote procedure call」內容交談視窗,可以看到rpcss服務的可執行文件的路徑為 「c:windowssystem32svchost -k rpcss」,這說明rpcss服務是依靠svchost呼叫「rpcss」參數 來實現的,而參數的內容則是存放在系統註冊表中的。 在執行交談視窗中輸入「regedit.exe」後Enter鍵,打開注 冊表編輯器,找到[hkey_local_machine systemcurrentcontrolsetservicesrpcss]項,找到類型為 「reg_expand_sz」的鍵「magepath」,其鍵值為「% systemroot%system32svchost -k rpcss」(這就是在服務視窗中看到的服務啟動命令),另 外在「parameters」子項中有個名為「servicedll」的鍵,其 值為「% systemroot%system32rpcss.dll」,其中「rpcss.dll」就是 rpcss服務要使用的動態鏈接庫文件。這樣 svchost工作行程通過讀取「rpcss」服務註冊表訊息,就能啟動該 服務了。 解惑 因為svchost工作行程啟動各種服務,所以病毒、木馬也想 盡辦法來利用它,企圖利用它的特性來迷惑用戶,達到感染、 入侵、破壞的目的(如衝擊波變種病毒「w32.welchia.worm」 )。但windows系統存在多個svchost工作行程是很正常的,在受感 染的機器中到底哪個是病毒工作行程呢?這裡僅舉一例來說明。 假設windows xp系統被「w32.welchia.worm」感染了。正常的svchost文件存 在於「c:windowssystem32」目錄下,如果發現該文件出現在其 他目錄下就要小心了。「w32.welchia.worm」病毒存在於 「c:windowssystem32wins」目錄中,因此使用工作行程管理器檢視 svchost工作行程的執行文件路徑就很容易發現系統是否感染了病毒 。 windows系統自帶的任務管理器不能夠檢視工作行程的路徑,可以使 用第三方工作行程管理軟件,如「windows優化大師」工作行程管理器, 通過這些工具就可很容易地檢視到所有的svchost工作行程的執行文 件路徑,一旦發現其執行路徑為不平常的位置就應該馬上進行 檢測和處理。 |
關於Svchost工作行程概述
在基於NT內核的Windows操作系統家族中,Svchost.exe是一個非常重要的工作行程。很多病毒、木馬駐留系統與這個工作行程密切相關,因此深入瞭解該工作行程是非常有必要的。本文主要介紹Svchost工作行程的功能,以及與該工作行程相關的知識。 Svchost工作行程概述 微軟對「Svchost工作行程」的定義是:Svchost.exe是從動態鏈接庫(DLL)中執行的服務的通用主機工作行程名稱。Svchost.exe文件位於「%SystemRoot%System32」資料夾中。當系統啟動時,Svchost將檢查註冊表中的服務部分,以構建需要載入的服務列表。Svchost的多個實例可以同時執行。每個Svchost會話可以包含一組服務,以便根據Svchost的啟動方式和位置的不同執行不同的服務,這樣可以更好地進行控制且更加便於除錯。 Svchost組是由註冊表[HKEY_LOCAL_MACHINE SoftwareMicrosoftWindows NTCurrentVersionSvchost]項來識別的。在這個註冊表項下的每個值都代表單獨的Svchost組,並在我們檢視活動工作行程時作為單獨的實例顯示。這裡的鍵值均為REG_MULTI_SZ類型的值,並且包含該Svchost組裡執行的服務名稱(如圖1)。 圖1 註冊表中的Svchost 實際上,Svchost只是作為服務的宿主,本身並不實現什麼功能。如果需要使用Svchost來啟動某個DLL形式實現的服務,該DLL的載體Loader指向Svchost,在啟動服務的時候由Svchost呼叫該服務的DLL來實現啟動的目的。使用Svchost啟動某個服務的DLL文件是由註冊表中的參數來決定的,在需要啟動服務的註冊表項下都有一個「Parameters」子項,其中的「ServiceDll」鍵值表明該服務由哪個DLL文件負責,並且這個DLL文件必須匯出一個ServiceMain()函數,為處理服務任務提供支持。 提示:不同版本的Windows系統,存在不同數量的Svchost工作行程。一般來說,Windows 2000有兩個Svchost工作行程,而Windows XP則有四個或四個以上的Svchost工作行程。 Svchost工作行程實例講解 要想檢視在Svchost中執行服務的列表,可以在Windows XP命令提示字元視窗中輸入「Tasklist /svc」命令後,Enter鍵執行(如果使用的是Windows 2000,可用Support Tools提供的Tlist工具檢視,命令為「Tlist -s」)。Tasklist命令顯示活動工作行程的列表,/svc命令開關指定顯示每個工作行程中活動服務的列表。從圖中可以看到,Svchost工作行程啟動很多系統服務,如:RpcSs(Remote Procedure Call)、Dhcp(DHCP Client)、Netman(Network Connections)服務等等(如圖2)。 圖2 Svchost的服務列表 這裡我們以RpcSs服務為例,來具體瞭解一下Svchost工作行程與服務的關係。執行Regedit,打開註冊表編輯器,依次展開[HKEY_LOCAL_MACHINESYSTEM CurrentControlSetServicesRpcSs ]分支,在「Parameters」子項中有個名為「ServiceDll」的鍵,其值為「%SystemRoot%system32 pcss.dll」。這表示系統啟動RpcSs服務時,呼叫「%SystemRoot%system32」目錄下的Rpcss.dll動態鏈接庫文件。 接下來,從控制台中依次雙擊「管理工具→服務」,打開服務控制台。在右側視窗內中雙擊「Remote Procedure Call(RPC)」服務項,打開其內容交談視窗,可以看到RpcSs服務的可執行文件的路徑為「C:Windowssystem32svchost -k rpcss」,這說明RpcSs服務是依靠Svchost啟動的,「-k rpcss」表示此服務包含在Svchost的Rpcss服務組中。 Svchost工作行程木馬淺析 從前面的介紹我們已經知道,在註冊表[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrent- VersionSvchost]分支中,存放著Svchost啟動的組和組內的各項服務,很多木馬和病毒正是利用這一點來實現自動載入的。它們通常的方法有: · 新增一個新的組,在組裡新增服務名; · 在現有的組裡新增服務名或者利用現有組一個未安裝的服務; · 修改現有組裡的服務,將它的ServiceDll指向自己的DLL文件。 例如PortLess BackDoor就是一款典型的利用Svchost工作行程載入的後門工具。那麼對於像PortLess BackDoor這樣的木馬、病毒,該如何檢測並清除呢?以Windows XP為例,首先我們可以利用「工作行程間諜」這樣的工作行程工具檢視Svchost工作行程中的模塊訊息(如圖3),並與之前的模塊訊息比較,可以發現Svchost工作行程中有一個可疑的DLL文件「SvchostDLL.dll」。同時,在「管理工具→服務」列表中會看到一項新的服務「Intranet Services」(顯示名稱),此服務名稱為:Iprip,由Svchost啟動,「-k netsvcs」表示此服務包含在Netsvcs服務組中。 圖3 Svchost工作行程中的模塊訊息 提示:在Windows 2000中,系統的Iprip服務偵聽由使用Routing Information協議版本1(RIPv1)的路由器發送的路由更新訊息,在服務列表中顯示的名稱為「RIP Listener」。 執行Regedit,打開註冊表編輯器,展開[HKEY_LOCAL_MACHINESYSTEMCurrentControlSet ServicesIPRIP]分支,檢視其「Parameters」子項,其中「ServiceDll」鍵值指向呼叫的DLL文件路徑和全稱,這正是後門的DLL文件。知道了這些,就可以動手清除了:在服務列表用右鍵單擊「Intranet Services」服務,從表表菜單中選擇「停止」,然後在上述註冊表分支中刪除「Iprip」項。重新啟動電腦,再按照「ServiceDll」鍵值提示的位置刪除後門程式主文件即可。最後需要提醒讀者的是,對註冊表進行修改前,應做好備份工作,以便出現錯誤時能夠及時還原。 |
Svchost工作行程揭秘
在基於NT內核的Windows操作系統家族中,Svchost.exe是一個非常重要的工作行程。很多病毒、木馬駐留系統與這個工作行程密切相關,因此深入瞭解該工作行程是非常有必要的。本文主要介紹Svchost工作行程的功能,以及與該工作行程相關的知識。 Svchost工作行程概述 微軟對「Svchost工作行程」的定義是:Svchost.exe是從動態鏈接庫(DLL)中執行的服務的通用主機工作行程名稱。Svchost.exe文件位於「%SystemRoot%\System32」資料夾中。當系統啟動時,Svchost將檢查註冊表中的服務部分,以構建需要載入的服務列表。Svchost的多個實例可以同時執行。每個Svchost會話可以包含一組服務,以便根據Svchost的啟動方式和位置的不同執行不同的服務,這樣可以更好地進行控制且更加便於除錯。 Svchost組是由註冊表[HKEY_LOCAL_MACHINE\ Software\Microsoft\Windows NT\CurrentVersion\Svchost]項來識別的。在這個註冊表項下的每個值都代表單獨的Svchost組,並在我們檢視活動工作行程時作為單獨的實例顯示。這裡的鍵值均為REG_MULTI_SZ類型的值,並且包含該Svchost組裡執行的服務名稱(如圖1)。 圖1 註冊表中的Svchost 實際上,Svchost只是作為服務的宿主,本身並不實現什麼功能。如果需要使用Svchost來啟動某個DLL形式實現的服務,該DLL的載體Loader指向Svchost,在啟動服務的時候由Svchost呼叫該服務的DLL來實現啟動的目的。使用Svchost啟動某個服務的DLL文件是由註冊表中的參數來決定的,在需要啟動服務的註冊表項下都有一個「Parameters」子項,其中的「ServiceDll」鍵值表明該服務由哪個DLL文件負責,並且這個DLL文件必須匯出一個ServiceMain()函數,為處理服務任務提供支持。 提示:不同版本的Windows系統,存在不同數量的Svchost工作行程。一般來說,Windows 2000有兩個Svchost工作行程,而Windows XP則有四個或四個以上的Svchost工作行程。 Svchost工作行程實例講解 要想檢視在Svchost中執行服務的列表,可以在Windows XP命令提示字元視窗中輸入「Tasklist /svc」命令後,Enter鍵執行(如果使用的是Windows 2000,可用Support Tools提供的Tlist工具檢視,命令為「Tlist -s」)。Tasklist命令顯示活動工作行程的列表,/svc命令開關指定顯示每個工作行程中活動服務的列表。從圖中可以看到,Svchost工作行程啟動很多系統服務,如:RpcSs(Remote Procedure Call)、Dhcp(DHCP Client)、Netman(Network Connections)服務等等(如圖2)。 圖2 Svchost的服務列表 這裡我們以RpcSs服務為例,來具體瞭解一下Svchost工作行程與服務的關係。執行Regedit,打開註冊表編輯器,依次展開[HKEY_LOCAL_MACHINE\SYSTEM\ CurrentControlSet\Services\RpcSs ]分支,在「Parameters」子項中有個名為「ServiceDll」的鍵,其值為「%SystemRoot%\system32\rpcss.dll」。這表示系統啟動RpcSs服務時,呼叫「%SystemRoot%\system32」目錄下的Rpcss.dll動態鏈接庫文件。 接下來,從控制台中依次雙擊「管理工具→服務」,打開服務控制台。在右側視窗內中雙擊「Remote Procedure Call(RPC)」服務項,打開其內容交談視窗,可以看到RpcSs服務的可執行文件的路徑為「C:\Windows\system32\svchost -k rpcss」,這說明RpcSs服務是依靠Svchost啟動的,「-k rpcss」表示此服務包含在Svchost的Rpcss服務組中。 Svchost工作行程木馬淺析 從前面的介紹我們已經知道,在註冊表[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Current- Version\Svchost]分支中,存放著Svchost啟動的組和組內的各項服務,很多木馬和病毒正是利用這一點來實現自動載入的。它們通常的方法有: · 新增一個新的組,在組裡新增服務名; · 在現有的組裡新增服務名或者利用現有組一個未安裝的服務; · 修改現有組裡的服務,將它的ServiceDll指向自己的DLL文件。 例如PortLess BackDoor就是一款典型的利用Svchost工作行程載入的後門工具。那麼對於像PortLess BackDoor這樣的木馬、病毒,該如何檢測並清除呢?以Windows XP為例,首先我們可以利用「工作行程間諜」這樣的工作行程工具檢視Svchost工作行程中的模塊訊息(如圖3),並與之前的模塊訊息比較,可以發現Svchost工作行程中有一個可疑的DLL文件「SvchostDLL.dll」。同時,在「管理工具→服務」列表中會看到一項新的服務「Intranet Services」(顯示名稱),此服務名稱為:Iprip,由Svchost啟動,「-k netsvcs」表示此服務包含在Netsvcs服務組中。 圖3 Svchost工作行程中的模塊訊息 提示:在Windows 2000中,系統的Iprip服務偵聽由使用Routing Information協議版本1(RIPv1)的路由器發送的路由更新訊息,在服務列表中顯示的名稱為「RIP Listener」。 執行Regedit,打開註冊表編輯器,展開[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\IPRIP]分支,檢視其「Parameters」子項,其中「ServiceDll」鍵值指向呼叫的DLL文件路徑和全稱,這正是後門的DLL文件。知道了這些,就可以動手清除了:在服務列表用右鍵單擊「Intranet Services」服務,從表菜單中選擇「停止」,然後在上述註冊表分支中刪除「Iprip」項。重新啟動電腦,再按照「ServiceDll」鍵值提示的位置刪除後門程式主文件即可。最後需要提醒讀者的是,對註冊表進行修改前,應做好備份工作,以便出現錯誤時能夠及時還原。 |
說說Windows的兩大工作行程:Explorer與Svchost.exe
在本文中我將著重介紹一下Windows系統的Svchost.exe和Explorer.exe兩種工作行程,作為Windows系統中兩種重要的工作行程,下面我們就來看看他們的特點以及在各個操作系統中的應用。 Explorer 在Windows系列的操作系統中,執行時都會啟動一個名為Explorer.exe的工作行程。這個工作行程主要負責顯示系統桌面上的圖示以及任務欄,它在不同的系統中有不同的妙用。 Explorer在Windows 9x中的應用 在Windows 9x中,這個工作行程是執行系統時所必需的。如果用「結束任務」的方法來結束Explorer.exe工作行程,系統就會重新整理桌面,並更新註冊表。所以,我們也可以利用此方法來快速更新註冊表。方法如下: 按下Ctrl+Alt+Del組合鍵,出現「結束任務」交談視窗。在該交談視窗中選擇「Explorer」選項,然後單擊「結束任務」按鈕,將出現「關閉Windows」交談視窗。單擊「否」按鈕,系統過一會兒將出現另一個交談視窗,告訴你該程式沒有響應,詢問是否結束任務。單擊「結束任務」按鈕,則更新註冊表並返回Windows 9x系統環境中。這比起煩瑣的重新啟動過程要方便多了? Explorer在Windows 2000/XP中的應用 在Windows 2000/XP和其他Windows NT內核的系統中,Explorer.exe工作行程並不是系統執行時所必需的,所以可以用任務管理器來結束它,並不影響系統的正常工作。打開你需要執行的程式,如記事本。然後右擊任務欄,選擇「任務管理器」,選中「工作行程」選擇項,在視窗中選擇Explorer.exe工作行程,單擊「結束工作行程」按鈕,,接下來桌面上除了壁紙(活動桌面Active Desktop的壁紙除外),所有圖示和任務欄都消失了。此時你仍可以像平常一樣操作一切軟件。 如果你想執行其他軟件,但此時桌面上空無一物,怎麼辦?別著急,下面有兩種可以巧妙地打開其他軟件: 第一種方法:按下Ctrl+Alt+Del組合鍵,出現「Windows安全」交談視窗,單擊「任務管理器」按鈕(或是直接按下Ctrl+Shift+Esc組合鍵),在任務管理器視窗中選中「應用程式」選擇項,單擊「新任務」,在彈出的「創建新任務」的交談視窗中,輸入你想要打開的軟件的路徑和名稱即可。 你還可以在正在執行的軟件上,選擇「文件→打開」,在「打開」交談視窗中,點擊「文件類型」下拉列表,選擇「所有文件」,再瀏覽到你想打開的軟件,右擊它,在快捷表菜單中選擇「打開」命令,就可以啟動你需要的軟件了。注意,此時不能夠通過單擊「打開」按鈕來打開軟件,此種方法適用於大多數軟件,Office系列除外。 通過結束Explorer.exe工作行程,還可以減少4520KB左右的系統已使用記憶體,無疑會加快系統的執行速度,為資源緊張的用戶騰出了寶貴的空間。 Svchost.exe Svchost.exe是NT核心系統的非常重要的工作行程,對於2000、XP來說,不可或缺。很多病毒、木馬也會呼叫它。所以,深入瞭解這個程式,是玩電腦的必修課之一。 大家對Windows操作系統一定不陌生,但你是否注意到系統中「Svchost.exe」這個文件呢?細心的朋友會發現Windows中存在多個 「Svchost」工作行程(通過「ctrl+alt+del」鍵打開任務管理器,這裡的「工作行程」標籤中就可看到了),為什麼會這樣呢?下面就來揭開它神秘的面紗。 在基於NT內核的Windows操作系統家族中,不同版本的Windows系統,存在不同數量的「Svchost」工作行程,用戶使用「任務管理器」可檢視其工作行程數目。一般來說,Win 2000有兩個Svchost工作行程,Win XP中則有四個或四個以上的Svchost工作行程(以後看到系統中有多個這種工作行程,千萬別立即判定系統有病毒了喲),而Win 2003 server中則更多。這些Svchost工作行程提供很多系統服務,如:rpcss服務(remote procedure call)、dmserver服務(logical disk manager)、dhcp服務(dhcp clieNT)等。 如果要瞭解每個Svchost工作行程到底提供了多少系統服務,可以在Win 2000的命令提示字元視窗中輸入「tlist -s」命令來檢視,該命令是Win 2000 support tools提供的。在Win XP則使用「tasklist /svc」命令。 Svchost中可以包含多個服務 Windows系統工作行程分為獨立工作行程和共享工作行程兩種,「Svchost.exe」文件存在於「%systemroot% system32」目錄下,它屬於共享工作行程。隨著Windows系統服務不斷增多,為了節省系統資源,微軟把很多服務做成共享方式,交由 Svchost.exe工作行程來啟動。但Svchost工作行程只作為服務宿主,並不能實現任何服務功能,即它只能提供條件讓其他服務在這裡被啟動,而它自己卻不能給用戶提供任何服務。那這些服務是如何實現的呢? 原來這些系統服務是以動態鏈接庫(dll)形式實現的,它們把可執行程式指向 Svchost,由Svchost呼叫相應服務的動態鏈接庫來啟動服務。那Svchost又怎麼知道某個系統服務該呼叫哪個動態鏈接庫呢?這是通過系統服務在註冊表中設置的參數來實現。 從啟動參數中可見服務是靠Svchost來啟動的。 因為Svchost工作行程啟動各種服務,所以病毒、木馬也想盡辦法來利用它,企圖利用它的特性來迷惑用戶,達到感染、入侵、破壞的目的(如衝擊波變種病毒「w32.welchia.worm」)。但Windows系統存在多個Svchost工作行程是很正常的,在受感染的機器中到底哪個是病毒工作行程呢?這裡僅舉一例來說明。 假設Windows XP系統被「w32.welchia.worm」感染了。正常的Svchost文件存在於「c:\Windows\system32」目錄下,如果發現該文件出現在其他目錄下就要小心了。「w32.welchia.worm」病毒存在於「c:\Windows\system32Win s」目錄中,因此使用工作行程管理器檢視Svchost工作行程的執行文件路徑就很容易發現系統是否感染了病毒。Windows系統自帶的任務管理器不能夠檢視工作行程的路徑,可以使用第三方工作行程管理軟件,如「Windows優化大師」工作行程管理器,通過這些工具就可很容易地檢視到所有的Svchost工作行程的執行文件路徑,一旦發現其執行路徑為不平常的位置就應該馬上進行檢測和處理。 |
全面瞭解系統中 svchost.exe文件
筆者經常在一些反病毒論壇上瀏覽時,發現一些朋友對任務管理器中的svchost工作行程不甚瞭解,看見存在許多svchost工作行程就以為自己中了病毒,其實不然。 svchost.exe是NT核心系統非常重要的文件,對於Win2000/XP來說,不可或缺。這些svchost工作行程提供很多系統服務,如:rpcss服務(remote procedure call)、dmserver服務(logical disk manager)、dhcp服務(dhcp client)等等。 本站出售特殊域名 高速高穩定,低價格 域名空間出售 如果要瞭解每個svchost工作行程到底提供了多少系統服務,可以在WinXP的命令提示字元視窗中輸入「tasklist /svc」命令來檢視。 工作原理 一般來說,Windows系統工作行程分為獨立工作行程和共享工作行程兩種。svchost.exe文件存在於%systemroot%\system32目錄下,屬於共享工作行程。 隨著Windows系統服務不斷增多,為了節省系統資源,微軟把很多服務都做成共享方式,交由svchost工作行程來啟動。但svchost工作行程只作為服務宿主,並不能實現任何服務功能,即它只能提供條件讓其他服務在這裡被啟動,而它自己卻不能給用戶提供任何服務。 這些服務是如何實現的呢?原來這些系統服務是以動態鏈接庫(dll)形式實現的,它們把可執行程式指向svchost,由svchost呼叫相應服務的動態鏈接庫來啟動服務。 那svchost又怎麼知道某個系統服務該呼叫哪個動態鏈接庫呢?這是通過系統服務在註冊表中設置的參數來實現的。 具體實例 下面以Remote Registry服務為例,來看看svchost工作行程是如何呼叫DLL文件的。在WinXP中,點擊「開始→執行」,輸入「services.msc」命令,會彈出服務交談視窗,然後打開「Remote Registry」內容交談視窗,可以看到Remote Registry服務的可執行文件的路徑為「c:\Windows\System32\svchost -k LocalService」(圖1),這說明Remote Registry服務是依靠svchost呼叫「LocalService」參數來實現的,而參數的內容則是存放在系統註冊表中的。 在執行交談視窗中輸入「regedit.exe」後Enter鍵,打開註冊表編輯器,找到「HKEY_LOcAL_MAcHINE\System\currentcontrolset\services\Remote Registry」項,再找到類型為「reg_expand_sz」的「Imagepath」項,其鍵值為「%systemroot%\system32\svchost -k LocalService」(這就是在服務視窗中看到的服務啟動命令),另外在「parameters」子項中有個名為「ServiceDll」的鍵,其值為「% systemroot%\system32\regsvc.dll」,其中「regsvc.dll」就是Remote Registry服務要使用的動態鏈接庫文件。這樣svchost工作行程通過讀取「Remote Registry」服務註冊表訊息,就能啟動該服務了。 也正是因為svchost的重要性,所以病毒、木馬也想盡辦法來利用它,企圖利用它的特性來迷惑用戶,達到感染、入侵、破壞的目的。那麼應該如何判斷到底哪個是病毒工作行程呢?正常的svchost.exe文件應該存在於「c:\Windows\system32」目錄下,如果發現該文件出現在其他目錄下就要小心了。 提示:svchost.exe文件的呼叫路徑可以通過「系統訊息→軟件環境→正在執行任務」來檢視. |
透析Svchost工作行程清除後門
網上有很多關於Svchost.exe的討論,我們今天首先來看一下Svchost.exe的原理,工作方法,然後結合著名DLL木馬,實戰瞭解一下使用Svchost.exe進行啟動的木馬的清除,希望大家能夠有所收穫。 Svchost.exe是NT核心系統非常重要的文件,對於Windows 2000/XP來說,不可或缺。 Svchost工作行程提供很多系統服務,如:logical disk manager、remote procedure call(RPC)、dhcp client、Automatic Updates、Background Intelligent Transfer Service、COM+ Event System、Internet Connection Sharing、Network Connections、Portable Media Serial Number Service、Remote Access Auto Connection Manager、Remote Access Connection Manager、Removable Storage、Routing and Remote Access、System Event Notification、Telephony、Wireless Configuration等等。 對於服務中使用Svchost.exe載入了哪些動態鏈接庫,我們可以在服務中點擊上面列出的某個服務來看看。比如我們要看Automatic Updates服務,就可以在在它上面點擊滑鼠右鍵,看它的內容。 同樣情況下,如果讀者還想進一步瞭解其它的那些服務是怎樣使用Svchost.exe的,可以使用與上面相同的方法來觀察一下。 聰明的讀者一眼就可以看出,Svchost.exe對於系統來說是多麼的重要了。也正是因為Svchost.exe的重要性,所以病毒、木馬也想盡辦法來利用它,企圖利用它的特性來迷惑用戶,達到感染、入侵、破壞的目的。那麼應該如何判斷到底哪個是病毒工作行程呢? 正常的Svchost.exe文件應該存在於「C:\Windows\system32」目錄下,如果發現該文件出現在其他目錄下就要小心了。 另外,黑客們為了使用Svchost.exe達到工作行程欺騙的目的,有可能使用一些迷惑性的名字,如將字母o變成數位0(零),這樣程式的名稱就變成了svch0st.exe了,如果不注意觀察,很容易逃過普通用戶的眼睛。 通常情況下,為了確定我們的電腦中正在執行的Svchost.exe是不是真正的系統的Svchost.exe,我們可以使用如下方法來檢視。Svchost.exe文件的呼叫路徑可以通過「電腦管理→系統工具→系統訊息→軟件環境→正在執行任務」來檢視。 這裡僅舉一例來說明。假設Windows XP系統被「w32.welchia.worm」感染了。 正常的Svchost文件存在於「c:\Windows\system32」目錄下,如果發現該文件出現在其他目錄下就要小心了。 「w32.welchia.worm」病毒存在於「c:\Windows\system32wins」目錄中,通過使用上面說的方法就可很容易地檢視到所有的Svchost工作行程的執行文件路徑,一旦發現其執行路徑為不平常的位置就應該馬上進行檢測和處理。 現在我們已經搞清楚了一部分疑問,但是,我們還不知道哪個服務呼叫了哪個動態鏈接庫文件,是不是沒有辦法呢? 如果沒有地方可以找到,那麼Windows自己又是如何知道呼叫哪一個呢? 大家知道,Windows將所有的系統訊息和應用程式訊息都儲存在了系統註冊表中,所以,我們可以在註冊表中找找看。 下面以Remote Procedure Call(RPC)服務為例,來看看Svchost工作行程是如何呼叫DLL文件的。在Windiws中,打開服務,然後打開「Remote Procedure Call(RPC)」內容交談視窗,可以看到Remote Procedure Call(RPC)服務的可執行文件的路徑為「C:\WINNT\system32\Svchost -k rpcss」,這說明Remote Procedure Call(RPC)服務是依*Svchost呼叫「rpcss」參數來實現的,而參數的內容則是存放在系統註冊表中的。 在執行交談視窗中輸入「regedit.exe」後Enter鍵,打開註冊表編輯器,找到「HKEY_LOCAL_MACHINE\System\currentcontrolset\services\ rpcss」項。 然後,再在裡面找到類型為「reg_expand_sz」的「Imagepath」項,其鍵值為「%SystemRoot%\system32\Svchost -k rpcss」(這就是在服務視窗中看到的服務啟動命令),另外在「parameters」子項中有個名為「ServiceDll」的鍵,其值為「%SystemRoot%\system32\rpcss.dll」,其中「rpcss.dll」就是Remote Procedure Call(RPC)服務要使用的動態鏈接庫文件。這樣Svchost工作行程通過讀取「rpcss」服務註冊表訊息,就能啟動該服務了。 同樣情況下,如果有程式試圖蠻天過海,假借Svchost.exe來啟動自己的動態鏈接庫文件(如將木馬作成動態鏈接庫文件),那麼我們就可以從這裡找到DLL木馬的路徑,將它大白於天下。 如果要瞭解每個Svchost工作行程到底提供了多少系統服務,可以在Windows 2000的命令提示字元視窗中輸入「tlist -s」命令來檢視,該命令是Windows 2000 support tools提供的。不過,在這裡看到的效果跟服務裡面看到的是一樣的,只不過是DOS界面而已。 小知識:在Windows xp下則使用「tasklist /svc」命令會收到同樣的效果。 由於篇幅的關係,不能對Svchost全部功能進行詳細介紹,這是一個Windows中的一個特殊工作行程,有興趣的可參考有關技術資料進一步去瞭解它。 下面,我們通過一個實例來看一下木馬程式是如何利用Svchost.exe進行啟動的。這裡,我選擇了PortLess BackDoor V1.2來做演示,這是一個使用Svchost.exe去啟動,平時不開連接阜,可以進行反連接的後門程式(和小榕的BITS是同一類型的後門)。 為了看一下這個後門是如何利用Svchost.exe進行啟動的,我們在執行軟件之前,先給註冊表做一個快照,這裡我選擇了Regshot 1.61e5 final版本,並將初始快照命名為1.hiv。然後我們將Portlessinst.exe和Svchostdll.dll(不要改名)上傳到系統目錄(%winnt%\system32目錄中)。 接下來,進入命令行,使用「Portlessinst.exe -install ActiveString Password」進行安裝,這裡的ActiveString就是連接那系統打開的連接阜後輸入的驗證字元串,這裡的密碼是使用正向連接你連接上後門打開的連接阜時需要輸入的密碼。比如,我輸入如下: portlessinst.exe –install smiler wind_003 這樣就安裝上去了,我們來看一下註冊表裡的變化。將1.hiv裝載進Regshot中的1st shot,然後對當前的註冊表做2st shot的快照,然後使用compare進行比較,其比較的結果如下: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\PortLess\FdsnqbTsuni`: "tjnkbu" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\PortLess\Wfttphuc: "tofiXdo" HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\Security\Security: 01 00 14 80 A0 00 00 00 AC 00 00 00 14 00 00 00 30 00 00 00 02 00 1C 00 01 00 00 00 02 80 14 00 FF 01 0F 00 01 01 00 00 00 00 00 01 00 00 00 00 02 00 70 00 04 00 00 00 00 00 18 00 FD 01 02 00 01 01 00 00 00 00 00 05 12 00 00 00 63 00 6F 00 00 00 1C 00 FF 01 0F 00 01 02 00 00 00 00 00 05 20 00 00 00 20 02 00 00 6D 00 00 00 00 00 18 00 8D 01 02 00 01 01 00 00 00 00 00 05 0B 00 00 00 20 02 00 00 00 00 1C 00 FD 01 02 00 01 02 00 00 00 00 00 05 20 00 00 00 23 02 00 00 6D 00 00 00 01 01 00 00 00 00 00 05 12 00 00 00 01 01 00 00 00 00 00 05 12 00 00 00 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\Parameters\ServiceDll: "C:\WINNT\system32\Svchostdll.dll" HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\Parameters\program: "SvchostDLL.exe" HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\Parameters\Interactive: 0x00000000 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\Type: 0x00000020 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\Start: 0x00000002 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\ErrorControl: 0x00000001 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\ImagePath: "%SystemRoot%\System32\Svchost.exe -k netsvcs" HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\DisplayName: "Intranet Services" HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IPRIP\ObjectName: "LocalSystem" HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\Security\Security: 01 00 14 80 A0 00 00 00 AC 00 00 00 14 00 00 00 30 00 00 00 02 00 1C 00 01 00 00 00 02 80 14 00 FF 01 0F 00 01 01 00 00 00 00 00 01 00 00 00 00 02 00 70 00 04 00 00 00 00 00 18 00 FD 01 02 00 01 01 00 00 00 00 00 05 12 00 00 00 63 00 6F 00 00 00 1C 00 FF 01 0F 00 01 02 00 00 00 00 00 05 20 00 00 00 20 02 00 00 6D 00 00 00 00 00 18 00 8D 01 02 00 01 01 00 00 00 00 00 05 0B 00 00 00 20 02 00 00 00 00 1C 00 FD 01 02 00 01 02 00 00 00 00 00 05 20 00 00 00 23 02 00 00 6D 00 00 00 01 01 00 00 00 00 00 05 12 00 00 00 01 01 00 00 00 00 00 05 12 00 00 00 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\Parameters\ServiceDll: "C:\WINNT\system32\Svchostdll.dll" HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\Parameters\program: "SvchostDLL.exe" HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\Parameters\Interactive: 0x00000000 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\Type: 0x00000020 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\Start: 0x00000002 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\ErrorControl: 0x00000001 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\ImagePath: "%SystemRoot%\System32\Svchost.exe -k netsvcs" HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\DisplayName: "Intranet Services" HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPRIP\ObjectName: "LocalSystem" 可以看出,PortLess BackDoor V1.2將自己註冊為了服務IPRIP,它使用的啟動參數是"%SystemRoot%\System32\Svchost.exe -k netsvcs",它使用的DLL文件是"C:\WINNT\system32\Svchostdll.dll"。 通過這裡,我們就可以找到PortLess,將它使用的服務禁止掉,然後將對應的DLL文件刪除,並將註冊表中這些多出來的鍵值幹掉,三下五除二就將Portless弄得一乾二淨!現在大家知道怎麼清理掉用Svchost載入的後門了吧?! |
所有時間均為台北時間。現在的時間是 05:05 PM。 |
Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.
『服務條款』
* 有問題不知道該怎麼解決嗎?請聯絡本站的系統管理員 *