Loading... #### 服务中几个重要的函数 ##### SERVICE_TABLE_ENTRYA结构 为可以在调用进程中运行的服务指定ServiceMain函数。它由StartServiceCtrlDispatcher函数使用。 ``` typedef struct _SERVICE_TABLE_ENTRYA{ LPSTR lpServiceName; LPAERVICE_MAIN_FUNCTIONA lpServiceProc; }SERVICE_TABLE_ENTRYA,*LPSERVICE_TABLE_ENTRYA; ``` lpServiceName:要在此服务进程中运行的服务的名称; lpServiceProc:指向ServiceMain函数的指针。 ##### StartServiceCtrlDispatcherA函数 将服务进程的主进程连接到服务控制器,从而使该线程成为调用进程的服务控制调度程序线程。 ``` BOOL StartServiceCtrlDispatcherA( const SERVICE_TABLE_ENTRYA *lpServiceStartTable ); ``` lpServiceStartTable:一个指向SERVICE_TABLE_ENTRY结构数组的指针,该数组包含每个可以在调用进程中执行的服务的一个条目。表中最后一个条目的成员必须具有NULL值以指定表的结尾。 ##### StartServiceA函数 ``` BOOL StartServiceA( SC_HANDLE hService, DWORD dwNumServiceArgs, LPCSTR *lpServiceArgVectors ); ``` hService:服务的句柄。该句柄由OpenService或CreateService函数返回,它必须具有SERVICE_START访问权限; dwNumServicerArgs:lpServiceVectors数组中的字符串数。如果lpServiceArgVectors为NULL,则此参数可以为零; lpServiceArgVectors:要作为参数传递给服务的ServiceMain函数的以空字符结尾的字符串。如果没有参数,则此参数可以为NULL。否则第一个参数(lpServiceArgVectors[0])是服务的名称,后跟任何其它参数(lpServiceArgVectors[1]到lpServiceArgVectors[dwNumServiceArgs-1]). ##### LPSERVICE_MAIN_FUCTIONA回调函数 服务的入口点。 所述LPSERVICE_MIAN_FUNCTION类型定义一个指向这个回调函数。ServiceMain是应用程序定义的函数名称占位符。 ``` LPSERVICE_MIAN_FUNCTIONA LpserviceMainFunctiona; void LpserviceMainFunctiona( DWORD dwNumServiceArgs, LPSTR *lpServiceArgVectors ) {...} ``` dwNumServiceArgs:dwServiceArgVectors数组中的参数数量。 lpServiceArgVectors:通过调用启动服务的StartService函数传递给服务的以空字符结尾的参数字符串。如果没有参数,则此参数可以为NULL。否则,第一个参数(lpServiceArgVectors[0])是服务的名称,后跟任何其它参数(lpServiceArgVectors[1]到lpServiceArgVectors[dwNumServicesArgs-1]). #### 实例 OpenSCManager返回一个服务控制器的句柄,CreateServiceA添加一个新服务到服务管理控制器: ![image.png](http://47.117.131.13/usr/uploads/2021/09/2668979128.png) StartServiceA启动一个服务: ![image.png](http://47.117.131.13/usr/uploads/2021/09/4178940760.png) 问:如何找到服务程序的主函数ServiceMain呢? 答:StartServiceCtrlDispatcherA。 StartServiceCtrlDispatcherA函数的参数为SERVICE_TABLE_ENTRYA结构,该结构的的成员ServiceStartTable.lpServiceProc指向ServiceMain函数,即,sub_40E340为服务的主函数ServiceMain: ![image.png](http://47.117.131.13/usr/uploads/2021/09/1270193107.png) **调试** StartService函数除去第一个参数,其余参数传递给ServiceMain,如在此例子中,将函数StartServiceA的参数修改为2个,call 0040E340,便可调试ServiceMain。 ![image.png](http://47.117.131.13/usr/uploads/2021/09/214926925.png) F7进来就是服务主函数ServiceMain: ![image.png](http://47.117.131.13/usr/uploads/2021/09/1347824376.png) 最后修改:2021 年 09 月 13 日 11 : 45 AM © 允许规范转载