我们选择Whole line拷贝整行,Whole Table可以拷贝整个列表的断点信息。
Breakpoints, item 0
Address=00401018
Module=CRACKME
Active=Always
Disassembly=OR EAX,EAX
拷贝下来的信息显示了断点的地址,对应的指令以及激活状态。
程序中断在断点处会在状态栏显示暂停状态。
暂停的原因如下:
接下来我们来了解一下当设置一个断点以后,OD调试器在底层二进制代码是如何将程序中断的,会发生什么变化。
单击鼠标右键选择-Follow in Dump-Selection
我们看看数据窗口中401018地址处的内容:
数据窗口和反汇编代码中我们看到的都是0B C0,对应的是OR EAX,EAX。似乎代码没有什么变化,但是真的没有变化吗?
我们将OR EAX,EAX对应的机器代码读取出来然后写到别处。
该指令将401018地址处的双字值保存到EAX中,我们看看OD的提示框中提示的信息。
在数据窗口中和提示框中显示的都是相同的内容:0B C0。但是,我们按下F7键看看EAX显示的内容。
读出来的401018处的内容并不是OD刚刚显示的0B C0 74 01(小端存储),按双字取出来是0174C00B,而现在显示的是0174C0CC,因此401018处字节值是CC。当我们设置断点后,OD会将对应指令处第一个字节指令替换成CC。但是为了不影响界面显示效果,OD会将CC显示为原字节。但是,我们可以在内存单元中读取出其真实的内容,并且可以在反调试中用此方法来检测断点。所以,我们设置的断点有时候莫名其妙的消失了不要感到奇怪,或许说这是调试器的本身的弱点吧。
除了F2设置断点以外,我们还可以通过命令栏来设置断点,如下:
BP 401018
在NT(2000,XP和2003)系统中我们也可以很容易的给API函数设置断点-我们前面章节中已经介绍过了。要给MessageBoxA设置断点,请输入:
还有一个比BP更加强大的命令BPX可以给引用或者调用了指定API函数的指令都下断点。
下面是BPX给MessageBoxA设置的断点列表。正如你所看到的,OD找到了3处地方调用MessageBoxA,并设置了3个断点。