PE文件详解(三)

本文转自小甲鱼的PE文件详解系列传送门

PE文件到内存的映射

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

但是要注意的是,系统装载可执行文件的方法又不完全等同于内存映射文件。 当使用内存映射文件的时候,系统对“原著”相当忠实,如果将磁盘文件和内存映像比较的话,可以发现不管是数据本身还是数据之间的相对位置它丫丫的都是完全相同的。

而我们知道,在装载可执行文件的时候,有些数据在装入前会被预处理,如重定位等,正因此,装入以后,数据之间的相对位置可能发生微妙的变化。 Windows 装载器在装载DOS部分、PE文件头部分和节表(区块表)部分是不进行任何特殊处理的,而在装载节(区块)的时候则会自动按节(区块)的属性做不同的处理。

一般情况下,它会处理以下几个方面的内容: 内存页的属性; 节的偏移地址; 节的尺寸; 不进行映射的节。

内存页的属性:

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

节的偏移地址:

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

注意,节事实上就是相同属性数据的组合!当节被装入到内存中的时候,相同一个节所对应的内存页都将被赋予相同的页属性。 事实上,Windows 系统对内存属性的设置是以页为单位进行的,所以节在内存中的对齐单位必须至少是一个页的大小。 (小甲鱼温馨提示:对于32位操作系统来说,这个值一般是4KB==1000H; 对于64位操作系统这个值一般是8KB==2000H) 在磁盘中就没有这个限制,因为在磁盘中排放是以什么为主?肯定是以空间为主导,在磁盘只是存放,不是使用,所以不用设置那么详细的属性。 试想想看,如果在磁盘中都是以4KB为大小对齐的话,不够就用0来填充,那么一个只占20字节的数据就要消耗4KB的空间来存放,是不是浪费? 有木有??

节的尺寸:

对节的尺寸的处理主要分为两个方面: 第一个方面,正如刚刚我们所讲的,由于磁盘映像和内存映像中节对齐存储单位的不同而导致了长度扩展不同(填充的0数量不同嘛~); 第二个方面,是对于包含未初始化数据的节的处理问题。既然是未初始化,那么没有必要为其在磁盘中浪费空间资源,但在内存中不同,因为程 序一运行,之前未初始化的数据便有可能要被赋值初始化,那么就必须为他们留下空间。

不进行映射的节:

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • PE文件简介

    PE文件的全称是Portable Executable,意为可移植的可执行的文件,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Win...

    Masimaro
  • Windows内核中的内存管理

    其中PAGED_CODE是一个WDK中提供的一个宏,只在debug版本中生效,用于判断当前的中断请求级别,当级别高于DISPATCH_LEVEL(包含这个级别)...

    Masimaro
  • Windows程序设计学习笔记(一)Windows内存管理初步

    学习Windows程序设计也有一些时间了,为了记录自己的学习成果,以便以后查看,我希望自己能够坚持写下一系列的学习心得,对自己学习的内容进行总结,同时与大家交流...

    Masimaro
  • Java网络编程与NIO详解8:浅析mmap和Direct Buffer

    本文转自:https://www.cnblogs.com/huxiao-tee/p/4660352.html

    Java技术江湖
  • centos释放无用内存

    centos中发现自己的进程消耗内存极少,但是系统的空闲内存确实没了,其实是CentOS为了提高效率,把部分使用过的文件缓存到了内存里。这样的话如果不需要这样的...

    似水的流年
  • Android性能优化(四)之内存优化实战

    在上一篇《Android性能优化(三)之内存管理》中我们对Android的内存管理有了一定的认识,本篇文章从实际出发对内存进行优化,主要包含以下部分:

    用户2898788
  • 疑案追踪:Spring Boot内存泄露排查记

    在项目迁移到Spring Boot之后,发生内存使用量过高的问题。本文介绍了整个排查过程以及使用到的工具,也非常适用于其他堆外内存排查。

    美团技术团队
  • liteos内存(三)

    内存管理模块管理系统的内存资源,它是操作系统的核心模块之一。主要包括内存的初始化、分配以及释放。

    233333
  • 笔记66 | eclipse/android studio/ADB查看Android应用内存使用情况

    项勇
  • 今咱们来聊聊JVM 堆外内存泄露的BUG是如何查找的前言内存泄露Bug现场查找线索总结

    美的让人心动

扫码关注云+社区

领取腾讯云代金券