软件断点的事理是用一条软件断点指令替代断点地址所在位置的操作码字节。在 x86 中,软件断点的指令是 int 3 指令,操作码值是 0xCC。
正常情形下,实行软件断点指令的时候,操作系统会将掌握权转移给监控被调试进程的调试器(比如 IDA 的)。利用这种办法,就可以做一些反调试的操作,比如有的程序会故意天生一些非常,这些非常会被调试器捕获到,以是就很烦。还有一个经典的反调试操作,便是自己fork一个子进程调试自己。这样IDA就无法调试该进程了,由于同一时候,一个进程只能被一个进程附加(调试)。
一些CPU支持硬件赞助的断点,用来代替软件断点。硬件断点利用专用的寄存器配置。在x86中,这些寄存器叫 DR0-7。
硬件断点是有数量限定的,在x86中一样平常是4个,利用的时候须要把稳一下,其他平台可以查一下文档。
设置硬件断点硬件断点设置方法:先设置普通断点,编辑断点,选中 [hardware],并配置右下角选项,如图:
硬件断点模式:
Read:断点地址被读取时命中Write:断点地址被写入时命中Execute:断点地址被实行时命中Size:地址的范围大小,Execute写1即可,Read/Write的大小可以设置为 1、2 或4 等字节。把稳我们的断点地址须要按照设置的大小对齐,如果将大小设置为 2 字节,则断点的地址必须为字对齐(2 字节的整数倍)。以在地址0804C834h 处设置的一个 4 字节写入式断点为例,这个断点将由 1 字节写入 0804C837h 、2 字节写入0804C836h 、4字节写入0804C832h 等操作触发。当我们选中了 Read/Write 模式的时候,实际上设置的是一个内存断点,常日我们会这样操作:
在 IDA-View 窗口中按下 G 键,定位到目标内存,这个地址一样平常是在数据区,再按下 F2 键设置断点,这个时候默认便是硬件断点了。当程序的任何指令访问(读取/写入)这个地址的时候,都会触发内存断点。
条件断点断点设置的对话框里面有一个 condition 输入框,这里我们可以输入条件。
IDA 的条件断点利用的是 IDC 表达式。非零值为真,知足时触发条件断点,这个做过开拓的该当都用过,调试循环好用。
断点表达式的一些示例:
EAX == 100 // break if eax holds the value 100ESI > EDI // break if esi is greater than ediDword(EBP-20) == 10 // Read current stack frame (var_20) and compare to 10GetRegValue("ZF") // break if zero flag is setEAX = 1 // Set EAX to 1, this also evaluates to true (non-zero)EIP = 0x0804186C // Change EIP, perhaps to bypass code
硬件断点的一个例子
材料传到了 p17
这是一个 linux下64位程序,以是我们须要利用 dbgsrv 下的 linux_server64 来调试。
将该程序上传到 kali 虚拟机上,并且启动:
将实验文件拖入 windows 的 ida 中,等待剖析完成,选择调试器,设置进程参数:
这里的ip便是 kali 虚拟的 ip 了。
然后在 start 函数上设置断点,由于这里是壳代码,以是我们可以直接设置软件断点:
设置好断点后,启动进程,中间会弹出几个窗,可能还会提示你输入文件没找到,但是找到一个匹配的程序,反正点连续就ok了,IDA进入调试界面:
这段的末了一行是一个分支跳转,我们按 F8,看看进入那个分支:
进入了左边,按下F7,连续程序:
进入到了一个新的函数,这里的全体函数比较长,我们看看结束语句在哪里:
是在这个块这里,我们利用 F4 让程序直接运行到这里:
后面还有很多函数的调用,就不一个一个贴了,反正便是 F4 + F7 合营,逐步找到我们的目标代码:
到了这里的时候,我们在 retn 位置按下 F7,IDA 会给出一个提示:
说IDA检讨到了 rip 寄存器指向了一个没有被定义成代码的位置。这解释了这些代码被壳给包装成了数据,IDA在剖析的时候把这些代码识别成了数据,当程序真正运行起来的时候,壳会将这些数据解密,规复成指令来实行。
我们点击Yes,IDA会将目标区域阐明成指令:
这里便是解密之后的指令了。
我们可以在这里设置断点,当下次剖析的时候,就可以直接跳转过来,不须要重新剖析一遍。但是有个问题,程序是在运行时解密的,如果我们利用软件断点,在解密时就会导致数据缺点,以是这里须要利用硬件断点:
我们关闭 IDA,重新调试一下看看效果:
可以看到 IDA 直接停在了我们上次设置断点的位置,但是有个问题,便是这里IDA还是认为它是数据,以是我们按一下C键,逼迫将它转换成代码,创造按了没啥用,有个骚操作便是从断点指令开始往下选中一大块数据(完备包含上次看到的所有指令,反正是数据区,选多点没事),点击U键,然后再按C键即可:
可以看到和上次手动剖析的指令是一样的。
图太多了,这篇就先到这里,觉得这个系列会很长长长的样子!
!
!