数据目录表

数据目录表我们当时解析可选 PE 头时 有一个字段为 DWORD 的值为多少 说明下面的 这种类型的结构体就有多少个我们编写一个程序 这个程序的 PE 结构分节 有代码节 数据节等等节 但是不能理解成一个这些节中只有我们写的代码或者定义

大家好,欢迎来到IT知识分享网。

一、数据目录概述

数据目录的引入

  • 我们当时解析可选PE头时,有一个字段为DWORD NumberOfRvaAndSizesNumberOfRvaAndSizes的值为多少,说明下面的_IMAGE_DATA_DIRECTORY DataDirectory[16];这种类型的结构体就有多少个
  • 我们编写一个程序,这个程序的PE结构分节,有代码节,数据节等等节,但是不能理解成一个这些节中只有我们写的代码或者定义的变量等,编译器也会替我们往每一个节中加很多重要的内容:
    • 比如我们写代码时会使用一写系统提供的函数,那么编译器就需要添加这个函数的相关信息,告诉系统需要去哪里找到这个函数;
    • 一个程序不仅可以使用别的函数,也可以提供函数给别人程序或人使用,所以此时编译器会添加此程序中供别人使用的函数相关信息

数据目录结构

img

  • 分别是:导出表的数据目录、导入表的数据目录、资源表的数据目录、异常信息表的数据目录、安全证书表的数据目录、重定位表的数据目录、调试信息表的数据目录、版权所有表的数据目录、全局指针表的数据目录、TLS表的数据目录、加载配置表的数据目录、绑定导入表的数据目录、IAT表的数据目录、延迟导入表的数据目录、COM信息表的数据目录、最后一个保留未使用
  • 其中比较重要的就是导出表、导入表、重定位表、IAT表这四张表的数据目录,这四张表和程序的运行有直接关系,不管是加壳、脱壳、激活成功教程、病毒或反病毒,这些都是基础中的基础

可选PE头最后一个成员,就是数据目录.一共有16个:

typedef struct _IMAGE_DATA_DIRECTORY {   DWORD   VirtualAddress; //内存偏移   DWORD   Size; //大小 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; 

16个数据目录的大小一样,都是8字节,一行16字节,一共占8行,可以从节表往上倒着推8行,就是数据目录

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 // Directory Entries //                             按顺序排列的数据目录表 ​ #define IMAGE_DIRECTORY_ENTRY_EXPORT         0   // Export Directory 导出表:动态链接库导出的函数会显示在这里 #define IMAGE_DIRECTORY_ENTRY_IMPORT         1   // Import Directory 导入表:写程序时调用的动态链接库会显示在这里 #define IMAGE_DIRECTORY_ENTRY_RESOURCE       2   // Resource Directory 资源表:图片,图标,字符串,嵌入的程序都在这里 #define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory 异常目录表:保存文件中异常处理相关的数据 #define IMAGE_DIRECTORY_ENTRY_SECURITY       4   // Security Directory 安全目录:存放数字签名和安全证书之类的东西 #define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table 基础重定位表:保存需要执行重定位的代码偏移 #define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory 调试表 //     IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage) #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE   7   // Architecture Specific Data 缓存信息表:有一些保留字段必须是0 #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP 全局指针偏移目录 #define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory 线程局部存储(暂时未知) #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG   10   // Load Configuration Directory 载入配置 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers 存储一些API的绑定输入信息 #define IMAGE_DIRECTORY_ENTRY_IAT           12   // Import Address Table 导入地址表:导入函数的地址 #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor com运行时的目录 ​

数据目录和16种表的关系

数据目录只是记录了对应的表的内存偏移地址和大小。我们通过找到表的数据目录,得到表的内存偏移地址,接着这个内存偏移地址处才是表本身真正的所在位置!

比如我们找到了导出表的数据目录,通过数据目录中的VirtualAddress + ImageBase得到导出表所在的地址

二、编程输出全部目录项

VOID OutputDataDirectory() { PVOID pFileBuffer; PVOID pImageBuffer; PVOID pNewBuffer; PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; ​ BOOL isOk = FALSE; DWORD size = 0; ReadPEFile(file_path, &pFileBuffer); if (!pFileBuffer) { printf("文件-缓冲区失败"); return; } /*FileBuffer->ImageBuffer*/ pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew) + 4); pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(((DWORD)pFileBuffer + pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)(((DWORD)pFileBuffer + pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER + pPEHeader->SizeOfOptionalHeader); ​ printf("%X   %X\n", pOptionHeader->DataDirectory[0].Size, pOptionHeader->DataDirectory[0].VirtualAddress); printf("%X   %X\n", pOptionHeader->DataDirectory[1].Size, pOptionHeader->DataDirectory[1].VirtualAddress); ​ }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/142808.html

(0)
上一篇 2025-05-07 20:45
下一篇 2025-05-07 21:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信