zoukankan      html  css  js  c++  java
  • PE文件结构

    可执行文件:可以由操作系统进行加载执行的文件

    在Windows平台中若要程序可执行,必须遵守可执行文件的格式

    可执行文件的格式:

    Windows平台:PE(Portable Executable)文件结构,其中Portable也就是Windows系统中能够跨平台运行

    Linux平台:ELF(Executable and Linking Format)文件结构


    PE文件特征:

    如exe、dll、vxd、sys和vdm等文件都遵守可执行文件的格式!

    常用的识别PE文件的方法:

    1、用HEX编辑器打开文件,头两个字节是不是MZ,然后向后到第64字节的位置,例如为10 01 00 00,因为存储模式为小端存储所以,实际是0x00000110

    2、再去找到0x00000110的位置,向后2字节,如果为字符显示为PE则基本就是PE文件了


    PE文件结构:

    PE文件结构分为四大部分:

    1、Dos部分 2、PE文件头 3、节表 4、节数据


    1、Dos部分:

    MZ文件头IMAGE_DOS_HEADER结构体,其大小占64个字节,并且该结构中的最后一个LONG类型e_lfanew成员指向PE文件头的位置为中的PE文件头标志的地址

    typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
        WORD   e_magic;                     // Magic number
        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;                        // Initial (relative) SS value
        WORD   e_sp;                        // Initial SP value
        WORD   e_csum;                      // Checksum
        WORD   e_ip;                        // Initial IP value
        WORD   e_cs;                        // Initial (relative) CS value
        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;                    // File address of new exe header 指向PE文件头的位置为中的PE文件头标志的地址
      } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
    

    Dos Stub:属于链接器进行填充的,大小不一定,属于DOS部分的DOS块,无实际作用,但是可以作为注入手段进行利用!图中第二个红框则是Dos Stub


    2、PE文件头:

    整个PE头的结构体

    typedef struct _IMAGE_NT_HEADERS {
        DWORD Signature;  //PE文件头标志
        IMAGE_FILE_HEADER FileHeader; //PE文件表头
        IMAGE_OPTIONAL_HEADER32 OptionalHeader; //扩展PE头
    } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
    

    PE文件头分为三部分:

    1、PE文件头标志(PE标识),占4个字节,作为标识用,如上图查看是否为PE文件就是利用这个方法!

    2、PE文件表头(标准PE头),占20个字节,为IMAGE_FILE_HEADER结构体,该结构体中SizeOfOptionalHeader结构体中有个成员可以看出可扩展文件表头的大小

    typedef struct _IMAGE_FILE_HEADER {
        WORD    Machine;
        WORD    NumberOfSections;
        DWORD   TimeDateStamp;
        DWORD   PointerToSymbolTable;
        DWORD   NumberOfSymbols;
        WORD    SizeOfOptionalHeader; // 可以看出可扩展文件表头的大小,也分为x32 x64 x32大小为E0 x64大小为F0
        WORD    Characteristics;
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
    

    3、可扩展文件表头(扩展PE头),占224字节,结构体分两种 一种是32位的,一种是16位的,分别是IMAGE_OPTIONAL_HEADER32结构体 和 16xIMAGE_DATA_DIRECTORY结构体

    typedef struct _IMAGE_OPTIONAL_HEADER {
        //
        // Standard fields.
        //
    
        WORD    Magic;
        BYTE    MajorLinkerVersion;
        BYTE    MinorLinkerVersion;
        DWORD   SizeOfCode;
        DWORD   SizeOfInitializedData;
        DWORD   SizeOfUninitializedData;
        DWORD   AddressOfEntryPoint;
        DWORD   BaseOfCode;
        DWORD   BaseOfData;
    
        //
        // NT additional fields.
        //
    
        DWORD   ImageBase;
        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;
    

    其中FileAlignment成员的值为文件对齐之后的大小,SizeOfHeaders成员的值一定是FileAlignment的值的整数倍,而且SizeOfHeaders保存的值是所有的头(有DOS部分 PE文件头)加上节表的大小

    如果FileAlignment(文件对齐之后的大小)是200 那么SizeOfHeaders头一定是200的整数倍,那么就是400,如果FileAlignment不到200那么SizeOfHeaders就按照200对齐,如下图可以看到文件对齐后的FileAlignment的大小为0x200H,SectionAlignment是在内存中加载的时候,文件对齐之后的大小,在FileAlignment前四个字节,那么就是0x1000H

    那么再去看下SizeOfHeaders的大小,相差二十个字节,继续往后移,结果如下:0x400,的确是FileAlignment的两倍

    如果每次都是整数倍,那肯定有很多地方空出来,实际上是用空间换取时间,增加了处理效率,具体以后自己知道了再补上!


    3、节表: 其中每个节大小占40个字节,十六进制 0x28

    IMAGE_SECTION_HEADER结构体(40字节) * 节的数量(大小取决于节的数量)

    typedef struct _IMAGE_SECTION_HEADER {
        BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
        union {
                DWORD   PhysicalAddress; //当前节的名称 , 占8字节
                DWORD   VirtualSize; //内存中文件对齐大小
        } Misc;
        DWORD   VirtualAddress; //在内存中的偏移地址
        DWORD   SizeOfRawData; //当前节在文件中对齐后的大小
        DWORD   PointerToRawData; //当前节在文件中的偏移
        DWORD   PointerToRelocations; // 调试相关
        DWORD   PointerToLinenumbers;// 调试相关
        WORD    NumberOfRelocations;// 调试相关
        WORD    NumberOfLinenumbers;// 调试相关
        DWORD   Characteristics; //文件属性,比如该节数据属性是否为可执行属性,都在这里面
    } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
    

    我这边有五个节,如下显示:


    4、节数据:

    sizeofHeaders 按照文件对齐.存储着 头 + 节表的大小,这里就是0x400之后的数据了!也就是如下:

    在硬盘中存储的时候文件的每个节数据之间的大小由FileAlignment决定!

    上面都是空的,同样可以进行非法利用!

  • 相关阅读:
    用代码控制CListCtrl的一行高亮显示或选择的问题
    机械版CG 实验3 变换
    机械版CG 实验5 Bezier曲线
    机械版CG 实验4 裁剪
    Avoiding UpdateData(ZZ)
    机械版CG 实验6 简单光照明模型实现
    机械版CG 实验2 直线生成算法的实现
    最近太忙了,没有时间打理Blog
    仿雅虎首页巨幅广告
    XML串行化,低层类
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/12308184.html
Copyright © 2011-2022 走看看