c语言+去掉屯屯屯+链表,MFC逆向初级研究(1)(2)

1

2007-3-16 11:12

【文章标题】: MFC逆向初级研究(2)

【文章作者】: 北斗之摇光

【作者邮箱】: hardlywhen@hotmail.com

【下载地址】: 自己搜索下载

【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

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

【详细过程】

在《MFC逆向初级研究(1)》中我们初步证明了我们的假设,在经过对几个文件的反汇编以后,现在我们可以总结出一条经过证明的推断:

"MFC中的类信息的存储可能是按照如下的顺序来存储的:

1.该类的MessageMap

2.该类的MessageEntry

3.该类的RTTI Complete Object Locator(如果该类有RTTI信息)

4.该类的虚函数表"

按照这样的顺序看下来,我们在.rdata区域开始一点一点往下,会得到几个类的信息。下面是通过IDA对我们的例子程序反编译以后我整理

好的.rdata的内容,仔细查看虚函数表,你会发现有部分虚函数没有像其他的虚函数那样指向其父类的相关函数,这是因为在我们的例子程序

中对这些函数进行了重载。那么到底重载的是哪些函数呢?你可以根据虚函数在其父类中的顺序确定,在注释中我已经标出。

.rdata:004021C0 ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?

.rdata:004021C0

.rdata:004021C0 ; Segment type: Pure data

.rdata:004021C0 ; Segment permissions: Read

.rdata:004021C0 _rdata          segment para public 'DATA' use32

.rdata:004021C0                 assume cs:_rdata

.rdata:004021C0                 ;org 4021C0h

.rdata:004021C0 off_4021C0      dd offset sub_401000    ; DATA XREF: sub_401010o

.rdata:004021C4                 dd offset dword_4021C8

.rdata:004021C8 dword_4021C8    dd 111h                 ; DATA XREF: .rdata:004021C4o

.rdata:004021CC                 dd 0

.rdata:004021D0                 dd 0E146h

.rdata:004021D4                 dd 0E146h

.rdata:004021D8                 dd 0Ch

.rdata:004021DC                 dd offset CWinApp::OnHelp(void)

.rdata:004021E0                 dd 0

.rdata:004021E4                 dd 0

.rdata:004021E8                 dd 0

.rdata:004021EC                 dd 0

.rdata:004021F0                 dd 0

.rdata:004021F4                 dd 0

.rdata:004021F8 off_4021F8      dd offset CWinApp::GetRuntimeClass(void)         \\虚函数表的开始

.rdata:004021F8                                         ; DATA XREF: unknown_libname_1-56    \\这个引用可能在类构造函数中

.rdata:004021FC                 dd offset sub_401040                             \\类析构函数

.rdata:00402200                 dd offset nullsub_2

.rdata:00402204                 dd offset nullsub_3

.rdata:00402208                 dd offset nullsub_2

.rdata:0040220C                 dd offset CCmdTarget::OnCmdMsg(uint,int,void *,AFX_CMDHANDLERINFO *)

.rdata:00402210                 dd offset CCmdTarget::OnFinalRelease(void)

.rdata:00402214                 dd offset CCmdTarget::IsInvokeAllowed(long)

.rdata:00402218                 dd offset CCmdTarget::GetDispatchIID(_GUID *)

.rdata:0040221C                 dd offset CCmdTarget::GetTypeInfoCount(void)

.rdata:00402220                 dd offset CCmdTarget::GetTypeLibCache(void)

.rdata:00402224                 dd offset CCmdTarget::GetTypeLib(ulong,ITypeLib * *)

.rdata:00402228                 dd offset sub_401010                            \\GetMessageMap

.rdata:0040222C                 dd offset CCmdTarget::GetCommandMap(void)

.rdata:00402230                 dd offset CCmdTarget::GetDispatchMap(void)

.rdata:00402234                 dd offset CCmdTarget::GetConnectionMap(void)

.rdata:00402238                 dd offset CCmdTarget::GetInterfaceMap(void)

.rdata:0040223C                 dd offset CCmdTarget::GetEventSinkMap(void)

.rdata:00402240                 dd offset CCmdTarget::OnCreateAggregates(void)

.rdata:00402244                 dd offset CCmdTarget::GetInterfaceHook(void const *)

.rdata:00402248                 dd offset CCmdTarget::GetExtraConnectionPoints(CPtrArray *)

.rdata:0040224C                 dd offset CCmdTarget::GetConnectionHook(_GUID const &)

.rdata:00402250                 dd offset sub_4010B0                           \\InitInstance

.rdata:00402254                 dd offset CWinApp::Run(void)

.rdata:00402258                 dd offset CWinThread::PreTranslateMessage(tagMSG *)

.rdata:0040225C                 dd offset CWinThread::PumpMessage(void)

.rdata:00402260                 dd offset CWinApp::OnIdle(long)

.rdata:00402264                 dd offset CWinThread::IsIdleMessage(tagMSG *)

.rdata:00402268                 dd offset CWinApp::ExitInstance(void)

.rdata:0040226C                 dd offset CWinApp::ProcessWndProcException(CException *,tagMSG const *)

.rdata:00402270                 dd offset CWinThread::ProcessMessageFilter(int,tagMSG *)

.rdata:00402274                 dd offset CWinThread::GetMainWnd(void)

.rdata:00402278                 dd offset CWinThread::Delete(void)

.rdata:0040227C                 dd offset CWinApp::OpenDocumentFile(char const *)

.rdata:00402280                 dd offset CWinApp::AddToRecentFileList(char const *)

.rdata:00402284                 dd offset CWinApp::InitApplication(void)

.rdata:00402288                 dd offset CWinApp::SaveAllModified(void)

.rdata:0040228C                 dd offset CWinApp::DoMessageBox(char const *,uint,uint)

.rdata:00402290                 dd offset CWinApp::DoWaitCursor(int)

.rdata:00402294                 dd offset CWinApp::OnDDECommand(char *)

.rdata:00402298                 dd offset CWinApp::WinHelpA(ulong,uint)

.rdata:0040229C                 align 10h

.rdata:004022A0 off_4022A0      dd offset sub_4011F0    ; DATA XREF: sub_401200o

.rdata:004022A4                 dd offset dword_4022A8

.rdata:004022A8 dword_4022A8    dd 0Fh                  ; DATA XREF: .rdata:004022A4o

.rdata:004022AC                 dd 0

.rdata:004022B0                 dd 0

.rdata:004022B4                 dd 0

.rdata:004022B8                 dd 0Ch

.rdata:004022BC                 dd offset sub_401250

.rdata:004022C0                 dd 37h

.rdata:004022C4                 dd 0

.rdata:004022C8                 dd 0

.rdata:004022CC                 dd 0

.rdata:004022D0                 dd 23h

.rdata:004022D4                 dd offset sub_401310

.rdata:004022D8                 dd 111h

.rdata:004022DC                 dd 0

.rdata:004022E0                 dd 3E8h

.rdata:004022E4                 dd 3E8h

.rdata:004022E8                 dd 0Ch

.rdata:004022EC                 dd offset sub_401320

.rdata:004022F0                 dd 0

.rdata:004022F4                 dd 0

.rdata:004022F8                 dd 0

.rdata:004022FC                 dd 0

.rdata:00402300                 dd 0

.rdata:00402304                 dd 0

.rdata:00402308 off_402308      dd offset CDialog::GetRuntimeClass(void)

.rdata:00402308                                         ; DATA XREF: sub_401150+31o

.rdata:0040230C                 dd offset sub_4011C0                               \\类析构函数

.rdata:00402310                 dd offset nullsub_2

.rdata:00402314                 dd offset nullsub_3

.rdata:00402318                 dd offset nullsub_2

.rdata:0040231C                 dd offset CDialog::OnCmdMsg(uint,int,void *,AFX_CMDHANDLERINFO *)

.rdata:00402320                 dd offset CWnd::OnFinalRelease(void)

.rdata:00402324                 dd offset CCmdTarget::IsInvokeAllowed(long)

.rdata:00402328                 dd offset CCmdTarget::GetDispatchIID(_GUID *)

.rdata:0040232C                 dd offset CCmdTarget::GetTypeInfoCount(void)

.rdata:00402330                 dd offset CCmdTarget::GetTypeLibCache(void)

.rdata:00402334                 dd offset CCmdTarget::GetTypeLib(ulong,ITypeLib * *)

.rdata:00402338                 dd offset sub_401200                                \\GetMessageMap

.rdata:0040233C                 dd offset CCmdTarget::GetCommandMap(void)

.rdata:00402340                 dd offset CCmdTarget::GetDispatchMap(void)

.rdata:00402344                 dd offset CCmdTarget::GetConnectionMap(void)

.rdata:00402348                 dd offset CCmdTarget::GetInterfaceMap(void)

.rdata:0040234C                 dd offset CCmdTarget::GetEventSinkMap(void)

.rdata:00402350                 dd offset CCmdTarget::OnCreateAggregates(void)

.rdata:00402354                 dd offset CCmdTarget::GetInterfaceHook(void const *)

.rdata:00402358                 dd offset CCmdTarget::GetExtraConnectionPoints(CPtrArray *)

.rdata:0040235C                 dd offset CCmdTarget::GetConnectionHook(_GUID const &)

.rdata:00402360                 dd offset CWnd::PreSubclassWindow(void)

.rdata:00402364                 dd offset CWnd::Create(char const *,char const *,ulong,tagRECT const &,CWnd *,uint,CCreateContext *)

.rdata:00402368                 dd offset CWnd::DestroyWindow(void)

.rdata:0040236C                 dd offset CWnd::PreCreateWindow(tagCREATESTRUCTA &)

.rdata:00402370                 dd offset CWnd::CalcWindowRect(tagRECT *,uint)

.rdata:00402374                 dd offset CWnd::OnToolHitTest(CPoint,tagTOOLINFOA *)

.rdata:00402378                 dd offset CWnd::GetScrollBarCtrl(int)

.rdata:0040237C                 dd offset CWnd::WinHelpA(ulong,uint)

.rdata:00402380                 dd offset CWnd::ContinueModal(void)

.rdata:00402384                 dd offset CWnd::EndModalLoop(int)

.rdata:00402388                 dd offset CWnd::OnCommand(uint,long)

.rdata:0040238C                 dd offset CWnd::OnNotify(uint,long,long *)

.rdata:00402390                 dd offset CWnd::GetSuperWndProcAddr(void)

.rdata:00402394                 dd offset nullsub_4                                 \\DoDataExchange

.rdata:00402398                 dd offset sub_401330                                \\BeginModalState

.rdata:0040239C                 dd offset sub_401340                                \\EndModalState

.rdata:004023A0                 dd offset CDialog::PreTranslateMessage(tagMSG *)

.rdata:004023A4                 dd offset CWnd::OnAmbientProperty(COleControlSite *,long,tagVARIANT *)

.rdata:004023A8                 dd offset CWnd::WindowProc(uint,uint,long)

.rdata:004023AC                 dd offset CWnd::OnWndMsg(uint,uint,long,long *)

.rdata:004023B0                 dd offset CWnd::DefWindowProcA(uint,uint,long)

.rdata:004023B4                 dd offset CWnd::PostNcDestroy(void)

.rdata:004023B8                 dd offset CWnd::OnChildNotify(uint,uint,long,long *)

.rdata:004023BC                 dd offset CDialog::CheckAutoCenter(void)

.rdata:004023C0                 dd offset CWnd::IsFrameWnd(void)

.rdata:004023C4                 dd offset CDialog::SetOccDialogInfo(_AFX_OCC_DIALOG_INFO *)

.rdata:004023C8                 dd offset CDialog::DoModal(void)

.rdata:004023CC                 dd offset sub_401210                                \\OnInitDialog

.rdata:004023D0                 dd offset CDialog::OnSetFont(CFont *)

.rdata:004023D4                 dd offset CDialog::OnOK(void)

.rdata:004023D8                 dd offset CDialog::OnCancel(void)

.rdata:004023DC                 dd offset CDialog::PreInitDialog(void)

.rdata:004023E0 dword_4023E0    dd 0FFFFFFFFh           ; DATA XREF: start+5o      \\再以下就是其他数据

.rdata:004023E4                 dd offset sub_4016AE

.rdata:004023E8                 dd offset sub_4016C2

.rdata:004023EC                 dd 0

.rdata:004023F0 stru_4023F0     dd 19930520h            ; Magic

.rdata:004023F0                                         ; DATA XREF: .text:loc_401768o

.rdata:004023F0                 dd 1                    ; Count

.rdata:004023F0                 dd offset stru_4023F0.Info; InfoPtr

.rdata:004023F0                 dd 0                    ; CountDtr

.rdata:004023F0                 dd 0                    ; DtrPtr

.rdata:004023F0                 dd 3 dup(0)             ; _unk

.rdata:004023F0                 dd -1                   ; Info.Id

.rdata:004023F0                 dd offset sub_401760    ; Info.Proc

.rdata:00402418 stru_402418     dd 19930520h            ; Magic

经过以上步骤以后我们对于MessageMap、MessageEntry、虚函数表三部分的处理已经完成,接下来的任务就是确定我们已经找好相关数据的类

到底是哪个类?根据MFC的了解,我们知道MFC在建立之处会让你选择建立哪个类型的工程,其中有:多文档、单文档、对话框三种可以选择。

对于我们这个工程中选择的Dialog类型,其建立之初就有2个类(如果选择包含About Dialog的话则有3个类):CReverseMFC和CReverseMFCDlg类。

对于这几个类的作用在《深入浅出MFC》中有过介绍,我们现在需要确定的是我们刚才找到的数据具体是那个类呢?

我们可以根据虚函数表的继承关系来找,CReverseMFCDlg类继承自CDialog

CReverseMFC类继承自CWinApp

这样基本确定了两个类以及他们的MeeeageMap。在确定MessageMap后,我们就可以根据这个消息处理流程来寻找我们需要的算法和软件处理过程了。

那么如何来完成在本文之初我们所设立的目标呢-"找到按钮的相关处理过程"?

首先我们要知道按钮的资源代码是多少,这一点我们可以通过相关的资源处理软件来处理(我用的是ResHacker)可以查到按钮的的资源ID为1000,

也就是0X3E8。MFC消息处理中将Button消息作为Command类消息,在windows.h头文件中对WM_COMMAND消息的定义为0X111。回顾对MessageEntry

的数据定义,第一个为windows消息代码,第3个为控件ID。而按钮类的处理过程一般是放在对话框类中实现,因此查看类CReverseMFCDlg类的

MessageEntry可以找到了如下的代码:

.rdata:004022D8                 dd 111h                  \\windows message id

.rdata:004022DC                 dd 0                     \\nCode

.rdata:004022E0                 dd 3E8h                  \\nID

.rdata:004022E4                 dd 3E8h                  \\nLastID

.rdata:004022E8                 dd 0Ch                   \\nSig

.rdata:004022EC                 dd offset sub_401320     \\pfn

跟入sub_401320:

.text:00401320 ; *************** S U B R O U T I N E ***************************************

.text:00401320

.text:00401320

.text:00401320 sub_401320      proc near               ; DATA XREF: .rdata:004022ECo

.text:00401320                 push    0

.text:00401322                 push    0

.text:00401324                 push    offset s_IFindIt ; "I find it!"

.text:00401329                 call    AfxMessageBox(char const *,uint,uint)

.text:00401329

.text:0040132E                 retn

.text:0040132E

.text:0040132E sub_401320      endp

恰恰是我们所定义的按钮行为!如此,我们便跟随着EXE文件给我们留下的“藤”摸到了我们需要的“瓜”,这些藤为我们编织了一张软件架构的

大网,需要我们仔细的分析才能达成目的。

总结以上,对于VC++6.0 MFC产生的EXE文件的逆向我们可以归结以下几个要点(当然,这个文件必须是没加壳同时确定是VC++6.0产生的):

1.IDA反汇编后直接跳到.rdata段,此段必然是相关的用于存储相关的虚函数表、MessageMap、MessageEntry等信息;

2.查找虚函数表时可以直接搜索GetRunTimeClass函数,该函数必然时各个虚函数表的开始;

3.通过完善虚函数表,我们可以找到重载的函数地址,在完善函数表时要注意确定正确的函数顺序;

结语

在此,这篇文章只是简单的对MFC逆向做了一个肤浅的分析,希望能起到抛砖引玉的作用的同时也能让刚刚接触MFC逆向的兄弟们有点头绪,知道

该如何去找到自己需要的函数处理过程。毕竟本文的例子只是一个非常简单的工程,在正式的商业软件中,往往有着十几个基本类以及自定义类,

还有大量的自定义消息和数据结构,类的成员变量和成员函数等等。这些都需要经验和时间的积累,小菜由于也是初次接触MFC的逆向,还没有

经验,等俺逆向过几个软件后再发吧,免的贻笑大方。

另:

让笨笨熊版主失望了,俺只写了2,没写3、4、5、6那么多,嘿嘿,经验不足

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

【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

2007年03月16日 11:14:49

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值