如何调试在启动时启动的进程?

时间:2014-06-20 03:59:44

标签: windows windbg boot

我正在尝试将断点设置为在启动时启动的Windows服务。由于我的一个不幸的错误,该服务强制机器进入一个重启循环:这意味着我无法进入一个稳定的状态,我可以从中部署一个修复程序,显然我不能尝试调试服务在更方便的时候。

我可以在内核模式下使用windbg。当服务遇到wmain函数时,我非常想破解,但我遇到了问题。

到目前为止,我发现使用以下命令加载图像时可以停止:

!gflag +ksl
sxe ld MyServiceExecutable.exe

问题是,一旦它破裂,我发现自己处于一个空洞的过程中,我显然无法设置断点。 bm MyServiceExecutable!wmain表示它找不到符号,并且断点将被“延迟”,但它实际上从未设置或达不到。在KERNEL32!BaseThreadInitThunk上设置断点似乎在所有正在运行的进程中或多或少地随机运行,到目前为止我没有很多运气来停止我的服务。

2 个答案:

答案 0 :(得分:9)

好吧,这可能不是最好的方法,但它有效。 MSFT,如果我正在做一些愚蠢的事情,请纠正我!

第一部分很好:

kd> !gflag +ksl
    New NtGlobalFlag contents: 0x00440000
        ksl - Enable loading of kernel debugger symbols
        ece - Enable close exception
kd> sxe ld MyServiceExecutable.exe
kd> g

在内核模式下,sxe ld将停止第一次仅加载可执行文件。

当调试器再次停止时,我们就在新创建的进程中。我们不再需要gflag了:

kd> !gflag -ksl
    New NtGlobalFlag contents: 0x00400000
        ece - Enable close exception

虽然我们需要EPROCESS指针。我们可以使用.process!process -1 0来获取它,但它已经在$proc伪注册中:

kd> r $proc
    $proc=0011223344556677
kd> .process
    Implicit process is now 00112233`44556677

从这一点开始,可以在nt符号上设置断点,所以让我们使用NtMapViewOfSection为每个加载的dll调用它。

kd> bp /p @$proc nt!NtMapViewOfSection
kd> g

在下一站中,应该加载ntdll(如果它在堆栈上,请检查kn,如果需要,请.reload /user),这样您就可以在RtlUserThreadStart上设置断点。此外,我们正在覆盖断点0,因为我们不再需要打破NtMapViewOfSection(这只会令人讨厌)。

kd> bp0 /p @$proc ntdll!RtlUserThreadStart
kd> g

所有符号应该在第一个用户线程启动时加载,因此您可以随意在任何地方设置断点。

kd> .reload /user
kd> bp /p @$proc MyServiceExecutable!wmain
kd> g

答案 1 :(得分:0)

使用MS描述的用于调试winlogon的技术,该技术涉及串联使用内核模式和用户模式调试器。请参阅"调试WinLogon"在" Windows调试工具"附带的debugger.chm文件中;下载。