1. Multiple services share a svchost.exe process profitability
Windows system services are divided into independent processes and shared processes. Only Server Manager SCM (Services.exe) when Windows NT has multiple shared services, with the increase of system built-in services, MS in Windows 2000, Many Services in WINDOWS 2000 Make a sharing method, started by svchost.exe. Windows 2000 typically has 2 SVCHOST processes, one is a RPCSS (Remote Procedure Call) service process, and another SVCHOST.EXE shared by many services. In Windows XP, there are generally more than 4 SVCHOST.exe service processes, and more in Windows 2003 Server, you can see that more system built-in services is started by SVCHOST in sharing processes by SVCHOST is a trend. This reduces the consumption of system resources to a certain extent, but it also brings certain instability because the service of any shared process will exit all services in the entire process because the service of the incorrect exit process causes all services in the entire process. In addition, there is a certain safety hazard, first introduce the implementation mechanism of SVCHOST.exe. 2. SVCHOST principle Svchost itself is just as a service host, does not implement any service functions, requiring SVCHOST start-up services to implement in the dynamic link library, when installing these services, point the service's executor points to SVCHOST, starting these services SVCHOST calls the dynamic link library of the corresponding service to start the service. So how does SVCHOST know which dynamic link library is responsible for a service? This is not provided by the parameter section in the service executable program path, but the service in the registry, the service is set under the registry, and the serviceDLL in the following servicedll is indicated by which the service is responsible for . And all of these service dynamic link libraries must export a servicemain () function to handle service tasks. E.g. rpcss (Remote Procedure Call) is a location in the registry HKEY_LOCAL_MACHINE / SYSTEM / CurrentControlSet / Services / RpcSs, its parameters Parameters sub-key has such a: "ServiceDll" = REG_EXPAND_SZ: "% SystemRoot% / system32 / rpcss .dll "When the RPCSS service is activated, SVCHOST calls RPCSS.DLL and executes its servicemain () function to perform specific services. Since these services are started by SVCHOST using shared process, why do you have multiple SVCHOST processes in your system? MS divide these services into several groups, and the group service shares a SVCHOST process. Different group services use multiple SVCHOST processes, the difference is determined by the parameters of the service's executable program. For example, RPCSS has such a HKEY_LOCAL_MACHINE / System / CurrentControlSet / Services / RPCSS in the registry: "imagePath" = reg_expand_sz: "% systemroot% / system32 / svchost -k rpcss" thus RPCSS belongs to the RPCSS group, this is in service management control It can also be seen.
All services in SVCHOST are in the registry as follows: hkey_local_machine / software / microsoft / windows NT / CurrentVersion / Svchost, such as Windows 2000 has 4 groups of RPCSS, Netsvcs, Wugroup, BitsGroup, where the most is Netsvcs = REG_MULTI_SZ: Eventsystem.ias.iPrip.irMon.Netman.nwsaPAgent.rasauto.Rasman.RemoteAccess.Sens.SharedAccess.tapism.Sns.SharedAccess.tapisrv.ntmssvc.wzcsvc .. When you start a SVCHOST.EXE, service manager is encountered The execution program content ImagePath already exists in the Image Library of the Services Manager, is not starting the second process SVCHOST, but directly starts the service. This enables multiple services to share a SVCHOST process. 3. SVCHOST code Now we basically know the principle of SVCHOST, but you have to write a DLL-form service, started by svchost, only the information on the top is not very clear. For example, the parameters received in the derive servicemain () function are ANSI or Unicode? Do we need to call RegisterServiceCtrlHandler and StartServiceCtrlDispatcher to register a service control and scheduling function? These issues are available by viewing the SVCHOST code. The following code is the SVCHOST disassembly fragment of Windows 2000 Service Pack 4, you can see that the SVCHOST program is still very simple. The main function first calls ProcCommandLine () to analyze the command line, get the service group to start, then call SVCHOSTOPTIONS () Query all services of the options and service groups of the service group, and use a data structure svctable to save these services and The service DLL, then call the preplayVCTable () function to create a service_table_entry structure, point all handler service_main_function points to your own function funcServiceMain (), and finally call API StartServiceCtrldispatcher () Registered the scheduling function of these services.
; =============================== =================== ====================================== 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: 010 01128; 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; LPSERVICESTABLE.TEXT: 01001137 CALL DS: StartServiceCtrldispatcherw.text: 0100113d JMP EXITPROGRAM.TEXT: 0100113D Start endp; ==================== =======
=== main funcion end =========================================== SVCHOST registers a process in SVCHOST for all services of the group, so the service manager SCM calls FuncServiceMain () when starting any service every time. This function uses the SVCTable query to start the service used to start the DLL used to call the service-export serviceMain () function to start the service, and then return.
; ============================== funcServiceMain () ================ ================================== = 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: 010015 27 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: 0100156 6 .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 ======================================== Calling StartServiceCtrLDispatcher to serve the scheduling function, so we are not available when implementing the DLL implementation, mainly because a process can only call a StartServiceCtrldispatcher API. However, it is necessary to register the function of the response control request with RegisterServiceCtrlHandler. Finally, our DLL receives a Unicode string. Since this service is loaded by SVCHOST, it does not increase the new process, just a DLL of SVCHOST, and will not go to HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows NT / CurrentVersion / SVCHOST to check whether the service group changes when auditing. Go check, do not necessarily find abnormalities, so if you add a such DLL back door, the camouflage is good, it is more concealed.
4. Installation Services and Settings To activate the service to start through SVCHOST, you must have this service name in HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows NT / CurrentVersion / SVCHOST, which can be implemented as follows: 1) Add a new Service group, add service name in group 2) Add service name in existing group 3) Directly use a service name in the existing service group, but the service is not installed 4) Modify the existing service group Existing service, pointing its serviceDLL to yourself, the first two can be used by normal service, such as using the first method, start its service to create a new SVCHOST process; in the second way, if the service is running, after installation Can't start the service immediately, because SVCHOST has been saved in memory after SVCHOST, and calls API StartServiceCtrLDispatcher () to register the dispatch function for all services, the newly added service can no longer register the scheduling process, need to be restarted The computer or the SVCHOST process of the group. The latter two may be used in the back door, especially the last type, did not add a service, just changed a setting in the registry, and couldn't see from the service management console. If it is still hidden as the back door. For example, EventSystem service, the default is the es. DLL, and it is difficult to find if ServicesDLL is changed to Eventsystem.dll. Therefore, the service is installed In addition to calling createService () creates a service, it is necessary to set the serviceDLL to set the service. If you use the first two registry options to set up the SVCHOST, it is also preferred to delete the added part. Specific code see the example behind (Method 3). Note: ImagePath and ServiceDLL are expandstring not a normal string. So if you use the .reg file installation. 5. The DLL service implementation is relatively simple, just implement a servicemain () function and a service control program, with the RegisterServiceCtrlHandler () registration service control program in the servicemain () function, and set the service's running status. In addition, because the installation of this service is outside the normal CreateService (), other settings are required, so it is best to implement installation and unload functions. For the convenience of installation, the implementation of the code provides the installService () function for installation. This function can receive service name as a parameter (if you do not provide parameters, use the default IPRIP), if you want to install, if you want to install, you are not installed in the Netsvcs group of svchost It will fail; if the service to be installed already exists, the installation will fail; after the installation is successful, the program will configure the serviceDLL of the service to the current DLL. The UninstallService () function provided can delete any functions without any check. In order to facilitate installation using Rundll32.exe, RundllInstalla () and RundllunInStalla () are also available to installService () and UninstallService ().
Because the function prototypes rundll32.exe using: 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) The corresponding command line is Rundll32 dllname, FunctionName [arguments] DLL service itself is just a process, the program command line is the first parameter provided when the service is started, and the default svchostdll.exe is used if not specified. If the second parameter is provided when the service is started, the process created is interacting with the desktop. Concrete code See Also on the Abstract 8, source code and DLL files please http://www.binglesite.net
download.
// main service process functionvoid __stdcall ServiceMain (int argc, wchar_t * argv []); // report service stat to the service control managerint TellSCM (DWORD dwState, DWORD dwExitCode, DWORD dwProgress); // service control handler, call back by service control managervoid __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 callerint InstallService ( char * name); // unInstall a Service, be CARE FOR call this to delete a serviceint UninstallService (char * name); // Install this dll as a Service host by svchost.exe, used by RUNDLL32.EXE to callvoid 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 servicevoid CALLBACK RundllUninstallA (HWND hwnd, HINSTANCE hinst, char * param, INT ncmdshow; // output the debug infor Into log file (or stderr i Fa Console Program Call Me) & DBGPrintvoid, ...); 6. Code uses C: /> TLIST -S 0 System Process 8 System240 Services.exe SVCS: Browser, DHCP, DMSERVER, DNSCACHE, EVENTLOG, lanmanserver, lanmanworkstation, LmHosts, PlugPlay, ProtectedStorage, TrkWks, Wmi504 svchost.exe Svcs: RpcSs1360 svchost.exe Svcs: EventSystem, Netman, RasMan, SENS, TapiSrvC: /> rundll32 svchostdll.dll, RundllInstall abcdSvcHostDLL: DllMain called DLL_PROCESS_ATTACHyou specify service name Not in Svchost / Netsvcs, Must Be One of Following: - Eventsystem- ias - iprip- ire- netman- nwsapagent- rasauto- rasman- limitedaccess- Sens- SharedAccess- TapsRV- NTMSSVC- WZCSVCC: />
rundll32 svchostdll.dll, RundllInstall IPRIPSvcHostDLL: DllMain called DLL_PROCESS_ATTACHCreateService (IPRIP) SUCCESS Config itConfig service IPRIP ok.C:. /> sc start iprip "cmd / k whoami" 1NT AUTHORITY / SYSTEMSvcHostDLL: ServiceMain (3, IPRIP) calledSvcHostDLL: RealService called 'cmd / k whoami' InteractSvcHostDLL: CreateProcess (cmd / k whoami) to 640C: /> tlist -s 0 System Process 8 System240 services.exe Svcs: Browser, Dhcp, dmserver, Dnscache, Eventlog, lanmanserver, lanmanworkstation, LmHosts, PlugPlay , ProtectedStorage, TrkWks, Wmi504 svchost.exe Svcs: RpcSs640 cmd.exe Title: C: /WINNT/System32/cmd.exe1360 svchost.exe Svcs: EventSystem, Netman, RasMan, SENS, TapiSrv, IPRIPC: /> net stop ipripThe IPRIP . service was stopped successfully.C: /> rundll32 svchostdll.dll, RundllUninstall ipripDeleteService (IPRIP) SUCCESS.7 reference Platform SDK: Tools - Rundll321) 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. Code // svchostdll.cpp: demo for a service DLL Used by svchost.exe to host it 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 buy by svchost.exe by bingle, at: http:/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
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 shop 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: RegisterSer ViceCtrlHandler% 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 ( "SVCHOSTDL L: 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) ;
}}}} // RealService Just Create a Process Int RealService (Char * cmd, int binteract) {OutputString ("SVCHOSTDLL: RealService Called '% S'% S", CMD, Binteract? "": "" ":" "" "); StartupInfo Si = {0}; process_information pi; si.cb = sizeof Si; if (binteract) si.lpdesktop = "Winsta0 // default"; if (! CreateProcess, Null, False, 0, Null, Null, False, 0, 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 , 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 (stricp (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, // noad ordering group null, // no Tag Identifier Null, // no dependendencies 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); ClosESERVICEHANDE (SCHSERVICE); ClosESERVICEHANDLE (HSCM); Return RC;} / * useed to install by rundll32.e xePlatform SDK:. Tools - Rundll32The 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)) {OutputString "OpenService (% s) error% D, SVCNAME, RC = getLastError ()); Return RC;} OutputString (" deleteService (% s) access. ", Svcname);} __ except (1) {OutputString (" Exception catched 0x% X ", GetExceptionCode ());} CloseServiceHandle (schService); CloseServiceHandle (hscm); return rc;} / * used to uninstall by rundll32.exePlatform SDK: Tools - Rundll32The Run DLL utility (Rundll32.exe) included in Windows Enables you to call functions exported from a 32-bit dll. Thase Functions Must Have The Following Syntax: * / Void Callback Rundlluninsta llA (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 & DbgPrintvoid 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"