首页
社区
课程
招聘
[原创]PE 文件结构(一)
2020-10-20 00:21 3424

[原创]PE 文件结构(一)

2020-10-20 00:21
3424
新人学习逆向,PE结构第一弹

PE 文件结构(一)

1.PE基本概念

  • PE(Portable Execute)

    PE文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS等,事实上,一个文件是否是PE文件与其扩展名无关,PE文件可以是任何扩展名。

  • PE文件的结构

    PE文件的结构一般来说如下图所示:从起始位置开始依次是DOS头,NT头,节表以及具体的节。


  • 基地址(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 (可选映像头)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    struct _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];
    };

    后续还会再搞,目前就整理了这么多。


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2020-10-20 00:23 被郁涛丶编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回