本帖最后由 宇宙第一魔王 于 2022-4-6 01:51 编辑
一、Visual Basic简介:
1.百度百科简介:
Visual Basic(简称VB)是Microsoft公司开发的一种通用的基于对象的程序设计语言,为结构化的、模块化的、面向对象的、包含协助开发环境的事件驱动为机制的可视化程序设计语言。是一种可用于微软自家产品开发的语言。
2.个人汇总:
tips:目前VB语言碰到的都是crackme里的一些验证算法中利用VB做一个图形界面,下面记载的知识点也基本是针对VB在Crack中的应用。
VB给我的感觉就是图形化的界面,VB函数的调用遵循 stdcall 原则,并且函数之间会有NOP分隔,而且VB程序不是直接调Windows API函数,而是调用VB库里的函数。可以看到下图导入的函数都来自于MSVBVM50.dll
- VB文件使用名为MSVBVM60.dll的VB专用引擎(Microsoft Visual Basic Virtual Machine 6.0)
- 根据使用的编译选项不同VB文件可以编译为本地代码(N code)与伪代码(P code),前者适用于调试器解析的IA-32指令;后者是一种解释器语言,它使用由VB引擎实现虚拟机并可自解析的指令(字节码)。因此,若想准确解析VB的伪代码就需要分析VB引擎并实现模拟器
- 这里面的N表示的是自然编译(Native):
- 自然编译的VB程序,直接生成x86汇编代码,可以直接使用OD、IDA进行分析
- 而P表示的是伪编译:
- 该语言适用于编写GUI图形界面,VB程序采用windows操作系统的事件驱动方式工作,所以在main()或Winmain()中并不存在用户代码(希望调试的代码),用户代码存在于各个事件处理程序之中。
二、关于VB语言在逆向中的分析:
以CrackMe的第二题为例,将它丢入OD中:1.vb程序的EP特征:
vb程序的EP一开始就是一条push命令,这里实际上压入的是一个指针,指向的是VBHeader结构体,然后就是call指令调用MSVBVM60.dll中的ThunRTMain。这两条指令的目的是调用ThunRTMain函数初始化各种变量。
VBHeader结构体:
可以在数据窗口跟踪push的结构体:
[C] 纯文本查看 复制代码 typedef struct{
char Signature[4]; //00H 四个字节的签名符号,和PEHEADER里的那个signature是类似性质的东西,VB文件都是"VB5!"
WORD RtBuild; //04H 运行时创立的变量(类似编译的时间)
BYTE LangDLL[14]; //06H 语言DLL文件的名字(如果是0x2A的话就代表是空或者是默认的)
BYTE BakLangDLL[14]; //14H 备份DLL语言文件的名字(如果是0x7F的话就代表是空或者是默认的,改变这个值堆EXE文件的运行没有作用)
WORD RtDLLVer; //22H 运行时DLL文件的版本
DWORD LangID; //24H 语言的ID
DWORD BakLangID; //28H 备份语言的ID(只有当语言ID存在时它才存在)
DWORD pSubMain; //2CH RVA(实际研究下来是VA) sub main过程的地址指针(3.)(如果时00000000则代表这个EXE时从FORM窗体文件开始运行的)
DWORD pProjInfo; //30H VA 工程信息的地址指针,指向一个ProjectInfo_t结构(2.)
DWORD fMDLIntObjs; //34H ?详细见"MDL 内部组建的标志表"
DWORD fMDLIntObjs2; //36H ?详细见"MDL 内部组建的标志表"
DWORD ThreadFlags; //38H 线程的标志
//* 标记的定义(ThreadFlags数值的含义)
//+-------+----------------+--------------------------------------------------------+
//| 值 | 名字 | 描述
//+-------+----------------+--------------------------------------------------------+
//| 0x01 | ApartmentModel | 特别化的多线程使用一个分开的模型
//| 0x02 | RequireLicense | 特别化需要进行认证(只对OCX)
//| 0x04 | Unattended | 特别化的没有GUI图形界面的元素需要初始化
//| 0x08 | SingleThreaded | 特别化的静态区时单线程的
//| 0x10 | Retained | 特别化的将文件保存在内存中(只对Unattended)
//+-------+----------------+--------------------------------------------------------+
//ex: 如果是0x15就表示是一个既有多线程,内存常驻,并且没有GUI元素要初始化
DWORD ThreadCount; //3CH 线程个数
WORD FrmCount; //41H 窗体个数
WORD pExternalComponentCount; //44H VA 外部引用个数例如WINSOCK组件的引用
DWORD ThunkCount; //48H ?大概是内存对齐相关的东西
DWORD GUITable; //4CH VA GUI元素表的地址指针(指向一个GUITable_t结构)
DWORD pExternalComponentTable; //50H VA 外部引用表的地址指针
// DWORD pProjDep; // VA 工程的描述的地址指针(这个其实没有)
DWORD pComRegData; //54H VA COM注册数据的地址指针
DWORD oProjExename; //58H Offset 指向工程EXE名字的字符串
DWORD oProjTitle; //5CH Offset 指向工程标题的字符串
DWORD oHelpFile; //60H Offset 指向帮助文件的字符串
DWORD oProjName; //64H Offset 指向工程名的字符串
}VBHeader_t; 可以在数据窗口跟踪push的结构体:
结构体的前面4个字节为魔数字段“VB5!”,对于该结构体需要重点关注的成员是pSubMain 它才是VB程序的真正入口。
关于这个结构体还有一个技巧叫做C4法,这个技巧将在下一篇文章”Crack160学习记录3 AfKayAs.2”中详细介绍。
2.网上关于VB博客的收集:- 常用函数的汇编解释:https://www.cnblogs.com/findeasy/archive/2012/10/11/4053150.html
- VB快速逆向法:https://bbs.pediy.com/thread-12133.htm
- 个人收集的一些VB常用API:https://magnificent-syrup-61f.notion.site/VB-API-990aca9082584cb692393b29a90ae8dc
|