// Analysis_VB.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "windows.h" #include "iostream" using namespace std; typedef struct { char Signature[4]; // 四个字节的签名符号,和PEHEADER里的那个signature是类似性质的东西,VB文件都是"VB5!" WORD RtBuild; // 运行时创立的变量(类似编译的时间) BYTE LangDLL[14]; // 语言DLL文件的名字(如果是0x2A的话就代表是空或者是默认的) BYTE BakLangDLL[14]; // 备份DLL语言文件的名字(如果是0x7F的话就代表是空或者是默认的,改变这个值堆EXE文件的运行没有作用) WORD RtDLLVer; // 运行是DLL文件的版本 DWORD LangID; // 语言的ID DWORD BakLangID; // 备份语言的ID(只有当语言ID存在时它才存在) DWORD pSubMain; // RVA(实际研究下来是VA) sub main过程的地址指针(3.)(如果时00000000则代表这个EXE时从FORM窗体文件开始运行的) DWORD pProjInfo; // VA 工程信息的地址指针,指向一个ProjectInfo_t结构(2.) DWORD fMDLIntObjs; // ?详细见"MDL 内部组建的标志表" DWORD fMDLIntObjs2; // ?详细见"MDL 内部组建的标志表" DWORD ThreadFlags; // 线程的标志 //* 标记的定义(ThreadFlags数值的含义) //+-------+----------------+--------------------------------------------------------+ //| 值 | 名字 | 描述 | //+-------+----------------+--------------------------------------------------------+ //| 0x01 | ApartmentModel | 特别化的多线程使用一个分开的模型 | //| 0x02 | RequireLicense | 特别化需要进行认证(只对OCX) | //| 0x04 | Unattended | 特别化的没有GUI图形界面的元素需要初始化 | //| 0x08 | SingleThreaded | 特别化的静态区时单线程的 | //| 0x10 | Retained | 特别化的将文件保存在内存中(只对Unattended) | //+-------+----------------+--------------------------------------------------------+ //ex: 如果是0x15就表示是一个既有多线程,内存常驻,并且没有GUI元素要初始化 DWORD ThreadCount; // 线程个数 WORD FrmCount; // 窗体个数 WORD pExternalComponentCount; // VA 外部引用个数例如WINSOCK组件的引用 DWORD ThunkCount; // ?大概是内存对齐相关的东西 DWORD pGUITable; // VA GUI元素表的地址指针(指向一个GUITable_t结构(4.四)) DWORD pExternalComponentTable; // VA 外部引用表的地址指针 // DWORD pProjDep; // VA 工程的描述的地址指针(这个其实没有) DWORD pComregData; // VA COM注册数据的地址指针 DWORD oProjExename; // Offset 指向工程EXE名字的字符串 DWORD oProjTitle; // Offset 指向工程标题的字符串 DWORD oHelpFile; // Offset 指向帮助文件的字符串 DWORD oProjName; // Offset 指向工程名的字符串 }VBHeader_t; typedef struct { DWORD Signature; // 结构的签名特性,和魔术字符类似 DWORD pObjectTable; // VA 结构指向的组件列表的地址指针(很重要的!(7.)) DWORD Null1; // ?没有用的东西 DWORD pStartOfCode; // VA 代码开始点,类似PEHEAD->EntryPoint这里告诉了VB代码实际的开始点 DWORD pEndOfCode; //VA 代码结束点 DWORD Flag1; // 标志1 DWORD Threadspace; // 多线程的空间????????????????? DWORD pVBAExcrptionhandler; // VA VBA意外处理机器地址指针 DWORD pNativeCode; // VA 本地机器码开始位置的地址指针 WORD oProjectLocation; // Offset 工程位置????????????????? WORD Flag2; // 标志2 WORD Flag3; // 标志3 BYTE OriginalPathName[MAX_PATH*2]; // 原文件地址,一个字符串,长度最长为MAX_PATH BYTE NullSpacer; // 无用的东西,用来占位置???????????????????? DWORD pExternalTable; // VA 引用表的指针地址 DWORD ExternalCount; // 引用表大小(个数) // sizeof() = 0x23c }ProjectInfo_t; int _tmain(int argc,_TCHAR* argv[]) { WCHAR File_Path[MAX_PATH] = L"C:\\1.v"; HANDLE hFile = NULL; HANDLE hMapping = NULL; HANDLE BaseAddress = NULL; char VB_Signature[5] = {0}; hFile = ::CreateFile(File_Path,GENERIC_ALL,FILE_SHARE_READ || FILE_SHARE_WRITE,NULL,OPEN_EXISTING,NULL); hMapping = ::CreateFileMapping(hFile,PAGE_READONLY,NULL); BaseAddress = ::MapViewOfFile(hMapping,FILE_MAP_READ,0); IMAGE_DOS_HEADER *DHeader = (IMAGE_DOS_HEADER *)BaseAddress; IMAGE_NT_HEADERS *NHeader = (IMAGE_NT_HEADERS *)((char *)BaseAddress + DHeader->e_lfanew); IMAGE_SECTION_HEADER *SHeader = (IMAGE_SECTION_HEADER *)((char *)BaseAddress + DHeader->e_lfanew + sizeof(IMAGE_FILE_HEADER) + 4 + NHeader->FileHeader.SizeOfOptionalHeader); DWORD EPRVA = NHeader->OptionalHeader.AddressOfEntryPoint; BYTE *Filepointer = (BYTE *)((char *)BaseAddress + EPRVA); DWORD VBHEADER_VA = Filepointer[4]*0x1000000 + Filepointer[3]*0x10000 + Filepointer[2]*0x100 + Filepointer[1]; // printf("\n%X",VBHEADER_VA); Filepointer = (BYTE *)BaseAddress + VBHEADER_VA - 0x00400000; VBHeader_t *VBHeader = (VBHeader_t *)Filepointer; printf("%x\n",VBHeader->oProjExename); Filepointer = (BYTE *)BaseAddress + VBHeader->pProjInfo - 0x00400000; ProjectInfo_t *_pProject = (ProjectInfo_t *)Filepointer; for (int i = 0 ; i < 4 ; i++) { VB_Signature[i] = VBHeader->Signature[i]; } printf("%s\n",VB_Signature); printf("%X\n",_pProject->pStartOfCode); printf("%X\n",_pProject->pEndOfCode); VBHeader_t sttemp; DWORD i = (DWORD)&sttemp.oProjExename - (DWORD)&sttemp; getchar(); CloseHandle(hFile); CloseHandle(hMapping); UnmapViewOfFile(BaseAddress); return 0; }