我正在尝试将断点设置为在启动时启动的Windows服务。由于我的一个不幸的错误,该服务强制机器进入一个重启循环:这意味着我无法进入一个稳定的状态,我可以从中部署一个修复程序,显然我不能尝试调试服务在更方便的时候。
我可以在内核模式下使用windbg。当服务遇到wmain
函数时,我非常想破解,但我遇到了问题。
到目前为止,我发现使用以下命令加载图像时可以停止:
!gflag +ksl
sxe ld MyServiceExecutable.exe
问题是,一旦它破裂,我发现自己处于一个空洞的过程中,我显然无法设置断点。 bm MyServiceExecutable!wmain
表示它找不到符号,并且断点将被“延迟”,但它实际上从未设置或达不到。在KERNEL32!BaseThreadInitThunk
上设置断点似乎在所有正在运行的进程中或多或少地随机运行,到目前为止我没有很多运气来停止我的服务。
答案 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文件中;下载。