PE文件格式
- 介绍
- Windows系统下使用的可执行文件格式
- Unix : COFF
- 32位:PE32 ; 64位:PE32+/PE+
- PE文件格式
- 文件种类:
- 可执行系列:EXE、SCR
- 库系列:DLL、OCX、CPL、DRV
- 驱动程序系列:SYS、VXD
- 对象文件系列:OBJ(不可执行)
- 基本结构:
- PE头:DOS头到节区头
- PE体:头下节区
- 文件中使用偏移(offset),内存中使用VA来表示位置
- 文件内容:代码,数据,资源节
- VA & RVA
- VA:进程虚拟内存的绝对地址
- RVA:相对虚拟地址,从某个基准位置开始的相对地址
- RVA + ImageBase = VA
- 文件种类:
- PE头
- DOS头
- 结构体:40字节
- DOS头
-
-
-
- e_magic
-
-
Dos签名("MZ")
-
-
-
- e_lfanew
-
-
指示NT头的偏移
-
- Dos存根(可选)代码+数据
- NT头
- 结构体
-
-
-
- 签名
-
-
50450000h("PE"00)
-
-
-
- 文件头
-
-
-
-
-
-
- Machine
-
-
-
每个cpu都拥有唯一的码
-
-
-
-
- NumberOfSections
-
-
-
指出文件中存在的节区数量( > 0)
-
-
-
-
- SizeOfOptionalHeader
-
-
-
用来指出NT头最后一个成员IMAGE_OPTIONAL_HEADER32的长度
-
-
-
-
- Characteristics
-
-
-
勇于表示文件的属:是否可运行状态,是否DLL文件等
-
-
-
-
- TimeDateStam
-
-
-
记录编译器创建此文件的时间
-
-
-
- 可选头
-
-
-
-
-
-
- Magic
-
-
-
IMAGE_OPTIONAL_HEADER32: 10B IMAGE_OPTIONAL_HEADER64: 20B
-
-
-
-
- AddressOfEntryPoint
-
-
-
持有EP的RVA值,指出该程序最先执行的代码起始地址
-
-
-
-
- ImageBase
-
-
-
指出文件有限装入地址 进程虚拟内存范围0~FFFFFFFF SYS:80000000~FFFFFFFF DLL:10000000 执行PE文件时,PE装载器先创建进程,再将文件载入内存,然后EIP = ImageBase + AddressOfEntryPoint
-
-
-
-
- SectionAlignment,FileAlignment
-
-
-
分别制定节区在内存中的最小单位和节区在磁盘文件中的最小单位
-
-
-
-
- SizeOfImage
-
-
-
指定了PE Image在虚拟内存中所占的空间大小
-
-
-
-
- SizeOfHeader
-
-
-
指出整个PE头的大小,必须是FileAlignment的整数倍
-
-
-
-
- Subsystem
-
-
-
区分系统驱动文件(*.sys)与普通可执行文件( *.exe / *.dll ) 1 Driver文件 系统驱动 2 GUI文件 窗口应用程序 3 CUI文件 控制台应用程序
-
-
-
-
- NumberOfRvaAndSizes
-
-
-
指定DataDirectory(IMAGE_OPTIONAL_HEADER32的最后一个成员)数组的个数
-
-
-
-
- DataDirectory
-
-
-
是由IMAGE_DATA_DIRECTORY组成的数组
-
- 节区头
- IMAGE_SECTION_HEADER
- 节区头
-
-
- VirtualSize
-
内存中节区所占的大小
-
-
- VirtualAddree
-
内存中节区的起始地址
-
-
- SizeOfRawData
-
磁盘文件中节区所占大小
-
-
- PointerToRawData
-
磁盘文件中节区起始位置
-
-
- Charactoristic
-
节区属性
- RVA to RWA
PE文件加载到内存时,每个街区都要能准确完成内存地址与文件偏移间的映射
-
- 查找RVA所在节区
- 使用简单的公式计算文件偏移
RAW - PointerToRawData = Rva - VirtualAddress RAW = RVA - VirtualAddress + PointToRawData
- IAT
导入地址表:保存的内容与Windows的核心进程、内存、DLL结构等有关
-
- DLL
动态链接库
-
-
- 显式链接
-
程序使用DLL时加载,使用完毕后释放内存
-
-
- 隐式链接
-
程序开始时及一同加载DLL,程序终止时在释放占用的内存
-
- IMAGE_IMPORT_DESCRIPTOR
记录PE文件要导入那些库文件
-
-
- OriginalFirstThunk
-
INT的地址(RVA),值为IMAGE_BY_NAME结构体指针
-
-
- Name
-
库名称字符串地址(RVA)
-
-
- FirstThunk
-
IAT的地址
-
-
- INT与IAT
-
大小应相同,都是四个字节的长整型数组,以NULL结束
- EAT
是一种核心机制,使不同的应用程序可以调用库文件中提供的函数,PE中有且仅有一个用来说明库EAT的特定结构体
-
- IMAGE_EXPORT_DIRECTORY
-
- NumberOfFunctions
实际Export函数的个数
-
- NumberOfNames
ExportHanshu中具名的函数个数
-
- AddressOfFunctions
Export函数地址数组
-
- AddressOfNames
函数名称地址数组
-
- AddressOfNameOrdinals
Ordinal地址数组