现在的位置: 首页 > 综合 > 正文

PE 文件格之总体结构

2013年10月01日 ⁄ 综合 ⁄ 共 3326字 ⁄ 字号 评论关闭

PE 文件格,也可以直接说,是可执行文件。也就是大家熟悉的exe、dll、ocx等类型的文件。(当然,并不是所有此类型的都是PE文件)。
Function NtCreateSection creates Section Object (virtual memory block with associated file),pe文件就是使用这个API来,分配虚拟内存块。
PE分三大块
一、Dos头,主要用于兼容Dos程序。
二、PE头,用于记录,文件相关信息

三、结点,用于记录结点的信息。

1、DOS头,DOS程序,为了兼容dos程序。

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;//魔术字, 50 45 00 00("PE",0x00004550)
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;


typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;//程序类型,X86、Intel Itanium、X64
    WORD    NumberOfSections;//节点的个数,与下面“三”相关
    DWORD   TimeDateStamp;//程序被链接器创建时的时间,This represents the date and time the image was created by the linker
    DWORD   PointerToSymbolTable;//符号表偏移
    DWORD   NumberOfSymbols;//符号表个数
    WORD    SizeOfOptionalHeader;//IMAGE_OPTIONAL_HEADER结构体的大小,一般在X86是224
    WORD    Characteristics;//文件类型,是exe、dll、systemfile等,
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;


typedef struct _IMAGE_OPTIONAL_HEADER {
    // Standard fields.
    WORD    Magic;//文件只读或可运行
    BYTE    MajorLinkerVersion;//版本,大号
    BYTE    MinorLinkerVersion;//版本,小号
    DWORD   SizeOfCode;//段中,代码的长度(大小)
    DWORD   SizeOfInitializedData;//已初始化的数据
    DWORD   SizeOfUninitializedData;//未初如化数据(与已初始化的区别,在磁盘文件中没有对应的数据,但具有大小,当分配内存时,依然会分配,并将其置0,所以,未初始化的全局或静态变量,会是0,这只是其中一种方式,还会有其它的方式,待研究...)
    DWORD   AddressOfEntryPoint;//程序的入口地址(偏移地址,相对ImageBase)
    DWORD   BaseOfCode;//代码段的基址,(偏移地址,相对ImageBase)
    DWORD   BaseOfData;//数据段的基址,(偏移地址,相对ImageBase)
    // NT additional fields.
    DWORD   ImageBase;//虚拟内存的地址,(并不完全固定,有可能会由于冲突而重定向)
    DWORD   SectionAlignment;//节对齐(在内存内),一定会大于等于FileAlignment,一个节点位置(相对)、大小,必须是这个数的倍数。
    DWORD   FileAlignment;//文件对齐,同上
    WORD    MajorOperatingSystemVersion;//运行系统最大要求
    WORD    MinorOperatingSystemVersion;//运行系统最要求
    WORD    MajorImageVersion;//映象文件主版本号
    WORD    MinorImageVersion;//映象文件次版本号
    WORD    MajorSubsystemVersion;//子系统主版本
    WORD    MinorSubsystemVersion;//子系统次版本
    DWORD   Win32VersionValue;//必须为0,(不知何用,求解)
    DWORD   SizeOfImage;//映像大小,虚拟内存大小
    DWORD   SizeOfHeaders;//这个PE头的大小,也就是此PE头这个段的大小
    DWORD   CheckSum;
    WORD    Subsystem;//The subsystem required to run this image,子系统要求,GUI、CUI and so on;(GUI  Graphical user interface图形用户接口,CUI Command user interface)
    WORD    DllCharacteristics;//属性
    DWORD   SizeOfStackReserve;//保留栈大小
    DWORD   SizeOfStackCommit;//初始化栈大小
    DWORD   SizeOfHeapReserve;//保留堆大小
    DWORD   SizeOfHeapCommit;//初始化栈大小
    DWORD   LoaderFlags;//已过时
    DWORD   NumberOfRvaAndSizes;//下面结构的个数
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
分别为:
0  Export Table //导出表
1  Import Table //导入表
2  Resource Table//资源表
3  Exception Table //异常表
4  Certificate File//证书表,数字验证等
5  Relocation Table//重定位表
6  Debug Data //调试表
7  Architecture Data 
8  Global Ptr 
9  TLS Table
10 Load Config Table
11 Bound Import Table 
12 Import Address Table a
13 Delay Import Descriptor 
14 COM+/CLI Header
15 Reserved = 00000000//全0,结束标志
   Reserved = 00000000

3、节点表
这个表的个数:IMAGE_FILE_HEADER.NumberOfSections,见上。

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];//名字,8字节长度,例如:".text" 、".data"、".rsrc"等
    union {
            DWORD   PhysicalAddress;//物理地址
            DWORD   VirtualSize;//大小
    } Misc;
    DWORD   VirtualAddress;//RVA
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;//属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

以上是PE结构示意。

之后,会着重分析,导入表、导出表、资源表等

我的PE文件分析:http://download.csdn.net/download/he702477275/4968971

抱歉!评论已关闭.