设置断点造成的风险
通过指定内存地址或符号加上偏移量来设置 断点 时,不得将此断点置于指令中间。
例如,请考虑以下反汇编代码。
770000f1 5e pop esi
770000f2 5b pop ebx
770000f3 c9 leave
770000f4 c21000 ret 0x10
770000f7 837ddc00 cmp dword ptr [ebp-0x24],0x0
前三个指令只有一个字节长。 但是,第四条指令的长度为三个字节。 (它包括字节0x770000F4、0x770000F5和0x770000F6.) 如果要使用 bp、 bu 或 ba 命令在此指令上放置断点,则必须指定0x770000F4地址。
如果使用 ba 命令在0x770000F5地址中放置断点,处理器会在该位置放置断点。 但永远不会触发此断点,因为处理器将0x770000F4视为指令的实际地址。
如果使用 bp 或 bu 命令在 0x770000F5 地址中放置断点,调试器会在该位置写入断点。 但是,由于调试器创建断点的方式,此断点可能会损坏目标:
调试器保存0x770000F5的内容,并使用断点指令覆盖此内存。
如果尝试在调试器中显示此内存,调试器不会显示它已写入的断点指令。 相反,调试器会显示“应该”的内存。 也就是说,调试器会显示原始内存,或者自插入断点以来对该内存所做的任何修改。
如果使用 BC 命令删除断点,调试器会将原始内存还原到其正确位置。
在0x770000F5放置断点时,调试器会保存此字节,并在此处写入中断指令。 但是,当应用程序运行时,它会到达0x770000F4地址,并将此地址识别为多字节指令的第一个字节。 然后,处理器尝试将0x770000F4、0x770000F5,以及以后的一些字节合并到单个指令中。 此组合可以创建各种行为,这些行为都不可取。
因此,使用 bp、 bu 或 ba 命令放置断点时,请确保始终将断点放在正确的地址。 如果使用 WinDbg 图形界面添加断点,则无需担心这种情况,因为会自动选择正确的地址。
不明确的断点解析
在调试器引擎的版本 10.0.25310.1001 及更高版本中,现在支持不明确的断点解析。 不明确的断点允许调试器在某些断点表达式解析为多个位置的情况下设置断点。 有关详细信息,请参阅 不明确的断点解析。