zoukankan      html  css  js  c++  java
  • PE结构学习笔记(三)

    Chinese:

    1、在执行一个PE文件的时候,windows并不是一开始就将整个文件读入内存的,而是采用与内存映射文件类似的机制。windows装载器在装载的时候仅仅建立好虚拟地址和PE文件之间的映射关系。当且仅当真正执行到某个内存页中的指令或者访问某一页中的数据时,这个页面才会从磁盘提交到物理内存,这种机制使文件装入的速度和文件大小没有太大的关系。

    2、系统装载可执行文件的方法不完全等同于内存映射文件,当使用内存映射文件的时候,系统对"原著"相当忠实,如果将磁盘文件和内存映像比较的话,可以发现不论是数据本身还是数据之间的相对位置,它们是完全相同的。而在装载可执行文件的时候,有些数据在装入前会被预处理,如重定位等,正因此,装入以后,数据之间的相对位置可能发生变化。

    3、Windows装载器在装载DOS部分、PE文件头部分和节表(区块表)部分是不进行任何特殊处理的,而在装载节(区块)的时候则会自动按节(区块)的属性做不同的处理。一般情况下,它会处理以下几个方面的内容:

    内存页的属性;节的偏移地址;节的尺寸;不进行映射的节。

    (1)内存页的属性:

    对于磁盘映射文件来说,所有的页都是按照磁盘映射文件函数指定的属性设置的。但是在装载可执行文件时,与节对应的内存页属性要按照节的属性来设置。所以,在同属于一个模块的内存页中,从不同节映射过来的内存页的属性是不同的。

    (2)节的偏移地址:

    节的起始地址在磁盘文件中是按照IMAGE_OPTIONAL_HEADER32结构的FileAlignment字段的值进行对齐的,而当被加载到内存中时是按照同一结构中的SectionAlignment字段的值对齐的,两者的值可能不同,所以一个节被装入内存后相对于文件头的偏移和在磁盘文件中的偏移可能是不同的。

    节事实上就是相同属性数据的组合,当节被装入到内存中的时候,相同一个节所对应的内存页都将被赋予相同的页属性,事实上,Windows系统对内存属性的设置是以页为单位进行的,所以节在内存中的对齐单位必须至少是一个页的大小。(对于32位系统来说,这个值一般是4KB==1000h; 对于64位系统这个值一般是8KB==2000h)

    在磁盘中就没有这个限制,磁盘只是起到了存放的作用,所以不用设置那么详细的属性。

    (3)节的尺寸:

    对节的尺寸的处理主要分为两个方面:

    第一,正如刚刚我们所讲的,由于磁盘映像和内存映像中节对齐存储单位的不同而导致了长度扩展不同(填充的0数量不同)

    第二,对于包含未初始化数据的节的处理问题。既然是未初始化,那么没有必要为其在磁盘中浪费空间资源,但在内存中不同,因为程序一运行,之前未初始化的数据便有可能要被赋值初始化,那么就必须要为他们留下空间。

    (4)不进行映射的节:

    有些节并不需要被映射到内存中,例如.reloc节,重定位数据对于文件的执行代码来说是透明的,无作用的,它只是提供Windows装载器使用,执行代码根本不会去访问到它们,所以没有必要将它们映射到物理内存中。

    4、节表(区块表)

    PE文件中所有节的属性都被定义在节表中,节表由一系列的IMAGE_SECTION_HEADER结构排列而成,每个结构用来描述一个节,结构的排列顺序和它们描述的节在文件中的排列顺序是一致的。全部有效结构的最后以一个空的IMAGE_SECTION_HEADER结构作为结束,所以节表中总的IMAGE_SECTION_HEADER结构数量等于节的数量加一。节表总是被存放在紧接在PE文件头的地方。

    另外,节表中IMAGE_SECTION_HEADER结构的总数总是由PE文件头IMAGE_NT_HEADERS结构中的FileHeader.NumberOfSections字段来指定的。

  • 相关阅读:
    Linux守护进程
    sequel pro无法连接mysql服务器
    socket编程之并发回射服务器2
    Unix的I/O模型
    nginx.conf laravel 配置
    phpstudy使用PHP+nginx配置Laravel
    nginx配置文件分开配置
    centos安装composer
    linux下 设置php的环境变量 php: command not found
    laravel 安装
  • 原文地址:https://www.cnblogs.com/maplewan/p/3231223.html
Copyright © 2011-2022 走看看