-
-
[原创]PE 文件结构(一)
-
发表于: 2020-10-20 00:21 4049
-
新人学习逆向,PE结构第一弹
PE 文件结构(一)
1.PE基本概念
基地址(ImageBase)
当PE文件通过Windows载入内存后,内存中的版本称为模块(Module)。映射文件的起始地址称为基地址(ImageBase)。
虚拟地址(Vitual Address,VA)
PE文件被系统加载器映射到内存中,每个程序都有自己的虚拟空间,这个虚拟空间的内存地址称为虚拟地址(Vitual Address,VA)
相对虚拟地址(Relative Vitual Address,RVA)
假设一个EXE文件从400000h出载入,它的代码区块开始于401000h处,代码区块的RVA计算方式如如下:
目标地址401000h - 载入地址400000h = RVA 1000h
将一个RVA转换成真实的地址,如下:
虚拟地址(VA)= 基地址(ImageBase)+相对虚拟地址(RVA)
文件偏移地址
当PE问津在磁盘中时,某个数据的位置相对于文件头的偏移量称为文件偏移地址(File Offset)或物理地址(RAW Offset)
2.MS-DOS头部
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | struct _IMAGE_DOS_HEADER { * 0x00 WORD e_magic; / / DOS可执行文件标记 "MZ" (MS - DOS的创建者之一), 5A4Dh 0x02 WORD e_cblp; 0x04 WORD e_cp; 0x06 WORD e_crlc; 0x08 WORD e_cparhdr; 0x0a WORD e_minalloc; 0x0c WORD e_maxalloc; 0x0e WORD e_ss; 0x10 WORD e_sp; 0x12 WORD e_csum; 0x14 WORD e_ip; / / DOS代码入口IP 0x16 WORD e_cs; / / DOS代码入口IP 0x18 WORD e_lfarlc; 0x1a WORD e_ovno; 0x1c WORD e_res[ 4 ]; 0x24 WORD e_oemid; 0x26 WORD e_oeminfo; 0x28 WORD e_res2[ 10 ]; * 0x3c DWORD e_lfanew; / / 指向PE文件头 "PE" , 0 , 0 。文件头的相对偏移(RVA) }; |
3.PE文件头
紧跟着DOS头的是PE文件头(PE Header)。PE Header是PE相关结构NT映像头(_IMAGE_NT_HEADERS)的简称。PE装载器从_IMAGE_DOS_HEADERS的 e_lfanew字段里找到PEHeader的起始偏移量,用其加上基址,得到PE文件头的指针。
PNTHeader = ImageBase + dosHeader->e_lfanew
- _IMAGE_NT_HEADERS
1 2 3 4 5 | struct _IMAGE_NT_HEADERS { 0x00 DWORD Signature; / / PE文件标识 0x04 _IMAGE_FILE_HEADER FileHeader; 0x18 _IMAGE_OPTIONAL_HEADER OptionalHeader; }; |
_IMAGE_FILE_HEADER
_IMAGE_FILE_HEADER指出了 _IMAGE_OPTIONAL_HEADER的大小
1 2 3 4 5 6 7 8 9 | struct _IMAGE_FILE_HEADER { / / 映像文件头 0x00 WORD Machine; / / 运行平台 0x02 WORD NumberOfSections; / / 文件的区块数 0x04 DWORD TimeDateStamp; / / 文件创建日期和时间 0x08 DWORD PointerToSymbolTable; / / 指向符号表(用于调试) 0x0c DWORD NumberOfSymbols; / / 符号表中符号的个数(用于调试) 0x10 WORD SizeOfOptionalHeader; / / _IMAGE_OPTIONAL_HEADER结构的大小 0x12 WORD Characteristics; / / 文件属性 }; |
_IMAGE_OPTIONAL_HEADER (可选映像头)
123456789101112131415161718192021222324252627282930313233struct _IMAGE_OPTIONAL_HEADER {
0x00
WORD Magic;
/
/
标志字
0x02
BYTE MajorLinkerVersion;
0x03
BYTE MinorLinkerVersion;
0x04
DWORD SizeOfCode;
/
/
所有含有代码的区块的大小
0x08
DWORD SizeOfInitializedData;
/
/
所有初始化数据区块的大小
0x0c
DWORD SizeOfUninitializedData;
0x10
DWORD AddressOfEntryPoint;
/
/
程序执行入口RVA
0x14
DWORD BaseOfCode;
/
/
代码区块起始RVA
0x18
DWORD BaseOfData;
/
/
数据区块起始RVA
0x1c
DWORD ImageBase;
0x20
DWORD SectionAlignment;
/
/
内存中区块的对齐值
0x24
DWORD FileAlignment;
/
/
文件区块的对齐值
0x28
WORD MajorOperatingSystemVersion;
0x2a
WORD MinorOperatingSystemVersion;
0x2c
WORD MajorImageVersion;
0x2e
WORD MinorImageVersion;
0x30
WORD MajorSubsystemVersion;
0x32
WORD MinorSubsystemVersion;
0x34
DWORD Win32VersionValue;
0x38
DWORD SizeOfImage;
/
/
映像载入内存后的总尺寸
0x3c
DWORD SizeOfHeaders;
/
/
MS
-
DOS头部、PE文件头、区块表总大小
0x40
DWORD CheckSum;
0x44
WORD Subsystem;
0x46
WORD DllCharacteristics;
0x48
DWORD SizeOfStackReserve;
0x4c
DWORD SizeOfStackCommit;
0x50
DWORD SizeOfHeapReserve;
0x54
DWORD SizeOfHeapCommit;
0x58
DWORD LoaderFlags;
0x5c
DWORD NumberOfRvaAndSizes;
0x60
_IMAGE_DATA_DIRECTORY DataDirectory[
16
];
};
后续还会再搞,目前就整理了这么多。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2020-10-20 00:23
被郁涛丶编辑
,原因:
赞赏
他的文章
- [原创]完全搞懂栈迁移 18339
- [原创]BUU_RE题目WP(一) 4464
- [原创]PE 文件结构(一) 4050
- [原创]汇编基础学习笔记 4673
看原图
赞赏
雪币:
留言: