调试Windows进程时,有时可以尽可能早地中断。
Inital Callstack看起来像这样:(例如,当您在DllMain
上的DLL_PROCESS_ATTACH
函数中设置断点时,可以得到此信息)
...
ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 bytes
ntdll.dll!_LdrpRunInitializeRoutines@4() + 0x205 bytes
> ntdll.dll!_LdrpInitializeProcess@20() - 0x96d bytes
ntdll.dll!__LdrpInitialize@12() + 0x6269 bytes
ntdll.dll!_KiUserApcDispatcher@20() + 0x7 bytes
因此,在其中一个ntdll例程中设置断点应该会很快打破这个过程。
但是,在调试器中启动进程之前,我无法弄清楚如何在处设置断点。是否可以在Visual Studio(2005)中使用?怎么样?可以在WinDbg中完成吗?
答案 0 :(得分:6)
我会使用GFlags之类的东西在进程启动时启动调试器。
以下是test.exe的示例gflags设置
这是调试器输出。注意带有ntdll!LdrpInitializeProcess
CommandLine:“C:\ temp \ test.exe” 符号搜索路径是: SRV *; SRV C:\符号 http://msdl.microsoft.com/download/symbols 可执行搜索路径是:ModLoad: 00000000
00d20000 00000000
00d28000
image0000000000d20000 (1b40.464): Break instruction exception - code 80000003 (first chance) ntdll!LdrpDoDebuggerBreak+0x30: 00000000
77c7cb60 cc int 3 0:000> k Child-SP RetAddr
致电网站000000000012ed70 00000000
77c32ef5 NTDLL!LdrpDoDebuggerBreak +的0x30 000000000012edb0 00000000
77c11a17 NTDLL!LdrpInitializeProcess + 0x1b4f 000000000012f2a0 00000000
77bfc32e NTDLL! ?? :: FNODOBFM ::string'+0x29220 00000000
0012f310 00000000`00000000 NTDLL!LdrInitializeThunk + 0xe
或者您可以在调试器中打开像Windbg这样的进程,默认情况下会突破ntdll!LdrpInitializeProcess
。
HTH
答案 1 :(得分:1)
我已经找到了如何在Visual Studio中完成它。
这里的问题是,在任何汇编函数中设置断点都将被记为“数据断点”。一旦进程停止,这些断点就会被禁用,所以即使我在这个函数中设置了一个(我可以这样做,因为如果我在任何DllMain函数中设置断点,我在堆栈上有函数)这个断点将被禁用新流程运行。
然而对于ntdll.dll(和kernel32.dll),加载地址几乎是固定的,不会改变(至少在重启之前)。
因此,在开始该过程之前,我只需要为与此NtDll函数对应的地址重新启用数据断点,然后调试器就会停在那里。