WinDbg 中的 ba 命令(Break on Access)没有像 Daniel Pravat 和 Mario Hewardt 的 Advanced Windows Debugging 一书中所宣传的那样工作

The ba command (Break on Access) in WinDbg is not working as advertised in the book Advanced Windows Debugging by Daniel Pravat and Mario Hewardt

我正在阅读 Daniel Pravat 和 Mario Hewardt 合着的书 Advanced Windows Debugging: Developing and Administering Reliable, Robust, and Secure Software。我对第 2 章有疑问。

我在 Windows 10 Pro Version 2004 build 19041.572 上使用 WinDBG 10.0.19041.1 X86。我使用 Microsoft Visual Studio 社区 2019 版本 16.7.6 构建了 02sample.exe,并将 GenerateDebugInformation 属性 设置为 DebugFull。我正在调试 02sample.exe.

的 Debug|x86 配置

我正在阅读第 2 章中名为 在 Access 上设置断点 的部分,我发现书中的内容与我所经历的有所不同。

行为上的第一个区别是使用以下命令。

0:000> dt gGlobal

此命令失败并出现以下错误。

Symbol gGlobal not found.

以下命令有效。

0:000> dt 02sample!gGlobal
*** WARNING: Unable to verify checksum for 02sample.exe
gGlobal
   +0x000 m_ref            : 0n0

下一个行为差异是使用以下命令。

0:000> ba w4 gGlobal+0

根据以下输出,这似乎有效。

0:000> bl
     0 e Disable Clear  00969130 w 4 0001 (0001)  0:**** 02sample!gGlobal

但是,没有命中断点。我不知道为什么。

符号可能尚未加载
尝试 .reload /f 或 .reload /f foo.exe
在尝试不合格的 dt gGlobal
之前 合格的 foo!gGlobal 将始终有效,因为它加载了符号

检查 !sym noisy

0:000> !sym noisy
noisy mode - symbol prompts off
0:000> dt gGlobal
Symbol gGlobal not found.
0:000> dt gGlobal
Symbol gGlobal not found.
0:000> dt gGlobal
Symbol gGlobal not found.
0:000> dt awd!gGlobal
SYMSRV:  BYINDEX: 0x2
snipxxxxxxxxxxxxxxx
DBGHELP: awd - public symbols & lines
        C:\Users\XXX\Desktop\awd\Chapter2\Debug\awd.pdb
   +0x000 m_ref            : 0n0
0:000>

这本书告诉你如何设置 ba 断点?
在系统断点处停止时无法在模块上设置 ba 断点
因为系统会重置线程上下文

您必须转到入口点,然后按照 windbg 的建议设置 ba 断点,您这样做了吗?

:\>cdb -c "g @$exentry;ba w4 awd!gGlobal;g;u .;kb;q" awd.exe |awk "/Reading/,/quit/"
0:000> cdb: Reading initial command 'g @$exentry;ba w4 awd!gGlobal;g;u .;kb;q'
*** WARNING: Unable to verify checksum for awd.exe
Breakpoint 0 hit
awd!Global::Global+0x21:
00a23461 8b45fc          mov     eax,dword ptr [ebp-4]
00a23464 83c404          add     esp,4
00a23467 3bec            cmp     ebp,esp
00a23469 e895ddffff      call    awd!ILT+510(__RTC_CheckEsp) (00a21203)
00a2346e 8be5            mov     esp,ebp
00a23470 5d              pop     ebp
00a23471 c3              ret
00a23472 cc              int     3
ChildEBP RetAddr  Args to Child
0026f9d4 00a21687 0026f9ec 522c59df 00a21670 awd!Global::Global+0x21
0026f9dc 522c59df 00a21670 00a2b208 0026fa50 awd!`dynamic initializer for 'gGlobal''+0x17
0026f9ec 00a24a5e 00a2b000 00a2b30c 91b61bad ucrtbased!_initterm+0x3f
0026fa50 00a2498d 0026fa60 00a24d08 0026fa6c awd!__scrt_common_main_seh+0xbe
0026fa58 00a24d08 0026fa6c 7683ed6c 7ffde000 awd!__scrt_common_main+0xd
0026fa60 7683ed6c 7ffde000 0026faac 773337eb awd!wmainCRTStartup+0x8
0026fa6c 773337eb 7ffde000 761f96f6 00000000 kernel32!BaseThreadInitThunk+0xe
0026faac 773337be 00a21145 7ffde000 00000000 ntdll!__RtlUserThreadStart+0x70
0026fac4 00000000 00a21145 7ffde000 00000000 ntdll!_RtlUserThreadStart+0x1b
quit:

如果你偶然误解了 wmain() 的入口点并在到达 wmain() 时设置了一个 ba 中断,它可能永远不会被命中,因为有问题的代码已经被执行了