我正在尝试弄清Windows进程如何启动并保持与services.exe的通信的内部。这是在Windows 8 x64上,但是如果您也有Windows 7提示,那也很好。 br />
现在我的问题是,如何将实际的“开始”传达给服务?我知道服务本身会执行以下操作:


主入口点(控制台程序)
调用services.exe

转到advapi!StartServiceCtrlDispatcher

这会跳到sechost!StartServiceCtrlDispatcher


我想弄清楚sechost!QueryServiceDynamicInformation中的哪种方法可以用于启动过程。理想情况下,我希望能够编写可以“启动”简单Windows服务并启动它的PoC代码,而无需将其注册为Windows Service,即包装在“独立服务控制管理器”中。我正在寻找下一步的最佳提示。

services.exe中也有对services.exe的引用。 Wikipedia上有关SCM的文章提到正在创建\pipe\ntsvcs,但据我所知,那是在Windows 2000(也许是XP)中,但我看不到Windows 8会发生这种情况。

#1 楼

这是我对Windows服务如何工作的基本理解。我已经在Windows XP和Windows 7中使用了它。无论如何,这些都是通用概念。

任何服务都需要提供三样东西:


主入口点
服务入口点
服务控制处理程序

您绝对正确。在主入口点服务中,必须调用StartServiceCtrlDispatcher(const SERVICE_TABLE_ENTRY *lpServiceTable),以提供服务控制管理器的形式填写SERVICE_TABLE_ENTRY,这是(根据MSDN):在SERVICE_TABLE_ENTRY结构中需要提供的东西。这些是指向服务名称的指针和指向服务主要功能的指针。服务注册后,服务控制管理器会立即调用服务主要功能,也称为ServiceMain或服务入口点。服务控制管理中心希望服务入口点执行以下任务:


注册服务控制处理程序。
设置服务状态
执行必要的初始化(创建事件,互斥锁等)

服务控制处理程序是具有以下定义的回调函数:VOID WINAPI ServiceCtrlHandler (DWORD CtrlCode)(MSDN)。它将处理服务停止,暂停,继续和关闭。每个服务都必须有一个处理程序来处理来自SCM的请求。服务控制处理程序已向RegisterServiceCtrlHandlerEx()(MSDN)注册,该服务返回SERVICE_STATUS_HANDLE。服务使用句柄与SCM通信。控制处理程序还必须在30秒内返回。如果没有发生,SCM将返回错误,指出服务无响应。这是由于以下事实:从SCM调用了处理程序,并且将冻结SCM,直到从处理程序返回为止。只有这样,服务才可以使用SetServiceStatus()(MSDN)功能以及服务状态句柄与SCM通信。

您不会将“开始”传达给服务。每当加载服务时,它都会以“启动”状态加载。向SCM报告其状态是服务的责任。您可以暂停或继续(加上大约十几个控制代码)。您可以使用ControlService()(MSDN)功能将其传达给SCM。 SCM随后使用已注册的服务控制处理程序功能将控制代码(例如SERVICE_CONTROL_PAUSE,SERVICE_CONTROL_CONTINUE或任何其他代码)中继到服务。之后,根据接收到的控制代码执行服务是服务的责任。

我不认为services.exe在实际服务后面执行或运行线程。它是单片机本身。我认为它总体上协调服务。每个服务都“存在”于svchost.exe实例中。考虑到上述情况,我可以假定服务入口点或服务主目录是在svchost.exe实例的上下文中执行的。相应地,svchost.exe在主线程的上下文中执行Service Main,阻塞主线程,直到Service Main存在,表明该服务已退出。

如果您正在考虑创建自己的服务控制管理器,不需要反向工程services.exe的工作方式。您可以按照自己喜欢的方式进行操作:)

希望对您有所帮助。

添加的内容: ,services.exe是服务控制管理器本身。

如果要创建自己的服务包装程序以在SCM之外运行现有的服务可执行文件,则必须遵守上述服务规则和要求。首先要求服务在SCM中注册并提供服务主入口点,这是通过调用StartServiceCtrlDispatcher()完成的。这将为您提供服务主入口。之后,您应该期望服务主叫RegisterServiceCtrlHandler()SetServiceStatus()。由于RegisterServiceCtrlHandler()在Service Main上下文中运行并阻塞Service Main线程,因此也应正确处理它。另外,您应该想到一种通过“监视” Service Main中的CreatThread()(MSDN)来控制/监视服务工作者线程的方法。

评论


好答案。为了清楚起见,我只添加(您确实暗示了)服务控制管理器的可执行文件是“ services.exe”,这是Winlogon在启动过程的早期启动的控制台应用程序。

–米克
2013年6月12日在2:40

谢谢PSS,反应很好。按照您所说的,在SCM外部启动服务EXE时,对StartServiceCtrlDispatcher的调用失败,错误代码1063服务进程无法连接至服务控制器。我怀疑如果我想编写自己的“包装器”,即在不使用SCM的情况下运行服务,则需要挂接advapi32!StartServiceCtrlDispatcher并替换为自己的函数以执行服务主体。这是正确的理解吗?

–chentiangemalc
2013年6月12日上午11:35

@MalcolmMcCaffery。究竟。请参阅上面。我已经修改了答案。

– PSS
2013年6月12日14:03