/ Windows / 137浏览

如何使用windbg从头调试 Windows 服务

背景

普通进程可以很容易的通过 windbg 来进行调试。对于服务,我们可能会优先想到附加进程的方式,可是如果想从头开始进行调试呢?

以下就以 Windows 上的大杂烩服务 scvhost.exe 为例,来从头调试下服务。

准备

1. 设置 IFEO

Windows 进程在创建的过程中,在打开要执行的镜像的时候,会去访问 ComputerHKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options 下寻找特定的 option。例如要打开的文件是SppExtComObj.exe,就会找到确认 Image File Execution Options 下是否存在 SppExtComObj.exe 子项,如果存在 PspAllocateProcess 就会再去找是否存在 debugger 的key,如果这个key存在,就会将 debugger 的值替换 SppExtComObj.exe,并且重新运行步骤一。

使用注册表编辑器,打开注册表路径:HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options ,添加一个主键,名称设置成我们要调试的服务的 exe 文件。这里是:scvhost.exe

然后在 Image File Execution Options 下添加一个字符串项,命名为 debugger ,然后再设置一下这个参数的值,这里我们想通过 windbg 来调试,所以设置成 windbg 的路径。

改完之后,重启电脑生效。

2. 调整服务超时

当调试服务的时候,其实是在服务器启动时进行调试的,而系统对服务设置了默认的超时时间,超过时间就会退出启动并报错。

系统默认启动服务的超时时间是30秒,但30秒远远不够对服务进行分析,所以要延长服务超时的时长。

打开注册表,在HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControl 键值下查找ServicesPipeTimeout参数,一般不存在,需要新建。新建DWORD值“ServicesPipeTimeout”,其值为欲设置的超时时间,先选择为十进制,数值单位是毫秒,如设置 24小时,则值为86400000毫秒:

3. 隔离服务

我们知道 svchost 是个大杂烩,所以可能有很多服务组合到单个 svchost 进程中。我们要调试这类服务,我们就得将其隔离到单独的 scvhost 中。

这里我们以计划任务这个服务为例:

  1. 先查询下这个服务:
C:UsersWDKRemoteUser>sc qc schedule
[SC] QueryServiceConfig 成功

SERVICE_NAME: schedule
        TYPE               : 20  WIN32_SHARE_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:Windowssystem32svchost.exe -k netsvcs -p
        LOAD_ORDER_GROUP   : SchedulerGroup
        TAG                : 0
        DISPLAY_NAME       : Task Scheduler
        DEPENDENCIES       : RPCSS
                           : SystemEventsBroker
        SERVICE_START_NAME : LocalSystem

注意其中的 C:Windowssystem32svchost.exe -k netsvcs -p

  1. HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsNTCurrentVersionSvcHost 下创建一个类型为REG_MULTI_SZ的值,名称为:tmpgrp(任意别重复就行),值为:schedule(服务的名称)
  2. HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsNTCurrentVersionSvcHost 下创建一个同名子健(tmpgrp)
  3. HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsNTCurrentVersionSvcHost 找到 netsvcs (步骤一中的 BINARY_PATH_NAME 中的 netsvcs),并将其中的内容拷贝到我们刚创建的 tmpgrp 子键下面:
  1. 再修改一下服务的配置:
sc config MyService binPath= "C:Windowssystem32svchost.exe -k tmpgrp -p"

最后,重启 Windows 就可以了。

参考链接:

如何通过 C++ 实时监听 ETW 事件
如何通过 C++ 实时监听 ETW 事件
【译】调查并确定 Windows 运行速度变慢问题
【译】调查并确定 Windows 运行速度变慢问题
【译】丢失的 WPA 文档 —— 磁盘使用
【译】丢失的 WPA 文档 —— 磁盘使用
【译】丢失的 WPA 文档 —— CPU 调度
【译】丢失的 WPA 文档 —— CPU 调度
【译】丢失的 WPA 文档 —— CPU 采样
【译】丢失的 WPA 文档 —— CPU 采样
如何通过 PDH(Performance Data Helper) 获取性能计数器的值

0

  1. This post has no comment yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注