自启动服务

通常windows服务运行在session 0,隔断了系统服务和桌面系统,各个session之间相互独立,不能交互和通信。

服务控制管理器(SCM:Services Control Manager)是一个管理系统所有服务的进程。当 SCM 启动某个服务时,它等待某个进程的主线程来调用 StartServiceCtrlDispatcher 函数。将分派表传递给 StartServiceCtrlDispatcher。这将把调用进程的主线程转换为控制分派器。该分派器启动一个新线程,该线程运行分派表中每个服务的 ServiceMain 函数分派器还监视程序中所有服务的执行情况。然后分派器将控制请求从 SCM 传给服务。

系统进程自启动是通过windows系统提供的api创建系统服务,并设置服务为自启动类型实现的,创建系统服务的时候要求具有管理员权限,作为系统服务启动的程序需要存在一个额外的服务入口点ServiceMain,ServiceMain应首先为服务向控制器注册,ServiceMain运行在一个单独的线程内,这个线程是由控制分派器创建的 ,通常需要把不需要用户交互的操作放在这里面,如果需要与用户交互,可以通过WTS系列函数来实现。

创建流程

  • 加载器:

  1. 获取SCManager句柄

  2. 通过SCManager对服务进行增删查改

  • 服务执行体

  1. 连接到SCM

  2. 注册服务控制处理器

  3. 在控制处理器中对服务控制进行处理(通过SetServiceStatus反馈服务状态和设置接受的控制)。

大致原理

服务控制管理器进程services.exe会在系统初始化时遍历名为HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services的注册表项,这个注册表项记录着所有注册的windows服务的实现文件(系统默认服务通常是一个dll)、启动权限。

遍历后将所有设置为auto-start的服务启动,通常表现形式为每个服务带起一个名为svchost.exe进程,这个进程是一个共享服务进程,具体服务线程的代码则是该进程额外载入的注册表内记录的dll文件。

代码实现

serviceloader.cpp

服务:

github:https://github.com/idiotc4t/SimpleService.git

最后更新于

这有帮助吗?