PE文件结构初探

PE概念:

        PE(Portable Execute)文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS等,然而不管什么后缀都可以是可执行文件,只要满足正确的PE结构。

PE文件的结构:

1、DOS头: 

        DOS MZ 头:

                偏移0位置为MZ标志

                偏移位置3Ch(e_lfanew)为PE头地址偏移     

     typedef struct _IMAGE_DOS_HEADER {     // DOS .EXE header
        WORD   e_magic;                     // 幻数MZ
        WORD   e_cblp;                      // Bytes on last page of file
        WORD   e_cp;                        // Pages in file
        WORD   e_crlc;                      // Relocations
        WORD   e_cparhdr;                   // Size of header in paragraphs
        WORD   e_minalloc;                  // Minimum extra paragraphs needed
        WORD   e_maxalloc;                  // Maximum extra paragraphs needed
        WORD   e_ss;                        // 初始化堆栈段
        WORD   e_sp;                        // 初始化栈顶指针
        WORD   e_csum;                      // Checksum
        WORD   e_ip;                        // DOS代码入口IP
        WORD   e_cs;                        // DOS代码入口CS
        WORD   e_lfarlc;                    // File address of relocation table
        WORD   e_ovno;                      // Overlay number
        WORD   e_res[4];                    // Reserved words
        WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
        WORD   e_oeminfo;                   // OEM information; e_oemid specific
        WORD   e_res2[10];                  // Reserved words
        LONG   e_lfanew;                    // 指向PE文件头
      } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

        DOS stub头,实质是有效的exe文件,用于在不支持PE的系统上显示错误

2、PE头:

        PE文件头:

     typedef struct _IMAGE_NT_HEADERS {
        DWORD Signature;                           //标志幻数P E 0x00 0x00
        IMAGE_FILE_HEADER FileHeader;              //映像文件头
        IMAGE_OPTIONAL_HEADER32 OptionalHeader;    //可选映像头
    } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

        映像文件头:包含文件基本信息

    typedef struct _IMAGE_FILE_HEADER {    
        WORD    Machine;                         //运行平台
        WORD    NumberOfSections;                //文件节数
        DWORD   TimeDateStamp;                   //文件创建日期和时间
        DWORD   PointerToSymbolTable;            //指向符号表
        DWORD   NumberOfSymbols;                 //符号表中符号数量
        WORD    SizeOfOptionalHeader;            //可选映像头长度
        WORD    Characteristics;                 //文件属性(exe,dll等)
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

        可选映像头

    typedef struct _IMAGE_OPTIONAL_HEADER {
        //标准域
        WORD    Magic;                       //幻数0x010B
        BYTE    MajorLinkerVersion;
        BYTE    MinorLinkerVersion;
        DWORD   SizeOfCode;
        DWORD   SizeOfInitializedData;
        DWORD   SizeOfUninitializedData;
        DWORD   AddressOfEntryPoint;        //文件执行的入口地址
        DWORD   BaseOfCode;
        DWORD   BaseOfData;
        //NT附加域    
        DWORD   ImageBase;                  //文件优先装入地址(初始VA)
        DWORD   SectionAlignment;             //内存中节的对齐粒度
        DWORD   FileAlignment;                //文件中节的对齐粒度
        WORD    MajorOperatingSystemVersion;
        WORD    MinorOperatingSystemVersion;
        WORD    MajorImageVersion;
        WORD    MinorImageVersion;
        WORD    MajorSubsystemVersion;
        WORD    MinorSubsystemVersion;
        DWORD   Win32VersionValue;
        DWORD   SizeOfImage;                //内存中整个PE映像尺寸
        DWORD   SizeOfHeaders;                //节数据到文件开始的偏移
        DWORD   CheckSum;
        WORD    Subsystem;
        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;

        DataDirectory选项字段            Tips:DataDirectory结构包含VirtualAddress和Size

    #define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // 导出表
    #define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // 导入表
    #define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // 资源表
    #define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory
    #define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // Security Directory
    #define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
    #define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
    //      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage)
    #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // Architecture Specific Data
    #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP
    #define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
    #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
    #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   
    #define IMAGE_DIRECTORY_ENTRY_IAT            12   // 导入函数表
    #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
    #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor

3、节表

    包含节的信息,有几个节就有几个成员      Tips:类似目录

    typedef struct _IMAGE_SECTION_HEADER {    
        BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];        //节名
        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;

4、节

    划分成块的PE文件真正内容,每一节是拥有共同属性的内容,载入到内存时会采用页对齐,即产生了节缝隙,可用于插入恶意代码。

    一般有以下几种节:

        代码节
        已初始化的数据节
        未初始化的数据节
        资源节
        引入函数节
        引出函数节

5、RVA与VA

    文件在磁盘上时,距离文件起始的距离为物理偏移(Offset)

    文件在装入到虚拟地址中时,由于采用按页对齐,所以地址的对应不与Offset一致

    在虚拟地址空间中,距离文件起始的距离为相对虚拟地址(RVA)

    在虚拟地址空间中,虚拟地址(VA)能起到访问绝对地址的作用(VA-起始VA=RVA)

    当程序指定的起始VA被其他程序占用时,操作系统会对VA进行重定向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值