WindowsPE文件格式资料
- 格式:ppt
- 大小:357.00 KB
- 文档页数:57
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文件格式中的哪些重要信息。
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)是完全⼀致的,在此处不⽤过多理会。
在Windows 11 PE中,分区格式的选择对系统的稳定性和性能有很大的影响。
常见的分区格式包括FAT32、NTFS和EXT4等。
首先,FAT32格式在PE系统上通常是一个不错的选择。
它是一种文件分配表格式,具有较小的磁盘空间要求,并且操作简单。
然而,FAT32格式在处理大文件和大型硬盘驱动器时可能会遇到问题,因为它只支持最大约为4GB的文件。
对于更高级的用户,NTFS格式是一个更好的选择,因为它提供了更高的文件管理能力和安全性。
在PE系统中,使用NTFS格式可以确保数据的安全性和稳定性,并且它对大文件和大型硬盘驱动器的支持也更好。
然而,转换为NTFS格式可能会涉及一些文件重命名或复制操作,因此需要注意备份重要数据。
此外,考虑到Windows 11 PE的操作系统需求,建议选择合适的分区大小。
通常,PE系统需要至少1GB的可用空间来运行,以确保系统的稳定性和性能。
对于更大的硬盘驱动器,可以考虑使用分区工具进行分区,以便为PE系统分配足够的空间。
在选择分区格式和分区大小后,建议进行磁盘分区测试,以确保PE系统能够正常运行并满足需求。
在测试过程中,可以尝试运行不同的软件和应用程序,以检查系统的稳定性和性能。
如果发现问题,可以及时调整分区格式或分区大小,以确保系统的正常运行。
总之,在Windows 11 PE中,选择合适的分区格式和大小非常重要。
FAT32格式适合小文件和简单的需求,而NTFS格式提供了更高的文件管理能力和安全性。
根据需求和可用空间,选择合适的分区大小也很关键。
经过测试和调整后,Windows 11 PE将能够正常运行并满足您的需求。
PE⽂件详解1——PE⽂件头部解析参考书籍:《WindowsPE⽂件权威指南》MSDN中winnt.h是PE⽂件定义的最终决定者。
EXE⽂件与DLL⽂件之间的区别完全是语义上的,⼆者PE结构完全相同。
唯⼀区别⽤⼀个字段标⽰处这个⽂件是exe还是dll。
许多DLL扩展,如OCX控件,控制⾯板等都是DLL,它们有⼀样的实体。
64位的Windows只是对PE格式做了⼀些简单的修饰,新格式叫PE32+。
没有新的结构加进去,其余的改变只是简单地将以前的32位字段扩展为64位字段。
1.PE⽂件基本结构:PE⽂件的头分为DOS头、NT头、节头。
注意,这是本⼈的分法。
这样分法会更加合理,更易理解。
因为这三个部分正好构成SizeOfHeaders所指的范围,所以将它们合为“头”。
2.⽂件头2.1 DOS头⽤记事本打开任何⼀个镜像⽂件,其头2个字节必为字符串“MZ”,这是Mark Zbikowski的姓名缩写,他是最初的MS-DOS设计者之⼀。
然后是⼀些在MS-DOS下的⼀些参数,这些参数是在MS-DOS下运⾏该程序时要⽤到的。
在这些参数的末尾也就是⽂件的偏移0x3C(第60字节)处是是⼀个4字节的PE⽂件签名的偏移地址。
该地址有⼀个专⽤名称叫做“E_lfanew”。
这个签名是“PE00”(字母“P”和“E”后跟着两个空字节)。
紧跟着E_lfanew的是⼀个MS-DOS程序。
那是⼀个运⾏于MS-DOS下的合法应⽤程序。
当可执⾏⽂件(⼀般指exe、com⽂件)运⾏于MS-DOS下时,这个程序显⽰“This program cannot be run in DOS mode(此程序不能在DOS模式下运⾏)”这条消息。
⽤户也可以⾃⼰更改该程序,有些还原软件就是这么⼲的。
同时,有些程序既能运⾏于DOS⼜能运⾏于Windows下就是这个原因。
Notepad.exe整个DOS头⼤⼩为224个字节,⼤部分不能在DOS下运⾏的Win32⽂件都是这个值。
一、PE文件结构PE文件被称为可移植的执行体是Portable Execute的全称,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的程序文件(可能是间接被执行,如DLL),Portable 是指对于不同的Windows版本和不同的CPU类型上PE文件的格式是一样的,当然CPU不一样了,CPU指令的二进制编码是不一样的。
只是文件中各种东西的布局是一样的。
在下面关于结构的定义中,WORD 表示变量大小为2个字节,DWORD表示变量大小是4个字节。
1.1 PE文件的结构PE文件有着固定的结构,分为五个部分,如下:1:DOS MZ Header(DOS文件头) 一个IMAGE_DOS_HEADER结构,大小为64字节。
2:DOS Stub(DOS加载模块) 没有固定大小。
3:PE Header(PE文件头)一个IMAGE_NT_HEADERS结构,大小为248字节。
4:Section Table(节表)一个IMAGE_SECTION_HEADER结构数组,数组大小依据节而定,如果PE文件有5个节,则数组大小为5。
5:Sections(节或段)没有固定大小,可以有多个节。
1.2 DOS文件头和DOS加载模块PE文件的一二部分完全是为了程序能在DOS运行下时给出一个提示。
IMAGE_DOS_HEADER结构的定义如下:Typedef struct IMAGE_DOS_HEADER{WORD e_magic; // 魔术数字WORD e_cblp; // 文件最后页的字节数WORD e_cp; // 文件页数WORD e_crlc; // 重定义元素个数WORD e_cparhdr; // 头部尺寸,以段落为单位WORD e_minalloc; // 所需的最小附加段WORD e_maxalloc; // 所需的最大附加段WORD e_ss; // 初始的SS值(相对偏移量)WORD e_sp; // 初始的SP值WORD e_csum; // 校验和WORD e_ip; // 初始的IP值WORD e_cs; // 初始的CS值(相对偏移量)WORD e_lfarlc; // 重分配表文件地址WORD e_ovno; // 覆盖号WORD e_res[4]; // 保留字WORD e_oemid; // OEM标识符(相对e_oeminfo)WORD e_oeminfo; // OEM信息WORD e_res2[10]; // 保留字LONG e_lfanew; // 新exe头部的文件地址} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;DOS文件头和DOS加载模块在 Windows下几乎已经没有什么作用了。
PE文件格式详解摘要Windows NT3.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 Win32SDK开发包中的WINNT.H文件,在这个文件中你会发现用来描述文件头部和数据目录等各种成分的结构类型定义。
但是,在WINNT.H中缺少对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、等等。
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文件是Win32的原生文件格式.每一个Win32可执行文件都遵循PE文件格式.对PE文件格式的了解可以加深你对Win32系统的深入理解.一、基本结构。
上图便是PE文件的基本结构。
(注意:DOS MZ Header和部分PE header的大小是不变的;DOS stub部分的大小是可变的。
)一个PE文件至少需要两个Section,一个是存放代码,一个存放数据。
NT上的PE文件基本上有9个预定义的Section。
分别是:.text, .bss, .rdata, .data, .rsrc, .edata, .idata, .pdata, 和 .debug。
一些PE文件中只需要其中的一部分Section.以下是通常的分类:l 执行代码Section , 通常命名为: .text (MS) or CODE (Borland)l 数据Section, 通常命名为:.data, .rdata, 或 .bss(MS) 或DATA(Borland).l 资源Section, 通常命名为:.edatal 输入数据Section, 通常命名为:.idatal 调试信息Section,通常命名为:.debug这些只是命名方式,便于识别。
通常与系统并无直接关系。
通常,一个PE文件在磁盘上的映像跟内存中的基本一致。
但并不是完全的拷贝。
Windows加载器会决定加载哪些部分,哪些部分不需要加载。
而且由于磁盘对齐与内存对齐的不一致,加载到内存的PE文件与磁盘上的PE文件各个部分的分布都会有差异。
当一个PE文件被加载到内存后,便是我们常说的模块(Module),其起始地址就是所谓的HModule.二、 DOS头结构。
所有的PE文件都是以一个64字节的DOS头开始。
这个DOS头只是为了兼容早期的DOS操作系统。
这里不做详细讲解。
只需要了解一下其中几个有用的数据。
1. e_magic:DOS头的标识,为4Dh和5Ah。
分别为字母MZ。
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文件格式标准PE文件是Windows操作系统中常见的可执行文件格式,它具有一定的规范和结构。
本文将介绍PE文件格式的标准,以帮助读者更好地理解和应用该文件格式。
一、文件类型PE文件是一种可执行文件格式,其后缀名通常为.exe、.dll或.sys。
根据文件头中的标识,可以确定文件是否为PE文件。
二、文件结构1. DOS头PE文件的第一个部分是DOS头,用于向操作系统提供兼容性支持。
它包含了DOS头标识、指向PE文件的偏移地址等信息。
PE头是PE文件的关键部分,包含了各种信息,如文件类型、入口点地址、导入表、导出表等。
其中,导入表和导出表记录了文件中使用的外部函数和数据。
节表用于描述PE文件的各个节(Sections),每个节都包含了特定的代码、数据或资源。
每个节在节表中都有一个条目,记录了节的名称、在文件中的偏移地址、大小等。
4. 数据目录数据目录记录了PE文件中存储重要信息的位置和大小,如导入表、导出表、资源表等。
每个数据目录都有一个条目,包含了相应信息的位置和大小。
三、文件解析PE文件可以通过解析文件头部和节表来获取所需的信息。
通过解析PE头的入口点地址,可以定位文件的入口点,从而启动程序。
1. 解析DOS头首先,解析DOS头,获取PE头的文件偏移地址。
通过该地址,可以定位到PE头的起始位置。
2. 解析PE头接下来,解析PE头,获取文件的相关信息,如文件类型、入口点地址等。
可以根据需要进一步解析导入表、导出表等信息。
3. 解析节表通过解析节表,可以获取PE文件中各个节的详细信息。
可以根据节的名称或索引来定位到相应的节,并获取节的起始地址、大小等。
四、常见问题与处理方法在处理PE文件时,可能会遇到一些常见的问题,以下列举几个常见问题,并提供相应的处理方法:1. 处理导入表若PE文件中存在外部函数调用,需要解析导入表,并将相应的函数地址重新映射到实际的函数地址上。
2. 处理资源表若PE文件中包含资源,需要解析资源表,并提取所需的资源。
32位Windows系统PE文件格式漏洞简要分析可移植的执行体(Portable Executable,PE)文件格式是微软制定的一种文件标准,它是从普遍运用于UNIX 操作系统的COFF发展而来,是目前Windows 平台上的主流可执行文件的文件格式,应用于所有的32位Windows。
可执行文件的格式是操作系统本身执行机制的反映。
基于PE文件格式的研究层出不穷,及这方面的漏洞分析不容忽视。
一、PE文件结构PE文件主要由DOS部首,PE文件头,节表,节和辅助结构等5部分组成,如图所示。
数据结构通常定义在WINNT. H。
二、基于PE文件格式的应用很多进一步的应用开发都是建立在此原理之上,比如在加密解密领域(在PE 文件的冗余空间中插入加密解密程序的代码),信息隐藏领域(主流的方法是利用PE文件中存在的冗余空间和冗余字段进行信息嵌入,该方法不会改变PE文件长度和结构。
也可利用静态分配字符串存储空间进行信息嵌入的方法,但只适用于未编译的PE文件源代码中进行信息隐藏)和文件病毒领域。
2.1 向PE文件中添加可执行代码PE文件的数据结构在磁盘和内存中是一样的,装载一个可执行文件到内存中,它不是作为单一内存映射文件被载入内存的,Windows加载器遍历PE文件并决定文件的哪一部分被映射。
依据PE文件的存储结构及其加载过程,得出两种典型的向PE文件中添加代码的方法。
2.1.1 插入方式PE文件在磁盘中,节与节之间必须遵循文件对齐原则,以利于PE文件快速定位,而程序的代码或数据可能没有占满该节,造成冗余空间,可乘机插入代码,实现思想如下:由DOS头结构字段e_lfanew定位PE 头结构位置;读取PE 头,得到节个数字段NumberOfSections;依据节个数分配节表缓冲区读取所有节表到缓冲区;遍历每个节,空白区的文件偏移等于(PointerToRawData+ VirtualSize);空白区大小为该节实际占用磁盘空间减去该节实际大小(SizeOfRawData-VirtualSize);修改节表结构让缓冲区中每个节表的字段VirtualSize等于字段SizeOfRawData;将缓冲区数据写入。
WindowsPECOFFWindows PE/COFFWindows的⼆进制⽂件格式PE/COFF在32位Windows平台下,微软引⼊了⼀种叫PE(Portable Executable)的可执⾏格式。
作为Win32平台的标准可执⾏⽂件格式,PE有着跟ELF⼀样良好的平台扩展性和灵活性。
PE⽂件格式事实上与ELF同根同源,他们都是由COFF(Common Object File Format)格式发展⽽来的,更加具体地讲是来源于当时著名的DEC(Digital Equipment Corporation)的VAX/VMS上的COFF⽂件格式。
因为当微软开始开发Windows NT的时候,最初的成员都是来⾃于DEC公司的VAX/VMS⼩组,所以他们很⾃然就将原来系统上熟悉的⼯具和⽂件格式都搬了过来,并且在此基础上做重新设计和改动。
请注意,上⾯在讲到PE⽂件格式的时候,只是说Windows平台下的可执⾏⽂件采⽤该格式。
事实上,在Windows平台,VISUAL C++编译器产⽣的⽬标⽂件仍然使⽤COFF格式。
由于PE是COFF的⼀种扩展,所以它们的结构在很⼤程度上相同,甚⾄跟ELF⽂件的基本结构也相同,都是基于段的结构。
所以我们下⾯在讨论Windows平台上的⽂件结构时,⽬标⽂件默认为COFF格式,⽽可执⾏⽂件为PE格式。
但很多时候我们可以将它们统称为PE/COFF⽂件。
随着64位Windows的发布,微软对64位Windows平台上的PE⽂件结构稍微做了⼀些修改,这个新的⽂件格式叫做PE32+。
新的PE32+并没有添加任何结构,最⼤的变化就是把那些原来32位的字段变成了64位,⽐如⽂件头中与地址相关的字段。
PE的前⾝——COFFCOFF⽂件结构⼏乎跟ELF⽂件⼀样,COFF也是由⽂件头及后⾯的若⼲个段组成,再加上⽂件末尾的符号表、调试信息的内容就构成了COFF⽂件的基本结构,我们在COFF⽂件中⼏乎都可以找到与ELF⽂件结构相对应的地⽅。