Windows PE文件格式

在PE文件头以前

理论

Windows的PE(Portable Executable)文件有两个头,一个是是Windows头,一个是DOS头。在文件的最开始会有一段DOS的EXE文件头,来讲明这个程序不能够在DOS环境下运行。咱们须要在DOS头+3Ch处,会有一个4字节的指针指向windows头。html

根据+3Ch处的值,定位到Windows文件头能够看到"PE"两个字节,Windows头就今后处开始。这也就是Windows EXE文件常常被称为PE文件的缘由。windows

实践

  1. 在xp环境下,用QuickView打开一个EXE文件,观察其头部。
    • 在00h处有两个字节4D 5A表示这是一个DOS头。
    • 在4Eh处,有一个字符串This program cannot be run in DOS mode. 代表这不是一个DOS文件
    • 在3C处,有一个四字节指针,其值为000000D0h,颜色标黄,指向windows头

  1. 查看文件地址D0处的值学习

    能够看到此处的两个字节为50 45即“PE”,表示这个EXE文件是一个PE文件,从这两个字节开始才是PE的文件头。ui

PE文件头

背景知识

要了解PE文件头的具体内容,咱们须要对Windows的内存管理,文件存储有必定的了解。接下来作简要的说明,想要了解更详细的内容能够去学习操做系统的相关知识。操作系统

Windows经过分段以及分页两种机制管理内存和实现进程的隔离及保护。如下说明会涉及到一些寄存器和比较抽象的概念,不懂也没有关系。只须要知道结论,*一个进程的虚拟地址会通过一些转换成为真正的物理地址. *进程之间的虚拟地址能够相同,但相同的虚拟地址会转化成不一样的物理地址。指针

  • 在Windows系统中,为了向下兼容,保留了分段(section)的的机制,可是CS,DS,SS这些段地址在GDT表中的值所有为0,因此通过分段后的逻辑地址(logical address)与线性地址(linear address)是彻底一致的,在此处不用过多理会。
  • 对于分页(paging)机制,每个进程都有一个属于他们本身的页目录表,每个页目录表是不同的,线性地址须要通过页表项的查询,转换成的真正的物理地址。因此对于不一样进程而言,相同的线性地址会转化成为不一样的物理地址。

有了分页的机制后,windows的exe在运行时统一被载入内存的基地址=400000hcode

在PE文件头中出现的内存地址都是以RVA(relative virtual address)相对虚拟地址的形式表示的,即htm

程序真正的虚拟地址 = 相对虚拟地址+载入内存的基地址=RVA+400000hblog

PE文件头的具体内容

有了上述的了解后,接下来咱们来看PE文件头的具体内容。如下的描述涉及到的偏移地址均为16进制,且均相对于PE文件头。进程

以一个EXE文件的PE头为例,咱们来讲明,PE文件头一些重要的项的具体含义。

000000d0: 5045 0000 4c01 0300 2fe6 a25d 0000 0000  PE..L.../..]....
			  |
		          +------------------------------- +06 用两个字节来保存段的数量,此时为0003个段
000000e0: 0000 0000 e000 0f01 0b01 0600 0050 0000  .............P..
000000f0: 0050 0000 0000 0000 4510 0000 0010 0000  .P......E.......
				|
				+------------------------- +28 程序的32位入口地址,即当前EXE在运行时,																													第一条指令执行的相对虚拟地址
00000100: 0060 0000 0000 4000 0010 0000 0010 0000  .`....@.........
		      |		|	    |
		      |		|	    +------------- +3C 文件对齐,两个字节,此处为1000h
		      |		+------------------------- +38 内存对齐,两个字节,此处为1000h
		      |				
		      +----------------------------------- +34 程序载入内存的基地址,4个字节EXE通常上都为400000h																												
00000110: 0400 0000 0000 0000 0400 0000 0000 0000  ................
00000120: 00b0 0000 0010 0000 0000 0000 0300 0000  ................
	    |	      |
            |	      |
            |	      +---------------------------------- +54 EXE文件头的文件长度(通过文件对齐以后),载入内存后会进行内存对齐(包括DOS头和Windows头)
            |                                                                                          																				 					
            +-------------------------------------------- +50 EXE文件载入内存后的总长度=文件头+各个section载入内存后的总长度(通过内存对齐后)
  • 在PE+F8处定义了各个section的描述,每个节的描述的大小为28h字节,在QV中查看具体的值以下:

  • PE+F8+0: 节名,8字节,以00做为结束标记
  • PE+F8+8:节的内存长度 4980h
  • PE+F8+C:节的内存偏移 1000h
  • PE+F8+10: 节的文件长度 5000h
  • PE+F8+14: 节的文件偏移 1000h
  • PE+F8+24: 节的属性,read,write,execute

关于PE文件头中的输出表、输入表、资源表、重定位表的描述比较复杂,会另写文档讲述。

输出表:To do...

输入表:Windows PE文件的输入表

重定位表:To do...

随笔是我的学习的总结,若有错误欢迎指出!

相关文章
相关标签/搜索