PE文件格式介绍

Useful Tools:

1. WDK安装目录下搜下depends.exe,这个工具可以查看.exe文件依赖的.dll,以及用到的dll中的api。

2.PE文件格式分析器:

   有很多的PE格式分析器,我随便试了两个,lordPE.exe,prjPEParserEx.exe都还不错,放我百度云盘了。

    http://yun.baidu.com/share/link?shareid=2025240688&uk=758458210

3.Visual Studio自带的的dumpbin工具

   dumpbin /ALL xxx.exe >>xx.txt

PE文件格式适用于.exe,.dll,.sys文件(.obj->COFF类似)

PE文件的布局:

 __________________________________
|                                  |<----Base of Image Header
|    DOS compatible EXE header     |--|
|__________________________________|  |
|                                  |  |
|             Unused               |  |
|__________________________________|  |
|                                  |  |
|         OEM identifier           |  |
|__________________________________|  |
|                                  |  |
|            OEM info              |  |-->Uninteresting(DOS Compatibility)
|__________________________________|  |
|                                  |  |
|        Offset to PE Header       |----->Very interesting
|__________________________________|  |
|                                  |  |
| DOS Stub program and reloc table |  |
|__________________________________|  |
|                                  |  |
|              Unused              |__|
|__________________________________|
|                                  |
|   PE header(IMAGE_FILE_HEADER)   |--|
|__________________________________|  |
|                                  |  |
| PE header(IMAGE_OPTIONAL_HEADER) |  |
|__________________________________|  |-->Very very interesting :)
|                                  |  |
|          Section Table           |  |
|__________________________________|  |
|                                  |  |
|            Sections              |__|
|__________________________________|

★ Dos Header Info (IMAGE_DOS_HEADER)

IMAGE_DOS_HEADER的定义如下

 1 typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
 2     WORD   e_magic;                     // Magic number
 3     WORD   e_cblp;                      // Bytes on last page of file
 4     WORD   e_cp;                        // Pages in file
 5     WORD   e_crlc;                      // Relocations
 6     WORD   e_cparhdr;                   // Size of header in paragraphs
 7     WORD   e_minalloc;                  // Minimum extra paragraphs needed
 8     WORD   e_maxalloc;                  // Maximum extra paragraphs needed
 9     WORD   e_ss;                        // Initial (relative) SS value
10     WORD   e_sp;                        // Initial SP value
11     WORD   e_csum;                      // Checksum
12     WORD   e_ip;                        // Initial IP value
13     WORD   e_cs;                        // Initial (relative) CS value
14     WORD   e_lfarlc;                    // File address of relocation table
15     WORD   e_ovno;                      // Overlay number
16     WORD   e_res[4];                    // Reserved words
17     WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
18     WORD   e_oeminfo;                   // OEM information; e_oemid specific
19     WORD   e_res2[10];                  // Reserved words
20     LONG   e_lfanew;                    // File address of new exe header
21   } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
比较有用的是:e_lfanew,表示IMAGE_NT_HEADERS在文件中地址。

★ PE Header Info (IMAGE_NT_HEADER)

1 IMAGE_NT_HEADERS STRUCT{
2   +00H        DWORD                Signature
3   +04H        IMAGE_FILE_HEADER        FileHeader
4   +18H        IMAGE_OPTIONAL_HEADER32     OptionalHeader
5 }IMAGE_NT_HEADERS

★ File Header Info (IMAGE_FILE_HEADER)

1 typedef struct _IMAGE_FILE_HEADER{
2     +04H        WORD    Machine;           //运行平台
3     +06H        WORD    NumberOfSections; //文件的区块数目   !!important
4     +08H        DWORD   TimeDateStamp;    //文件创建日期和事件
5     +0CH        DWORD   PointerToSymbolTable; //只想符号表(主要用于调试)
6     +10H        DWORD   NumberOfSymbols;      //符号表中的符号个数(同上)
7     +14H        WORD    SizeOfOptionalHeader;  //IMAGE_OPTIONAL_HEADER32结构大小
8     +16H        WORD    Characteristics;      //文件属性
9 }IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER;

★ Optional Header Info (IMAGE_OPTIONAL_HEADER)

1 typedef struct _IMAGE_OPTIONAL_HEADER{
2   +28H    DWORD   AddressOfEntryPoint;     // 程序执行入口RVA
3   +34H    DWORD   ImageBase;               // 程序的首选装载地址
4   +38H    DWORD   SectionAlignment;        // 内存中的区块的对齐大小
5   +3CH    DWORD   FileAlignment;           // 文件中的区块的对齐大小
6   +5CH    WORD    Subsystem;               // 可执行文件期望的子系统
7   +78H    IMAGE_DATA_DIRECTORY     DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; //IMAGE_NUMBEROF_DIRECTORY_ENTRIES=0x10
8 }IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTION_HEADER32
Directory Entry的结构
1
IMAGE_DATA_DIRECTORY STRUCT{ 2   VirtualAddress DWORD ? ;相对虚拟地址 3   isize DWORD ? ;大小 4 }IMAGE_DATA_DIRECTORY

那16个Directory Entry,根据其RVA(VirtualAddress)可以推算出其在哪个section,在文件哪个位置。

比如:Export Entry一般在.rdata section中, Import Entry在.idata section(The imports table),

Resource Entry在.rsrc section(The resources),BaseReloc Entry在.reloc section

Debug Entry 在.rdata section, IAT Entry在.idata section...

★ Section Header Info

 1 typedef struct IMAGE_SECTION_HEADER
 2 {
 3     BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //IMAGE_SIZEOF_SHORT_NAME = 8
 4     union
 5     {
 6         DWORD PhysicalAddress;
 7         DWORD VirtualSize;
 8     }Misc;
 9     DWORD VirtualAddress; //节被载到内存之后的偏移
10     DWORD SizeOfRawData;
11     DWORD PointerToRawData;
12     DWORD PointerToRelocations;
13     DWORD PointerToLinenumbers;
14     WORD NumberOfRelocations;
15     WORD NumberOfLinenumbers;
16     DWORD Characteristics;
17 }IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

共0x28个Byte.

IMAGE_FILE_HEADER里面会制定section的个数

.text .data .rdata .idata .didat .reloc .rsrc.

在这个section table之后,会按照IMAGE_OPTIONAL_HEADER->FileAlignment来对其,然后就是各个section的内容了。

如果没有symbol啥的信息的话,各个section填完之后,文件就结束了。

=================================================

section table,

所有section都有两个对齐值(文件内offset(0x200),内存offset(一个Page)),section的其实地址需要以此对齐。

如:

01 .text     VirtSize: 00074658  VirtAddr:  00001000    raw data offs:   00000400  raw data size: 00074800...  
02 .data VirtSize: 000028CA VirtAddr: 00076000 raw data offs: 00074C00 raw data size: 00002400

Can refer this useful link:
http://en.wikibooks.org/wiki/X86_Disassembly/Windows_Executable_Files#Relative_Virtual_Addressing_.28RVA.29
原文地址:https://www.cnblogs.com/zzSoftware/p/3342283.html