欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
創(chuàng )建SvcHost.exe調用的服務(wù)原理與實(shí)踐
1. 多個(gè)服務(wù)共享一個(gè)Svchost.exe進(jìn)程利與弊

       windows 系統服務(wù)分為獨立進(jìn)程和共享進(jìn)程兩種,在windows NT時(shí)只有服務(wù)器管理器SCM(Services.exe)有多個(gè)共享服務(wù),隨著(zhù)系統內置服務(wù)的增加,在windows 2000中ms又把很多服務(wù)做成共享方式,由svchost.exe啟動(dòng)。windows 2000一般有2個(gè)svchost進(jìn)程,一個(gè)是RPCSS(Remote Procedure Call)服務(wù)進(jìn)程,另外一個(gè)則是由很多服務(wù)共享的一個(gè)svchost.exe。而在windows XP中,則一般有4個(gè)以上的svchost.exe服務(wù)進(jìn)程,windows 2003 server中則更多,可以看出把更多的系統內置服務(wù)以共享進(jìn)程方式由svchost啟動(dòng)是ms的一個(gè)趨勢。這樣做在一定程度上減少了系統資源的消耗,不過(guò)也帶來(lái)一定的不穩定因素,因為任何一個(gè)共享進(jìn)程的服務(wù)因為錯誤退出進(jìn)程就會(huì )導致整個(gè)進(jìn)程中的所有服務(wù)都退出。另外就是有一點(diǎn)安全隱患,首先要介紹一下svchost.exe的實(shí)現機制。


2. Svchost原理

      Svchost本身只是作為服務(wù)宿主,并不實(shí)現任何服務(wù)功能,需要Svchost啟動(dòng)的服務(wù)以動(dòng)態(tài)鏈接庫形式實(shí)現,在安裝這些服務(wù)時(shí),把服務(wù)的可執行程序指向svchost,啟動(dòng)這些服務(wù)時(shí)由svchost調用相應服務(wù)的動(dòng)態(tài)鏈接庫來(lái)啟動(dòng)服務(wù)。

       那么svchost如何知道某一服務(wù)是由哪個(gè)動(dòng)態(tài)鏈接庫負責呢?這不是由服務(wù)的可執行程序路徑中的參數部分提供的,而是服務(wù)在注冊表中的參數設置的,注冊表中服務(wù)下邊有一個(gè)Parameters子鍵其中的ServiceDll表明該服務(wù)由哪個(gè)動(dòng)態(tài)鏈接庫負責。并且所有這些服務(wù)動(dòng)態(tài)鏈接庫都必須要導出一個(gè)ServiceMain()函數,用來(lái)處理服務(wù)任務(wù)。

例如rpcss(Remote Procedure Call)在注冊表中的位置是  HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/RpcSs,它的參數子鍵Parameters里有這樣一項:
"ServiceDll"=REG_EXPAND_SZ:"%SystemRoot%/system32/rpcss.dll"
當啟動(dòng)rpcss服務(wù)時(shí),svchost就會(huì )調用rpcss.dll,并且執行其ServiceMain()函數執行具體服務(wù)。

       既然這些服務(wù)是使用共享進(jìn)程方式由svchost啟動(dòng)的,為什么系統中會(huì )有多個(gè)svchost進(jìn)程呢?ms把這些服務(wù)分為幾組,同組服務(wù)共享一個(gè)svchost進(jìn)程,不同組服務(wù)使用多個(gè)svchost進(jìn)程,組的區別是由服務(wù)的可執行程序后邊的參數決定的。

例如rpcss在注冊表中 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/RpcSs 有這樣一項:
"ImagePath"=REG_EXPAND_SZ:"%SystemRoot%/system32/svchost -k rpcss"
因此rpcss就屬于rpcss組,這在服務(wù)管理控制臺也可以看到。

svchost的所有組和組內的所有服務(wù)都在注冊表的如下位置: 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..

在啟動(dòng)一個(gè)svchost.exe負責的服務(wù)時(shí),服務(wù)管理器如果遇到可執行程序內容ImagePath已經(jīng)存在于服務(wù)管理器的映象庫中,就不在啟動(dòng)第2個(gè)進(jìn)程svchost,而是直接啟動(dòng)服務(wù)。這樣就實(shí)現了多個(gè)服務(wù)共享一個(gè)svchost進(jìn)程。


3. Svchost代碼

        現在我們基本清楚svchost的原理了,但是要自己寫(xiě)一個(gè)DLL形式的服務(wù),由svchost來(lái)啟動(dòng),僅有上邊的信息還有些問(wèn)題不是很清楚。比如我們在導出的ServiceMain()函數中接收的參數是ANSI還是Unicode?我們是否需要調用RegisterServiceCtrlHandler和StartServiceCtrlDispatcher來(lái)注冊服務(wù)控制及調度函數?

        這些問(wèn)題要通過(guò)查看svchost代碼獲得。下邊的代碼是windows 2000+ service pack 4 的svchost反匯編片段,可以看出svchost程序還是很簡(jiǎn)單的。

        主函數首先調用ProcCommandLine()對命令行進(jìn)行分析,獲得要啟動(dòng)的服務(wù)組,然后調用SvcHostOptions()查詢(xún)該服務(wù)組的選項和服務(wù)組的所有服務(wù),并使用一個(gè)數據結構 svcTable 來(lái)保存這些服務(wù)及其服務(wù)的DLL,然后調用PrepareSvcTable() 函數創(chuàng )建SERVICE_TABLE_ENTRY 結構,把所有處理函數SERVICE_MAIN_FUNCTION 指向自己的一個(gè)函數FuncServiceMain(),最后調用API StartServiceCtrlDispatcher() 注冊這些服務(wù)的調度函數。

; =============================== Main Funcion ===========================================
.text:010010B8                 public start
.text:010010B8 start           proc near
.text:010010B8                 push    esi
.text:010010B9                 push    edi
.text:010010BA                 push    offset sub_1001EBA ; lpTopLevelExceptionFilter
.text:010010BF                 xor     edi, edi
.text:010010C1                 call    ds:SetUnhandledExceptionFilter
.text:010010C7                 push    1               ; uMode
.text:010010C9                 call    ds:SetErrorMode
.text:010010CF                 call    ds:GetProcessHeap
.text:010010D5                 push    eax
.text:010010D6                 call    sub_1001142
.text:010010DB                 mov     eax, offset dword_1003018
.text:010010E0                 push    offset unk_1003000 ; lpCriticalSection
.text:010010E5                 mov     dword_100301C, eax
.text:010010EA                 mov     dword_1003018, eax
.text:010010EF                 call    ds:InitializeCriticalSection
.text:010010F5                 call    ds:GetCommandLineW
.text:010010FB                 push    eax             ; lpString
.text:010010FC                 call    ProcCommandLine
.text:01001101                 mov     esi, eax
.text:01001103                 test    esi, esi
.text:01001105                 jz      short lab_doservice
.text:01001107                 push    esi
.text:01001108                 call    SvcHostOptions
.text:0100110D                 call    PrepareSvcTable
.text:01001112                 mov     edi, eax        ; SERVICE_TABLE_ENTRY returned
.text:01001114                 test    edi, edi
.text:01001116                 jz      short loc_1001128
.text:01001118                 mov     eax, [esi+10h]
.text:0100111B                 test    eax, eax
.text:0100111D                 jz      short loc_1001128
.text:0100111F                 push    dword ptr [esi+14h] ; dwCapabilities
.text:01001122                 push    eax             ; int
.text:01001123                 call    InitializeSecurity
.text:01001128
.text:01001128 loc_1001128:                            ; CODE XREF: start+5Ej
.text:01001128                                         ; start+65j
.text:01001128                 push    esi             ; lpMem
.text:01001129                 call    HeapFreeMem
.text:0100112E
.text:0100112E lab_doservice:                          ; CODE XREF: start+4Dj
.text:0100112E                 test    edi, edi
.text:01001130                 jz      ExitProgram
.text:01001136                 push    edi             ; lpServiceStartTable
.text:01001137                 call    ds:StartServiceCtrlDispatcherW
.text:0100113D                 jmp     ExitProgram
.text:0100113D start           endp
; =============================== Main Funcion end ===========================================


       由于svchost為該組的所有服務(wù)都注冊了svchost中的一個(gè)處理函數,因此每次啟動(dòng)任何一個(gè)服務(wù)時(shí),服務(wù)管理器SCM都會(huì )調用FuncServiceMain() 這個(gè)函數。這個(gè)函數使用 svcTable 查詢(xún)要啟動(dòng)的服務(wù)使用的DLL,調用DLL導出的ServiceMain()函數來(lái)啟動(dòng)服務(wù),然后返回。

; ============================== FuncServiceMain() ===========================================
.text:01001504 FuncServiceMain proc near               ; DATA XREF: PrepareSvcTable+44o
.text:01001504
.text:01001504 arg_0           = dword ptr  8
.text:01001504 arg_4           = dword ptr  0Ch
.text:01001504
.text:01001504                 push    ecx
.text:01001505                 mov     eax, [esp+arg_4]
.text:01001509                 push    ebx
.text:0100150A                 push    ebp
.text:0100150B                 push    esi
.text:0100150C                 mov     ebx, offset unk_1003000
.text:01001511                 push    edi
.text:01001512                 mov     edi, [eax]
.text:01001514                 push    ebx
.text:01001515                 xor     ebp, ebp
.text:01001517                 call    ds: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                 push    dword ptr [eax+ecx]
.text:01001537                 push    edi
.text:01001538                 call    ds:lstrcmpiW
.text:0100153E                 test    eax, eax
.text:01001540                 jz      short StartThis
.text:01001542                 add     dword ptr [esp+10h], 0Ch
.text:01001547                 inc     esi
.text:01001548                 cmp     esi, dwGroupSize
.text:0100154E                 jb      short 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                 push    eax
.text:0100155F                 call    GetDLLServiceMain
.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                 push    ebx
.text:01001567                 call    ds:LeaveCriticalSection
.text:0100156D                 test    ebp, ebp
.text:0100156F                 jz      short loc_100157B
.text:01001571                 push    [esp+10h+arg_4]
.text:01001575                 push    [esp+14h+arg_0]
.text:01001579                 call    ebp
.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                 retn    8
.text:01001580 FuncServiceMain endp ; sp = -8
; ============================== FuncServiceMain() end ========================================


       由于svchost已經(jīng)調用了StartServiceCtrlDispatcher來(lái)服務(wù)調度函數,因此我們在實(shí)現DLL實(shí)現時(shí)就不用了,這主要是因為一個(gè)進(jìn)程只能調用一次StartServiceCtrlDispatcher API。但是需要用 RegisterServiceCtrlHandler 來(lái)注冊響應控制請求的函數。最后我們的DLL接收的都是unicode字符串。

       由于這種服務(wù)啟動(dòng)后由svchost加載,不增加新的進(jìn)程,只是svchost的一個(gè)DLL,而且一般進(jìn)行審計時(shí)都不會(huì )去HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Svchost 檢查服務(wù)組是否變化,就算去檢查,也不一定能發(fā)現異常,因此如果添加一個(gè)這樣的DLL后門(mén),偽裝的好,是比較隱蔽的。


4. 安裝服務(wù)與設置
       要通過(guò)svchost調用來(lái)啟動(dòng)的服務(wù),就一定要在HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Svchost下有該服務(wù)名,這可以通過(guò)如下方式來(lái)實(shí)現:
1) 添加一個(gè)新的服務(wù)組,在組里添加服務(wù)名
2) 在現有組里添加服務(wù)名
3) 直接使用現有服務(wù)組里的一個(gè)服務(wù)名,但本機沒(méi)有安裝的服務(wù)
4) 修改現有服務(wù)組里的現有服務(wù),把它的ServiceDll指向自己

        其中前兩種可以被正常服務(wù)使用,如使用第1種方式,啟動(dòng)其服務(wù)要創(chuàng )建新的svchost進(jìn)程;第2種方式如果該組服務(wù)已經(jīng)運行,安裝后不能立刻啟動(dòng)服務(wù),因為svchost啟動(dòng)后已經(jīng)把該組信息保存在內存里,并調用API StartServiceCtrlDispatcher() 為該組所有服務(wù)注冊了調度處理函數,新增加的服務(wù)不能再注冊調度處理函數,需要重起計算機或者該組的svchost進(jìn)程。而后兩種可能被后門(mén)使用,尤其是最后一種,沒(méi)有添加服務(wù),只是改了注冊表里一項設置,從服務(wù)管理控制臺又看不出來(lái),如果作為后門(mén)還是很隱蔽的。比如EventSystem服務(wù),缺省是指向es.dll,如果把ServiceDll改為EventSystem.dll就很難發(fā)現。

         因此服務(wù)的安裝除了調用CreateService()創(chuàng )建服務(wù)之外,還需要設置服務(wù)的ServiceDll,如果使用前2種還要設置svchost的注冊表選項,在卸載時(shí)也最好刪除增加的部分。

具體代碼參見(jiàn)后邊的附例(使用的是方法3)。

注: ImagePath 和ServiceDll 是ExpandString不是普通字符串。因此如果使用.reg文件安裝時(shí)要注意。


5. DLL服務(wù)實(shí)現
         DLL程序的編寫(xiě)比較簡(jiǎn)單,只要實(shí)現一個(gè)ServiceMain()函數和一個(gè)服務(wù)控制程序,在ServiceMain()函數里用RegisterServiceCtrlHandler()注冊服務(wù)控制程序,并設置服務(wù)的運行狀態(tài)就可以了。

          另外,因為此種服務(wù)的安裝除了正常的CreateService()之外,還要進(jìn)行其他設置,因此最好實(shí)現安裝和卸載函數。

          為了方便安裝,實(shí)現的代碼提供了InstallService()函數進(jìn)行安裝,這個(gè)函數可以接收服務(wù)名作為參數(如果不提供參數,就使用缺省的iprip),如果要安裝的服務(wù)不在svchost的netsvcs組里安裝就會(huì )失??;如果要安裝的服務(wù)已經(jīng)存在,安裝也會(huì )失??;安裝成功后程序會(huì )配置服務(wù)的ServiceDll為當前Dll。提供的UninstallService()函數,可以刪除任何函數而沒(méi)有進(jìn)行任何檢查。

         為了方便使用rundll32.exe進(jìn)行安裝,還提供了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服務(wù)本身只是創(chuàng )建一個(gè)進(jìn)程,該程序命令行就是啟動(dòng)服務(wù)時(shí)提供的第一個(gè)參數,如果未指定就使用缺省的svchostdll.exe。啟動(dòng)服務(wù)時(shí)如果提供第二個(gè)參數,創(chuàng )建的進(jìn)程就是和桌面交互的。

具體代碼參見(jiàn)后邊的附例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.exe    Svcs:  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.exe    Svcs:  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/Index.cfm?ArticleID=8943&pg=3
2) Platform SDK: Tools - Rundll32, at: http://msdn.microsoft.com/library/en-us/tools/tools/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/svchost-dll-service.html
// 2. Inside Win32 Services, Part 2 by: Mark Russinovich, at: http://www.winnetmag.com/Articles/Index.cfm?ArticleID=8943&pg=3
// 3. Platform SDK: Tools - Rundll32, at: http://msdn.microsoft.com/library/en-us/tools/tools/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,
                       DWORD  ul_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_list    arglist;
    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);
}
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
電腦進(jìn)程詳解
驅動(dòng)程序安裝類(lèi)(C#)
Windows系統進(jìn)程列表完全解析
IE瀏覽器打開(kāi)網(wǎng)頁(yè)速度慢的解決方法_會(huì )飛的狼
經(jīng)過(guò)半小時(shí)整理,讓你快速看懂系統進(jìn)程
認識Windows XP的系統進(jìn)程 - ucsai的日志 - 網(wǎng)易博客
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久