《逆向工程核心原理》读书笔记——第8章 Visual Basic编写的exe程序特征
Posted 大灬白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《逆向工程核心原理》读书笔记——第8章 Visual Basic编写的exe程序特征相关的知识,希望对你有一定的参考价值。
第8章
本章分析第二个crackme文件abex’crackme #2,它使用Visual Basic语言编写,你会感受到与使用Visual C++或Assembly编写的文件相比具有不同的形态。
32位的PE文件格式,由Microsoft Visual Basic编译器编译。
8.1运行abex’crackme #2
运行之后才能了解它是什么样的程序,如图8-1所示。
图8-1 运行画面
这个程序具有典型的crackme形态,要求我们找出程序的序列号。从单独输入Name来看,生成Serial时才会用到Name字符串(依据经验推测)。输入合适的Name与Serial,按Check按钮,如图8-2所示。
图8-2“Wrong serial!”消息框
弹出“Wrong serial!”消息框,即使多次尝试其他值也依然是这个结果。下面通过调试仔细分析其代码。
8.2 Visual Basic文件的特征
要调试的abex’s crackme #2文件由Visual Basic编写而成。调试前最好先了解Visual Basic文件的特征。
8.2.1 VB专用引擎
VB文件使用名为MSVBVM60.d1l(Microsoft Visual Basic Virtual Machine 6.0 )的VB专用引擎(也称为The Thunder Runtime Engine )。
举个使用VB引擎的例子,显示消息框时,VB代码中要调用MsgBox()函数。其实,VB编辑器真正调用的是MSVBVM60.dll里的rtcMsgBox()函数,在该函数内部通过调用user32.dll里的MessageBoxW)函数( Win32 API )来工作(也可以在VB代码中直接调用user32.dl里的MessageBoxW( )。
8.2.2 本地代码和伪代码
根据使用的编译选项的不同,VB文件可以编译为本地代码(N code)与伪代码(P code )。本地代码一般使用易于调试器解析的IA-32指令;而伪代码是一种解释器(Interpreter)语言,它使用由VB引擎实现虚拟机并可自解析的指令(字节码)。因此,若想准确解析VB的伪代码,就需要分析VB引擎并实现模拟器。
提示
伪代码具有与Java (Java虚拟机)、Python (Python专用引擎)类似的形态结构。使用伪代码的好处是非常方便代码移植(编写/发布针对特定平台的引擎,用户代码借助它几乎可以不加任何修改地在指定平台上运行)。
8.2.3 事件处理程序
VB主要用来编写GUI程序,IDE用户界面本身也最适合于GUI编程。由于VB程序采用Windows操作系统的事件驱动方式工作,所以在main()或WinMain()中并不存在用户代码(希望调试的代码),用户代码存在于各个事件处理程序( event handler)之中。
就上述abex’crackme #2而言,用户代码在点击Check按钮时触发的事件处理程序内。
8.2.4 未文档化的结构体
VB中使用的各种信息(Dialog、Control、Form、Module、Function等)以结构体形式保存在文件内部。由于微软未正式公开这种结构体信息,所以调试VB文件会难一些。
8.3开始调试
运行OllyDbg,查看abex’crackme #2文件的反汇编代码,如图8-3所示。
图8-3 EP
加载abex’crackme #2文件后,程序停在00401238。执行程序后,在EP代码中首先要做的是调用VB引擎的主函数(ThunRTMain()):
<jmp.&MSVBVM60.#ThunRTMain_100>的地址就是00401232
00401232 $- FF25 A0104000 jmp dword ptr ds:[<&MSVBVM60.#ThunRTMain>; msvbvm60.ThunRTMain
00401238 > $ 68 141E4000 push abexcm2-.00401E14
0040123D . E8 F0FFFFFF call <jmp.&MSVBVM60.#ThunRTMain_100>
EP的地址为401238。401238地址处的PUSH 401E14命令用来把RT_MainStruct结构体的地址(401E14)压入栈。然后40123D地址处的CALL 00401232命令调用401232地址处的JMP DWORDPTR DS:[4010A0]指令。该JMP指令会跳转至VB引擎的主函数ThunRTMain()(前面压入栈的401E14的值作为ThunRTMain()的参数)。
以上3行代码是VB文件的全部启动代码。虽然非常简单,但有3个方面需要各位留意。
8.3.1 间接调用
40123D地址处的CALL 401232命令用于调用ThunRTMain()函数,这里使用了较为特别的技法。不是直接转到MSVBVM60.dll里的ThunRTMain()函数,而是通过中间401232地址处的JMP命令跳转。
00401232 FF25 A0104000— JMP DWORD PTR DS:[4010A0]
这就是VCH4、VB编译器中常用的间接调用法(Indirect Call)。
提示
4010AO地址是IAT( Import Address Table,导入地址表)区域,包含着MSVBVM60.ThunRTMain()函数的实际地址。第13章将详细讲解IAT。
8.3.2 RT_MainStruct结构体
要注意的是ThunRTMain()函数的参数RT_MainStruct结构体。这里,RT_MainStruct结构体存在于401E14地址处,如图8-4所示。
图8-4 RT_MainStruct
微软未公开RT_MainStruct,但是有国外的逆向分析高手已经完成了对RT_MainStruct结构体的分析,并公布在网络上。
RT_MainStruct结构体的成员是其他结构体的地址。也就是说,VB引擎通过参数传递过来的RT_MainStruct结构体获取程序运行需要的所有信息。
此处省略对RT_MainStruct结构体的详细说明。
8.3.3 ThunRTMain()函数
前面提到了ThunRTMain()函数,下面了解一下。
图8-5显示了ThunRTMain()代码的开始部分,可以看到内存地址完全不同了。这是MSVBVM60.dll模块的地址区域。换言之,我们分析的不是程序代码,而是VB引擎代码(现在还不需要分析如此庞大的代码)。对VB文件的讲解到此为止。
图8-5 ThunRTMain(代码开始
以上是关于《逆向工程核心原理》读书笔记——第8章 Visual Basic编写的exe程序特征的主要内容,如果未能解决你的问题,请参考以下文章