/////////////////////////////////////////////////////////////////////////////////////////////////
文件名称:逆向动态调试分析“基于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)中跑来跑去,根本回不到主程序的领空上,一着急程序就跑飞了,这样调试危险的病毒时是件很郁闷的事。估计我上边所写的方法会有一些朋友看不懂,大家慢慢理解吧,多实际调试几次就明白原理了。以前的前辈们所总结的类似文章网络上一定应该是存在的,可能我只是没找到。本文总结的方法是我自己想出来的,希望对需要的朋友们有些帮助。
==================================================================
/////////////////////////////////////////////////////////////////////////////////////////////////
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课