如何调试在启动时启动的进程? [英] How do I debug a process that starts at boot time?

查看:216
本文介绍了如何调试在启动时启动的进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Windows服务中设置一个在启动时启动的断点.由于不幸的错误,该服务迫使计算机进入重新启动循环:这意味着我无法进入可以部署修补程序的稳定状态,而且显然我无法尝试调试该服务在更方便的时间.

I am trying to set a breakpoint into a Windows service that starts at boot time. Because of an unfortunate mistake on my end, the service forces the machine into a reboot loop: this means that I can't get to a stable state from which I could deploy a fix, and obviously I can't try to debug the service at a more convenient time.

我可以在内核模式下使用windbg.我非常想在服务命中wmain功能时中断,但是我遇到了问题.

I can use windbg in kernel mode. I'd very much like to break when the service hits the wmain function, but I'm having issues with that.

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

Up to now, I found that I can stop when the image is loaded by using the following commands:

!gflag +ksl
sxe ld MyServiceExecutable.exe

问题在于,一旦中断,我发现自己陷入了一个空白进程,显然我无法设置断点. bm MyServiceExecutable!wmain表示找不到符号,并且断点将推迟",但是实际上从未设置或到达该断点.在KERNEL32!BaseThreadInitThunk上设置断点似乎在所有正在运行的进程中或多或少地随机起作用,到目前为止,我没有很多运气可以停止服务.

The problem is that once it breaks, I find myself in an empty process, in which I am apparently unable to set breakpoints. bm MyServiceExecutable!wmain says that it can't find the symbol and that the breakpoint will be "deferred", but it is effectively never set or reached. Setting a breakpoint on KERNEL32!BaseThreadInitThunk seems to work more or less at random across all the processes running and I didn't have a lot of luck with it to stop in my service so far.

推荐答案

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

Alright, this might not the best way to do it, but it worked. MSFTs, please correct me if I'm doing something dumb!

第一部分很好:

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首次停止加载可执行文件.

In kernel mode, sxe ld will stop the first time the executable is loaded only.

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

When the debugger stops again, we're inside the freshly created process. We don't need the gflag anymore:

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

尽管我们将需要EPROCESS指针.我们可以用.process!process -1 0来获得它,但是它已经在$proc伪寄存器中:

Though we're going to need the EPROCESS pointer. We can get it with .process or !process -1 0, but it is already in the $proc pseudo-register:

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

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

From this point it's possible to set breakpoints on nt symbols, so let's use NtMapViewOfSection as it's called for each dll loaded.

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

在下一个停止处,应加载ntdll(如果在堆栈中,请在kn中进行检查,如果需要,请在.reload /user中进行检查),以便可以在RtlUserThreadStart上设置断点.另外,我们将覆盖断点0,因为既然我们不再需要在NtMapViewOfSection上中断(这将是一个麻烦).

On the next stop ntdll should be loaded (check with kn if it's on the stack, .reload /user if necessary), so you can set a breakpoint on RtlUserThreadStart. Also, we are overwriting breakpoint 0, because since we don't need to break on NtMapViewOfSection anymore(it would just be a nuisance).

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

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

All symbols should have been loaded by the time the first user thread starts, so you're free to set your breakpoint wherever you want.

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

这篇关于如何调试在启动时启动的进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆