软件纵横谈笔记(3)硬件断点与单步
-
DR7对设置的硬件断点进行描述
-
DR0-DR3存放断点位置
在设置(硬件)断点的时候,调试器帮助我们把我们要监视的地址放到四个(DR0-DR3)当中的一个,然后DR7(对设置的硬件断点进行描述)设置一些标志位,比如我们要监视的这个地址是对它写的时候停下来,还是读写的时候都停下来;监视的长度是多少,R/W0,Len0是对断点0的设置,R/W1,Len1…(还有2,3共计四组标志位); -
DR6是报告断点状态的
我们设置好断点之后,CPU每执行一条指令的时候,CPU都会做匹配,来检查当前这条指令访问的内存是不是和地址匹配,如果匹配 ,就设置DR6里面的标志位,然后一个异常报告给操作系统,操作系统断下来再检查这些标志位,就知道哪一个命中匹配了,DR7的标志位恰好支持4个硬件断点的,故DR4和DR5一直没有用,( 理论上每个CPU可以监视4个地址);软件层:每个线程可以设置4个地址,
image.png
硬件断点不需要改自己的程序;
WinDbg: ba指令设置硬件断点
每个CPu都有一组寄存器,故理论上每个CPU 可以监视四个硬件断点;但是今天软件层次对称多处理,调试器设置硬件断点的时候会(内核调试时候是所有CPU都会设置断点来监视),当应用层次层来调试的时候 ,切换线程状态的时候,操作系统确保针对当前进程的硬件断点是会被正确地设置到物理 CPU当中,
image.png -
8个通用寄存器,+EIP+段寄存器+Eflg
-
Eflg里面有一位(bit 8)即TF位
单步:
如果单步执行的话,TF会被置1,置1之后,让 CPU恢复执行被调试的那个程序 ,CPU每执行一条指令,就检查这个标志位,看到这个标志位置位,立刻触发一个异常,这个程序就又断下来了,CPU看到TF之后,会自动清除 TF位,故在观察的时候我们是很难观察到TF位置1的,因为 CPU看到TF位会清0,否则会出问题,你想,CPU看到TF位就break,看到TF位了,肯定要执行处理异常的那个代码 ,CPU处理异常的那个代码,我们不希望再断下来,所以是很合理的,CPU自动清TF位,然后执行异常处理代码,通知调试器;
(我自己的理解:vs中按下F7,TF会被置1,置1之后CPU会检测到TF为1,同时程序走到这里会断下来,并且CPU会将TF置为0,然后继续下一步,继续F7...而F8大体上和F7一样,只有一处,遇到调用函数的时候(即call 指令),会执行int3指令)
对硬件断点的一些理解:
硬件断点一般有四种断点:
http://blog.csdn.net/wowolook/article/details/7607206
(OD中各种断点的原理)
读写(访问)断点,写入断点,执行断点,I/O断点
- 写入断点,类似于
mov [0x0040 0000],eax
,第一个操作数一定是0xXXXXXXXX - 读写断点,类似于
mov eax,[0x0040 0000]
,第二个操作数一定是0xXXXXXXXX - 执行断点,有点类似于int3(软件断点)
拓展:一般内存分页的访问属性中有可读可写可执行,这里的可执行属性就是说这段代码可以"跑";
还有一个属性为写时复制(http://blog.csdn.net/junbopengpeng/article/details/38072223),