首页 > 编程知识 正文

pe文件结构详解,卡在初始化pe文件系统

时间:2023-05-05 13:12:35 阅读:167128 作者:1679

PE文件PE结构图PE文件结构简介1. DOS头1.1 MZ头1.2 DOS残留2. PE头2.1 PE标记2.2文件头2.3可选头3.3节表4 .节结构图PE详细信息1. DOS头2. PE头2 3可选标题3 .节表4 .节地址文件偏移地址文件偏移基地址ImageBase虚拟地址VA相对于虚拟地址RVA PE文件从存储器RVA映射到文件偏移

参考

甲鱼PE详细系列

PE文件PE (可移植可执行体)是什么? 利用PE文件构造的可执行文件被称为PE文件,Win下面包含exe、DLL、SYS、OCX等

PE结构图

PE文件结构概述1. DOS头部1.1 MZ头部MZ头部是真实的DOS头部,其前2个字节是MZ。 此部分用于在DOS系统上加载程序,其结构定义为IMAGES_DOS_HEADER

1.2 DOS提供了一个简单的程序,主要用于输出' thisprogramcannotberunindosmode.'的提示字符串

2. PE表头2.1 PE标识宏: IMAGE_NT_SIGNATRUE

2.2文件头结构: IMAGE_FILE_HEADER

2.3可选磁头结构: IMAGE_OPTIONAL_HEADER

三.节表和节

程序的组织存储在每个属性的不同部分中,每个部分由一个IMAGE_SECTION_HEADER表示。 如果PE文件包含n个节,则节表是由n个IMAGE_SECTION_HEADER结构和表示结束的空IMAGE_SECTION_HEADER结构组成的数组。

空结构不计入节数pimagentheaders-file header.number of sections中

“节”表包含各节的属性、文件位置和内存位置等信息,并且是节的索引。

4 .子句实际上是同一属性数据的组合,一个子句可能有多种类型的数据,它们只是因为读写属性相同而被编入同一子句。 将节加载到内存中后,相同节对应的内存页将分配相同的页属性。 实际上,在Windows系统上,内存中各节的对齐单位必须至少为一页大小,因为内存属性的设置是按页进行的。 )小鳖温馨提示:对于32位操作系统,该值通常为4KB或1000H; 对于64位操作系统,此值通常为8KB或2000H。)

结构关系图的源

PE详查1. DOS头的DOS头用于加载DOS残留,其中的一个字段中存储了向PE头的位置

在这个结构体中

e_magic:2B,DOS可执行文件的标识符

此标识符在winnt.h中有宏定义

# define images _ dos _ signature0x 5a 4d

由于系统以小字节序方式保存,因此实际保存时的前两个字节为4D 5A

e_lfanew:2B,PE头的开始位置

偏移将保存在0x0000003C的位置

那个值是0x0110

2. PE头

2.1查看PE标记0x00000110的位置

Signature:4B,值为0x00004550,即PE

2.2文件头PE标记后的20字节是文件头,主要描述与文件有关的信息

结构_IMAGE_FILE_HEADER的定义:

Machine:2B,可执行文件的目标处理器类型

图中的0x8664示出了x64处理器

NumberOfSections:2B,节数

图中0x0008表示有8个节区

TimeDataStamp:4B,从1970年到创建文件之间的秒数

SizeOfOptionHeader:2B,可选的头大小。 图中为0x00f 0,10进制数为240字节

Characteristics:2B,文件类型。 图中为0x0022

2.3可选的标题选项标题主要用于管理在将PE文件加载到OS中时所需的信息。

注:可选标题之所以称为可选标题,是因为数据目录数组中可以有也可以没有数据目录条目,但此标题必须存在。

从文件头的SizeOfOptionHeader中发现,选项头的大小为240字节,紧跟在文件头之后。 文件头的结束位置为0x00000127时,选项头的地址范围为0x00000128 ~0x00000217

结构的定义如下:

SizeOfCode:4B,所有代码节的大小之和。 图中为0x001c6400

AddressOfEntryPoint :

数据目录:

例如,导入表RVA:8000H、大小: 1964

从PE文件中读取所需的块(部分)时,块名称不能作为定位依据。 将数据目录中的虚拟地址

标准,因为区块名没有任何意义。

3. 节表

紧挨在可选头之后,由文件头标识有8个节区
一个IMAGE_SECTION_HEADER大小为40字节,图中从0x00000218开始,下图为第一个节区对应的节表

ISH结构体定义如下:

Name:8B,多余的自动截断。图中为

VirtualSize:该区块的数据没有进行对齐处理前的实际大小。

VirtualAddress:装入内存中的RVA地址,按内存页对齐,因此其数值是OptionalHeader->SectionAlignment的整数倍
如内存分页大小为4096B

两个节的RVA分别为4096和12288

4.节

一个区块(节)中的数据仅仅只是由于属性相同而放在一起,并不一定是同一种用途的内容。如输入表、输出表等就有可能和只读常量一起被放在同一个区块中,因为他们的属性都是可读不可写的

几种地址 文件偏移地址FileOffset

PE文件中某处相对于文件头的地址

基地址ImageBase

内存中PE文件的头地址

虚拟地址VA

内存中某处相对于基地址的位置

相对虚拟地址RVA

内存中某一虚拟地址相对于基地址的偏移量

PE文件映射到内存

注意:块与块之间有空隙,因为要对齐

映射与装载的区别:

RVA转FileOffset

PE文件在磁盘上和内存上的结构是一致的,略有不同的是,在磁盘上PE文件是按照可选头的FileAlignment值对齐的,在内存中,PE文件是按可选头的SectionAlignment值对齐的。

FA的最小值是512B,Win32下的SA值一般为4096B

如果PE文件的SA值和FA值相等,则其磁盘文件结构与内存映像的结构是完全一样的。如果不相等,则略有差异。

当知道某数据的RVA,想要在文件中读取同样的数据时,就要将RVA转换为FileOffset,反之同理。

如:

观察输入表
RVA:6000H
ImageBase:40000H
SectionAlignment:1000H
FileAlignment:200H
内容:

接下来进行RVA到FileOffset的转换:
总体的思路是:

输入表属于节表数据的部分,所以首先要判断此RVA在哪一节。依次计算各节的RVA范围:起始RVA 到 起始RVA+节数据大小判断出在哪一节之后,用此RVA减去此节的起始RVA,得到一个偏移量。无论是在内存中还是在文件中,这个偏移量都是相同的。而节的FileOffset在节表中存着(IMAGE_SECTION_HEADER->PointerTORawData)所以可以得到此RVA的FileOffset = 节FileOffset + 目标RVA相对于节的偏移量。 查看区段表

.text节的RVA范围是:VisualOffset 到 VisualOffset + RawDataSize
即:1000H到2788H
.data节的RVA范围是:3000H到3030H

.idata节的RVA范围是6000H到659EH输入表的RVA为6000H,属于.idata节。输入表的RVA相对于.idata节的偏移量为6000H - 6000H = 0.idata节的ROffset (2400H)即此节的文件偏移地址用2400H + 0H 即得到导入表的FileOffset 2400H

使用C32ASM查看其文件偏移地址为2400H的内容,一致

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。