在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

PE文件结构体-IMAGE_SECTION_HEADER的更多相关文章

  1. PE文件结构体-IMAGE_OPTIONAL_HEADER

    typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // WORD Magic; // 标志字, ROM 映像(0107h), ...

  2. PE文件结构体-IMAGE_DATA_DIRECTORY

    IMAGE_OPTIONAL_HEADER结构体最后一个成员是数组结构,大小为16,每个元素都是一个IMAGE_DATA_DIRECTORY结构体 typedef struct _IMAGE_DATA ...

  3. PE文件结构体-IMAGE_FILE_HEADER

    struct _IMAGE_FILE_HEADER { WORD Machine; //运行平台 WORD NumberOfSections; //文件的区块数目 DWORD TimeDateStam ...

  4. COFF/PE文件结构

    COFF/PE文件结构 原创 C++应用程序在Windows下的编译.链接(二)COFF/PE文件结构 2.1概述 在windows操作系统下,可执行文件的存储格式是PE格式:在Linux操作系统下, ...

  5. PE文件结构及其加载机制

    一.PE文件结构 PE即Portable Executable,是win32环境自身所带的执行体文件格式,其部分特性继承自Unix的COFF(Common Object File Format)文件格 ...

  6. PE文件结构详解(五)延迟导入表

    PE文件结构详解(四)PE导入表讲 了一般的PE导入表,这次我们来看一下另外一种导入表:延迟导入(Delay Import).看名字就知道,这种导入机制导入其他DLL的时机比较“迟”,为什么要迟呢?因 ...

  7. PE文件结构详解(四)PE导入表

    PE文件结构详解(二)可执行文件头的最后展示了一个数组,PE文件结构详解(三)PE导出表中解释了其中第一项的格式,本篇文章来揭示这个数组中的第二项:IMAGE_DIRECTORY_ENTRY_IMPO ...

  8. 初识PE文件结构

    前言 目前网络上有关PE文件结构说明的文章太多了,自己的这篇文章只是单纯的记录自己对PE文件结构的学习.理解和总结. 基础概念 PE(Portable Executable:可移植的执行体)是Win3 ...

  9. 再探.NET的PE文件结构(安全篇)

    一.开篇 首先写在前面,这篇文章源于个人的研究和探索,由于.NET有自己的反射机制,可以清楚的将源码反射出来,这样你的软件就很容易被破解,当然这篇文章不会说怎么样保护你的软件不被破解,相反是借用一个软 ...

随机推荐

  1. Python安装numpy,pandas慢,超时报错,下载不了的解决方法

    由于python的默认源是国外的,所以下载的时候会很慢,甚至会出现超时下载失败,提供两个解决方法 1.设置pip的超时限制 打开cmd 输入pip --default-timeout=100 inst ...

  2. windows与linux的文件路径

    在windows操作系统中,文件路径的分隔符是反斜杠(“\\”),例如: E:\\hsta\\pdf(这里为防止转义,所以要写成两个反斜杠) 但是在linux操作系统中,文件的分隔符是斜杠(“/”), ...

  3. conda常用命令(待续)

    1.常用命名 # 查看虚拟环境列表 conda env list # 创建虚拟环境 conda create -n python36 python=3.6.2 # 切换环境 activate pyth ...

  4. RestTemplate post请求使用map传参 Controller 接收不到值的解决方案 postForObject方法源码解析.md

    结论 post方法中如果使用map传参,需要使用MultiValueMap来传递 RestTemplate 的 postForObject 方法有四个参数 String url => 顾名思义 ...

  5. C/C++网络编程9——多进程服务器端实现

    #include <iostream> #include <unistd.h> #include <cstdlib> #include <arpa/inet. ...

  6. UIScrollView学习指南

    --前言 笔者结合自己的工作经验,梳理关于UIScrollView究竟需要掌握哪些知识才算是一个好手.至于具体的实施方案,网上资源很多,自行了解吧. --正文 1.涉及到滚动和放大的功能,优先考虑使用 ...

  7. ES的基本概念

    elasticsearch 的索引与文档是开发关注的视角:节点.集群.分片是运维关注的视角 elasticearch 文档的介绍 - elasticearch 是面向文档的,文档是所有可搜索数据的最小 ...

  8. C++ 判断是文件还是文件夹

    转载:https://www.csdn.net/gather_23/NtDaIg1sMDYtYmxvZwO0O0OO0O0O.html Windows平台代码如下: #include <wind ...

  9. ToString 奇淫技巧

    int和float同样结果 decimal decTemp = 2.1m; Console.WriteLine(decTemp.ToString("#0.00")); //输出2. ...

  10. STM32单片机的软件重启和远程重启

    STM32单片机可以通过以下代码实现重启(core_cm3.h).同时如果利用AT命令进行无线通讯,服务器后台和客户端之间用MODBUS通讯即4G+MODBUS RTU,可以利用F05写单个线圈的方法 ...