在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

最新文章

  1. sublime常用快捷键
  2. angular懒加载机制 刷新后无法回退解决方案
  3. 页面设计--CheckBoxList
  4. check_area
  5. 怎样用sourceTree将自己本地的项目上传到github网站上
  6. [工作问题总结]MyEclipse 打开项目
  7. Cloudera Manager、CDH零基础入门、线路指导 http://www.aboutyun.com/thread-9219-1-1.html (出处: about云开发)
  8. django User model
  9. 火狐浏览器下使用jquery修改img的src
  10. shell是什么,各种shell的初步认识,适用于初学者
  11. [Python]程序性能分析
  12. 120. 单词接龙 (BFS)
  13. Python sqlalchemy orm 常用操作
  14. winform创建快捷方式
  15. MyBatis实战之配置
  16. Odoo进销存(采购、销售、仓库)入门教程 - 下
  17. android中使用WebView请求网页
  18. XMOJ 1133: 膜拜大牛 计算几何/两圆相交
  19. html canvas 圆弧
  20. ceph故障:too many PGs per OSD

热门文章

  1. mcast_join函数
  2. [运维] 如何访问虚拟机上的 Tomcat ?
  3. redis几种数据导出导入方式
  4. mysql查询最大值,最小值,平均值,总和
  5. Django继承drf的user模型的demo
  6. word2vec词向量处理英文语料
  7. extractvalue报错注入
  8. Caffe2 用户手册概览(Caffe2 Tutorials Overview)[1]
  9. 自定义更改 Xcode 新建 .h/.m 文件头部注释说明(文件名、工程名、作者、公司、版权等)信息
  10. Android开发_*.R文件无法自动生成