pe文件格式

合集下载

PE分析文件格式(helloword)

PE分析文件格式(helloword)

PE分析文件格式(helloword)Dump of file H:\桌面\PE文件学习\PE 文件格式启发式学习\hello.exeFile HeaderMachine: 014CNumber of Sections: 0004TimeDateStamp: 48202B13PointerT oSymbolTable: 00000000NumberOfSymbols: 00000000SizeOfOptionalHeader: 00E0Characteristics: 010FRELOCS_STRIPPEDEXECUTABLE_IMAGELINE_NUMS_STRIPPEDLOCAL_SYMS_STRIPPED32BIT_MACHINEOptional HeaderMagic 010Blinker versio 5.12size of code 200size of initialized data 800size of uninitialized data 0entrypoint RVA 1000base of code 1000base of data 2000image base 400000section align 1000file align 200required OS version 4.00image version 0.00subsystem version 4.00size of image 43A0size of headers 800checksum 0Subsystem 0002stack reserve size 100000stack commit size 1000heap reserve size 100000heap commit size 1000RVAs & sizes 10Data DirectoryEXPORT rva: 00000000 size: 00000000 IMPORT rva: 00002010 size: 0000003C RESOURCE rva: 00004000 size: 000003A0 EXCEPTION rva: 00000000 size: 00000000 SECURITY rva: 00000000 size: 00000000 BASERELOC rva: 00000000 size: 00000000 DEBUG rva: 00000000 size: 00000000 COPYRIGHT rva: 00000000 size: 00000000 GLOBALPTR rva: 00000000 size: 00000000 TLS rva: 00000000 size: 00000000LOAD_CONFIG rva: 00000000 size: 00000000 BOUND_IMPORT rva: 00000000 size: 00000000 IAT rva: 00002000 size: 00000010unused rva: 00000000 size: 00000000 unused rva: 00000000 size: 00000000unused rva: 00000000 size: 00000000Section Table01 .text virtSize: 00000028 VirtAddr: 00001000 raw data offs: 00000800 raw data size: 00000200 relocation offs: 00000000 relocations: 00000000 line # offs: 00000000 line #`s: 00000000 characteristics: 60000020CODE MEM_EXECUTE MEM_READ02 .rdat VirtSize: 00000092 VirtAddr: 00002000 raw data offs: 00000A00 raw data size: 00000200 relocation offs: 00000000 relocations: 00000000 line # offs: 00000000 line #`s: 00000000 characteristics: 40000040INITIALIZED_DATA MEM_READ03 .data VirtSize: 00000034 VirtAddr: 00003000 raw data offs: 00000C00 raw data size: 00000200 relocation offs: 00000000 relocations: 00000000 line # offs: 00000000 line #`s: 00000000 characteristics: C0000040INITIALIZED_DATA MEM_READ MEM_WRITE04 .rsrc VirtSize: 000003A0 VirtAddr: 00004000 raw data offs: 00000E00 raw data size: 00000400 relocation offs: 00000000 relocations: 00000000 line # offs: 00000000 line #`s: 00000000characteristics: 40000040 INITIALIZED_DATA MEM_READImports Table:user32.dllHint/Name Table: 00002054 TimeDateStamp: 00000000 ForwarderChain: 00000000 First thunk RVA: 00002008 Ordn Name413 MessageBoxAkernel32.dllHint/Name Table: 0000204C TimeDateStamp: 00000000 ForwarderChain: 00000000 First thunk RVA: 00002000 Ordn Name128 ExitProcess。

PE文件格式详解

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文件格式

PE文件格式

地址(DE C)地址(HEX)整体名称整体名称下级名称下级结构下级结构00 11 22 33 44 5566 77 88 99 10A 11B 12C 13D 14E 15F 1610 1711 1812 1913 2014 2115 2216 2317 2418 2519 261A 271B 3624 3725 3826 3927 603C 613D 623E 633F 208D0 209D1 210D2 211D3 212D4 213D5 214D6 215D7 216D8 217D9 218DA 219DB 220DC 221DD 222DEe_crlce_cparhdre_minalloce_magice_cblpe_cpe_maxalloce_sse_spe_csume_ipe_cse_lfarlce_ovnoe_oemide_oeminfoNumberOfSectionsTimeDateStampPointerToSymbolTableSignaturee_lfanewMachineMS-DOS头部IMAGE_DOS_HEADERSignature文件头IMAGE_FILE_HEADERMS-DOS头部IMAGE_DOS_HEADERDOS STUB223DF 224E0 225E1 226E2 227E3 228E4 229E5 230E6 231E7 232E8 233E9234EA MajorLink erVersion235EB MinorLink erVersion236EC 237ED 238EE 239EF 240F0 241F1 242F2 243F3 244F4 245F5 246F6 247F7 248F8 249F9 250FA 251FB 252FC 253FD 254FE 255FF 256100 257101 258102 259103 260104 261105 262106 263107 264108 265109 26610A 26710B 26810C 26910D 27010E 27110F 272110 273111 274112SymbolTableNumberOfSymbolsSizeOfOptionalHeadCharacteristicsBaseOfCodeBaseOfDataImageBaseMagicSizeOfCodeSizeOfInitializedDataSizeOfUninitializedDataAddressOfEntryPointSectionAlignmentFileAlignmentMajorOperatingSystMinorOperatingSyst IMAGE_FILE_HEADER27511327611427711527811627911728011828111928211A 28311B 28411C 28511D 28611E 28711F 28812028912129012229112329212429312529412629512729612829712929812A 29912B 30012C 30112D 30212E 30312F 30413030513130613230713330813430913531013631113731213831313931413A 31513B 31613C 31713D 31813E 31913F 320140321141322142323143324144325145326146327147328148VirtualAddress IMAGE_EXPORT_D IRECTORYMinorOper atingSyst MajorImag eVersion MinorImag eVersion MajorSubs ystemVers MinorSubs ystemVers Win32Vers ionValueSizeOfImageSizeOfHea dersCheckSumSubsystem DllCharac teristics SizeOfSta ckReserveSizeOfSta ckCommitSizeOfHea pReserveSizeOfHea pCommitLoaderFlags NumberOfR vaAndSizesPE文件头Signature IMAGE_FIL E_HEADER IMAGE_OPT IONAL_HEAIMAG7E_DIRECT ORY_ENTRY_EXP329149 33014A 33114B 33214C 33314D 33414E 33514F 336150 337151 338152 339153 340154 341155 342156 343157 344158 345159 34615A 34715B 34815C 34915D 35015E 35115F 352160 353161 354162 355163 356164 357165 358166 359167 360168361169 36216A 36316B 36416C 36516D 36616E 36716F 368170 369171 370172 371173 372174 373175 374176 375177 376178 377179 37817A 37917B 38017C 38117D 38217EVirtualAddressSizeVirtualAddressIMAGE_BASE_RELOCATIONSizeVirtualAddressIMAGE_DEBUG_DIRECTORYSizeVirtualAddressIMAGE_EXPORT_DIRECTORYSizeVirtualAddressIMAGE_IMPORT_DESCRIPTORSizeVirtualAddressIMAGE_RESOURCE_DIRECTORYSizeSizeA_DIRECTOVirtualAddress 选择文件头IMAGE_OPTIONAL_HEADERPE文件头SignatureIMAGE_FILE_HEADERIMAGE_OPTIONAL_HEADERIMAG7E_DIRECTORY_ENTRY_EXPORT1IMAGE_DIRECTORY_ENTRY_IMPORT2IMAGE_DIRECTORY_ENTRY_RESOURCE3IMAGE_DIRECTORY_ENTRY_EXCEPTION4IMAGE_DIRECTORY_ENTRY_SECURITY5IMAGE_DIRECTORY_ENTRY_BASERELOC6IMAGE_DIRECTORY_ENTRY_DEBUG38317F 384180 385181 386182 387183 388184 389185 390186 391187 392188 393189 39418A 39518B 39618C 39718D 39818E 39918F 400190 401191 402192 403193 404194 405195 406196 407197 408198 409199 41019A 41119B 41219C 41319D 41419E 41519F 4161A0 4171A1 4181A2 4191A3 4201A44211A5 4221A6 4231A7 4241A8 4251A9 4261AA 4271AB 4281AC 4291AD 4301AE 4311AF 4321B0 4331B1 4341B2 4351B3 4361B4SizeVirtualAddressSizeVirtualAddressSizeVirtualAddressSizeVirtualAddressVirtualAddressVirtualAddressSizeIMAGE_DATA_DIRECTORYDataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]16个IMAGE_DATA_DIRECTORY11IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT12IMAGE_DIRECTORY_ENTRY_IAT13IMAGE_DIRECTORY_ENTRY_DELAY_IMPORTSizeVirtualAddressSize8IMAGE_DIRECTORY_ENTRY_GLOBALPTR9IMAGE_DIRECTORY_ENTRY_TLS10IMAGE_DIRECTORY_ENTRY_LOAD_CONFIGIMAGE_DIRECTORY_ENTRY_DEBUG7IMAGE_DIRECTORY_ENTRY_ARCHITECTU4371B5 4381B6 4391B7 4401B8 4411B9 4421BA 4431BB 4441BC4451BD 4461BE 4471BF 4481C0 4491C1 4501C2 4511C3 4521C4 4531C5 4541C6 4551C7 4561C8 4571C9 4581CA 4591CB 4601CC 4611CD 4621CE 4631CF 4641D0 4651D1 4661D2 4671D3 4681D4 4691D5 4701D6 4711D7 4721D8 4731D9 4741DA 4751DB 4761DC 4771DD 4781DE 4791DF 4801E0 4811E1 4821E2 4831E3 4841E4 4851E5 4861E6 4871E7 4881E8 4891E9 4901EASizeSizeVirtualAddress15未使用SizeOfRawDataIMAGE_SECTION_HEADERName[IMAGE_SIZEOF_SHORT_NAME]8个字节union {DWORDPhysicalAddress;VirtualAddressPointerToRawDataPointerToRelocationsPointerToLinenumbersNumberOfRelocationNumberOfLinenumberIMAGE_DIRECTORY_ENTRY_DELAY_IMPORT14IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR未使用IMAGE_SECTION_HEADER4911EB 4921EC 4931ED 4941EE 4951EF 4961F0 4971F1 4981F2 4991F3 5001F4 5011F5 5021F6 5031F7 5041F8 5051F9 5061FA 5071FB 5081FC 5091FD 5101FE 5111FF 512200NumberOfL inenumber Character istics描述典型值及说明M Z208000P E00魔术数字"MZ"文件最后页的字节数文件页数 重定义元素个数文件最后页的字节数所需的最小附加段所需的最大附加段初始的SS值(相对偏移量)初始的SP值校验和初始的IP值初始的CS值(相对偏移量)重分配表文件地址重分配表文件地址OEM标识符(相对e_oeminfo)OEM信息新exe头部的文件地址PE头部标识"PE\0\0"该文件运行所要求的CPU。

PE文件结构及其加载机制

PE文件结构及其加载机制

PE⽂件结构及其加载机制⼀、PE⽂件结构PE即Portable Executable,是win32环境⾃⾝所带的执⾏体⽂件格式,其部分特性继承⾃Unix的COFF(Common Object File Format)⽂件格式。

PE表⽰该⽂件格式是跨win32平台的,即使Windows运⾏在⾮Intel的CPU上,任何Win32平台的PE装载器也能识别和使⽤该⽂件格式的⽂件。

所有Win32执⾏体(除了VxD和16位的DLL)都使⽤PE⽂件格式,如EXE⽂件、DLL⽂件等,包括NT的内核模式驱动程序(Kernel Mode Driver)。

PE⽂件⾄少包含两个段,即数据段和代码段。

Windows NT 的应⽤程序有9个预定义的段,分别为 .text 、.bss 、.rdata 、.data 、.pdata 和.debug 段,这些段并不是都是必须的,当然,也可以根据需要定义更多的段(⽐如⼀些加壳程序)。

在应⽤程序中最常出现的段有以下6种:.执⾏代码段,通常 .text (Microsoft)或 CODE(Borland)命名;.数据段,通常以 .data 、.rdata 或 .bss(Microsoft)、DATA(Borland)命名;.资源段,通常以 .rsrc命名;.导出表,通常以 .edata命名;.导⼊表,通常以 .idata命名;.调试信息段,通常以 .debug命名;PE⽂件的结构在磁盘和内存中是基本⼀样的,但在装⼊内存中时⼜不是完全复制。

Windows装载器在装载的时候仅仅建⽴好虚拟地址和PE ⽂件之间的映射关系,只有真正执⾏到某个内存页中的指令或访问某⼀页中的数据时,这个页才会被从磁盘提交到物理内存。

但因为装载可执⾏⽂件时,有些数据在装⼊前会被预先处理(如需要重定位的代码),装⼊以后,数据之间的相对位置也可能发⽣改变。

因此,⼀个节的偏移和⼤⼩在装⼊内存前后可能是完全不同的。

..PE的基本结构就是这样了。

PE文件格式

PE文件格式
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
么正确的开始地址是0x401560。如果可执行程序调入0x100000处,则开始地址为0x101560。
因为PE文件的每一个段不必按同样的边界对齐方式调入,因此RVA地址的计算变得比较复
杂。例如,在文件中每一个段往往按512个字节的方式对齐,而在内存中可能以4096字节的方
式对齐。这方面的介绍可见下面的“SectionAlignment”、“FileAlignment”。举个例子,
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
三、文件头(File Header)
通过DOS头,你可以找到一个叫做IMAGE_FILE_HEADER的结构,如下;下面我分别介绍一
下。
typedef struct _IMAGE_FILE_HEADER {
中只有大约100个字节的代码,只输出一个诸如“this program needs windows NT ”之类的
信息。
你可以通过一个叫做IMAGE_DOS_HEADER的结构来识别一个合法的DOS头。这个结构的头两
个字节一定是“MZ”(#define IMAGE_DOS_SIGNATURE "MZ")。怎么才能找到PE开始的标志呢

WindowsPE文件格式

WindowsPE文件格式

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文件格式(内容详细)
EXE文件的格式
简介
在DOS环境下有四种基本的可执行文件格式
批处理文件,以.BAT结尾的文件
设备驱动文件,是以.SYS结尾的文件,如CONFIG.SYS
COM文件,是以.COM结尾的纯代码文件
• 没有文件头部分,缺省情况下总是从0x100H处开始执行, 没有重定位项,所有代码和数据必须控制在64K以内
在Win32位平台可执行文件格式:可移植的可执行文件 (Portable Executable File)格式,即PE格式。MZ文件头 之后是一个以“PE”开始的文件头
安装在硬盘上的程序没运行-静态 加载到内存-动态
EXE文件的格式
MZ文件格式-Mark Zbikowski
.EXE文件由三部分构成:文件头、重定位表和二进制代码 允许代码、数据、堆栈分别处于不同的段,每一段都可以是64KB.
EXE文件的格式
PE文件格式
一般来说,病毒往往先于HOST程序获得控制权。运行 Win32病毒的一般流程示意如下:
①用户点击或系统自动运行HOST程序; ②装载HOST程序到内存;
③通过PE文件中的AddressOfEntryPoint+ImageBase,
定位第一条语句的位置(程序入口); ④从第一条语句开始执行(这时执行的其实是病毒代码); ⑤病毒主体代码执行完毕,将控制权交给HOST程序原来的
病毒通过“MZ”、“PE”这两个标志,初步判断当前程序 是否是目标文件——PE文件。如果要精确校验指定文件是 否为一有效PE文件,则可以检验PE文件格式里的各个数 据结构,或者仅校验一些关键数据结构。大多数情况下, 没有必要校验文件里的每一个数据结构,只要一些关键数 据结构有效,就可以认为是有效的PE文件
PE的意思就是Portable Executable(可移植、可执 行),它是Win32可执行文件的标准格式

pe文件

pe文件
文件层次解释
A.
谢谢观看
Hale Waihona Puke pe文件可移植的可执行的文件
01 定义
03 PE首部
目录
02 相关概念 04 文件格式
PE文件的全称是Portable Executable,意为可移植的可执行的文件,常见的EXE、DLL、OCX、SYS、COM都 是PE文件,PE文件是微软Windows操作系统上的程序文件(可能是间接被执行,如DLL)
定义
一个操作系统的可执行文件格式在很多方面是这个系统的一面镜子。虽然学习一个可执行文件格式通常不是 一个程序员的首要任务,但是你可以从这其中学到大量的知识。在这篇文章中,我会给出 Microsoft的所有基于 win32系统(如winnt,win9x)的可移植可执行(PE)文件格式的详细介绍。在可预知的未来,包括Windows2000, PE文件格式在 MicroSoft的操作系统中扮演一个重要的角色。如果你在使用 Win32或 Winnt,那么你已经在使 用 PE文件了。甚至你只是在 Windows3.1下使用 Visual C++编程,你使用的仍然是 PE文件(Visual C++的 32位MS-DOS扩展组件用这个格式)。简而言之,PE格式已经普遍应用,并且在不短的将来仍是不可避免的。
和微软的其它可执行格式一样,你可以通过查找它的起始偏移来得到真实首部,这个偏移放在DOS残留首部 中。WINNT.H头文件包含了DOS残留程序的数据结构定义,使得很容易找到PE首部的起始位置。e_lfanew域是PE 真实首部的偏移。为了得到PE首部在内存中的指针,只需要把这个值加到映像的基址上即可。
线程局部变量
我最后不会让你盯住无穷无尽的十六进制Dump,也不会详细讨论页面的每一个单独的位的重要性。代替的, 我会向你介绍包含在 PE文件中的概念,并且将他们和你每天都遇到的东西联系起来。比如,线程局部变量的概 念,如下所述:

《计算机病毒》实验二:PE文件格式实验

《计算机病毒》实验二:PE文件格式实验
实验报告
题目:PE文件格式实验
姓名:王宇航
学号:09283020
实验环境:Visual Studio 6.0
操作系统:windows系统XP(√)2003()其他:
软件:Visual Studio 6.0
硬件环境:CPU主频(3.00 GHz)内存(0.99GB)
实验内容:
1、了解PE文件格式及其运行原理。
实验过程:
1.使用编译环境大开源代码工程,运行编译生成可执行文件winpe.exe
2.运行winpe.exe,并打开任一exe文件,选择不同的菜单,可以查看到exe文件的内部结构。
结果和总结:
1.PE(portable executable,可移植的可执行文件)文件格式,是可执行的二进制文件的格式。在一个PE文件的开始处,有一个MS-DOS可执行体,它使任何PE文件都是一个有效的MS-DOS可执行文件,在DOS-根之后是一明该二进制文件将运行在何种机器之上、分几个区段、链接的时间、是可执行文件还是DLL等。
3.之后是可选头,它会告诉我们该二进制文件怎样被载入的更多信息:开始的地址、保留的堆栈数、数据段的大小等等。
4.可选头的一个有趣的部分是尾部的“数据目录”数组;这些目录包含许多指向各“节”数据的指针。跟在各种头后面我们就发现各个“节”了,它们都由“节头”引导。

PE文件格式详解(上)

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文件格式详解

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文件结构

PE文件结构
2.2.2 PE文件内存映射 在Windows系统下,当一个PE应用程序运行时,这个PE文件在磁盘中的数据结构布局和内存中的数据结构布局是一致的。系 统在载入一个可执行程序时,首先是Windows装载器(又称PE装载器)把磁盘中的文件映射到进程的地址空间,它遍历PE文 件并决定文件的哪一部分被映射。其方式是将文件较高的偏移位置映射到较高的内存地址中。磁盘文件一旦被装入内存中,其 某项的偏移地址可能与原始的偏移地址有所不同,但所表现的是一种从磁盘文件偏移到内存偏移的转换,如图2.2所示。
PE文件结构总体层次分布
· DOS MZ Header
所有 PE文件(甚至32位的DLLs)必须以简单的DOS MZ header开始,它是一个IMAGE_DOS_HEADER结构。有了它,一 旦程序在DOS下执行,DOS就能识别出这是有效的执行体,然后运行紧随MZ Header之后的DOS Stub。
PE文件格式要用到RVA,主要是为了减少PE装载器的负担。因为每个模块都有可能被重载到任何虚拟地址空间,如果让PE 装载器修正每个重定位项,这肯定是个梦魇。相反,如果所有重定位项都使用RVA,那么PE装载器就不必操心那些东西了, 即 它只要将整个模块重定位到新的起始VA。这就像相对路径和绝对路径的概念:RVA类似相对路径,VA就像绝对路径。
2.2.1 PE文件结构布局 找到文件中某一结构信息有两种定位方法。第一种是通过链表方法,对于这种方法,数据在文件的存放位置比较自由。第二种 方法是采用紧凑或固定位置存放,这种方法要求数据结构大小固定,它在文件中的存放位置也相对固定。在PE文件结构中同 时采用以上两种方法。
因为在PE文件头中的每个数据结构大小是固定的,因此能够编写计算程序来确定某一个PE文件中的某个参数值。在编写程序 时,所用到的数据结构定义,包括数据结构中变量类型、变量位置和变量数组大小都必须采用Windows提供的原型。图2.1所 示的PE文件结构的总体层次分布如下:

PE文件格式

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文件介绍(1)

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⽂件格式学习感觉这博客写起来和抄书差不多。

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文件格式标准

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文件中包含资源,需要解析资源表,并提取所需的资源。

PE文件格式实验报告

PE文件格式实验报告
五、指导教师评语
成绩
批阅人
日期
1.利用LoadPE软件查询PE文件格式信息。
我们使用LoadPE软件打开3-2.exe文件,位于“实验三”文件夹目录下。
如图所示:
在以上界面中,我们可以看见入口点的值。
点击Sections按钮,可以查询exe文件的区段信息。
点击Directories按钮,可以查询数据目录表信息。
2.使用PE Explorer软件查询PE文件格式信息。
3.利用加壳软件进行加壳处理。
我们这里使用的是ASPACK.exe软件。
下载该软件,打开运行。载入win-1.exe文件,即可进行加壳处理。
将原文件和加壳后处理的提交至网站,分析结果如下:
原文件:
加壳之后的文件:
四、实验小结(包括问题和解决方法、心得体会、意见与建议等)
本次实验是对PE文件格式进行分析,对PE文件有了一个大致的了解,如什么是PE文件的文件头,什么是区段,什么是数据目录。由于现阶段大都的病毒都是PE病毒,所以了解它们可以更好地知道PE病毒是如何感染PE文件的。不仅如此,对PE文件的修改、加壳等操作也证实了PE文件并不是不可编辑的,也可以让我们更好地了解PE文件的内部结构。
打开PE Explorer软件,载入win-1.exe文件,该文件位于“实验三”目录下。
默认查询文件头信息,这里我们可以查询到入口点等信息。
点击“数据目录”按钮,可以查看数据目录信息。
点击“区段头”,可以查询区段信息。
点击“资源”按钮,可以查询资源信息。
点击“多重保存”,可以提取资源信息。
点击“资源编辑”按钮,可以进入编辑状态。选择需要替换的资源,即可成功替换。这里需要注意的是资源图片的大小必须与之前一致。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PE文件格式详解(一)――基础知识什么是PE文件格式:我们知道所有文件都是一些连续(当然实际存储在磁盘上的时候不一定是连续的)的数据组织起来的,不同类型的文件肯定组织形式也各不相同;PE文件格式便是一种文件组织形式,它是32位Wind ow系统中的可执行文件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文件的时候有W indow的加载器负责把EXE文件加载到线性地址空间,加载的时候便是根据上一节中说到的PE文件格式中的哪些重要信息。

然后生成一个进程,如果进程中涉及到多个线程还要生成一个主线程;此后进程便开始运行;这里面涉及的东西很多,包括:PE文件格式的内容;内存管理(CPU内存管理的硬件环境以及在此基础上的OS内存管理方式);模块,进程,线程的知识;只有把这些都弄清楚之后才能比较清楚的了解这整个过程。

下面就让我们先来学习PE文件格式吧。

PE文件的总体结构:下图便是PE文件的一个总体结构:注意,图2是在图1的基础上进一步细化了,不过图2的顺序是从下向上代表文件的从头到尾的顺序。

DOS MZ HeaderDOS stubPE headerSection tableSection 1Section 2Section ...Section n图一图2我们的EXE文件在磁盘上就是按照上面的格式顺序存储的,当运行的时候它就很容易被加载器加载到线性地址空间;但是在线性空间中和在磁盘上不同,在线性空间中各个部分不一定是占据连续的线性地址空间。

下面对PE文件格式的介绍就按照上图中对从头到尾对每个部分进行介绍。

好的,今天刚去医院回来有些累了,就先写到这儿吧。

嗯,不行,还有几个重要而又基础的概念需要在这儿先澄清一下,否则后面就会出乱子了。

几个重要的基本概念:1)节:PE文件的真正内容划分成块,称之为sections(节)。

每节是一块拥有共同属性的数据,比如代码/数据、读/写等。

我们可以把PE文件想象成一逻辑磁盘,PE header 是磁盘的boot扇区,而se ctions就是各种文件,每种文件自然就有不同属性如只读、系统、隐藏、文档等等。

值得我们注意的是---- 节的划分是基于各组数据的共同属性: 而不是逻辑概念。

重要的不是数据/代码是如何使用的,如果PE文件中的数据/代码拥有相同属性,它们就能被归入同一节中。

不必关心节中类似于"data", "code"或其他的逻辑概念: 如果数据和代码拥有相同属性,它们就可以被归入同一个节中。

(节名称仅仅是个区别不同节的符号而已,类似"data", "code"的命名只为了便于识别,惟有节的属性设置决定了节的特性和功能)如果某块数据想付为只读属性,就可以将该块数据放入置为只读的节中,当PE装载器映射节内容时,它会检查相关节属性并置对应内存块为指定属性。

下面是常见的节名及作用:节名作用.arch 最初的构建信息(Alpha Architecture Information).bss 未经初始化的数据.CRT C运行期只读数据.data 已经初始化的数据.debug 调试信息.didata 延迟输入文件名表.edata 导出文件名表.idata 导入文件名表.pdata 异常信息(Exception Information).rdata 只读的初始化数据.reloc 重定位表信息.rsrc 资源.text .exe或.dll文件的可执行代码.tls 线程的本地存储器.xdata 异常处理表注意:上面已经说过了“节的划分是基于各组数据的共同属性: 而不是逻辑概念。

重要的不是数据/代码是如何使用的,如果PE文件中的数据/代码拥有相同属性,它们就能被归入同一节中”所以上面表中列出的节并不一定单独成节,也就是说即使存在上面表中的某一节,在节表(section table)(后面会讲到)中也不一定就有于之对应的项,因为它可能和别的具有共同属性的节共同组成了一节。

比如 .idata 可以和 .text 合成一节而命名为 .text,而在节表中只有和 .text 对应的项。

这也就是后面的optional header中数据目录(DataDirectory)存在的作用,因为很多有用的节被合并了,因此加载器无法通过节表来定位它们,所以这就是数据目录(DataDirec tory)发挥作用的时候了(具体作用后面会讲到)。

2)虚拟地址:虚拟地址即程序中使用的地址,也就是从程序员的角度看到的地址,有时也叫逻辑地址;通常使用段地址:偏移量的形式表示,不过在32位系统中使用的是平坦(Flat)内存模式(1.它的数据段和代码段是32位的,所以能访问4G的内存。

2.在“平坦内存模式”,cs、ds、es的值不需你操心,也不必知道它们的值是多少,它们的值是相等的),所以我们可以不用管段地址,只考虑32位的偏移量即可,认为32位的偏移量就是虚拟地址,这样一来程序员就可以认为他是在一个段中写程序,这个段的大小是2^32 = 4G的容量,当然这部分地址空间是程序和OS共享的,程序员可以利用的大约有2G(具体可以参考Win98和WinNT的内存布局);所以我们平时在写程序申请内存的时候实际上申请的就是这2G的线性地基空间,由于所有的4G线性地址空间都被OS作为资源来管理(这4G的线性地址空间是通过页表来表现出来的,OS分配线性地址空间給进程也就是分配相应的页表給进程),所以我们无论用什么方式使用内存最终都是转换为OS为我们分配线性地址空间,至于分配的线性地址空间又如何被映射为真正的物理内存完全是有OS负责的(更详细资料参见“Windows 内存管理”),程序员不必操心。

3)相对虚拟地址:「相对虚拟地址(Relative Virtual Address,R VA)」即相对于上面的基地址的偏移量。

PE 文件中的许多字段内容都是以RVA 表示,一个RVA 是某一资料项的offset(偏移)值-- 从文件被映像进来的起点(即基地址)算起。

举个例子,我们说Win dows加载器把一个PE 文件映像到虚拟地址空间的0x400000 处,如果此image 有一个表格开始于0x401464,那么这个表格的RVA 就是0x1464:虚拟地址0x401464 - 基地址0x400000 = RVA 0x1464只要把RVA 加上基地址,RVA 就可以被转换为一个有用的指针。

在PE文件中大多数地址多是RVA 而 RVA只有当PE文件被PE装载器装入内存后才有意义。

如果我们直接将文件映射到内存而不是通过PE装载器载入,那么我们就不能直接使用那些RVA。

必须先将那些RVA转换成文件偏移量,RVAToOffset函数就起到这个作用。

4)基地址:「基地址(base address)」是一个重要概念,用来描述被映像到内存中的EXE 或DLL 的起始地址。

为了方便,Windows NT 和Windows 95 都以模块的基地址做为模块的instance handle (HINSTANCE,实例句柄)。

Windows95加载器把一个PE 文件映像到虚拟地址空间的0x400000 处;而WindowNT加载器把一个PE 文件映像到虚拟地址空间的0x10000 处。

5)文件偏移量:文件中的地址与内存中表示不同,它是用偏移量(F ile offset)来表示的,文件中的第一个字节的偏移量是0,后面的字节依次递增。

在SoftICE和W32Dasm下显示的地址值是内存线性地址,或称之为虚拟地址(Virual Address,VA)。

而十六进制工具里,如:Hiew、Hex Workshop等显示的地址就是文件地址,称之为偏移量(File offset) 或物理地址(RAW offset,注意这个物理地址不是内存寻址中说到的物理地址 )。

6)模块:「模块(module)」一词表示一个EXE 或DLL 被加载内存后的程序代码、数据和资源(就是被加载到内存后的EXE或DLL整体,包括代码、数据和资源,而不是说代码、数据、资源分别都是模块)。

除了程序代码和数据是你的程序直接使用的之外,模块还内含一些支持性数据,Windows 用它来决定程序代码和数据放在内存的什么地方,在Win32,这些信息保留在PE头部(即图1中的PE header,实际上它是一个IMAGE_NT_HEADERS 结构)中。

7)逻辑地址:见“虚拟地址”8)线性地址:线性地址是由虚拟地址(逻辑地址)转换来的,转换需要CPU和OS共同合作来完成;里面涉及到全局描述符表GDT和局部描述符表LDT;不过由于32位的Window系统采用flat内存模式,所以我们可以认为虚拟地址就是线性地址,即我们可以认为逻辑地址中的32位偏移量就是线性地址。

相关文档
最新文档