PE文件结构体-IMAGE_SECTION_HEADER
在PE文件头与原始数据之间存在一个区块表(Section Table),它是一个IMAGE_SECTION_HEADER结构数组,
区块表包含每个块在映像中的信息(如位置、长度、属性),分别指向不同的区块实体。
全部有效结构的最后以一个空的IMAGE_SECTION_HEADER结构作为结束,所以节表中总的IMAGE_SECTION_HEADER结构数量等于节的数量加一。
另外,节表中 IMAGE_SECTION_HEADER 结构的总数总是由PE文件头NumberOfSections 字段来指定的。
每个该结构体占40个字节大小;
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//8个字节
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
(1)Name:这是一个8位的ASCII(不是Unicode内码),用来定义块名,多数块名以,开始(如.Text),这个实际上不是必需的,注意如果块名超过了8个字节,则没有最后面的终止标志NULL字节,带有$的区块的名字会从编译器里将带有$的相同名字的区块被按字母顺序合并。
(2)VirtualSize:指出实际的,被使用的区块大小,是区块在没有对齐处理前的实际大小.如果VirtualSize > SizeOfRawData,那么SizeOfRawData是可执行文件初始化数据的大小(SizeOfRawData – VirtualSize)的字节用0来填充。这个字段在OBJ文件中被设为0。
(3)VirtualAddress:该块时装载到内存中的RVA,注意这个地址是按内存页对齐的,她总是SectionAlignment的整数倍,在工具中第一个块默认RVA为1000,在OBJ中为0。
(4)SizeofRawData:该块在磁盘中所占的大小,在可执行文件中,该字段包括经过FileAlignment调整后块的长度。例如FileAlignment的大小为200h,如果VirtualSize中的块长度为19Ah个字节,这一块保存的长度为200h个字节。
//在内存中展开该节的时,VirtualSize 和 SizeofRawData 哪个值比较大,按照哪个值展开。
(5)PointerToRawData:该块是在磁盘文件中的偏移,程序编译或汇编后生成原始数据,这个字段用于给出原始数据块在文件的偏移,即在文件中展开该节时的起始地址,如果程序自装载PE或COFF文件(而不是由OS装载),这种情况,必须完全使用线性映像方法装入文件,需要在该块处找到块的数据。
(6)PointerToRelocations 在PE中无意义
(7)PointerToLinenumbers 行号表在文件中的偏移值,文件调试的信息
(8)NumberOfRelocations 在PE中无意义
(9)NumberOfLinenumbers 该块在行号表中的行号数目
(10)Characteristics 块属性,(如代码/数据/可读/可写)的标志
区块名称以及意义:
区块属性标志:这个值可通过链接器的/SECTION选项设置.
区块对齐:
区块大小是要对齐的,有两种对齐值,一种用于磁盘文件内,另一种用于内存中。PE文件头指出了这两个值,他们可以不同。PE 文件头里边的FileAligment 定义了磁盘区块的对齐值。每一个区块从对齐值的倍数的偏移位置开始存放。而区块的实际代码或数据的大小不一定刚好是这么多,所以在多余的地方一般以00h 来填充,这就是区块间的间隙。例如,在PE文件中,一个典型的对齐值是200h ,这样,每个区块都将从200h 的倍数的文件偏移位置开始,假设第一个区块在400h 处,长度为90h,那么从文件400h 到490h 为这一区块的内容,而由于文件的对齐值是200h,所以为了使这一区块的长度为FileAlignment 的整数倍,490h 到 600h 这一个区间都会被00h 填充,这段空间称为区块间隙,下一个区块的开始地址为600h 。
PE 文件头里边的SectionAligment 定义了内存中区块的对齐值。PE 文件被映射到内存中时,区块总是至少从一个页边界开始。一般在X86 系列的CPU 中,页是按4KB(1000h)来排列的;在IA-64 上,是按8KB(2000h)来排列的。所以在X86 系统中,PE文件区块的内存对齐值一般等于 1000h,每个区块按1000h 的倍数在内存中存放。
文件偏移与RVA
由于一些PE文件为减少体积,磁盘对齐值不是一个内存页 1000h,而是 200h,当这类文件被映射到内存后,同一数据相对于文件头的偏移量在内存中和磁盘文件中是不同的,这样就存在着文件偏移地址与虚拟地址的转换问题。
由上图可以看出,文件被映射到内存,DOS文件头,PE文件头,区块表的偏移位置和大小都没有发生改变。而各区块映射到内存后,起偏移位置发生了改变。
转换需要前面提到的一个公式:设:ΔK为相对虚拟地址RVA与文件偏移地址File Offset的差值
VA = ImageBase + RVA
File Offset = RVA - ΔK
File Offset = VA - ImageBase - ΔK
最新文章
- sublime常用快捷键
- angular懒加载机制 刷新后无法回退解决方案
- 页面设计--CheckBoxList
- check_area
- 怎样用sourceTree将自己本地的项目上传到github网站上
- [工作问题总结]MyEclipse 打开项目
- Cloudera Manager、CDH零基础入门、线路指导 http://www.aboutyun.com/thread-9219-1-1.html (出处: about云开发)
- django User model
- 火狐浏览器下使用jquery修改img的src
- shell是什么,各种shell的初步认识,适用于初学者
- [Python]程序性能分析
- 120. 单词接龙 (BFS)
- Python sqlalchemy orm 常用操作
- winform创建快捷方式
- MyBatis实战之配置
- Odoo进销存(采购、销售、仓库)入门教程 - 下
- android中使用WebView请求网页
- XMOJ 1133: 膜拜大牛 计算几何/两圆相交
- html canvas 圆弧
- ceph故障:too many PGs per OSD
热门文章
- mcast_join函数
- [运维] 如何访问虚拟机上的 Tomcat ?
- redis几种数据导出导入方式
- mysql查询最大值,最小值,平均值,总和
- Django继承drf的user模型的demo
- word2vec词向量处理英文语料
- extractvalue报错注入
- Caffe2 用户手册概览(Caffe2 Tutorials Overview)[1]
- 自定义更改 Xcode 新建 .h/.m 文件头部注释说明(文件名、工程名、作者、公司、版权等)信息
- Android开发_*.R文件无法自动生成