详谈消息断点
前两天看了加密与解密第四版的消息断点部分似懂非懂(怪我太菜!),在网上查找了一些资料后又结合实例琢磨了好长时间才把消息断点搞明白,
想着总结一下希望能帮助到需要帮助的人(我要有理解不对的地方还请路过的大佬们指点一二:))。
了解Windows编程的人都知道windows是消息驱动的。我们每点击一下按钮,每移动一次鼠标windows都会产生一个消息。
这些消息最终会由消息处理函数(Wndproc函数)处理。首先我们要知道我们设置消息断点的目的是为了找到在Wndproc函数(回调函数)中处理此消息的代码,从而分析其具体做了什么操作。
下面我们以看雪加密与解密(第四版)第五章拆解时间限制的程序为例讲解消息断点(主要是了解消息断点)。
我们先运行一下程序,然后我们来分析有关消息断点的几个问题。
消息断点的基本原理
我们用OD运行程序后点击查看-》窗口,会显示出程序的各个窗口和控件的信息。
如果我们想捕获某个按钮或控件所产生的的消息就在相关按钮或控件处右击-》在ClassProc上设置消息断点, 其会弹出一个窗口然后我们选择我们想要捕获的消息。
假如这里我们需要捕获点击Exit按钮所产生的的消息(即松开鼠标右键WM_LBUTTONUP),
我们在Exit控件那一列右击-》在ClassProc上设置消息断点,弹出一个窗口,我们设置捕获的消息WM_LBUTTONUP。
然后我们发下所有的**按钮控件**都被设置了消息断点,这是因为window系统为相同种类的控件(这里是Button按钮控件)构造了一个公共的**系统消息处理函数ClassProc,
所有按钮产生的消息都要先经过系统消息处理函数(ClassProc)后在调用我们自己编写的消息处理函数(Wndproc回调函数)。即消息产生后并不是直接就被WndProc函数处理
下面我们借助一下一张有关windows消息处理机制的图来理解一下:消息断点设置的依据。
我们可以看到所有的消息都是先经过windows系统(user32.dll)即图中的4过程,再传给我们自己编写的ProcWinMain消息处理函数(WndProc回调函数)。
我们所说的系统消息处理函数ClassProc就在user32.dll中,即我们设置消息断点对消息进行拦截就是在图中的4 到 5 这个过程中间来拦截的。
因为相同控件类系统为其准备一个系统消息处理函数ClassProc,所以在Exit按钮的ClassProc函数处设置断点其他的按钮类也会同时设置。其按钮类的ClassProc函数在截获WM_LDUPPONUT消息
我们这里用OD来验证一遍上面的过程。
刚才我们已经对Exit按钮处产生的WM_LDUPPONUT下了消息断点,我们点击Exit按钮后程序被暂停在ClassProc函数的头部,在user.dll模块中(即刚完成图4.4的过程4)。
我们F7跟踪进入这个函数发现正好所编写的消息处理函数(WndProc函数),即图4.4的过程5
紧接着我们就可以找到Exit按钮所产生的WM_LDUPPONUT消息的处理代码了(上述验证过程也可以采用在代码段设置内存访问断点来完成)。
2. 如何正确的设置消息断点
①消息断点和int3断点不同其必须在程序运行后设置(程序不运行是无法获得窗口以及控件的信息的,即不显示下图),而int3可以在程序运行先设置
②前面我们知道如果要想设置Exit按钮控件所产生的的消息就在Exit那一行右击然后点击在ClassProc函数处设置消息断点,也可以在其他按钮控件上右击设置(因为相同类的控件是同一个ClassProc函数)也就是想设置由哪个控件产生的消息就在任意一个那一类控件右击设置。
如果想设置WM_TIMER或者是WM_QUIT这些由程序调用API所产生的消息,需要在相应主窗口处右击设置
例如这个程序我们要想解除时间限制就需要去查看WM_TIMER消息的处理代码,我们就需要对WM_TIMER下断点。
因为WM_TIMER是由主程序调用API函数产生的所以我们就应该在主窗口处右击设置消息断点。
3. 消息断点其实就是特殊的条件断点
我们打开断点窗口查看我们刚刚在按钮类ClassProc函数处下的WM_LDUPPONUT消息断点,选中后右击编辑条件。
我们看到其条件断点的条件为[esp 8] == WM_LBUTTONUP(即ClassProc函数的uMsg消息标志参数为WM_LBUTTONUP消息)
由上述消息断点的判断条件我们可以得知,其只能在特定控件类的ClassProc函数处把所有这类控件所产生的WM_LBUTTONUP消息给拦截下来(即只要是这种控件产生的WM_LBUTTONUP消息其都会拦下来),
所以就不能确定是不是我们想要的那个控件所产生的的WM_LBUTTONUP消息。
我们需要在被拦截下来之后观察ClassProc的**hWnd参数**来确定是哪个控件所产生的WM_LBUTTONUP。
如果不是我们想要的那个按钮产生的WM_LBUTTONUP我们就需要反复运行到此处直到ClassProc的hWnd参数显示为我们想要的按钮后,
我们在利用内存访问断点在主模块的代码块设置在访问上设置断点来到达我们自己编写的WndProc(回调函数)的WM_LBUTTONUP消息处理处分析其具体操作。
发表吐槽
你肿么看?
既然没有吐槽,那就赶紧抢沙发吧!