对话框回调函数
上一篇文章带领大家找过主窗口的回调函数了,相信大家对回调函数一定不陌生了,对话框的回调函数实际上和主窗口的回调函数一样。
我们来看看上文中讲的显示对话框的函数:
DialogBox(hInst, (LPCWSTR)IDD_DIALOG1, NULL, DiaLogProc);
我们看到,第四个参数就是对话框的回调函数。
在调用这个函数的时候,肯定会将参数压栈,那我们直接到堆栈窗口找函数地址,就能很容易地找到回调函数了:
这里实际上OD已经帮我们解析出来了很多东西:
我们能很清晰地看到DialogBox()
函数的几个参数,我们直接根据函数地址跟到回调函数就找到了,我们在对话框回调函数中也可以做条件断点
那么我们需要逆向出当点击了取消按钮后底层做了什么工作
- 我们首先来看一下到底是哪个消息触发了这个消息,我们前面将结果消息类型了,我们也知道是当鼠标左键点击之后触发了消息,那么到底是鼠标左键按下(WM_LBUTTONDOWN),还是鼠标左键弹起(WM_LBUTTONUP)时呢?
- 这里大家可以去试一下,当鼠标左键按下的时候,代码很明显没有运行,当我们鼠标左键放开的时候,能很直观地看到代码运行了。
- 经过上面的操作,我们已经知道了我们要做断点的消息是什么了
我们知道了要做断点的条件,根据上一篇文章讲解的,直接做条件断点就可以了:
- 堆栈窗口:
我们能看到回调函数地址,跟到反汇编:
大家可以看到,这个就是对话框回调函数了,我们根据上篇文章的讲解做断点即可。
消息断点讲解
我们在逆向比较简单的应用程序的时候,可以直接找窗口的回调函数,那么当我们要逆向别人的程序的时候,别人发布的应用程序肯定不会像我这个应用程序这样简单,他们的有应用程序很复杂,那么我们该逆向呢?
我们需要逆向出当点击了取消按钮后底层做了什么工作:
- 我们首先来看一下到底是哪个消息触发了这个消息,我们前面将结果消息类型了,我们也知道是当鼠标左键点击之后触发了消息,那么到底是鼠标左键按下(WM_LBUTTONDOWN),还是鼠标左键弹起(WM_LBUTTONUP)时呢?
- 这里大家可以去试一下,当鼠标左键按下的时候,代码很明显没有运行,当我们鼠标左键放开的时候,能很直观地看到代码运行了。
- 经过上面的操作,我们已经知道了我们要做断点的消息是什么了(WM_LBUTTONDOWN),那么我们就来到OllyDbg来做一下消息断点:
1. 找到按钮:
我们可以看到在OD中有这样一行按钮:
我们先让应用程序运行,对话框运行之后,我们点击这里的W按钮,就可以看到很多窗口句柄等信息:
这里有当前应用程序显示出来的所有窗口,我们发现ClassProc已经帮我们找到了定义窗口类的时候写进去的回调函数,我们可以鼠标右键单击我们想要找的窗口,点击跟随ClassProc,就可以找到系统定义的回调函数了。注意这是系统定义的默认回调函数!!!
我们在这里就可以设置消息断点了:
当我们设置了消息断点之后,我们发现有两处都做了断点:
这是因为不管是哪个按钮,都会调用系统定义的同一个回调函数。
我们来点击按钮测试一下:
这时候我们发现应用程序断在了系统提供的默认的回调函数这里,但是我们想让它停在我们自己写的回调函数,该怎样操作?
你也可以一直单步跟下去,但是这样真的太浪费时间了,而且没有人会这样做。
我们发现,系统提供的回调函数,地址都是7…,说明在应用程序领空,应该是在DLL领空。
这里给大家教一种技巧:大家想想,系统提供的默认回调函数,是不是迟早会调用我们写的那个回调函数?那么我们来到Memory map窗口:
大家都是学过PE结构的人,相信大家都能理解上述的data,rdata,rsrc几段吧?那么我们在代码断下一个访问断点:
这样呢,当访问应用程序的代码段的时候,也就是系统提供的默认回调函数调用我们自己编写的回调函数的时候,就会在我们自己写的那个回调函数上做断点了。
今天的文章就分享到这里,如果大家发现文章中有错误之处或者是个人理解不到位的地方,还请大家指出来,我会非常虚心地学习,希望大家共同进步!!!