Windows PE结构 之 开篇下

0x0 PE文件总体结构

  • PE (Portable Execute) 文件是Windows下可执行文件的总称,常见的有 DLL,EXE,OCX,SYS,COM 等。它是微软在 UNIX 平台的 COFF(通用对象文件格式)基础上制作而成。最初设计用来提高程序在不同操作系统上的移植性,但实际上这种文件格式仅用在 Windows 系列操作系统下。
  • PE文件是指 32 位可执行文件,也称为PE32。64位的可执行文件称为 PE+ 或 PE32+,是PE(PE32)的一种扩展形式(请注意不是PE64)。
  • 事实上,一个文件是否是 PE 文件与其扩展名无关,PE文件可以是任何扩展名。那 Windows 是怎么区分可执行文件和非可执行文件的呢?我们调用 LoadLibrary 传递了一个文件名,系统是如何判断这个文件是一个合法的动态库呢?这就涉及到PE文件结构了。
  • PE文件的结构一般来说如下图所示:从起始位置开始依次是 DOS头NT头节表 以及 具体的节
  • 可以看到先前判断PE文件特征里的头两个字节对应这里的文件头:DOS “MZ” HEADER,后面根据3Ch得到的50 45(对应ACSII码为PE)对应这里的PE文件头中的”PE
  • 可以通过用HEX编辑器打开可执行文件,通过找”PE”的标识,来判断是否是PE文件
Windows PE结构 之 开篇下-侠者安全社区
Windows PE结构 之 开篇下-侠者安全社区
Windows PE结构 之 开篇下-侠者安全社区
  • DOS头 是用来兼容 MS-DOS 操作系统的,目的是当这个文件在 MS-DOS 上运行时提示一段文字,大部分情况下是:This program cannot be run in DOS mode. 还有一个目的,就是指明 NT 头在文件中的位置。
  • NT头 包含 windows PE 文件的主要信息,其中包括一个 ‘PE’ 字样的签名,PE文件头(IMAGE_FILE_HEADER)和 PE可选头(IMAGE_OPTIONAL_HEADER32)。
  • 节表:是 PE 文件后续节的描述,windows 根据节表的描述加载每个节。
  • 节:每个节实际上是一个容器,可以包含 代码、数据 等等,每个节可以有独立的内存权限,比如代码节默认有读/执行权限,节的名字和数量可以自己定义,未必是上图中的三个。
Windows PE结构 之 开篇下-侠者安全社区

0x2 PE文件执行顺序

  1. 当一个 PE 文件被执行时,PE 装载器 首先检查 DOS header 里的 PE header 的偏移量。如果找到,则直接跳转到 PE header 的位置。
  2. 当 PE装载器 跳转到 PE header 后,第二步要做的就是检查 PE header 是否有效。如果该 PE header 有效,就跳转到 PE header 的尾部。
  3. 紧跟 PE header 尾部的是节表。PE装载器执行完第二步后开始读取节表中的节段信息,并采用文件映射( 在执行一个PE文件的时候,Windows并不在一开始就将整个文件读入内存,而是采用与内存映射的机制,也就是说,Windows装载器在装载的时候仅仅建立好虚拟地址和PE文件之间的映射关系,只有真正执行到某个内存页中的指令或者访问某一页中的数据时,这个页面才会被从磁盘提交到物理内存,这种机制使文件装入的速度和文件大小没有太大的关系 )的方法将这些节段映射到内存,同时附上节表里指定节段的读写属性。
  4. PE文件映射入内存后,PE装载器将继续处理PE文件中类似 import table (输入表)的逻辑部分。

0x3 PE文件两种状态

00 运行态非运行态

  • 一个PE文件可以分为两种状态:运行态非运行态
    • 非运行态 (硬盘状态):当一个PE文件尚未被运行时,其数据存储在磁盘中,也就是正常文件状态即非运行态
    • 运行态 (文件状态):当一个PE文件被打开后,PE文件的相关数据将被装载到内存中,此时为运行态
  • 在非运行态下:
    • DOS部首和PE文件头及块表连续存储,中间没有空隙
    • 而块表和块之间由于文件对齐可能会存在空隙
    • 块和块之间也由于文件对齐可能会存在空隙
  • 在运行态下:
    • DOS部首和PE文件头及块表连续存储,中间没有空隙
    • 而块表和块之间由于内存对齐可能会存在空隙
    • 块和块之间也由于内存对齐可能会存在空隙
Windows PE结构 之 开篇下-侠者安全社区
Windows PE结构 之 开篇下-侠者安全社区
Windows PE结构 之 开篇下-侠者安全社区
Windows PE结构 之 开篇下-侠者安全社区

01 对比PE两种状态

  • 相同点
    • 无论是在运行态还是在非运行态,DOS部首、PE文件头、块表块表均为连续存储,中间没有空隙
    • 第一个块表的首地址都受DOS部首大小+PE文件头大小+块表大小影响,都需要对齐,块和块之间也都需要对齐
  • 不同点
    • 运行态和非运行态的起始地址不同
    • 在非运行态中,块表和块之间的空隙由 文件对齐 产生,块和块之间的空隙由 文件对齐 产生
    • 在运行态中,块表和块之间的空隙由 内存对齐 产生,块和块之间的空隙由 内存对齐 产生

0x4 虚拟地址空间

  • 虚拟内存:Windows下的虚拟内存指的是在硬盘上建一个文件,用来放置系统非活跃性内存数据或交换数据 ( 怎么放,放多少由操作系统决定)。虚拟内存通常只在系统物理内存用完时,才会使用到,但这个时候系统已经非常卡了。但也不是一点用处没有,非活跃性进程的部分数据,系统是完全可以放在虚拟内存中的。
  • 虚拟地址空间:指 Windows下 每个进程的私有内存空间,大小是4G,能访问的是不到2G的空间,其余是系统保留的。这2G是能访问的,但并不是立即分配的,当进程使用多少时,才从物理内存中划分给它多少,划分的的方式是 “映射”,操作系统将虚拟内存的起始地址做个标记,标记成对应的物理内存的某个地址上。在这里,只有操作系统知道,进程是没有任何办法知道的,这是 WINDOWS 的高级内存管理机制决定的。物理内存的地址空间,只有操作系统才能访问(硬件驱动也可以,但已经属于系统低层了,进程是属于用户层 ) 。进程 虚拟内存空间 和 物理内存空间 的关系仅仅是看不见的映射关系。( 虚拟地址空间:在多任务操作系统中,每个进程都运行在属于自己的内存沙盘中,这个沙盘就是 虚拟地址空间(virtual address space)。虚拟地址空间由内核空间(kernel space)和用户模式空间(user mode space)两部分组成。虚拟地址会通过页表(page table)映射到物理内存,页表由操作系统维护并被处理器引用,每个进程都有自己的页表。内核空间在页表中拥有较高特权级,因此用户态程序试图访问这些页是会导致一个页错误(page fault)。其中内核空间是持续存在的,并且在所有进程中都映射到同样的物理内存。与此相反,用户模式空间的映射随进程切换的发生而不断变化。)

0x5 PE文件结构超详细图

Windows PE结构 之 开篇下-侠者安全社区
Windows PE结构 之 开篇下-侠者安全社区
© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容