PE文件是Windows系统下可执行文件的总称,英文全称 Portable Executable 可移植的可执行文件,常见的有exe、dll、sys、com、ocx
对于学习反(木马、免杀、病毒、外挂、内核),了解PE文件结构是非常有必要且非常非常重要的!
PE结构包括:
- MS-DOS头
- 标准PE头
- 扩展PE头
- 数据目录
- 节表
代码段(.text 或 .code): 可读 可执行 不可写
数据段(.data 或 .rdata 或.bss): 可读 可写 不可执行
未初始化数据段(.bss):可读 可写 不可执行
资源段(.rsrc): 可读 不可执行 不可写
导入表(.idata) : 简称 IAT 表 Import Address Table
导出表(.edata): 简称 EAT 表 Export Address Table
IMAGE_DOS_HEADER (长度不定)
MZ标记: 4D5A EXE程序的标志 在DOS头里 4字节
DOS_STUB (长度不定)
DOS STUB : 在dos系统下,会执行 DOS Stub 中的内容,不会出现不可预料的错误
IMAGE_NT_HEADERS (f8h)
PE Signature: PE标记 MZ偏移3C的位置 是e_lfanew 指向PE标记 PE头相对于文件的偏移地址 4字节
IMAGE_FILE_HEADER PE文件头 (14h)
Machine : PE标记后2个字节是Machine 14C代表32位CPU 8664代表64位CPU 2字节
NumberOfSections: 代表区段数量 代码段 数据段 资源段 2字节
Timestamp: 时间戳,文件创建时间, 表示从1970年1月1日 00:00:00 到文件创建时间的秒数 4字节
PointerOfSymbolTable: 用于调试 4字节
NumberOfSymbols: 用于调试 4字节
SizeOfOptionalHeader: 可选头大小 e0h 2字节
Characteristics: 文件信息标志 如dll/exe 2字节
IMAGE_OPTIONAL_HEADER 可选PE头 (e0h)
Magic :代表文件的格式 010b是32位应用程序 020b是64位应用程序 107是系统的ROM文件 2字节
Major LinkerVersion : 连接器首版本号 1字节
Minor LinkerVersion : 连接器次版本号 1字节
SizeOfCode : 代码块大小 4字节 (512为一个磁盘扇区)
SizeOfInitializedData : 已初始化数据块大小 4字节 也就是.data
SizeOfUninitializedData : 未初始化数据块大小 4字节 也就是.data
AddressOfEntryPoint : 程序执行入口(OEP) 4字节 RVA(相对偏移)(相对虚拟内存地址)
BaseOfCode: 代码块起始RVA 4字节 表示代码段起始RVA
BaseOfData : 数据块起始RVA 4字节 表示数据段的起始RVA
ImageBase: 基址 4字节 入口点
EXE,DLL文件被装载到用户内存的0~7FFFFFFF中,SYS文件被加载到80000000~FFFFFFFF中
执行PE文件的时候。PE装载器先创建进程,再将文件载入内存,然后把EIP寄存器的值设置为ImageBase+AddressOfEntryPoint
BaseofCode + ImageBase可以得到代码段的起始地址
BaseOfData + ImageBase可以得到数据段段的起始地址
SectionAlignment: 块对齐值 4字节
FileAlignment : 文件对齐值 4字节
Major Operating System Version : 操作系统首版本号 2字节
Minor Operating SystemVersion: 操作系统次版本号 2字节
Major Image Version:用户程序首版本号 2字节
Minor Image Version:用户程序次版本号 2字节
MajorSub System Version :子系统首版本号 2字节
MinorSub System Version :子系统次版本号 2字节
Win32 Version Value : 32位系统版本号值 4字节
SizeOfImage : 整个程序在内存中占用的空间(PE映像尺寸)映像大小 4字节
SizeOfHeaders : 块前头部大小 4字节 所有头(头的结构体大小)+节表的大小
Checksum : 校验和 4字节 对于驱动程序,可能会使用
SubSystem : 程序运行所需子系统 2字节 重要
DICharacteristics:当文件为dll文件时使用 2字节
SizeOf StackReserve :保留栈大小 4字节
SizeOf StackCommit :使用栈大小 4字节
SizeOf HapReserve : 保留堆大小 4字节
SizeOf HeapCommit : 使用堆大小 4字节
LoaderFlags : 设置自动调用断点或调试器 4字节 与调试有关
NumberOfRvaAndSizes: Rva的大小的数量 4字节 下面的成员,数据目录结构的项目数量
DataDirectory : Image_Data Directorys 80字节 数据目录,默认16个,16是宏,这里方便直接写成16
SECTION TABLE (长度不定)
IMAGE_SECTION_HEADER (28h)
Name :块名 8字节
VirtualSize: 内存中快大小 4字节
VirtusalAddress: 内存中块RVA值 4字节
SizeOfRawData:文件中块大小 4字节
PointerToRawData:文件中块偏移 4字节
PointerToRelocations: OBJ文件使用 4字节
PointerToLineNumbers: OBJ文件使用 4字节
NumberOfRelocations : OBJ文件使用 2字节
NumberOfLineNumbers : OBJ文件使用 2字节
Characteristics : 块属性
- RVA 相对虚拟地址,映像文件在虚拟内存中相对于加载基址的偏移。
- VA 虚拟地址,映像文件在虚拟内存中的地址。
- FOA 文件偏移地址,映像文件在磁盘文件中相对于文件开头的偏移。
三个地址概念:
- VA:( Virtual Address )虚拟内存地址,范围00000000h - 0FFFFFFFh,就是进程的基地址 + RVA相对虚拟内存地址
- RVA:相对虚拟内存地址,RVA是相对某个模块而存在的
- FOA:文件偏移地址,文件头的偏移地址
VA = ImageBase + RVA
RVA = VA - ImageBase
PE头部分用于宏观上记录文件的一些信息,运行平台,大小,创建日期,属性等
节表部分用于对各中类型的数据进行定义分段
节数据就是文件的数据部分,实际上我们编写程序的过程中就是对该部分的数据进行编写。
而其他的部分则是由编译器依照我们编写的部分进行相应的填写而得到
DOS头结构
在winnt.h里已经定义了,在使用的时候包含windows.h头文件即可
#include<Windows.h>
DOS头的结构体
typedef struct _IMAGE_DOS_HEADER { // DOS-MZ文件头
WORD e_magic;
PE文件是Windows系统下可执行文件的总称,英文全称 Portable Executable 可移植的可执行文件,常见的有exe、dll、sys、com、ocx
对于学习反(木马、免杀、病毒、外挂、内核),了解PE文件结构是非常有必要且非常非常重要的!
PE结构包括:
- MS-DOS头
- 标准PE头
- 扩展PE头
- 数据目录
- 节表
代码段(.text 或 .code): 可读 可执行 不可写
数据段(.data 或 .rdata 或.bss): 可读 可写 不可执行
未初始化数据段(.bss):可读 可写 不可执行
资源段(.rsrc): 可读 不可执行 不可写
导入表(.idata) : 简称 IAT 表 Import Address Table
导出表(.edata): 简称 EAT 表 Export Address Table
IMAGE_DOS_HEADER (长度不定)
MZ标记: 4D5A EXE程序的标志 在DOS头里 4字节
DOS_STUB (长度不定)
DOS STUB : 在dos系统下,会执行 DOS Stub 中的内容,不会出现不可预料的错误
IMAGE_NT_HEADERS (f8h)
PE Signature: PE标记 MZ偏移3C的位置 是e_lfanew 指向PE标记 PE头相对于文件的偏移地址 4字节
IMAGE_FILE_HEADER PE文件头 (14h)
Machine : PE标记后2个字节是Machine 14C代表32位CPU 8664代表64位CPU 2字节
NumberOfSections: 代表区段数量 代码段 数据段 资源段 2字节
Timestamp: 时间戳,文件创建时间, 表示从1970年1月1日 00:00:00 到文件创建时间的秒数 4字节
PointerOfSymbolTable: 用于调试 4字节
NumberOfSymbols: 用于调试 4字节
SizeOfOptionalHeader: 可选头大小 e0h 2字节
Characteristics: 文件信息标志 如dll/exe 2字节
IMAGE_OPTIONAL_HEADER 可选PE头 (e0h)
Magic :代表文件的格式 010b是32位应用程序 020b是64位应用程序 107是系统的ROM文件 2字节
Major LinkerVersion : 连接器首版本号 1字节
Minor LinkerVersion : 连接器次版本号 1字节
SizeOfCode : 代码块大小 4字节 (512为一个磁盘扇区)
SizeOfInitializedData : 已初始化数据块大小 4字节 也就是.data
SizeOfUninitializedData : 未初始化数据块大小 4字节 也就是.data
AddressOfEntryPoint : 程序执行入口(OEP) 4字节 RVA(相对偏移)(相对虚拟内存地址)
BaseOfCode: 代码块起始RVA 4字节 表示代码段起始RVA
BaseOfData : 数据块起始RVA 4字节 表示数据段的起始RVA
ImageBase: 基址 4字节 入口点
EXE,DLL文件被装载到用户内存的0~7FFFFFFF中,SYS文件被加载到80000000~FFFFFFFF中
执行PE文件的时候。PE装载器先创建进程,再将文件载入内存,然后把EIP寄存器的值设置为ImageBase+AddressOfEntryPoint
BaseofCode + ImageBase可以得到代码段的起始地址
BaseOfData + ImageBase可以得到数据段段的起始地址
SectionAlignment: 块对齐值 4字节
FileAlignment : 文件对齐值 4字节
Major Operating System Version : 操作系统首版本号 2字节
Minor Operating SystemVersion: 操作系统次版本号 2字节
Major Image Version:用户程序首版本号 2字节
Minor Image Version:用户程序次版本号 2字节
MajorSub System Version :子系统首版本号 2字节
MinorSub System Version :子系统次版本号 2字节
Win32 Version Value : 32位系统版本号值 4字节
SizeOfImage : 整个程序在内存中占用的空间(PE映像尺寸)映像大小 4字节
SizeOfHeaders : 块前头部大小 4字节 所有头(头的结构体大小)+节表的大小
Checksum : 校验和 4字节 对于驱动程序,可能会使用
SubSystem : 程序运行所需子系统 2字节 重要
DICharacteristics:当文件为dll文件时使用 2字节
SizeOf StackReserve :保留栈大小 4字节
SizeOf StackCommit :使用栈大小 4字节
SizeOf HapReserve : 保留堆大小 4字节
SizeOf HeapCommit : 使用堆大小 4字节
LoaderFlags : 设置自动调用断点或调试器 4字节 与调试有关
NumberOfRvaAndSizes: Rva的大小的数量 4字节 下面的成员,数据目录结构的项目数量
DataDirectory : Image_Data Directorys 80字节 数据目录,默认16个,16是宏,这里方便直接写成16
SECTION TABLE (长度不定)
IMAGE_SECTION_HEADER (28h)
Name :块名 8字节
VirtualSize: 内存中快大小 4字节
VirtusalAddress: 内存中块RVA值 4字节
SizeOfRawData:文件中块大小 4字节
PointerToRawData:文件中块偏移 4字节
PointerToRelocations: OBJ文件使用 4字节
PointerToLineNumbers: OBJ文件使用 4字节
NumberOfRelocations : OBJ文件使用 2字节
NumberOfLineNumbers : OBJ文件使用 2字节
Characteristics : 块属性
- RVA 相对虚拟地址,映像文件在虚拟内存中相对于加载基址的偏移。
- VA 虚拟地址,映像文件在虚拟内存中的地址。
- FOA 文件偏移地址,映像文件在磁盘文件中相对于文件开头的偏移。
三个地址概念:
- VA:( Virtual Address )虚拟内存地址,范围00000000h - 0FFFFFFFh,就是进程的基地址 + RVA相对虚拟内存地址
- RVA:相对虚拟内存地址,RVA是相对某个模块而存在的
- FOA:文件偏移地址,文件头的偏移地址
VA = ImageBase + RVA
RVA = VA - ImageBase
PE头部分用于宏观上记录文件的一些信息,运行平台,大小,创建日期,属性等
节表部分用于对各中类型的数据进行定义分段
节数据就是文件的数据部分,实际上我们编写程序的过程中就是对该部分的数据进行编写。
而其他的部分则是由编译器依照我们编写的部分进行相应的填写而得到
DOS头结构
在winnt.h里已经定义了,在使用的时候包含windows.h头文件即可
#include<Windows.h>
DOS头的结构体
typedef struct _IMAGE_DOS_HEADER { // DOS-MZ文件头
WORD e_magic;