还记得上一篇《OllyDBG 入门系列(三)-函数参考》中的内容吗?在那篇
文章中我们分析后发现一个 ESI 寄存器值不知是从什么地方产生的,要弄清这个
问题必须要找到生成这个 ESI 值的计算部分。今天我们的任务就是使用 OllyDBG 的内存断点功能找到这个地方,搞清楚这个值是如何算出来的。这次分析的目标程序还是上一篇的那个 crackme,附件我就不再上传了,用上篇中的附件就可以了。下面我们开始:
还记得我们上篇中所说的关键
代码的地方吗?温习一下:
00401323 |. E8 4C010000 CALL <JMP.&USER32.GetWindowTextA> ; GetWindowTextA
00401328 |. E8 A5000000 CALL CrackHea.004013D2 ; 关键,要按F7键跟进去
0040132D |. 3BC6 CMP EAX,ESI ; 比较
0040132F |. 75 42 JNZ SHORT CrackHea.00401373 ; 不等则完蛋
我们重新用 OllyDBG 载入目标程序,F9运行来到上面
代码所在的地方(你上次设的断点应该没删吧?),我们向上看看能不能找到那个 ESI 寄存器中最近是在哪里赋的值。哈哈,原来就在附近啊:

我们现在知道 ESI 寄存器的值是从内存
地址 40339C 中送过来的,那内存
地址 40339C 中的数据是什么时候产生的呢?大家注意,我这里信息窗口中显示的是 DS:[0040339C]=9FCF87AA,你那可能是 DS:[0040339C]=XXXXXXXX,这里的 XXXXXXXX 表示的是其它的值,就是说与我这里显示的 9FCF87AA 不一样。我们按上图的
操作在数据窗口中看一下:

从上图我们可以看出内存
地址 40339C 处的值已经有了,说明早就算过了。现在怎么办呢?我们考虑一下,看情况程序是把这个值算出来以后写在这个内存
地址,那我们要是能让 OllyDBG 在程序开始往这个内存
地址写东西的时候中断下来,不就有可能知道目标程序是怎么算出这个值的吗?说干就干,我们在 OllyDBG 的菜单上点 调试->重新开始,或者按 CTR+F2 组合键(还可以点击工具栏上的那个有两个实心左箭头的图标)来重新载入程序。这时会跳出一个“进程仍处于激活状态”的对话框(我们可以在在调试选项的安全标签下把“终止活动进程时警告”这条前面的勾去掉,这样下次就不会出现这个对话框了),问我们是否要终止进程。这里我们选“是”,程序被重新载入,我们停在下面这一句上:
00401000 >/$Content$nbsp;6A 00 PUSH 0 ; pModule = NULL
现在我们就要来设内存断点了。在 OllyDBG 中一般我们用到的内存断点有内存访问和内存写入断点。内存访问断点就是指程序访问内存中我们指定的内存
地址时中断,内存写入断点就是指程序往我们指定的内存
地址中写东西时中断。更多关于断点的知识大家可以参考 论坛精华7->基础知识->断点技巧->断点原理 这篇 Lenus 兄弟写的《如何对抗硬件断点之一 --- 调试寄存器》
文章,也可以看这个帖:http://bbs.pediy.com/showthread.php?threadid=10829。根据当前我们调试的具体程序的情况,我们选用内存写入断点。还记得前面我叫大家记住的那个 40339C 内存
地址吗?现在我们要用上了。我们先在 OllyDBG 的数据窗口中左键点击一下,再右击,会弹出一个如下图所示的菜单。我们选择其中的转到->表达式(也可以左键点击数据窗口后按 CTR+G 组合键)。如下图:

现在将会出现这样一个对话框:

我们在上面那个编辑框中输入我们想查看内容的内存
地址 40339C,然后点确定按钮,数据窗口中显示如下:

我们可以看到,40339C
地址开始处的这段内存里面还没有内容。我们现在在 40339C
地址处后面的 HEX 数据或 ASCII 栏中按住左键往后拖放,选择一段。内存断点的特性就是不管你选几个字节,OllyDBG 都会分配 4096 字节的内存区。这里我就选从 40339C
地址处开始的四个字节,主要是为了让大家提前了解一下硬件断点的设法,因为硬件断点最多只能选 4 个字节。选中部分会显示为灰色。选好以后松开鼠标左键,在我们选中的灰色部分上右击:

经过上面的
操作,我们的内存断点就设好了(这里还有个要注意的地方:内存断点只在当前调试的进程中有效,就是说你如果重新载入程序的话内存断点就自动删除了。且内存断点每一时刻只能有一个。就是说你不能像按 F2 键那样同时设置多个断点)。现在按 F9 键让程序运行,呵,OllyDBG 中断了!
7C932F39 8808