在debuggingWindows进程时,尽可能早地中断有时会很方便。
Inital Callstack看起来像这样:(例如,当你在DLL_PROCESS_ATTACH
的DllMain
函数中设置一个断点时,你会得到这个)
... 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例程之一中设置一个断点应该很早就打破这个过程。
但是,我不知道如何在debugging器中启动进程之前设置断点。 在Visual Studio(2005)中可能吗? 怎么样? 可以在WinDbg中完成吗?
我将使用类似GFlags的东西来启动调试器,当进程启动。
这里是test.exe的gflags设置示例
这里是调试器的输出。 注意ntdll!LdrpInitializeProcess
的调用堆栈
CommandLine:“C:\ temp \ test.exe”符号搜索路径是:srv *; srv c:\ symbols http://msdl.microsoft.com/download/symbols可执行搜索路径是:
00d20000 00000000
:0000000000d20000 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
我已经发现如何在Visual Studio中完成它。
这里的问题是,在任何汇编函数中设置一个断点将被记住为“数据断点”。 这些断点在进程停止时被禁止,所以即使我在这个函数中设置了一个(我可以这样做,因为如果我在任何DllMain函数中设置了一个断点,我在堆栈上有函数),这个断点将被禁用新的进程运行。
但是对于ntdll.dll(和kernel32.dll),加载地址几乎是固定的,不会改变(至少在重新启动之前)。
因此,在启动过程之前,我只需要重新启用与此NtDll函数对应的地址的数据断点,然后调试器就会在那里停止。