PE结构详解

本文详细介绍了PE文件的结构,包括DOS头、NT头、区段头表、数据目录等部分,以及RVA转FOA的实例代码。内容涵盖PE文件的各个组成部分、NT头的字段解释、数据目录的定义、区段头表的结构,以及导出表、导入表、资源表、重定位、TLS表和延迟载入表等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PE文件结构

PE文件是portable File Format(可移植文件)的简写

PE的解释:PE文件是指某一种格式的文件 比如可执行文件(exe) 动态链接库文件(dll) 驱动文件(sys)等

PE文件大概分为两部分:头与主体 两部分会在内部进行细分

PE格式文件的组成:
DOS头部: 为兼容DOS程序设立
NT头部 : 存储PE文件的全部属性 初始化信息等
区段头表: 对于PE文件主体属性的分段描述 个数不定
各个区段: PE文件的主体 分别存储着可执行代码的各种数据 资源等
一些调试信息:未知

========================================================

RVA转FOA的实例代码:

DWORD RVAtoFOA(DWORD dwRva, char * buf)
{
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)buf;
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + buf);//先获取NT的RVA

	DWORD dwSectionCount = pNt->FileHeader.NumberOfSections;//获取区段的数量
	PIMAGE_SECTION_HEADER pSec = IMAGE_FIRST_SECTION(pNt);//找到第一个区段的地址

	for (DWORD i = 0; i < dwSectionCount; i++)
	{
	//判断形参1是否在在该区段中 
		if (dwRva >= pSec->VirtualAddress && dwRva < pSec->VirtualAddress + pSec->SizeOfRawData)
		{
			return dwRva - pSec->VirtualAddress + pSec->PointerToRawData;
		}
		pSec++;//找到下一个区段 继续循环
	}
	return 0;
}

参数1:需要转换的RVA

参数2:这段内存的起始地址(4A5D)

返回值:FOA的地址 DWORD类型

DOS头:

结构体说明:

DOS头一般占64个字节0x40 它之后就是DOS stub

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // PE文件的标识
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // NT头部的偏移地址
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

该头部两个字段有用: e_magic 与 e_lfanew

  1. e_magic 是一个标记 DOS头标志位 其值恒为 5A4D 系统宏定义为 IMAGE_DOS_SIGNATURE
  2. e_lfanew 意思为新exe文件的偏移 它表示NT头部在文件中的偏移

使用:

e_magic字段 可以作为判断该文件是否为PE文件 如果e_magic成员不是IMAGE_DOS_SIGNATRUE 那么它就不是一个PE文件

if((PIMAGE_DOS_HEADER)pFile->e_magic != IMAGE_DOS_SIGNATRUE)
    return false;

e_lfanew 可以用来算出NT头在文件中的偏移 找到地址 e_lfanew一般都为0x100

PIMAGE_NT_HEADER pNt = (PIMAGE_NT_HEADER)(pFile+pFile->e_lfanew);

DOS与NT头部之间:

这两个头部之间存在一些区域 存储着一些被DOS头使用的数据 因为这部分数据的大小不确定 所以NT头部的地址需要用DOS头的 e_lfanew 字段来确定 没有DOS stub程序也可以正常执行

NT头部:

结构体说明:

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;                             //标记 用于判断文件是否为PE文件
    IMAGE_FILE_HEADER FileHeader;                //文件头 存储着PE文件的基本信息
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;      //扩展头 存储着关于PE文件加载时的信息
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32

一些字段的解释:

  1. Signature:如果是PE文件 标记的值为 0x00004550 其ASCII值为 PE00 系统宏定义:IMAGE_NT_SIGNATURE
    其实该字段与DOS头部中e_magic字段作用以及用法都差不多 可以用来判断是否为PE文件

文件头:(在NT头中)FileHeader

文件头占24个字节

结构体说明:

typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;                              //文件的运行平台
    WORD    NumberOfSections;                     //区段的数量 最大为96
    DWORD   TimeDateStamp;                        //文件创建时间
    DWORD   PointerToSymbolTable;                 //符号表转移
    DWORD   NumberOfSymbols;                      //符号个数
    WORD    SizeOfOptionalHeader;                 //扩展头的大小
    WORD    Characteristics;                      //PE文件的属性
} IMAGE_FILE
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值