吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 17364|回复: 28
收起左侧

[原创] 发一篇关于MFC查找按钮事件(映射消息)的文章,初级

[复制链接]
ucantseeme 发表于 2012-6-5 18:02
本帖最后由 ucantseeme 于 2012-6-5 18:05 编辑

附件下载: 附件.rar (391.69 KB, 下载次数: 192)

本文的知识点完全出自一本名叫《深入浅出MFC》的书。当然同样的知识点,网上也有很多其他版本

不过这些并非以找按钮事件为目的,他们都是以知识点介绍为主

那你要说我这是炒冷饭,那我就不高兴了,这应该叫做“换一个角度看问题”


关于文章的定位问题:

本来这篇文章是写得比较复杂的,涉及MFC的知识,但我觉得这样不好,就改啊改,把文章改成定位为初级的

不过读者还是必须掌握C++与对C++逆向的基础知识,这两点必须有,不一定要懂MFC


对于文章,原本我只讲思路,可思路往往又只有学过、理解的人才看得懂,既然理解了何必再看我

这便一个矛盾的地方,也与我觉得不好的地方

基于这点考虑,我把文章分为了两部分:

<1> 方法

所谓方法就是指具体操作做法,就是具体到点鼠标、运算加减乘除上,当然还有不可避免的极少分析

<2> 原理

所谓原理就是用来支持方法的,为什么这样做总得有个说法对吧。作为一个提高存在,实在理解不了算了


------------------------------------废话可能有点多,大家不要嫌,那么让我们切入正题-----------------------------------------


方法:


我必须先把操作步骤提出来:

1,我们要定位按钮事件,是从一个关键的数据结构中获得事件函数的指针,这个结构名叫AFX_MSGMAP_ENTRY
2,定位AFX_MSGMAP_ENTRY又需要定位一条虚函数,名叫GetMessageMap,这是条包装函数,他包装的函数取AFX_MSGMAP_ENTRY结构指针
3,虚函数的定位,自然是通过虚函数表,至于定位虚函数表那自然就是定位MFC类对象的this指针

步骤的含义将在原理中说的,不理解没关系,但是结构懂不懂?虚函数是什么知不知道?这每本C++的书都会讲,这是我前面提到的第一个要求,掌握C++基础

总结下来,我们唯一不确定的就是this指针,只要能找到MFC类对象的this指针,那就大功告成了

this指针的方法多种多样,可以通过成员函数找到,但我认为最好的还是找构造函数(一般构造更容易找)

这也是我前面提的第二个要求,掌握C++逆向的基础,this指针你总得能找到对吧

提示:这里所谓的this指针是指窗口类的this指针,因为按钮在窗口上嘛

接下来看代码了,我带大家走一次,OD载入例子程序1,停在OEP处:

例子程序是我随手找来的一个计算器,上面有太多按钮,打个比方我们现在要定位其中某个按钮,比如说Enter按钮
00427747 >  E8 0EFF0000     call    0043765A                         ; OEP
0042774C  ^ E9 16FEFFFF     jmp     00427567
一路F8走到这里
004276D0    51              push    ecx
004276D1    50              push    eax
004276D2    6A 00           push    0
004276D4    68 00004000     push    00400000
004276D9    E8 7BBE0200     call    00453559                         ; F7进入
进入call以后,来到以下,继续F8一路走
00453559   /E9 31000000     jmp     0045358F

0045358F    53              push    ebx
00453590    56              push    esi
00453591    57              push    edi
00453592    83CB FF         or      ebx, FFFFFFFF
00453595    E8 5B38FBFF     call    00406DF5
0045359A    8BF0            mov     esi, eax
0045359C    E8 D768FBFF     call    00409E78
004535A1    FF7424 1C       push    dword ptr [esp+1C]
004535A5    8B78 04         mov     edi, dword ptr [eax+4]
004535A8    FF7424 1C       push    dword ptr [esp+1C]
004535AC    FF7424 1C       push    dword ptr [esp+1C]
004535B0    FF7424 1C       push    dword ptr [esp+1C]
004535B4    E8 DFE0FCFF     call    00421698
004535B9    85C0            test    eax, eax
004535BB    74 3C           je      short 004535F9
004535BD    85FF            test    edi, edi
004535BF    74 0E           je      short 004535CF
004535C1    8B07            mov     eax, dword ptr [edi]
004535C3    8BCF            mov     ecx, edi
004535C5    FF90 90000000   call    dword ptr [eax+90]
004535CB    85C0            test    eax, eax
004535CD    74 2A           je      short 004535F9
004535CF    8B06            mov     eax, dword ptr [esi]
004535D1    8BCE            mov     ecx, esi
004535D3    FF50 50         call    dword ptr [eax+50]               ; 这里F7进入
F7进入call dword ptr [eax+50]这句以后,让我数一下,我一共贴出了33句代码,多得真是用上了全部手指脚趾都数不完

我们接着看进入以后的代码
00401080    55              push    ebp                              ; 进到这里
00401081    8BEC            mov     ebp, esp
00401083    6A FF           push    -1
00401085    68 1B364500     push    0045361B
0040108A    64:A1 00000000  mov     eax, dword ptr fs:[0]
00401090    50              push    eax
00401091    81EC F0000000   sub     esp, 0F0
00401097    A1 B4AF4600     mov     eax, dword ptr [46AFB4]
0040109C    33C5            xor     eax, ebp
0040109E    50              push    eax
0040109F    8D45 F4         lea     eax, dword ptr [ebp-C]
004010A2    64:A3 00000000  mov     dword ptr fs:[0], eax
004010A8    898D 04FFFFFF   mov     dword ptr [ebp-FC], ecx
004010AE    6A 00           push    0
004010B0    8D8D 14FFFFFF   lea     ecx, dword ptr [ebp-EC]          ; 取窗口的this指针,跟随地址到数据窗口
004010B6    E8 15010000     call    004011D0                         ; 这就是构造函数,要F8走过这一句,要走过
好了,this指针,也找到了,我再多说几句,this指针的格式是这样的:

lea     ecx, dword ptr [ebp/esp加或减??]
call    xxxxxxxx

这里有两个问题:

1,按照这个格式找到的call不一定是构造函数,不过ecx装的是this指针基本没跑的
2,虽然是this指针,但又不一定是窗口类的,这个就不好说了,一般来讲我以上步骤找到的都正确
   我建议换上IDA来识别,因为IDA能认出是否是窗口类的this指针(


找到this指针以后,看上面的三步骤,这里是逆向,也就是说要倒着看那三条

第三条找this指针,这就是刚刚做过的事

第二条通过虚函数表找虚函数GetMessageMap,看图中说明

(图一) 1.jpg

(图二)
2.jpg

图2中都是虚函数指针,哪一条才是我们要的GetMessageMap

这里我已经勾出来了,要想找出这条虚函数,必须了解它的“规律”

我这里说一下规律:

(图三)
3.jpg

既然我已经勾出来,那就看一下GetMessageMap的代码,如图3

在步骤2的说明中我已经提到过,GetMessageMap是条包装函数,意味着他不做任何实际有意义的事,除了调用

那么第一条规律就是:包装

从图3中可以看到,一共有8句代码,其中头两句和末三句是进出函数的惯例了,没什么好看的,第三第四句实际上是废操作

只剩第五句,调用了一条有意义的函数,这就是一个彻头彻尾的包装

接着必须要看一下被调用的关键函数

(图四)
4.jpg

依旧是十分简单的,同时也引出了第二条规律:至关重要的函数实际上有意义只有一条mov eax, 全局指针

这个全局指针就是AFX_MSGMAP_ENTRY的结构指针


提示:你必须搞清楚我所谓的“规律”是什么意思。比如说GetMessageMap的包装,并非所有的包装都是图三中那样,请看例子程序2,他的包装只有一句jmp。他们的代码不同,但是规律相同,就是什么都不做,调用一条有意义的函数。

步骤二也已完成,剩下的就是最后一条,步骤一,也就是找按钮事件的指针了

跟随00456AA8到数据窗口

(图五)
5.jpg

完成图5的操作后就是大功告成的前夕,先别急,我们还得给按钮事件下个断点呢,不然这按钮事件找来有何意义

(图六)
6.jpg

图6中,我用蓝色框框标出来的所有指针,给他们下断,这些都是按钮事件(消息映射)

看出规律了吗,他这是一个结构数组,每隔6个dword,就是一个按钮事件(消息映射),最后以0结尾

我们要找的Enter按钮事件,就在其中


原理:


保持帖子整洁,原理放入文档中供下载观看了


----------------------------------------------------------------------------------------------------

附注:

关于IDA识别窗口类的操作如下:

首先改一个选项

(图七)
7.jpg

(图八)
8.jpg

然后就看函数名,函数名中出现了CDialog、CWnd、CFrameWnd的这些就是窗口类

(图九)
9.jpg

结语:

看完本文,我要说的是,我们现在把找按钮事件的难点转换成了找窗口的this指针

这么难度就大大降低,因为这点可以通过IDA来协助查找

我不敢保证各位一定能找到窗口的this指针,但至少如果你能看懂本文,那以后就不要再发帖问“请问MFC按钮事件怎么找?”,而是这样问“请问这个程序的窗口this指针怎么找?”


实际情况下,找窗口的this指针可能还是有点复杂

打个比方,现在有个程序,他有好几个窗口,上面都是不同的按钮,我现在只想断其中一个窗口的其中一个按钮

那每个窗口都有个this指针,定位起来难度就会加大

还是请多多使用IDA,因为他能认出很多MFC类成员函数,从中找到窗口类的this指针


补充:
MFC消息映射中有一个设定(宏),他能设置范围,此范围内的所有按钮共用一个按钮事件。

比如本例计算器,0~9,一共有10个按钮,他们共用同一个按钮事件。

现在问题已经非常明显了,界面上不止15个按钮事件,却只有15条处理程序,实际上我们把0~9算成一个按钮,刚好有14个按钮。

15!=14,其原因是还有一条(第一条)并非按钮事件,他那是WM_PAINT消息映射,不用管他。


发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

yejiaxi82 发表于 2012-6-5 18:14
老大到哪里  我们就顶到哪里
索马里的海贼 发表于 2012-6-5 18:24
19nuclear91 发表于 2012-6-5 18:39
ying5567890 发表于 2012-6-5 18:39
谢谢楼主分享,而且推荐了一本好书。学习了
o0dc0o 发表于 2012-6-5 18:53
谢谢分享!!辛苦了!!!
nofriend 发表于 2012-6-5 18:59
膜拜。看不懂。
willJ 发表于 2012-6-5 19:50
果断支持LZ,写得很好
qzy0549 发表于 2012-6-5 19:52
表示只看得懂很小一部分 看来学习不够啊  膜拜楼主
老大
Sound 发表于 2012-6-6 11:32
写的不错,挺适合学习的..支持了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-4 06:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表