使用OllyDbg从零开始Cracking 第十章-断点
第十章-断点本章将介绍各种类型的断点。断点可以让你在程序代码执行到合适的时候暂停下来。这次我们的实验的对象还是CrueHead’a的CrackMe。普通断点这是一个很普通的断点,我们前面章节已经使用了。在SoftIce中我们可以使用BPX命令来设置断点。OD中可以使用BP命令或者F2快捷键来设置断点。也可以再按一次F2快捷键来取消断点。我们来到CrueHead’a的CrackMe的入口点处。举个例子,拿401018这行来说吧,按F2键-这行就会以红色突出显示,在该地址处设置的断点就会加入了断点列表中。我们来看看断点列表刚刚设置的断点,此时该断点是激活状态。断点列表中Active栏显示的是Always。在该行上单击鼠标右键会弹出一些操作断点的菜单项。Remove:从列表中删除断点。Disable:禁用断点但并不将断点从列表中删除。禁用时,断点并不会触发。Edit condition:给断点设置触发条件,我们后面再来讨论。Follow indisassembler:在反汇编窗口中显示断点。Disable all orenable all:禁用/启用列表中的全部断点。这里没有启用的选项,因为列表中唯一的断点没有被禁用。Copy to Clipboard:把选中断点的信息复制到剪贴板。我们来实验一下。我们选择Whole line拷贝整行,WholeTable可以拷贝整个列表的断点信息。Breakpoints, item 0 Address=00401018 Module=CRACKME Active=Always Disassembly=OR EAX,EAX拷贝下来的信息显示了断点的地址,对应的指令以及激活状态。按下F9键-CrackMe运行起来了。然后正如猜想的一样中断了下来。在状态栏显示暂停状态。暂停的原因如下:我们来了解一下当设置一个断点以后,二进制代码会发生什么变化。单击鼠标右键选择-Follow in Dump-Selection我们看看数据窗口中401018地址处的内容:我们初看一下数据窗口中的内容和反汇编代码中代码是一样的:数据窗口和反汇编代码中我们看到的都是0B C0,对应的是OREAX,EAX。似乎代码没有什么变化,但是真的没有变化吗?我们保留401018处的断点,重新加载CrackMe。我们将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设置断点,请输入:并且你必须指定API函数的确切名称,而且大小写敏感。还有一个比BP更加强大的命令BPX可以给引用或者调用了指定API函数的指令都下断点。下面是BPX给MessageBoxA设置的断点列表。正如你所看到的,OD找到了3处地方调用MessageBoxA,并设置了3个断点。还有一种设置断点的方法:在反汇编窗口中你想设置断点的那一行双击机器码即可。如果想删除的话,再双击一次即可。
内存断点内存访问断点有时候也称之为BPM,但是不要与SoftIce中的BPM弄混淆了,这二者是完全不同的。这种类型的断点修改内存页的访问属性。当前我们设置了内存断点。任何代码访问(读,写或者执行代码)了该处代码的话,都会触发异常。我们来看一个例子:现在我们在CrackMe的入口点处,我们尝试设置一个内存断点。单击鼠标右键选择-Goto-Expression输入4020CA,转到这个地址。我们在4020CA处设置4个字节的内存断点。当前有指令尝试读取这几个字节的时候,就会中断下来。我们这4字节上单击鼠标右键选择-Breakpoint-Memory,onaccess,这里不一定要设置的4个字节,你也可以设置长一点,也可以设置短一点。内存访问断点有两个缺点:1.它们不会出现断点列表中和其他的地址。所以,你必须记得设置在什么地址处。2.不能同时设置多个内存断点。如果你设置了一个那么你之前设置的就会被自动删除。当运行到401007地址处的时候,该地址处指令试图写入内容到4020CA内存单元中。下面状态栏清楚了描述了暂停的原因:当指令尝试将EAX的值写入4020CA内存单元的时候,OD会断下来。记住,当我们对指定内存单元没有写权限,尝试写入的时候会触发异常,OD会拦截到这个异常,并中断下来,我们看到断下来的时候,OD已经将内存页的访问属性设置正常了。如果此时我们按F7键,EAX的值会被写入到4020CA内存单元中,此处的异常不会再次发生。400000h的值成功写入。我们运行起来,由于内存访问断点仍然存在,如果程序尝试访问4020CA内存单元的话,会再次触发异常。正如你看到的,该指令尝试读取4020CA内存单元的内容,证明内存访问断点又触发了。再次按F7键运行一步,将4020CA内存单元内容读取出来并保存到EAX中。再次F9键运行起来,还会不会出发内存断点呢?对,依然会。OD会再次中断在尝试读取4020CA内存单元的指令处,这是一个push指令,该指令会尝试将4020CA内存单元的内容压入堆栈。要删除内存断点的话,可以数据窗口中单击鼠标右键选择-Breakpoint-Remove memory breakpoint。你还可以设置一个新的内存断点,旧的内存断点会自动被删除。“Memory,on access”是内存访问断点(读或者写),“Memory,on write”是内存写断点。OD也可以对区段设置内存断点,我们选择菜单项View-Memory,也可以按工具栏中的按钮打开内存窗口。这个列表包含了CrackMe加载的一些区段以及其加载的一些DLL的区段,如图我们选中了以401000开头的区段。在选中部分上单击鼠标右键选择-Set Memory breakpoint on access。下面还有Set memory breakpoint on write的选项,但是这里我们选择Set memory breakpoint on access并且运行起来。中断在了下一行指令上。因为试图执行401002处的代码,而当前代码段设置了内存访问断点,尝试执行当前代码段的任何一条指令都会触发内存访问断点。我们对kernel32的代码段设置内存访问断点,列表的下面可以找到。 我们选择-Set memory breakpoint on access,当试图读取/写入/执行Kernel32代码段的时候就会中断下来,我们运行起来。从堆栈的顶部来看,调用API函数的时候中断下来了。当前执行kernel32.dll中的第一个API函数的时候中断下来了,从堆栈中我们可以看到返回地址:在返回地址上单击鼠标右键选择-Follow in Disassembler。返回地址是401007,是调用GetModuleHandleA后面的一行。正下方是调用FindWindowA,调用这个函数的时候不会触发内存访问断点,应该这个函数是属于另一个DLL-user32.dll的。如果你再次运行的话,会中断在下一条指令处,因为下一条指令也属于kernel32的代码段,所以执行GetModuleHandleA的每一条指令的时候内存访问断点都会触发,所以这个时候我们可以选择-Removememory breakpoint删除内存断点。如果你想要返回到主程序模块中,可以选择主菜单项-Debug-Executetill user code。有的时候,这个方法不起作用。我们可以在函数返回指令处设置断点,然后运行起来,等中断下来以后,再F7或者F8单步到主程序的代码中。这里Execute till user code起作用了,我们回到了主程序模块的代码中。后面我们会介绍哪些情况下这种方式不奏效。现在,你可以再次对kernel32.dll的代码段设置内存访问断点了,让程序调用Kernel32.dll中的API函数的时候再次中断下来。此外,如果程序会检测函数首字节是否为0xCC的话,这个时候我们使用bpMessageBoxA命令下断点就无效了,这个时候我们可以尝试一下内存访问断点。我们来看个例子:MessageBoxA在我的机器上的对应的地址是77D504EA。通过单击鼠标右键选择-Goto-Expression输入该函数的名称:
第一条指令被高亮显示:
这里我们单击鼠标右键选择-Breakpoint-Memory,on access或者memory,on write,这里我选择Memory,onaccess然后运行起来。选择help-Register,然后输入任意用户名和序列号:单击OK。在同一个API函数中,如果通过bp命令设置断点会被程序检测而导致断点失效的话,也许设置内存访问断点可以绕过这个检测。设置内存访问断点这个方法也可以通过检测内存页的属性并恢复内存页的属性来进行保护,但是这在反调试技巧中并不常见。下一章,我们将介绍硬件断点和消息断点,条件断点我们会在后面介绍。
本系列文章汉化版转载看雪论坛
感谢原作者:RicardoNarvaja(西班牙人) 原作者个人主页:http://www.ricardonarvaja.info/
感谢热心翻译的朋友:1~3章译者:BGCoder4~58章译者:安于此生
全集配套程序下载地址:链接: http://pan.baidu.com/s/1eQzTWfo 密码: vytv
[快捷回复]-感谢楼主热心分享! [吾爱汇编论坛52HB.COM]-感谢分享,虽说用的不多,有备无患,nice,谢谢,给力非常感谢破解思路 很强大啊,楼主厉害 不错,感谢楼主分享! 楼主辛苦了,谢谢分享! 楼主威武!!!!!! 谢谢分享新手
页:
[1]
2