• 标 题:逆向动态调试分析“基于MFC对话框(非文本框)程序”时,定位用户初始化代码入口的方法
  • 作 者:coderui
  • 时 间:2008-05-23 16:20
  • 链 接:http://bbs.pediy.com/showthread.php?t=65322

/////////////////////////////////////////////////////////////////////////////////////////////////
文件名称:逆向动态调试分析“基于MFC对话框(非文本框)程序”时,定位用户初始化代码入口的方法
目标程序:由VC++ 6.0 MFC类库框架编写的对话框程序(Release版)
操作环境:Windows XP-SP2
使用工具:Ollydbg 1.10版
编写作者:Coderui
编写时间:2008年05月23日(新)
联系方式:coderui@163.com
作者博客:http://hi.baidu.com/coderui
==================================================================
前言:
    目前网络上流传的程序有一部分是使用VC++ 6.0(MFC)开发编写而成的,当然木马病毒也占据着一定的数量。了解MFC框架的朋友都知道它是一套功能比较强大的封装类库,在编程时可能会给程序员带去一定的方便性。但进行逆向工程反汇编动态调式分析MFC编写的程序时,就显得比较麻烦了。因为在反汇编出来的代码中,有非常多的代码都是由MFC封装类库产生的,而不是由程序作者编写出来的,这些代码严重干扰着我们的分析。所以我们在逆向分析由MFC编写而成的程序时,就需要跳过所有由MFC类库生成的代码,直接跳到作者编写的代码中去调试分析有价值的代码。

说明:
    今天所讲的内容比较适合用在调试分析木马病毒程序和破解应用软件上。大家都知道病毒运行后,是不需要出现对话框也不需要点击任何按钮就可以直接运行的;一些应用软件被破解修改后,就不显示程序正常的窗口,而是直接弹出文件被非法修改的警告框。这些现象都是表示软件作者把功能和校验代码的调用位置都加在了程序的初始化函数里。在VC++ 6.0的MFC中,这些初始化函数一般为“InitInstance()”函数和“OnInitDialog()”函数。但为了开发方便,一般使用居多的都是“OnInitDialog()”函数,对这个函数内部用户代码首先执行位置的定位方法已经在今年年初时整理发布过了。今天主要是讲下“InitInstance()”函数内部用户代码开头的定位方法,顺带着也会把上次的方法一起整理后,写到这篇文章里发布给大家的。

用途:
    逆向动态调试分析“基于MFC对话框(非文本框)程序”时,定位主程序用户代码首先执行位置的方法。使用到这种技术的理由有两个。
    第一个是:在调试分析由MFC编写的程序时,可以不去看类库框架生成的代码,直接定位到关键代码处,会节省很多的时间。
    第二个是:获得由MFC编写程序的用户代码首先执行位置开头处,这样就可以知道作者最开始在初始化程序时都做了些什么。分析病毒时是必要使用这种技术的,如果不能准确的定位到这个地址上,就不知道病毒第一步做了什么,然后接着做了什么,最后做了什么,分析清楚工作顺序是非常重要的。

==================================================================
第一启动函数“InitInstance()”:(作者:Coderui)

定位方法:
-----------------------------------------------------------
OD设置:(OD设置为不忽略任何异常。[F2]:下软断点、[F4]:执行到当前代码处、[F7]:单步步入、[F8]单步步过、[F9]运行。)
请按照注解顺序观看(00)-(01)-(02)…(99),不然很容易混乱。

00401750 >/$  55            PUSH EBP                                   ; (00)程序被OD打开后会停在这里,这个是程序的入口点OEP。
00401751  |.  8BEC          MOV EBP,ESP
00401753  |.  6A FF         PUSH -1
00401755  |.  68 00254000   PUSH Samples.00402500
0040175A  |.  68 D6184000   PUSH <JMP.&MSVCRT._except_handler3>        ; SE 处理程序安装
0040175F  |.  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
00401765  |.  50            PUSH EAX
00401766  |.  64:8925 00000>MOV DWORD PTR FS:[0],ESP
0040176D  |.  83EC 68       SUB ESP,68
00401770  |.  53            PUSH EBX
00401771  |.  56            PUSH ESI
00401772  |.  57            PUSH EDI
00401773  |.  8965 E8       MOV DWORD PTR SS:[EBP-18],ESP
00401776  |.  33DB          XOR EBX,EBX
00401778  |.  895D FC       MOV DWORD PTR SS:[EBP-4],EBX
0040177B  |.  6A 02         PUSH 2
0040177D  |.  FF15 98214000 CALL DWORD PTR DS:[<&MSVCRT.__set_app_type>]
00401783  |.  59            POP ECX
00401784  |.  830D 8C314000>OR DWORD PTR DS:[40318C],FFFFFFFF
0040178B  |.  830D 90314000>OR DWORD PTR DS:[403190],FFFFFFFF
00401792  |.  FF15 94214000 CALL DWORD PTR DS:[<&MSVCRT.__p__fmode>]
00401798  |.  8B0D 80314000 MOV ECX,DWORD PTR DS:[403180]
0040179E  |.  8908          MOV DWORD PTR DS:[EAX],ECX
004017A0  |.  FF15 90214000 CALL DWORD PTR DS:[<&MSVCRT.__p__commode>]
004017A6  |.  8B0D 7C314000 MOV ECX,DWORD PTR DS:[40317C]
004017AC  |.  8908          MOV DWORD PTR DS:[EAX],ECX
004017AE  |.  A1 8C214000   MOV EAX,DWORD PTR DS:[<&MSVCRT._adjust_fdiv>]
004017B3  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
004017B5  |.  A3 88314000   MOV DWORD PTR DS:[403188],EAX
004017BA  |.  E8 16010000   CALL Samples.004018D5
004017BF  |.  391D A0304000 CMP DWORD PTR DS:[4030A0],EBX
004017C5  |.  75 0C         JNZ SHORT Samples.004017D3
004017C7  |.  68 D2184000   PUSH Samples.004018D2
004017CC  |.  FF15 88214000 CALL DWORD PTR DS:[<&MSVCRT.__setusermatherr>]
004017D2  |.  59            POP ECX
004017D3  |>  E8 E8000000   CALL Samples.004018C0
004017D8  |.  68 14304000   PUSH Samples.00403014
004017DD  |.  68 10304000   PUSH Samples.00403010
004017E2  |.  E8 D3000000   CALL <JMP.&MSVCRT._initterm>
004017E7  |.  A1 78314000   MOV EAX,DWORD PTR DS:[403178]
004017EC  |.  8945 94       MOV DWORD PTR SS:[EBP-6C],EAX
004017EF  |.  8D45 94       LEA EAX,DWORD PTR SS:[EBP-6C]
004017F2  |.  50            PUSH EAX
004017F3  |.  FF35 74314000 PUSH DWORD PTR DS:[403174]
004017F9  |.  8D45 9C       LEA EAX,DWORD PTR SS:[EBP-64]
004017FC  |.  50            PUSH EAX
004017FD  |.  8D45 90       LEA EAX,DWORD PTR SS:[EBP-70]
00401800  |.  50            PUSH EAX
00401801  |.  8D45 A0       LEA EAX,DWORD PTR SS:[EBP-60]
00401804  |.  50            PUSH EAX
00401805  |.  FF15 80214000 CALL DWORD PTR DS:[<&MSVCRT.__getmainargs>]
0040180B  |.  68 0C304000   PUSH Samples.0040300C
00401810  |.  68 00304000   PUSH Samples.00403000
00401815  |.  E8 A0000000   CALL <JMP.&MSVCRT._initterm>
0040181A  |.  83C4 24       ADD ESP,24
0040181D  |.  A1 7C214000   MOV EAX,DWORD PTR DS:[<&MSVCRT._acmdln>]
00401822  |.  8B30          MOV ESI,DWORD PTR DS:[EAX]
00401824  |.  8975 8C       MOV DWORD PTR SS:[EBP-74],ESI
00401827  |.  803E 22       CMP BYTE PTR DS:[ESI],22
0040182A  |.  75 3A         JNZ SHORT Samples.00401866
0040182C  |>  46            /INC ESI
0040182D  |.  8975 8C       |MOV DWORD PTR SS:[EBP-74],ESI
00401830  |.  8A06          |MOV AL,BYTE PTR DS:[ESI]
00401832  |.  3AC3          |CMP AL,BL
00401834  |.  74 04         |JE SHORT Samples.0040183A
00401836  |.  3C 22         |CMP AL,22
00401838  |.^ 75 F2         \JNZ SHORT Samples.0040182C
0040183A  |>  803E 22       CMP BYTE PTR DS:[ESI],22
0040183D  |.  75 04         JNZ SHORT Samples.00401843
0040183F  |>  46            INC ESI
00401840  |.  8975 8C       MOV DWORD PTR SS:[EBP-74],ESI
00401843  |>  8A06          MOV AL,BYTE PTR DS:[ESI]
00401845  |.  3AC3          CMP AL,BL
00401847  |.  74 04         JE SHORT Samples.0040184D
00401849  |.  3C 20         CMP AL,20
0040184B  |.^ 76 F2         JBE SHORT Samples.0040183F
0040184D  |>  895D D0       MOV DWORD PTR SS:[EBP-30],EBX
00401850  |.  8D45 A4       LEA EAX,DWORD PTR SS:[EBP-5C]
00401853  |.  50            PUSH EAX
00401854  |.  FF15 04204000 CALL DWORD PTR DS:[<&KERNEL32.GetStartupInfoA>]
0040185A  |.  F645 D0 01    TEST BYTE PTR SS:[EBP-30],1
0040185E  |.  74 11         JE SHORT Samples.00401871
00401860  |.  0FB745 D4     MOVZX EAX,WORD PTR SS:[EBP-2C]
00401864  |.  EB 0E         JMP SHORT Samples.00401874
00401866  |>  803E 20       /CMP BYTE PTR DS:[ESI],20
00401869  |.^ 76 D8         |JBE SHORT Samples.00401843
0040186B  |.  46            |INC ESI
0040186C  |.  8975 8C       |MOV DWORD PTR SS:[EBP-74],ESI
0040186F  |.^ EB F5         \JMP SHORT Samples.00401866
00401871  |>  6A 0A         PUSH 0A
00401873  |.  58            POP EAX
00401874  |>  50            PUSH EAX
00401875  |.  56            PUSH ESI
00401876  |.  53            PUSH EBX
00401877  |.  53            PUSH EBX
00401878  |.  FF15 00204000 CALL DWORD PTR DS:[<&KERNEL32.GetModuleHandleA>]
0040187E  |.  50            PUSH EAX
0040187F  |.  E8 5E000000   CALL Samples.004018E2                      ; (01)找到“exit”退出函数上边的这个CALL,按[F4]执行到这里,然后再按[F7]进去。
00401884  |.  8945 98       MOV DWORD PTR SS:[EBP-68],EAX
00401887  |.  50            PUSH EAX
00401888  |.  FF15 78214000 CALL DWORD PTR DS:[<&MSVCRT.exit>]         ; "exit"函数
0040188E  |.  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]
00401891  |.  8B08          MOV ECX,DWORD PTR DS:[EAX]
00401893  |.  8B09          MOV ECX,DWORD PTR DS:[ECX]
00401895  |.  894D 88       MOV DWORD PTR SS:[EBP-78],ECX
00401898  |.  50            PUSH EAX
00401899  |.  51            PUSH ECX
0040189A  |.  E8 15000000   CALL <JMP.&MSVCRT._XcptFilter>
0040189F  |.  59            POP ECX
004018A0  |.  59            POP ECX
004018A1  \.  C3            RETN
              .
              .
              .
004018E2  /$  FF7424 10     PUSH DWORD PTR SS:[ESP+10]                 ; (02)进去后来到这里。
004018E6  |.  FF7424 10     PUSH DWORD PTR SS:[ESP+10]
004018EA  |.  FF7424 10     PUSH DWORD PTR SS:[ESP+10]
004018EE  |.  FF7424 10     PUSH DWORD PTR SS:[ESP+10]
004018F2  |.  E8 43000000   CALL <JMP.&MFC42.#1576_?AfxWinMain>        ; (03)按[F4]执行到这里,接着对该主程序的代码段下内存访问断点,然后按[F9]运行。
004018F7  \.  C2 1000       RETN 10
              .
              .
              .
0040193A   $- FF25 6C214000 JMP DWORD PTR DS:[<&MFC42.#1576_?AfxWinMain>]; (04)[F9]后来到这里,再按[F9]运行。
00401940   .  8D4D 8C       LEA ECX,DWORD PTR SS:[EBP-74]
00401943   .^ E9 A2FCFFFF   JMP <JMP.&MFC42.#800_?CString>
00401948   .  8D4D 90       LEA ECX,DWORD PTR SS:[EBP-70]
0040194B   .^ E9 10F8FFFF   JMP Samples.00401160
00401950   $  B8 10254000   MOV EAX,Samples.00402510                   ; 结构异常处理程序
00401955   .^ E9 E8FDFFFF   JMP <JMP.&MSVCRT.__CxxFrameHandler>
              .
              .
              .
00401524   .- FF25 1C204000 JMP DWORD PTR DS:[<&MFC42.#3922_?InitApplication>]; (05)[F9]后来到这里,再按[F9]运行。
0040152A   .- FF25 20204000 JMP DWORD PTR DS:[<&MFC42.#1089_?AddToRecentFileList>]
00401530   .- FF25 24204000 JMP DWORD PTR DS:[<&MFC42.#5199_?OpenDocumentFile@CWinApp>]
00401536   .- FF25 28204000 JMP DWORD PTR DS:[<&MFC42.#2396_?Delete@CWinThread>]
0040153C   .- FF25 2C204000 JMP DWORD PTR DS:[<&MFC42.#3346_?GetMainWnd@CWinThread>]
              .
              .
              .
004010B0   .  6A FF         PUSH -1                                    ; (06)[F9]后来到这里,这里就是“InitInstance()”函数的入口处。
004010B2   .  68 50194000   PUSH Samples.00401950                      ; SE 处理程序安装
004010B7   .  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
004010BD   .  50            PUSH EAX
004010BE   .  64:8925 00000>MOV DWORD PTR FS:[0],ESP
004010C5   .  83EC 68       SUB ESP,68
004010C8   .  56            PUSH ESI
004010C9   .  8BF1          MOV ESI,ECX
004010CB   .  6A 00         PUSH 0
004010CD   .  E8 3C050000   CALL <JMP.&MFC42.#1134_?AfxEnableControlContainer>
004010D2   .  83C4 04       ADD ESP,4
004010D5   .  8D4C24 04     LEA ECX,DWORD PTR SS:[ESP+4]
004010D9   .  68 20304000   PUSH Samples.00403020                      ; (07)第一处初始化位置:“InitInstance()”函数中的用户代码开头!
004010DE   .  E8 25050000   CALL <JMP.&MFC42.#537_?CString>
004010E3   .  8B4424 04     MOV EAX,DWORD PTR SS:[ESP+4]
004010E7   .  6A 00         PUSH 0
004010E9   .  6A 00         PUSH 0
004010EB   .  50            PUSH EAX
004010EC   .  C78424 800000>MOV DWORD PTR SS:[ESP+80],0
004010F7   .  E8 06050000   CALL <JMP.&MFC42.#1200_?AfxMessageBox>
004010FC   .  8BCE          MOV ECX,ESI
004010FE   .  E8 F9040000   CALL <JMP.&MFC42.#2621_?Enable3dControls@CWinApp>
00401103   .  6A 00         PUSH 0
00401105   .  8D4C24 0C     LEA ECX,DWORD PTR SS:[ESP+C]
00401109   .  E8 B2000000   CALL Samples.004011C0
0040110E   .  8D4C24 08     LEA ECX,DWORD PTR SS:[ESP+8]
00401112   .  C64424 74 01  MOV BYTE PTR SS:[ESP+74],1
00401117   .  894E 20       MOV DWORD PTR DS:[ESI+20],ECX
0040111A   .  8D4C24 08     LEA ECX,DWORD PTR SS:[ESP+8]
0040111E   .  E8 D3040000   CALL <JMP.&MFC42.#2514_?DoModal@CDialog>
00401123   .  8D4C24 08     LEA ECX,DWORD PTR SS:[ESP+8]
00401127   .  C64424 74 00  MOV BYTE PTR SS:[ESP+74],0
0040112C   .  E8 BF040000   CALL <JMP.&MFC42.#641_?CDialog>
00401131   .  8D4C24 04     LEA ECX,DWORD PTR SS:[ESP+4]
00401135   .  C74424 74 FFF>MOV DWORD PTR SS:[ESP+74],-1
0040113D   .  E8 A8040000   CALL <JMP.&MFC42.#800_?CString>
00401142   .  8B4C24 6C     MOV ECX,DWORD PTR SS:[ESP+6C]
00401146   .  33C0          XOR EAX,EAX
00401148   .  5E            POP ESI
00401149   .  64:890D 00000>MOV DWORD PTR FS:[0],ECX
00401150   .  83C4 74       ADD ESP,74
00401153   .  C3            RETN
-----------------------------------------------------------
==================================================================

==================================================================
第二启动函数“OnInitDialog()”:(作者:Coderui)

定位方法:
-----------------------------------------------------------
OD设置:(OD设置为不忽略任何异常。[F2]:下软断点、[F4]:执行到当前代码处、[F7]:单步步入、[F8]单步步过、[F9]运行。)
请按照注解顺序观看(00)-(01)-(02)…(99),不然很容易混乱。

00401750 >/$  55            PUSH EBP                                   ; (00)程序被OD打开后会停在这里,这个是程序的入口点OEP。然后使用命令“BP SendMessageA”对“SendMessageA”函数下断点,[F9]运行。
00401751  |.  8BEC          MOV EBP,ESP
00401753  |.  6A FF         PUSH -1
00401755  |.  68 00254000   PUSH Samples.00402500
0040175A  |.  68 D6184000   PUSH <JMP.&MSVCRT._except_handler3>        ; SE 处理程序安装
0040175F  |.  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
00401765  |.  50            PUSH EAX
00401766  |.  64:8925 00000>MOV DWORD PTR FS:[0],ESP
0040176D  |.  83EC 68       SUB ESP,68
00401770  |.  53            PUSH EBX
00401771  |.  56            PUSH ESI
00401772  |.  57            PUSH EDI
00401773  |.  8965 E8       MOV DWORD PTR SS:[EBP-18],ESP
00401776  |.  33DB          XOR EBX,EBX
00401778  |.  895D FC       MOV DWORD PTR SS:[EBP-4],EBX
0040177B  |.  6A 02         PUSH 2
0040177D  |.  FF15 98214000 CALL DWORD PTR DS:[<&MSVCRT.__set_app_type>]
00401783  |.  59            POP ECX
00401784  |.  830D 8C314000>OR DWORD PTR DS:[40318C],FFFFFFFF
0040178B  |.  830D 90314000>OR DWORD PTR DS:[403190],FFFFFFFF
00401792  |.  FF15 94214000 CALL DWORD PTR DS:[<&MSVCRT.__p__fmode>]
00401798  |.  8B0D 80314000 MOV ECX,DWORD PTR DS:[403180]
0040179E  |.  8908          MOV DWORD PTR DS:[EAX],ECX
004017A0  |.  FF15 90214000 CALL DWORD PTR DS:[<&MSVCRT.__p__commode>]
004017A6  |.  8B0D 7C314000 MOV ECX,DWORD PTR DS:[40317C]
004017AC  |.  8908          MOV DWORD PTR DS:[EAX],ECX
004017AE  |.  A1 8C214000   MOV EAX,DWORD PTR DS:[<&MSVCRT._adjust_fdiv>]
004017B3  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
004017B5  |.  A3 88314000   MOV DWORD PTR DS:[403188],EAX
004017BA  |.  E8 16010000   CALL Samples.004018D5
004017BF  |.  391D A0304000 CMP DWORD PTR DS:[4030A0],EBX
004017C5  |.  75 0C         JNZ SHORT Samples.004017D3
004017C7  |.  68 D2184000   PUSH Samples.004018D2
004017CC  |.  FF15 88214000 CALL DWORD PTR DS:[<&MSVCRT.__setusermatherr>]
004017D2  |.  59            POP ECX
004017D3  |>  E8 E8000000   CALL Samples.004018C0
004017D8  |.  68 14304000   PUSH Samples.00403014
004017DD  |.  68 10304000   PUSH Samples.00403010
004017E2  |.  E8 D3000000   CALL <JMP.&MSVCRT._initterm>
004017E7  |.  A1 78314000   MOV EAX,DWORD PTR DS:[403178]
004017EC  |.  8945 94       MOV DWORD PTR SS:[EBP-6C],EAX
004017EF  |.  8D45 94       LEA EAX,DWORD PTR SS:[EBP-6C]
004017F2  |.  50            PUSH EAX
004017F3  |.  FF35 74314000 PUSH DWORD PTR DS:[403174]
004017F9  |.  8D45 9C       LEA EAX,DWORD PTR SS:[EBP-64]
004017FC  |.  50            PUSH EAX
004017FD  |.  8D45 90       LEA EAX,DWORD PTR SS:[EBP-70]
00401800  |.  50            PUSH EAX
00401801  |.  8D45 A0       LEA EAX,DWORD PTR SS:[EBP-60]
00401804  |.  50            PUSH EAX
00401805  |.  FF15 80214000 CALL DWORD PTR DS:[<&MSVCRT.__getmainargs>]
0040180B  |.  68 0C304000   PUSH Samples.0040300C
00401810  |.  68 00304000   PUSH Samples.00403000
00401815  |.  E8 A0000000   CALL <JMP.&MSVCRT._initterm>
0040181A  |.  83C4 24       ADD ESP,24
0040181D  |.  A1 7C214000   MOV EAX,DWORD PTR DS:[<&MSVCRT._acmdln>]
00401822  |.  8B30          MOV ESI,DWORD PTR DS:[EAX]
00401824  |.  8975 8C       MOV DWORD PTR SS:[EBP-74],ESI
00401827  |.  803E 22       CMP BYTE PTR DS:[ESI],22
0040182A  |.  75 3A         JNZ SHORT Samples.00401866
0040182C  |>  46            /INC ESI
0040182D  |.  8975 8C       |MOV DWORD PTR SS:[EBP-74],ESI
00401830  |.  8A06          |MOV AL,BYTE PTR DS:[ESI]
00401832  |.  3AC3          |CMP AL,BL
00401834  |.  74 04         |JE SHORT Samples.0040183A
00401836  |.  3C 22         |CMP AL,22
00401838  |.^ 75 F2         \JNZ SHORT Samples.0040182C
0040183A  |>  803E 22       CMP BYTE PTR DS:[ESI],22
0040183D  |.  75 04         JNZ SHORT Samples.00401843
0040183F  |>  46            INC ESI
00401840  |.  8975 8C       MOV DWORD PTR SS:[EBP-74],ESI
00401843  |>  8A06          MOV AL,BYTE PTR DS:[ESI]
00401845  |.  3AC3          CMP AL,BL
00401847  |.  74 04         JE SHORT Samples.0040184D
00401849  |.  3C 20         CMP AL,20
0040184B  |.^ 76 F2         JBE SHORT Samples.0040183F
0040184D  |>  895D D0       MOV DWORD PTR SS:[EBP-30],EBX
00401850  |.  8D45 A4       LEA EAX,DWORD PTR SS:[EBP-5C]
00401853  |.  50            PUSH EAX
00401854  |.  FF15 04204000 CALL DWORD PTR DS:[<&KERNEL32.GetStartupInfoA>]
0040185A  |.  F645 D0 01    TEST BYTE PTR SS:[EBP-30],1
0040185E  |.  74 11         JE SHORT Samples.00401871
00401860  |.  0FB745 D4     MOVZX EAX,WORD PTR SS:[EBP-2C]
00401864  |.  EB 0E         JMP SHORT Samples.00401874
00401866  |>  803E 20       /CMP BYTE PTR DS:[ESI],20
00401869  |.^ 76 D8         |JBE SHORT Samples.00401843
0040186B  |.  46            |INC ESI
0040186C  |.  8975 8C       |MOV DWORD PTR SS:[EBP-74],ESI
0040186F  |.^ EB F5         \JMP SHORT Samples.00401866
00401871  |>  6A 0A         PUSH 0A
00401873  |.  58            POP EAX
00401874  |>  50            PUSH EAX
00401875  |.  56            PUSH ESI
00401876  |.  53            PUSH EBX
00401877  |.  53            PUSH EBX
00401878  |.  FF15 00204000 CALL DWORD PTR DS:[<&KERNEL32.GetModuleHandleA>]
0040187E  |.  50            PUSH EAX
0040187F  |.  E8 5E000000   CALL Samples.004018E2
00401884  |.  8945 98       MOV DWORD PTR SS:[EBP-68],EAX
00401887  |.  50            PUSH EAX
00401888  |.  FF15 78214000 CALL DWORD PTR DS:[<&MSVCRT.exit>]         ; "exit"函数
0040188E  |.  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]
00401891  |.  8B08          MOV ECX,DWORD PTR DS:[EAX]
00401893  |.  8B09          MOV ECX,DWORD PTR DS:[ECX]
00401895  |.  894D 88       MOV DWORD PTR SS:[EBP-78],ECX
00401898  |.  50            PUSH EAX
00401899  |.  51            PUSH ECX
0040189A  |.  E8 15000000   CALL <JMP.&MSVCRT._XcptFilter>
0040189F  |.  59            POP ECX
004018A0  |.  59            POP ECX
004018A1  \.  C3            RETN
              .
              .
              .
77D2F383 >  8BFF            MOV EDI,EDI                                ; (01)[F9]后来到这里,我们先按[F2]取消掉此处的断点,再按[Alt + F9]返回到用户代码领空。
77D2F385    55              PUSH EBP
77D2F386    8BEC            MOV EBP,ESP
77D2F388    56              PUSH ESI
77D2F389    8B75 0C         MOV ESI,DWORD PTR SS:[EBP+C]
77D2F38C    F7C6 0000FEFF   TEST ESI,FFFE0000
77D2F392    0F85 981D0100   JNZ USER32.77D41130
77D2F398    8B4D 08         MOV ECX,DWORD PTR SS:[EBP+8]
77D2F39B    83F9 FF         CMP ECX,-1
77D2F39E    0F84 82F10000   JE USER32.77D3E526
77D2F3A4    81F9 FFFF0000   CMP ECX,0FFFF
77D2F3AA    0F84 76F10000   JE USER32.77D3E526
77D2F3B0    E8 1B91FEFF     CALL USER32.77D184D0
77D2F3B5    85C0            TEST EAX,EAX
77D2F3B7    0F84 62F10000   JE USER32.77D3E51F
77D2F3BD    6A 01           PUSH 1
77D2F3BF    FF75 14         PUSH DWORD PTR SS:[EBP+14]
77D2F3C2    FF75 10         PUSH DWORD PTR SS:[EBP+10]
77D2F3C5    56              PUSH ESI
77D2F3C6    50              PUSH EAX
77D2F3C7    E8 07C4FEFF     CALL USER32.77D1B7D3
77D2F3CC    5E              POP ESI
77D2F3CD    5D              POP EBP
77D2F3CE    C2 1000         RETN 10
              .
              .
              .
00401280   .  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]                   ;  (02)这里就是“OnInitDialog()”函数的入口处。
00401286   .  6A FF         PUSH -1
00401288   .  68 90194000   PUSH Samples.00401990
0040128D   .  50            PUSH EAX
0040128E   .  64:8925 00000>MOV DWORD PTR FS:[0],ESP
00401295   .  83EC 08       SUB ESP,8
00401298   .  56            PUSH ESI
00401299   .  57            PUSH EDI
0040129A   .  8BF1          MOV ESI,ECX
0040129C   .  E8 8B030000   CALL <JMP.&MFC42.#4710_?OnInitDialog@CDialog>
004012A1   .  8B46 20       MOV EAX,DWORD PTR DS:[ESI+20]              ; (03)[Alt + F9]后程序返回到这里。向下找两处连续的“SendMessageA”函数调用。
004012A4   .  6A 00         PUSH 0                                     ; /Revert = FALSE
004012A6   .  50            PUSH EAX                                   ; |hWnd
004012A7   .  FF15 C0214000 CALL DWORD PTR DS:[<&USER32.GetSystemMenu>]; \GetSystemMenu
004012AD   .  50            PUSH EAX
004012AE   .  E8 39040000   CALL <JMP.&MFC42.#2863_?FromHandle@CMenu>
004012B3   .  8BF8          MOV EDI,EAX
004012B5   .  85FF          TEST EDI,EDI
004012B7   .  74 5E         JE SHORT Samples.00401317
004012B9   .  8D4C24 08     LEA ECX,DWORD PTR SS:[ESP+8]
004012BD   .  E8 24040000   CALL <JMP.&MFC42.#540_?CString>
004012C2   .  6A 65         PUSH 65
004012C4   .  8D4C24 0C     LEA ECX,DWORD PTR SS:[ESP+C]
004012C8   .  C74424 1C 000>MOV DWORD PTR SS:[ESP+1C],0
004012D0   .  E8 0B040000   CALL <JMP.&MFC42.#4160_?LoadStringA@CString>
004012D5   .  8B4C24 08     MOV ECX,DWORD PTR SS:[ESP+8]
004012D9   .  8B41 F8       MOV EAX,DWORD PTR DS:[ECX-8]
004012DC   .  85C0          TEST EAX,EAX
004012DE   .  74 26         JE SHORT Samples.00401306
004012E0   .  8B57 04       MOV EDX,DWORD PTR DS:[EDI+4]
004012E3   .  53            PUSH EBX
004012E4   .  8B1D BC214000 MOV EBX,DWORD PTR DS:[<&USER32.AppendMenuA>]
004012EA   .  6A 00         PUSH 0                                     ; /pItem = NULL
004012EC   .  6A 00         PUSH 0                                     ; |ItemID = 0
004012EE   .  68 00080000   PUSH 800                                   ; |Flags = MF_BYCOMMAND|MF_SEPARATOR|MF_ENABLED|MF_STRING
004012F3   .  52            PUSH EDX                                   ; |hMenu
004012F4   .  FFD3          CALL EBX                                   ; \AppendMenuA
004012F6   .  8B4424 0C     MOV EAX,DWORD PTR SS:[ESP+C]
004012FA   .  8B4F 04       MOV ECX,DWORD PTR DS:[EDI+4]
004012FD   .  50            PUSH EAX                                   ; /pItem
004012FE   .  6A 10         PUSH 10                                    ; |ItemID = 10 (16.)
00401300   .  6A 00         PUSH 0                                     ; |Flags = MF_BYCOMMAND|MF_ENABLED|MF_STRING
00401302   .  51            PUSH ECX                                   ; |hMenu
00401303   .  FFD3          CALL EBX                                   ; \AppendMenuA
00401305   .  5B            POP EBX
00401306   >  8D4C24 08     LEA ECX,DWORD PTR SS:[ESP+8]
0040130A   .  C74424 18 FFF>MOV DWORD PTR SS:[ESP+18],-1
00401312   .  E8 D3020000   CALL <JMP.&MFC42.#800_?CString>
00401317   >  8B46 60       MOV EAX,DWORD PTR DS:[ESI+60]
0040131A   .  8B56 20       MOV EDX,DWORD PTR DS:[ESI+20]
0040131D   .  8B3D DC214000 MOV EDI,DWORD PTR DS:[<&USER32.SendMessageA>];  USER32.SendMessageA
00401323   .  50            PUSH EAX                                    ; /lParam
00401324   .  6A 01         PUSH 1                                      ; |wParam = 1
00401326   .  68 80000000   PUSH 80                                     ; |Message = WM_SETICON
0040132B   .  52            PUSH EDX                                    ; |hWnd
0040132C   .  FFD7          CALL EDI                                    ; \SendMessageA  //(04)第一处“SendMessageA”函数调用。
0040132E   .  8B46 60       MOV EAX,DWORD PTR DS:[ESI+60]
00401331   .  50            PUSH EAX                                    ; /lParam
00401332   .  8B46 20       MOV EAX,DWORD PTR DS:[ESI+20]               ; |
00401335   .  6A 00         PUSH 0                                      ; |wParam = 0
00401337   .  68 80000000   PUSH 80                                     ; |Message = WM_SETICON
0040133C   .  50            PUSH EAX                                    ; |hWnd
0040133D   .  FFD7          CALL EDI                                    ; \SendMessageA  //(05)第二处“SendMessageA”函数调用。
0040133F   .  68 5C304000   PUSH Samples.0040305C                       ;  (06)第二处初始化位置:OnInitDialog()函数中的用户代码开头!
00401344   .  8D4C24 10     LEA ECX,DWORD PTR SS:[ESP+10]
00401348   .  E8 BB020000   CALL <JMP.&MFC42.#537_?CString>
0040134D   .  8B4C24 0C     MOV ECX,DWORD PTR SS:[ESP+C]
00401351   .  6A 00         PUSH 0
00401353   .  6A 00         PUSH 0
00401355   .  51            PUSH ECX
00401356   .  C74424 24 010>MOV DWORD PTR SS:[ESP+24],1
0040135E   .  E8 9F020000   CALL <JMP.&MFC42.#1200_?AfxMessageBox>
00401363   .  8D4C24 0C     LEA ECX,DWORD PTR SS:[ESP+C]
00401367   .  C74424 18 FFF>MOV DWORD PTR SS:[ESP+18],-1
0040136F   .  E8 76020000   CALL <JMP.&MFC42.#800_?CString>
00401374   .  8B4C24 10     MOV ECX,DWORD PTR SS:[ESP+10]
00401378   .  5F            POP EDI
00401379   .  B8 01000000   MOV EAX,1
0040137E   .  5E            POP ESI
0040137F   .  64:890D 00000>MOV DWORD PTR FS:[0],ECX
00401386   .  83C4 14       ADD ESP,14
00401389   .  C3            RETN
-----------------------------------------------------------
==================================================================
总结:
    其实,在调试由MFC编写的木马病毒时,想定位到程序第一步(只要定位出第一步,后边的按照顺序就很好跟了)执行了什么真不是件很容易的事,我为这个苦恼了很久。在网络上没搜索到什么结果(貌似我搜索能力很差,呵呵),后来只能去自己慢慢的调试找寻规律了,大概用了半个小时的时间,终于搞定了,呵呵。个人感觉想准确定位MFC程序中,作者的代码最先执行了什么真的不是件容易的事(相反由汇编和C语言直接编写的程序会容易调试些)。MFC类库封装出来的东西是绝对可以难住新手去进行详细的逆向调试分析的,因为它在启动初始化程序时(初始化对话框、初始化消息响应循环等等)所使用的代码都是跳到MFC的动态连接库中去执行的,里边还用到了消息响应循环,想得到程序被初始化后返回主程序代码领空的地址,真的不容易。不了解的朋友一般在单步调试分析由MFC编写的程序时,都是在系统的函数(DLL)中跑来跑去,根本回不到主程序的领空上,一着急程序就跑飞了,这样调试危险的病毒时是件很郁闷的事。估计我上边所写的方法会有一些朋友看不懂,大家慢慢理解吧,多实际调试几次就明白原理了。以前的前辈们所总结的类似文章网络上一定应该是存在的,可能我只是没找到。本文总结的方法是我自己想出来的,希望对需要的朋友们有些帮助。
==================================================================
/////////////////////////////////////////////////////////////////////////////////////////////////

上传的附件 MFC_Samples.rar