在我们逆向分析一个程序的时候,程序的二进制代码往往是很多的,而危险漫步要分析的代码是其中具体的一部分,怎么在茫茫的代码海洋中一下就找到我们需要分析的代码呢? 这就用到了断点技术,用户需要系统在设置断点处停下来后再进行调试,适当的利用中断来控制程序流程,使我们尽快定位到我们需要分析的代码。 断点是调试器的功能之一,可以让程序中断在需要的地方,从而方便其分析。也可以在一次调试中设置断点,下一次只需让程序自动运行到设置断点位置,便可在上次设置断点的位置中断下来,极大的方便了操作,同时节省了时间。 一般来说断点根据原理和用途不一样又分为指软件断点和硬件断点两种。 软件断点是相对于硬件断点来说的,它不需要硬件的支持,只是简单的通过在代码中设置特征值的方式来实现。当需要在某地址代码处设置软件断点的时候,仿真器会先将此处代码进行备份保护,然后将预先设定好的断点特征值(一般为Ox0000、OxCC等不易与代码混淆的值)写入此地址,覆盖原来的代码数据。当程序运行到此特征值所在的地址时,仿真器识别出此处是一个软断点,便会产生中断。当取消断点时,之前受保护的代码信息会被自动恢复。 int3断点是软件断点的一种,在OD中的快捷键是F2,是一种很常用的断点类型。为什么叫int3断点呢?int3其实是一条汇编指令,int3指令的机器码为OxCC.所以通常也称之为CC指令,程序在执行过程中如果遇到int3指令则会触发异常导致中断。用int3断点的好处是可以设置无数个断点,缺点是改变了原程序指令,容易被软件检测到。 普通的int3断点在OD里只要选中需要设置断点的那一句代码,然后按快捷键F2既可,然后被设置断点的那条语句会高亮显示。 这里来看一个简单的例子,这个程序要求你输入一个字符串。如果你输入的字符串不正确则会弹出一个对话框提示你“Sorry,your stringincorrect”。 现在打开OD,加载这个程序,这里向大家介绍OD的一款插件,叫“Ultra String Reference”,顾名思义它是一个关于字符串参考的插件,其实OD本身是带有的字符串参考功能的,但是相对而言对于中文的支持比较差,因此这个插件诞生了,它对中文的支持效果比较好,有ASCII和UNICODE两种模式。 单击菜单栏里的“插件”,然后选“Ultra String Reference”菜单,接下来选择“Find ASCII”或者“Find UNICODE”,具体运用哪个请自行决定,打开插件以后,这里看到了刚才输入字符串错误的时候提示的信息“Sorry, your string incorrect!”,双击这一句就会来到对应的代码处,来看看这里的代码: 这里可以看出如果向下执行则会提示“yes,you got it!”,如果跳转被执行了就会提示“sorry, your string incorrect!”,而这里跳转不跳转全是由第二句test指令的参数eax说了算,如果eax是O则提示“yes,you got it!”,否则提示“sorry, your string incorrect!”,那eax的值是怎么得来的,就要看看上面的代码了。上面的代码是这样的: 现在按F9让程序运行起来,然后随便输入一个字符串,这里假设是“abcdefg”,然后按“CHECK”按钮,接着程序就被中断了,中断以后按快捷键F8步过,然后下面是1ea指令,lea指令用来传递有效指针,这里继续F8步过,前面说过一般来说函数的返回值是通过eax寄存器传出的,那我们现在看看寄存器里的数据,eax和ecx现在是都是指针,分别指向字符串“monster”和“abcdefg”,我们知道字符串“abcdefg”是我们输入的值,那“monster”是什么呢,看看下面的代码就知道了。 仔细分析一下逻辑就可以看出这里的代码是用来比较两个字符串是不是相同的,我们可以理解成这里把我们输入的字符串和正确的字符串比较,而我们输入的字符串是“monster”,那么程序真正需要的字符串就是“monster”了。运行程序测验一下,输入字符串“monster”,按“CHECK”按钮,可以看到程序弹出了对话框提示“yes,you got it!,测验成功。 但是有些代码在程序运行过程可能会被执行多次,但是我们不需要它每次都被中断,这时就需要用到条件断点了。条件断点,就是在设置断点的时候再给OD-个条件,只有这个条件被满足的时候才会执行中断。在OD里设置一个普通的条件断点只要按快捷键SHIFT+F2既可。 把刚才的CrackMe稍微做一下修改,把字符串比较的代码放到一个函数里,看看反汇编代码,与上一节的就有一点不一样: 按快捷键CTRL+G,在弹出的对话框中输入002F1050然后按“确定”就会看到002F1050处的代码,我们需要在这里设置一个断点,这样当程序猎取编辑框里的字符串后拿来和正确的字符串比较的时候就会被中断,但是字符串比较的函.数会在程序中运用多次,如果每一次都中断,那么对新手来说就会迷失在茫茫的代码海洋中。这时候就需要用到条件断点了,选中这一句代码,然后按SHIFT+F2,在弹出的对话框里输入需要追加的条件,这里输入的条件是“unicode[eax]=”abcdefg””,意思是当eax指向一个unicode字符串“abcdefg”时满足条件,通过前面的代码可以知道eax是指向从编辑框里获得的代码的指针,而我们在测验的时候输入的字符串就是“abcdefg”。这里简述一下常用的条件断点的设置方式:操作符(和C语言基本一致): 序在执行过程中为了实现某些功能(比如弹出对话框)通常会调用一些Win API函数,而函数断点就是在对应的函数的入口点设置一个int3断点,每当程序要调用这个函数的时候就会中断。 看个简单的例子,程序只有一个按钮,但是按钮是灰色的,按不了,这里我们就来充当一回灰色按钮克星。首先来了解一下,让按钮变成灰色一般会用到一个API函数EnableWindow,看看MSDN里给出的解释。函数原型如下: hWnd 指向将要禁止或者激活的窗口的句柄 bEnable 禁止或者激活的标志。如果该参数的值为TRUE则激活,如果为FALSE则为禁止。 这个函数的返回值为BOOL,如果窗口原来就是被禁止的,返回值为非零,如果窗口原来不是被禁止的,返回值为零。 可以看到这里调用了EnableWindow函数,hWncd的值为“CHECK”按钮的句柄,bEnable参数的值为FALSE,通过上面可以知道如果bEnable参数的值为FALSE则为禁止。因为可以确定下来这里的代码就是要使按钮变成灰色了。再注意标记部分,当前执行的代码并非位于程序的模块,而在user32,而我们要分析程序的代码,要返回程序领空才可以,按快捷键ALT+F9让程序执行到用户代码,现在OD里的代码如下: 双击这一句代码,就会弹出汇编窗口,在这里输入“push l”然后点汇编按钮就可以修改此处的汇编代码,修改以后按“取消”,然后在反汇编窗口中点击鼠标右键,选择“复制到可执行文件”-“所有修改”,然后OD会提示你“要把选中内容复制到可执行文件中吗?”,这里选择“所有复制”既可,然后还会弹出一个新的窗口,在这个窗口中再点击鼠标右键,选择“保存文件”,保存修改过的文件后运行测验一下,按钮已经变为可用状态。这里是常用的函数中断方式: 禁止菜单条目EnableMenultem 禁止子窗口 EnableWindow 创建文件句柄CreateFileW(A) 打开文件OpenFile 读取文件 ReadFile 写文件WriteFile 调整文件指针SetFilePointor 退出进程 ExitProcess 创建进程 CreateProcessW(A) 打开注册表项RegOpenKeyW(A) 创建注册表项RegCreateKeyW(A) 删除注册表值RegDeleteValueW(A) 设置注册表值RegSetValueW(A) 获得系统时间GetSysterrTime 发送消息 SendMessageW(A) 传统万能断点hmemcpy |