1、虚拟地址VA:PE对应的进程支配了自己独立的4GB虚拟空间,在这个空间定位的地址称为虚拟地址VA。在PE中进程本身的VA被解释为:进程的基地址+相对虚拟内存地址。
2、相对虚拟内存地址:一个进程被加载内存空间后,其相关的动态库也会被加载。这些同时加载到进程虚拟地址空间的文件称为模块。每一个模块在加载时都会有一个基地址、不同模块的基地址一般是不同的。但如果两个模块的基地址相同,就有操作系统来决定这两个模块在虚拟空间中的具体位置。
相对虚拟内存地址RVA是相对于基地址的偏移,几RVA是虚拟内存中用来定位某个特定未知的,该地址的值是这个特定位置距离某个模块基地址的偏移量。所以RVA是针对某个模块而存在的。RVA和VA的概念可如下图表示:
RVA是相对于模块而言的,VA是相对于进程而言的。
3、文件偏移地址FOA:和内存无关,它是指某个位置距离文件头的偏移。
4、数据目录:Windows下的可执行文件是PE中的一种,这种文件除了包含代码及数据段的相关数据以外还包含了许多与文件执行有关的其他数据。PE中有一个数据结构称为数据目录表,其中记录了所有可能的数据类型,包括导出表、导入表、资源表等。
5、节:无论是结构化程序设计还是面向对象程序设计,都提倡程序与数据的独立性。因此程序中的代码和数据是分开存放的。为了保证程序执行的安全,保证内核的稳定,Windows操作系统通常对不同用途的数据设置不同的访问权限。如代码段中的字节码在程序运行的时候,一般不允许用户进行修改,数据段则允许在程序运行的过程中读和写,常量只能读等。Windows操作系统在加载可执行文件时,会为这些具有不同属性怼的数据分别分配标记有不同属性的页面(当然,相同属性的数据可能会被放到同一个页面中),以确保程序运行时的安全。基于这个原因,PE中出现了节的概念。节就是存放不同类型数据(如代码、数据、常量、资源等)多大的地方。不同的节具有不同的访问权限。节是PE文件中存放代码或者数据的基本单元。一个目标文件中的所有代码可以组合成单个节,或者每个每个函数独占一个节。一个节中的所有原始数据必须被加载到连续的内存空间中。从操作系统的角度来看,节是相同属性数据的集合。与数据目录不同的是,尽管有些数据类不同,分别属于不同的数据目录,但由于其访问属性相同,便被归类到同一个节中。这些节最终可能会占用一个或者多个页面,但无论页面数量有多少,所有页面均会被赋予相同的页属性。
6、PE文件划分如下图:
一个标准的PE文件一般由四大部分组成:DOS头、PE头(IMAGE_NT_HAEADERS)、节表(多个IMAGE_SECTION_HEADER结构)、节内容。
PE头又叫NT头,包含三个部分:4字节的标识符号(Signature)、20个字节的标准PE头(IMAGE_FILEHEADER,基本头信息)和216个字节的扩展PE头(又叫可选PE头,IMAGE_OPTIONAL_HEADER32)。
7、数据目录项IMAGE_DATA_DIRECTORY:IAMGE_OPTIONAL_HEADER_32(扩展PE头)结构的最后一个字段为DataDirectory。该字段定义了PE文件中出现的所有不同类型的数据的目录信息,如导入表、导出表、资源、重定位表等。在内存中这些数据被操作系统义页为单位组织起来并赋予不同的访问属性,在文件中这些数据也同样被组织起来,按照不同类别分别存放在文件的指定位置。该结构就是用来描述这些不同类别的数据在文件(和内存)中的位置和大小的。
参考链接:《Windows PE权威指南》 戚利