中断了一段时间PE的学习,从昨天开始捡起来,研究了一下NT头里边的optionalheader的数据目录项,里边存放着很多重要的表的数据,想要解析那些表,就必须要能够解析这个数组。
typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; //相对虚拟地址 DWORD Size; //大小 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
这是vs里边给出的定义,数据目录在winnt.h中的定义为[C++] 纯文本查看 复制代码#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 导出表#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 导入表 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 资源目录#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 异常目录#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 安全目录#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 重定位基本表#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 调试目录#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 描术字串#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 机器值#define IMAGE_DIRECTORY_ENTRY_TLS 9 TLS目录#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 载入配值目录#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 绑定输入表#define IMAGE_DIRECTORY_ENTRY_IAT 12 导入地址表#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 延迟载入描述#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 COM信息
这是15个基本表,其实一共有16个但是第十六个保留不适用所以没有写,想要用代码找必须要会手动查找。这里我是用的软件是windows自带的notepad 工具为UltraEdit
通过查询PE文件结构可以知道,数据目录项在节表上方,16项每项的大小为8个字节,所以从节表开始出向上找8行。
(但是这个地方我有点不理解为什么是virtualaddress在前,size在后边,看定义的时候位置是相反的。)
手动找到完成之后开始使用代码写,大体步骤为:
1、将文件读到缓冲区。
2、定义每个pe头的信息。
3、定义数据目录项指针将指针指向数据目录项、
4、打印信息。代码为:[C++] 纯文本查看 复制代码 VOID DirectoryPrintf(){ PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL; PIMAGE_DATA_DIRECTORY pDirectory = NULL; BYTE Length = 8; //本来是想通过加上长度来移动指针,发现不可以 这个地方忽略 LPVOID pFileBuffer = NULL; ReadPEFile(INFILEPATH, &pFileBuffer); //判断读取文件是否成功 if (!pFileBuffer){ printf("读取文件失败"); free(pFileBuffer); return; } //如果读取成功进行操作 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER); pDirectory = (PIMAGE_DATA_DIRECTORY)(((DWORD)pOptionalHeader) + 96); //输出各种表的信息~ printf("导出表:size: %x virtualaddress: %x\n",pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("导入表:SIZE:%x virtualaddress:%x\n", pDirectory->Size,pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("资源目录:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("异常目录:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("安全目录:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("重定位基本表:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("调试目录:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("描述字串:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("机器值:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("TLS目录:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("载入配值目录:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("绑定输入表:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("导入地址表:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("延迟载入描述:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("COM信息:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); pDirectory++; printf("未使用的表:Size %x VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress); printf("=====================================\n"); free(pFileBuffer); }运行结果为:
跟上边UE查询的数据对应。好了,数据目录项已经读取完成,明天更新下导出表的一些操作代码算是给自己的flag毕竟学生嘛,惰性还是太严重。
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |