PE文件格式(内容详细)
- 格式:ppt
- 大小:519.50 KB
- 文档页数:49
PE文件格式详解(一)基础知识什么是PE文件格式:我们知道所有文件都是一些连续(当然实际存储在磁盘上的时候不一定是连续的)的数据组织起来的,不同类型的文件肯定组织形式也各不相同;PE文件格式便是一种文件组织形式,它是32位Window系统中的可执行文件EXE以及动态连接库文件DLL的组织形式。
为什么我们双击一个EXE文件之后它就会被Window运行,而我们双击一个DOC文件就会被Word打开并显示其中的内容;这说明文件中肯定除了存在那些文件的主体内容(比如EXE文件中的代码,数据等,DOC 文件中的文件内容等)之外还存在其他一些重要的信息。
这些信息是给文件的使用者看的,比如说EXE文件的使用者就是Window,而DOC文件的使用者就是Word。
Window可以根据这些信息知道把文件加载到地址空间的那个位置,知道从哪个地址开始执行;加载到内存后如何修正一些指令中的地址等等。
那么PE文件中的这些重要信息都是由谁加入的呢?是由编译器和连接器完成的,针对不同的编译器和连接器通常会提供不同的选项让我们在编译和联结生成PE文件的时候对其中的那些Window需要的信息进行设定;当然也可以按照默认的方式编译连接生成Window中默认的信息。
例如:WindowNT默认的程序加载基址是0x40000;你可以在用VC连接生成EXE文件的时候使用选项更改这个地址值。
在不同的操作系统中可执行文件的格式是不同的,比如在Linux上就有一种流行的ELF格式;当然它是由在Linux上的编译器和连接器生成的,所以编译器、连接器是针对不同的CPU架构和不同的操作系统而涉及出来的。
在嵌入式领域中我们经常提到交叉编译器一词,它的作用就是在一种平台下编译出能在另一个平台下运行的程序;例如,我们可以使用交叉编译器在跑Linux的X86机器上编译出能在Arm上运行的程序。
程序是如何运行起来的:一个程序从编写出来到运行一共需要那些工具,他们都对程序作了些什么呢?里面都涉及哪些知识需要学习呢?先说工具:编辑器-》编译器-》连接器-》加载器;首先我们使用编辑器编辑源文件;然后使用编译器编译程目标文件OBJ,这里面涉及到编译原理的知识;连接器把OBJ文件和其他一些库文件和资源文件连接起来生成EXE文件,这里面涉及到不同的连接器的知识,连接器根据OS的需要生成EXE文件保存着磁盘上;当我们运行EXE文件的时候有Window的加载器负责把EXE文件加载到线性地址空间,加载的时候便是根据上一节中说到的PE文件格式中的哪些重要信息。
PE文件格式”完整译文(附注释)一、前言(Preface)PE(“portable executable”,可移植的可执行文件)文件格式,是微软WindwosNT,Windows95和Win32子集①中的可执行的二进制文件的格式;在WindowsNT中,驱动程序也是这种格式。
它还能被应用于各种目标文件②和库文件中。
这种文件格式是由微软设计的,并于1993年被TIS(tool interface standard,工具接口标准)委员会(由Microsoft,Intel,Borland,Watcom,IBM,等等组成)所批准,它明显的基于COFF文件格式的许多知识。
COFF(“common object file fromat”,通用目标文件格式)是应用于好几种UNIX系统③和VMS④系统中的目标文件和可执行文件的格式。
Win32 SDK⑤中包含一个名叫<winnt.h>的头文件,其中含有很多用于PE格式的#define和typedef定义。
我将逐步地提到其中的很多结构成员名字和#define定义。
你也可能发现DLL文件“imagehelp.dll”很有用途,它是WindowNT的一部分,但其书面文件却很缺乏。
它的一些功用在“Developer Network”(开发者网络)中有所描述。
二、总览(General Layout)在一个PE文件的开始处,我们会看到一个MS-DOS可执行体(英语叫“stub”,意为“根,存根”);它使任何PE文件都是一个有效的MS-DOS 可执行文件。
在DOS-根之后是一个32位的签名以及魔数0x00004550 (IMAGE_NT_SIGNATURE)(意为“NT签名”,也就是PE签名;十六进制数45和50分别代表ASCII码字母E和P----译者注)。
之后是文件头(按COFF格式),用来说明该二进制文件将运行在何种机器之上、分几个区段、链接的时间、是可执行文件还是DLL、等等。
WindowsPE⽂件格式在PE⽂件头之前理论Windows的PE(Portable Executable)⽂件有两个头,⼀个是是Windows头,⼀个是DOS头。
在⽂件的最开始会有⼀段DOS的EXE⽂件头,来说明这个程序不可以在DOS环境下运⾏。
我们需要在DOS头+3Ch处,会有⼀个4字节的指针指向windows头。
根据+3Ch处的值,定位到Windows⽂件头可以看到"PE"两个字节,Windows头就从此处开始。
这也就是Windows EXE⽂件经常被称为PE⽂件的原因。
实践1. 在xp环境下,⽤QuickView打开⼀个EXE⽂件,观察其头部。
在00h处有两个字节4D 5A表⽰这是⼀个DOS头。
在4Eh处,有⼀个字符串This program cannot be run in DOS mode. 表明这不是⼀个DOS⽂件在3C处,有⼀个四字节指针,其值为000000D0h,颜⾊标黄,指向windows头2. 查看⽂件地址D0处的值可以看到此处的两个字节为50 45即“PE”,表⽰这个EXE⽂件是⼀个PE⽂件,从这两个字节开始才是PE的⽂件头。
PE⽂件头背景知识要了解PE⽂件头的具体内容,我们需要对Windows的内存管理,⽂件存储有⼀定的了解。
接下来做简要的说明,想要了解更详细的内容可以去学习操作系统的相关知识。
Windows通过分段以及分页两种机制管理内存和实现进程的隔离及保护。
以下说明会涉及到⼀些寄存器和⽐较抽象的概念,不懂也没有关系。
只需要知道结论,*⼀个进程的虚拟地址会经过⼀些转换成为真正的物理地址. *进程之间的虚拟地址可以相同,但相同的虚拟地址会转化成不同的物理地址。
在Windows系统中,为了向下兼容,保留了分段(section)的的机制,但是CS,DS,SS这些段地址在GDT表中的值全部为0,所以经过分段后的逻辑地址(logical address)与线性地址(linear address)是完全⼀致的,在此处不⽤过多理会。
pe格式化方法PE格式(Portable Executable format)是Windows操作系统下的一种可执行文件的格式标准,它定义了可执行文件、动态链接库(DLL)和驱动程序等二进制文件的结构和标识方法。
本文将介绍PE格式化的基本原理和方法,并举例说明。
一、PE格式基本原理1. PE格式定义:PE格式是一种COFF(Common Object File Format)文件格式的变体,用于描述32位和64位Windows可执行文件的结构和组织。
2. 文件头部分:PE格式文件的开头是一个固定大小的文件头(File Header),用于描述整个PE文件的组织结构和属性信息,如文件类型、目标体系结构、节表位置等。
3. 节部分:紧随文件头部分的是节(Section)部分,它描述了PE格式文件中各个段或区块的属性和内容,如代码段、数据段、资源段等。
4. 数据目录:PE格式文件中包含了多个数据目录(Data Directory),每个数据目录描述了PE文件中某个特定功能的位置和大小信息,如导入表、导出表、资源表等。
1. 创建空白PE文件:使用合适的开发工具,如Visual Studio等,新建一个空白的PE 文件。
2. 定义文件头:根据所需的文件类型和目标体系结构,填写文件头部分的属性信息。
如指定文件类型为可执行文件(Executable)、目标体系结构为32位或64位等。
3. 定义节表:根据需求,定义PE文件中的各个节的属性和内容,如代码段、数据段、资源段等。
可以使用合适的工具,如Hex编辑器等,手动修改节表。
4. 填充数据目录:根据PE格式的规定,将所需的功能的位置和大小信息填写入数据目录表中,如导入表、导出表、资源表等。
5. 填充节内容:根据需求,将代码、数据和资源等内容填写入相应的节中。
可以使用合适的工具,如文本编辑器等,手动修改和填充节内容。
6. 调整文件大小:根据实际内容大小,调整整个PE文件的大小,确保文件大小与实际内容相符。
PE文件格式分析及修改(图)PE 的意思是 Portable Executable(可移植的执行体)。
它是 Win32环境自身所带的执行文件格式。
它的一些特性继承自Unix的Coff(common object file format)文件格式。
“Portable Executable”(可移植的执行体)意味着此文件格式是跨Win32平台的;即使Windows运行在非Intel的CPU上,任何win32平台的PE装载器都能识别和使用该文件格式。
PE文件在文件系统中,与存贮在磁盘上的其它文件一样,都是二进制数据,对于操作系统来讲,可以认为是特定信息的一个载体,如果要让计算机系统执行某程序,则程序文件的载体必须符合某种特定的格式。
要分析特定信息载体的格式,要求分析人员有数据分析、编码分析的能力。
在Win32系统中,PE 文件可以认为.exe、.dll、.sys 、.scr类型的文件,这些文件在磁盘上存贮的格式都是有一定规律的。
一、PE格式基础下表列出了PE的总体结构一个完整的PE文件,前五项是必定要有的,如果缺少或者数据出错,系统会拒绝执行该文件如下图DOS MZ header部分是DOS时代遗留的产物,是PE文件的一个遗传基因,一个Win32程序如果在DOS 下也是可以执行,只是提示:“This program cannot be run in DOS mode.”然后就结束执行,提示执行者,这个程序要在Win32系统下执行。
DOS stub 部分是DOS插桩代码,是DOS下的16位程序代码,只是为了显示上面的提示数据。
这段代码是编译器在程序编译过程中自动添加的。
PE header 是真正的Win32程序的格式头部,其中包括了PE格式的各种信息,指导系统如何装载和执行此程序代码。
Section table部分是PE代码和数据的结构数据,指示装载系统代码段在哪里,数据段在哪里等。
对于不同的PE文件,设计者可能要求该文件包括不同的数据的Section。
Microsoft可移植可执行文件和通用目标文件格式文件规范修订版8.1 - 2008年2月15日摘要本规范描述了Microsoft® Windows®操作系统家族下的可执行文件(映像)和目标文件的结构。
这些文件分别被称为可移植可执行(PE)文件和通用目标文件格式(COFF)文件。
注意:提供本文档是为了辅助开发用于Microsoft Windows操作系统上的工具和应用程序,但并不保证它在各个方面都是完整的规范。
Microsoft保留更改本文档而不通知的权利。
Microsoft可移植可执行文件和通用目标文件格式文件规范的此次修订版取代了本规范的6.0修订版。
本规范中的信息适用于以下操作系统:Windows Server® 2008Windows Vista®Windows Server 2003Windows XPWindows 2000本规范最后列出了参考信息和相关资源。
本规范的最新版在万维网的以下地址被维护:/whdc/system/platform/firmware/PECOFF.mspxSmartTech译电子信箱:zhzhtst@法律声明Microsoft可移植可执行文件和通用目标文件格式文件规范Microsoft Corporation修订版 8.1注意:提供本规范是为了辅助开发某些用于Microsoft Windows操作系统平台上的开发工具。
但是Microsoft并不保证它在各个方面都是完整的规范,也无法保证这里的所有信息在发布之后一直都是准确的。
Microsoft保留更改本规范而不通知的权利。
在合理的和非歧视性条款和条件下,Microsoft将针对任何Microsoft认为仅在面向Microsoft Windows的被称为编译器、链接器以及汇编程序的软件开发工具中实现和遵守本规范中所需部分这种有限用途下所需要的Microsoft权利要求书(如果存在)授予您免版税许可。
PE文件格式详解(上)Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式。
PE文件格式的规范包含在了MSDN的CD 中(Specs and Strategy, Specifications, Windows NT File Format Specifications),但是它非常之晦涩。
然而这一的文档并未提供足够的信息,所以开发者们无法很好地弄懂PE格式。
本文旨在解决这一问题,它会对整个的PE文件格式作一个十分彻底的解释,另外,本文中还带有对所有必需结构的描述以及示范如何使用这些信息的源码示例。
为了获得PE文件中所包含的重要信息,我编写了一个名为PEFILE.DLL的动态链接库,本文中所有出现的源码示例亦均摘自于此。
这个DLL和它的源代码都作为PEFile示例程序的一部分包含在了CD中(译注:示例程序请在MSDN 中寻找,本站恕不提供),你可以在你自己的应用程序中使用这个DLL;同样,你亦可以依你所愿地使用并构建它的源码。
在本文末尾,你会找到PEFILE.DLL的函数导出列表和一个如何使用它们的说明。
我觉得你会发现这些函数会让你从容应付PE文件格式的。
介绍Windows操作系统家族最近增加的Windows NT为开发环境和应用程序本身带来了很大的改变,这之中一个最为重大的当属PE文件格式了。
新的PE文件格式主要来自于UNIX 操作系统所通用的COFF规范,同时为了保证与旧版本MS-DOS及Windows操作系统的兼容,PE文件格式也保留了MS-DOS中那熟悉的MZ头部。
在本文之中,PE文件格式是以自顶而下的顺序解释的。
在你从头开始研究文件内容的过程之中,本文会详细讨论PE文件的每一个组成部分。
许多单独的文件成分定义都来自于Microsoft Win32 SDK开发包中的WINNT.H文件,在这个文件中你会发现用来描述文件头部和数据目录等各种成分的结构类型定义。
但是,在WINNT.H中缺少对PE文件结构足够的定义,在这种情况下,我定义了自己的结构来存取文件数据。
PE文件格式详解(一)基础知识什么是PE文件格式:我们知道所有文件都是一些连续(当然实际存储在磁盘上的时候不一定是连续的)的数据组织起来的,不同类型的文件肯定组织形式也各不相同;PE文件格式便是一种文件组织形式,它是32位Window系统中的可执行文件EXE以及动态连接库文件DLL的组织形式。
为什么我们双击一个EXE文件之后它就会被Window运行,而我们双击一个DOC文件就会被Word打开并显示其中的内容;这说明文件中肯定除了存在那些文件的主体内容(比如EXE文件中的代码,数据等,DOC 文件中的文件内容等)之外还存在其他一些重要的信息。
这些信息是给文件的使用者看的,比如说EXE文件的使用者就是Window,而DOC文件的使用者就是Word。
Window可以根据这些信息知道把文件加载到地址空间的那个位置,知道从哪个地址开始执行;加载到内存后如何修正一些指令中的地址等等。
那么PE文件中的这些重要信息都是由谁加入的呢?是由编译器和连接器完成的,针对不同的编译器和连接器通常会提供不同的选项让我们在编译和联结生成PE文件的时候对其中的那些Window需要的信息进行设定;当然也可以按照默认的方式编译连接生成Window中默认的信息。
例如:WindowNT默认的程序加载基址是0x40000;你可以在用VC连接生成EXE文件的时候使用选项更改这个地址值。
在不同的操作系统中可执行文件的格式是不同的,比如在Linux上就有一种流行的ELF格式;当然它是由在Linux上的编译器和连接器生成的,所以编译器、连接器是针对不同的CPU架构和不同的操作系统而涉及出来的。
在嵌入式领域中我们经常提到交叉编译器一词,它的作用就是在一种平台下编译出能在另一个平台下运行的程序;例如,我们可以使用交叉编译器在跑Linux的X86机器上编译出能在Arm上运行的程序。
程序是如何运行起来的:一个程序从编写出来到运行一共需要那些工具,他们都对程序作了些什么呢?里面都涉及哪些知识需要学习呢?先说工具:编辑器-》编译器-》连接器-》加载器;首先我们使用编辑器编辑源文件;然后使用编译器编译程目标文件OBJ,这里面涉及到编译原理的知识;连接器把OBJ文件和其他一些库文件和资源文件连接起来生成EXE文件,这里面涉及到不同的连接器的知识,连接器根据OS的需要生成EXE文件保存着磁盘上;当我们运行EXE文件的时候有Window的加载器负责把EXE文件加载到线性地址空间,加载的时候便是根据上一节中说到的PE文件格式中的哪些重要信息。
PE文件格式详解摘要Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式。
PE文件格式的规范包含在了MSDN的CD中(Specs and Strategy, Specifications, Windows NT File Format Specifications),但是它非常之晦涩。
然而这一的文档并未提供足够的信息,所以开发者们无法很好地弄懂PE格式。
本文旨在解决这一问题,它会对整个的PE文件格式作一个十分彻底的解释,另外,本文中还带有对所有必需结构的描述以及示范如何使用这些信息的源码示例。
为了获得PE文件中所包含的重要信息,我编写了一个名为PEFILE.DLL的动态链接库,本文中所有出现的源码示例亦均摘自于此。
这个DLL和它的源代码都作为PEFile示例程序的一部分包含在了CD中(译注:示例程序请在MSDN中寻找,本站恕不提供),你可以在你自己的应用程序中使用这个DLL;同样,你亦可以依你所愿地使用并构建它的源码。
在本文末尾,你会找到PEFILE.DLL的函数导出列表和一个如何使用它们的说明。
我觉得你会发现这些函数会让你从容应付PE文件格式的。
介绍Windows操作系统家族最近增加的Windows NT为开发环境和应用程序本身带来了很大的改变,这之中一个最为重大的当属PE文件格式了。
新的PE文件格式主要来自于UNIX操作系统所通用的COFF 规范,同时为了保证与旧版本MS-DOS及Windows操作系统的兼容,PE文件格式也保留了MS-DOS中那熟悉的MZ头部。
在本文之中,PE文件格式是以自顶而下的顺序解释的。
在你从头开始研究文件内容的过程之中,本文会详细讨论PE文件的每一个组成部分。
许多单独的文件成分定义都来自于Microsoft Win32 SDK开发包中的WINNT.H文件,在这个文件中你会发现用来描述文件头部和数据目录等各种成分的结构类型定义。
但是,在WINNT.H中缺少对PE文件结构足够的定义,在这种情况下,我定义了自己的结构来存取文件数据。
pe文件格式总体结构
PE文件格式(Portable Executable)是Windows操作系统的可执行文件格式,其总体结构包括以下几个部分:
1.DOS头:PE文件的最前面是DOS头,用于兼容DOS系统。
它包
含了文件标识符、魔数(0x5A4D,即MZ)以及DOS头长度等
信息。
2.PE头:紧接着DOS头的是PE头,它包含了PE文件的元数据
信息,如文件标志、机器类型、节区数量、可选头大小等。
3.可选头:可选头包含了PE文件的属性、入口点地址、基址等
信息。
它是一个可选部分,某些PE文件可能没有这个部分。
4.节区:PE文件由多个节区组成,每个节区包含了一部分程序
代码或数据。
每个节区都有自己的头部信息,用于描述节区的属性。
以上是PE文件格式的总体结构,具体细节可能因不同的PE文件而有所差异。
PE⽂件介绍(1)
PE⽂件介绍
PE⽂件主要是windows操作系统下使⽤的可执⾏⽂件格式,PE⽂件是指32位的可执⾏⽂件也叫做PE32,64位可执⾏⽂件叫做PE+或者PE32+
PE⽂件格式
种类主扩展名
可执⾏类型EXE,SCR
驱动程序类型SYS,VXD
库系列DLL,OCX,CPL,DRV
对象⽂件系统OBJ
PE⽂件种类
严格地说OBJ(对象)⽂件之外的所有⽂件都是可执⾏的。
DLL,SYS⽂件虽然不能直接在shell中运⾏,但是可以使⽤其他⽅法(调试器,服务等)执⾏。
VA&RVA
VA 指的是进程虚拟内部的绝对地址,RVA相对虚拟地址,指从某个基准位置(ImageBase)开始的相对地址VA与RVA满⾜下⾯的换算关系。
RVA+ImageBase=VA
PE内部信息⼤多以RVA形式存在的。
原因在于,PE⽂件(主要是DLL)加载到进程虚拟内存的特定位置时,该位置可能已经加载了其他的PE⽂件(DLL)。
此时必须通过重定位将其加载到其他位置。
如果使⽤VA,则⽆法正常访问。
因此使⽤RVA来定位,即使发⽣了重定位,只要相对于基准位置的相对地址没有变化,就能正常访问。
32位window OS中,各进程分配有4GB的虚拟内存,因此进程中VA值的范围是 00000000~ FFFFFFFF。
PE⽂件格式学习感觉这博客写起来和抄书差不多。
PE⽂件结构概述PE⽂件,即Portable Executable File Format,可移植的执⾏体,Windows下的所有可执⾏⽂件都是PE⽂件格式,⽐如.exe,.dll,.sys等PE⽂件格式是⼀种对⽂件组织管理的⽅式⽤RadASM编写⼀个简单的可执⾏程序做为分析的对象(⼯程类型win32(nores))这玩意好像没法写注释语句,那我就按c的语法写注释了.386 // ⽤到的汇编指令的指令集是.386.model flat, stdcall // flat表⽰使⽤的是内存的平坦模式,stdcall是函数调⽤的⼀种⽅式option casemap:none // casemap:none就是不区分⼤⼩写// 调⽤头⽂件和链接库include windows.incinclude kernel32.incinclude user32.incincludelib kernel32.libincludelib user32.lib// 定义数据.dataszCaption db 'hello', 0 // db是字节的意思,定义了⼀个hello的字符串,汇编中win32⽤, 0进⾏结尾szText db 'hello world!', 0// 写代码.codestart: // 代码从标号开始执⾏,下⾯的end start也就是说标号是startpush 0lea eax, szCaptionpush eaxlea eax, szTextpush eaxpush 0call MessageBoxpush 0call ExitProcessend start编译,连接,然后运⾏.exe这就是这段代码的含义⽤WinHex来对⽐可执⾏⽂件在⽂件和内存中的差异打开WinHex并打开刚刚编译的pe.exe,并且不关闭对话框,然后在winhex⾥打开ram找到PE下⾯的dll⽂件就是该exe所依赖的dll⽂件,不管他们,我们直接点PE.exe点确定左边这个是在磁盘打开的,右边这个是从内存打开的第⼀个区别,左边的⽂件Offset(偏移)是从0000000开始的,⽽右边的⽂件Offset是从00400000开始的磁盘内的⽂件是根据⼀些规范映射到内存中的,所以这个偏移量是不同的第⼆个区别,从400220开始两个⽂件都是00,但是左边的⽂件到400就有数据了,⽽右边的要到1000才有数据并且这两坨数据是⼀样的在左边的600,右边的2000处,可以看到调⽤的dll是⼀样的,但是数据不同了还有左边的800,右边的3000是我们定义的字符串剩下的全是00⽤PEView查看可执⾏⽂件的结构⽤PEView打开PE.exepFile是⽂件中的偏移,Raw Data是原始数据,Value是字符串形式显⽰,不能显⽰的⽤'.'代替在左边打开IMAGE_DOS_HEADER,这东西对该⽂件进⾏了解析注意到⽽原来我们看到第⼀⾏前2个数字是4D 5A,他倒过来了,这种玩意叫“字节序”在IMAGE_NT_HEADERS⾥⾯点Signature我们跟着找⼀下这个偏移这个数据也是倒着的,也是字节序导致的我们再看看左边这串英⽂IMAGE_DOS_HEADER:dos头MS-DOS Stub Program:DOS存根Signature:PE⽂件的标识IMAGE_FILE_HEADER:⽂件头IMAGE_OPTIONAL_HEADER:可选头(但不是可以不选的那种,只是其中某些东西只需要占位,不需要有具体数据)IMAGE_SECTION_HEADER:节区,给出了三种数据在⽂件和在内存中的位置.text:代码.rdata: 只读数据.data:数据SECTION:真正的数据⽂件中的数据不会变化,但是在映射到内存中后⼀些相对位置就变了DOS头DOS头是PE⽂件结构的第⼀个头,⽤来保持对DOS系统的兼容,并且⽤于定位真正的PE头DOS头在winnt.h头⽂件中的定义如下(该⽂件头⼤⼩为40h,64d)typedef struct _IMAGE_DOS_HEADER {WORD e_magic; // 0x00 EXE标志MZWORD e_cblp; // 0x02 最后(部分)页中的字节数WORD e_cp; // 0x04 ⽂件中的全部和部分页数WORD e_crlc; // 0x06 重定位表中的指针数WORD e_cparhdr; // 0x08 头部尺⼨,以段落为单位WORD e_minalloc; // 0x0A 所需的最⼩附加段WORD e_maxalloc; // 0x0C 所需的最⼤附加段WORD e_ss; // 0x0E 初始的SS值(相对偏移量)WORD e_sp; // 0x10 初始的SP值WORD e_csum; // 0x12 校验和WORD e_ip; // 0x14 初始的IP值WORD e_cs; // 0x16 初始的CS值WORD e_lfarlc; // 0x18 重定位表的字节偏移量WORD e_ovno; // 0x1A 覆盖号WORD e_res[4]; // 0x1C 保留字WORD e_oemid; // 0x24 EM标识符(相对e_oeminfo )WORD e_oeminfo; // 0x26 OEM信息; e_oemid specificWORD e_res2[10]; // 0x28 保留字LONG e_lfanew; // 0x3C PE头相对于⽂件的偏移地址} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;#define IMAGE_DOS_SIGNATURE 0x4D5A // MZ其中我们最关⼼的是e_magic和e_lfanew(MZ其实是⼀个开发⼈员的名字的缩写,被保留了下来)如何判断⽂件是否为PE结构的⽂件⽤C32ASM打开上次编写的那个PE.exe这⼏⾏其实就是DOS头WORD e_magic; // 0x00 EXE标志MZWORD在windows下是2个字节前2个字节4D 5A就是e_magic,win下所有可执⾏⽂件前2个字节都是他们,其ASCII码是MZLONG e_lfanew;LONG在windows下是4个字节最后4个字节是B0 00 00 00,它们指向了我们PE头的偏移但是,此处存储⽅式是⼩端序存储,也就是低地址保存低位数据,⾼地址保存⾼位数据,实际上他指向的位置是00 00 00 B0 intel架构的cpu存储数据都是⼩端序,⼤端序存储⼀般在其他cpu架构或者⽹络传输数据时使⽤B0⾏的开头是50 45 00 00,前2个字节翻译成字符串是PE,这就是PE⽂件头总结⼀下,判断⼀个⽂件是否为PE⽂件的步骤观察其前2字节是否为MZ找到e_lfanew根据e_lfanew找到地址,观察其前2字节是否为PE找到了PE的话⼀般都是PE⽂件了计算IMAGE_DOS_HEADER结构体⼤⼩#include <stdio.h>#include <windows.h>using namespace std;int main(){printf("%d %x\r\n", sizeof(IMAGE_DOS_HEADER), sizeof(IMAGE_DOS_HEADER));return 0;}10进制是64,16进制是40⼀个⼩实验在刚刚的PE.exe中,在B0 00 00 00 到 50 45 00 00中间的数据实际上是完全没⽤的实际上这些是DOS的代码将其全部填充为00,保存,然后打开PE.exe他还是可以运⾏的我们最关⼼的是e_magic和e_lfanew那我们尝试把DOS头其他的数据全部填充为00再次运⾏还是可以运⾏的,也就是说我们改的数据其实是完全不需要的,那他们有些啥⽤呢在c32asm中新建⼀个⽂件,把00-A0的代码复制下来,保存为dos.bin扔进IDA打开这⼀块代码实际上是在编译-连接的时候⾃动添加进来的⼀个程序,被称为DOS存根读⼀下汇编,它的作⽤就是输出"This program cannot be run in DOS mode.",然后关闭程序。
PE⽂件结构详解1、PE⽂件的结构1、什么是可执⾏⽂件?可执⾏⽂件 (executable file) 指的是可以由操作系统进⾏加载执⾏的⽂件。
可执⾏⽂件的格式:- Windows平台:PE(Portable Executable)⽂件结构- Linux平台:ELF(Executable and Linking Format)⽂件结构PE和ELF⾮常相似,它们都是源于同⼀种可执⾏⽂件格式 COFF- COFF 是由Unix System V Release 3⾸先提出并且使⽤的格式规范,- 微软基于COFF格式,制定了PE格式标准,并将其⽤于当时的Windows NT系统- System V Release 4在COFF的基础上引⼊了ELF格式。
事实上,在Windows平台,VISUAL C++编译器产⽣的⽬标⽂件仍然使⽤COFF格式,⽽可执⾏⽂件为PE格式微软对64位Windows平台上的PE⽂件结构叫做PE32+,就是把那些原来32位的字段变成了64位。
2、PE⽂件的特征识别⼀个⽂件是不是PE⽂件不应该只看⽂件后缀名,还应该通过PE指纹使⽤UE打开⼀个exe⽂件,发现⽂件的头两个字节都是MZ,0x3C位置保存着⼀个地址,查该地址处发现保存着“PE”,这样基本可以认定改⽂件是⼀个PE⽂件通过这些重要的信息(“MZ”和“PE”)验证⽂件是否为PE⽂件,这些信息即PE指纹。
3、PE⽂件的整体结构这⾥将⼀个PE⽂件的主要部分列为4部分,这⾥可以先有模糊概念,后⾯会详细解释“节”或“块”或”区块“都是⼀个意思,后⽂会穿插使⽤下⾯从⼆进制层⾯整体把握其结构,看看⼀个PE⽂件的组成PE⽂件存储在磁盘时的结构和加载到内存后的结构有所不同。
当PE⽂件通过Windows加载器载⼊内存后,内存中的版本称为模块(Module)。
映射⽂件的起始地址称为模块句柄(hModule),也称为基地址(ImageBase)。
(模块句柄是不是和其他句柄不太⼀样呢?)⽂件数据⼀般512字节(1扇区)对齐(现也多4k),32位内存⼀般4k(1页)对齐,512D = 200H,4096D = 1000H⽂件中块的⼤⼩为200H的整数倍,内存中块的⼤⼩为1000H的整数倍,映射后实际数据的⼤⼩不变,多余部分可⽤0填充PE⽂件头部(DOS头+PE头)到块表之间没有间隙,然⽽他们却和块之间有间隙,⼤⼩取决于对齐参数VC编译器默认编译时,exe⽂件基地址是0x400000,DLL⽂件基地址是0x10000000VA:虚拟内存地址RVA:相对虚拟地址即相对于基地址的偏移地址FOA: ⽂件偏移地址5、DOS部分DOS MZ⽂件头实际是⼀个结构体(IMAGE_DOS_HEADER),占64字节typedef struct _IMAGE_DOS_HEADER { // DOS .EXE headerWORD e_magic; // Magic numberWORD e_cblp; // Bytes on last page of fileWORD e_cp; // Pages in fileWORD e_crlc; // RelocationsWORD e_cparhdr; // Size of header in paragraphsWORD e_minalloc; // Minimum extra paragraphs neededWORD e_maxalloc; // Maximum extra paragraphs neededWORD e_ss; // Initial (relative) SS valueWORD e_sp; // Initial SP valueWORD e_csum; // ChecksumWORD e_ip; // Initial IP valueWORD e_cs; // Initial (relative) CS valueWORD e_lfarlc; // File address of relocation tableWORD e_ovno; // Overlay numberWORD e_res[4]; // Reserved wordsWORD e_oemid; // OEM identifier (for e_oeminfo)WORD e_oeminfo; // OEM information; e_oemid specificWORD e_res2[10]; // Reserved wordsLONG e_lfanew; // File address of new exe header} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;DOS头⽤于16位系统中,在32位系统中DOS头成为冗余数据,但还存在两个重要成员e_magic字段(偏移 0x0)和 e_lfanew字段(偏移 0x3C)e_magic保存“MZ”字符,e_lfanew保存PE⽂件头地址,通过这个地址找到PE⽂件头,得到PE⽂件标识“PE”。