软件纵横谈学习笔记(1)软件断点

int 3指令:

  • 机器码为1个字节,即0xcc
  • 没有数量限制
  • 局限:属于代码类断点,可以让CPU执行到代码段内的某个地址停下来,不适用与数据段和I/o空间
  • 原理解释:在VS中某一处按下F9,实际上是VS在那个位置插入了一条int 3指令(替换了那个字节,替换为cc
一个例子:
软件纵横谈学习笔记(1)软件断点_第1张图片
image.png

打开扫雷:


软件纵横谈学习笔记(1)软件断点_第2张图片
image.png
软件纵横谈学习笔记(1)软件断点_第3张图片
image.png
软件纵横谈学习笔记(1)软件断点_第4张图片
image.png

X ntdll!*readfile*

软件纵横谈学习笔记(1)软件断点_第5张图片
image.png

输入: u ntdll!NtReadFile
ntdll!NtReadFile这个命令可以在上面一个命令里面得到
软件纵横谈学习笔记(1)软件断点_第6张图片
image.png

在此函数地址设一个软件断点:


软件纵横谈学习笔记(1)软件断点_第7张图片
image.png

bp下软件断点,bl列出断点


软件纵横谈学习笔记(1)软件断点_第8张图片
image.png

让软件跑起来:g,可以看到程序加载模块,然后就开始读文件了,断点就命中


软件纵横谈学习笔记(1)软件断点_第9张图片
image.png

命令k:可以查看因为什么命中!


软件纵横谈学习笔记(1)软件断点_第10张图片
image.png

利用反汇编指令继续查看刚才那个断点位置:
软件纵横谈学习笔记(1)软件断点_第11张图片
image.png

调试器隐藏了int 3,如果非要看,怎么看??

先继续g一次,直到:(此时程序跑起来了)


软件纵横谈学习笔记(1)软件断点_第12张图片
image.png

再打开另外一个WinDbg:

软件纵横谈学习笔记(1)软件断点_第13张图片
image.png

以非入侵方式打开的话,只能进行只读操作!(但是这样够了)

软件纵横谈学习笔记(1)软件断点_第14张图片
image.png

反汇编同一个地址:
注意:因为有 int 3指令,故后面的指令被打乱了
Add 的机器码 00


软件纵横谈学习笔记(1)软件断点_第15张图片
image.png

小结:

调试器让一个程序g(运行)起来的时候,才能 把int 3写到内存里面, 当程序执行起来碰到这个断点断(break)下来的时候,把int 3恢复成原来的内容 ,断下来的时候看不到int 3,因为调试器把int 3替换掉的内容又恢复回去,所以我们看到的是原来的指令,g起来的时候,再把这条指令(int 3)写下去

(我的理解:一开始在某一处下了个软件断点,只有在调试运行的时候才将int 3指令写到那个刚刚下断点的地方, 然后程序执行起来碰到cc就会断下来(碰到cc就会触发异常),调试器立即int 3替换掉的内容又恢复回去,所以我们看到的是原来的指令,g起来的时候,再把这条指令(int 3)写下去)

值得注意的是,内存断点被触发后需要将EIP减1,还原内存数据,这样做是为了什么呢?
E912345678这是一条跳转指令,下了0xcc断点后变成了这样:
CC12345678,EIP不减1,CPU会从12345678处继续执行,这样下去,指令全部乱套.所以要将EIP减1
将EIP减1后,CPU重CC处执行,会继续触发异常,陷入死循环,所以要将内存数据还原
但是还原内存数据之后,这个断点下一次就不能使用了.
解决的办法就是恢复数据后触发TF断点,在TF断点触发时将CC重新写入.

举个例子:

E9 12345678 ,在这个指令地方下个int 3断点(软件断点)
将int 3指令写入下断点的地方,调试运行的时候刚执行完cc这个字节,就触发了这个异常,停下来,EIP-1(为什么要减1,如果不减1的话,下次执行就从12345678这里开始执行了,显然这是不行的!),同时,调试器立即int 3替换掉的内容又恢复回去,运行起来的时候,再把这条指令(int 3)写下去

注意:int3 是陷阱异常,陷阱异常就是当指令执行之后才会产生异常,因此,int3异常产生之后,eip就是已经执行了int 3指令之后的eip了,因此收到调试事件之后,需要将EIP减1,才能得到异常真正产生异常的地址;
在下软件断点之前,先读取一个字节的内存保存起来,再写入0xCC,执行完CC字节之后,产生异常,引发中断,中断之后,需将原先的一个字节的数据写回内存中,再将EIP-1

你可能感兴趣的:(软件纵横谈学习笔记(1)软件断点)