《逆向工程核心原理》读书笔记——第8章 Visual Basic编写的exe程序特征

Posted 大灬白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《逆向工程核心原理》读书笔记——第8章 Visual Basic编写的exe程序特征相关的知识,希望对你有一定的参考价值。

  本章分析第二个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程序特征的主要内容,如果未能解决你的问题,请参考以下文章

《逆向工程核心原理》读书笔记——第13章 PE文件格式

《逆向工程核心原理》读书笔记——第10章 函数调用约定

《逆向工程核心原理》读书笔记——第5章 栈

《逆向工程核心原理》读书笔记——第14章 运行时压缩

《逆向工程核心原理》读书笔记——第6章 汇编编写的exe程序入口

《逆向工程核心原理》读书笔记——第15章 调试UPX压缩的notepad程序