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

zne*_*eak 10 windows boot windbg

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

我可以在内核模式下使用windbg.当服务遇到这个wmain功能时,我非常想破解,但我遇到了问题.

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

!gflag +ksl
sxe ld MyServiceExecutable.exe
Run Code Online (Sandbox Code Playgroud)

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

zne*_*eak 11

好吧,这可能不是最好的方法,但它有效.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
Run Code Online (Sandbox Code Playgroud)

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

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

kd> !gflag -ksl
    New NtGlobalFlag contents: 0x00400000
        ece - Enable close exception
Run Code Online (Sandbox Code Playgroud)

虽然我们需要EPROCESS指针.我们可以用.process或得到它!process -1 0,但它已经在$proc伪寄存器中:

kd> r $proc
    $proc=0011223344556677
kd> .process
    Implicit process is now 00112233`44556677
Run Code Online (Sandbox Code Playgroud)

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

kd> bp /p @$proc nt!NtMapViewOfSection
kd> g
Run Code Online (Sandbox Code Playgroud)

在下一站中,应加载ntdll(如果需要,检查kn它是否在堆栈中.reload /user),这样就可以设置断点了RtlUserThreadStart.此外,我们正在覆盖断点0,因为我们不需要再打破NtMapViewOfSection(这只会是一个麻烦).

kd> bp0 /p @$proc ntdll!RtlUserThreadStart
kd> g
Run Code Online (Sandbox Code Playgroud)

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

kd> .reload /user
kd> bp /p @$proc MyServiceExecutable!wmain
kd> g
Run Code Online (Sandbox Code Playgroud)