Option PE header

可选PE头

  • file header Characteristics
  • option PE code

Option PE header_第1张图片

file header Characteristics

Option PE header_第2张图片
PE文件解析官方文档

option PE code

  • pe文档

    //可选PE头
    IMAGE_OPTIONAL_HEADER32 STRUCT{
        0x00 WORD    Magic;         // 标志字, ROM 映像(0107h),普通可执行文件(010Bh)	010B
        0x02 BYTE    MajorLinkerVersion;     // 链接程序的主版本号	05
        0x03 BYTE    MinorLinkerVersion;     // 链接程序的次版本号	0C
        0x04 DWORD   SizeOfCode;     // 所有含代码的节的总大小		0000200
        0x08 DWORD   SizeOfInitializedData;    // 所有含已初始化数据的节的总大小	00000400
        0x0c DWORD   SizeOfUninitializedData; // 所有含未初始化数据的节的大小		00000000
        0x10 DWORD   AddressOfEntryPoint;    // 程序执行入口RVA		00001000
        0x14 DWORD   BaseOfCode;      // 代码的区块的起始RVA (代码段基址)		00001000
        0x18 DWORD   BaseOfData;      // 数据的区块的起始RVA	(数据段基址)	00002000
        0x1c DWORD   ImageBase;      // 程序的首选装载地址		00400000
        0x20 DWORD   SectionAlignment;      // 内存中的区块的对齐大小		00001000
        0x24 DWORD   FileAlignment;      // 文件中的区块的对齐大小		00000200
        0x28 WORD    MajorOperatingSystemVersion;  // 要求操作系统最低版本号的主版本号		0004
        0x2a WORD    MinorOperatingSystemVersion;  // 要求操作系统最低版本号的副版本号		0000
        0x2c WORD    MajorImageVersion;       // 可运行于操作系统的主版本号		0004
        0x2e WORD    MinorImageVersion;       // 可运行于操作系统的次版本号		0000
        0x30 WORD    MajorSubsystemVersion;  // 要求最低子系统版本的主版本号		0004
        0x32 WORD    MinorSubsystemVersion;  // 要求最低子系统版本的次版本号		0000
        0x34 DWORD   Win32VersionValue;       // 莫须有字段,不被病毒利用的话一般为0	00000000
        0x38 DWORD   SizeOfImage;       // 映像装入内存后的总尺寸		00003038
        0x3c DWORD   SizeOfHeaders;       // 所有头 + 区块表的尺寸大小	00000200
        0x40 DWORD   CheckSum;       // 映像的校检和		000020A7
        0x44 WORD    Subsystem;       // 可执行文件期望的子系统		0002
        0x46 WORD    DllCharacteristics;       // DllMain()函数何时被调用,默认为 0		0000
        0x48 DWORD   SizeOfStackReserve;       // 初始化时保留堆栈虚拟内存大小		00100000
        0x4c DWORD   SizeOfStackCommit;       // 初始化时实际提交的堆栈大小		00001000
        0x50 DWORD   SizeOfHeapReserve;        // 初始化时保留的堆大小		00100000
        0x54 DWORD   SizeOfHeapCommit;        // 初始化时提交的堆大小		00001000
        0x58 DWORD   LoaderFlags;        // 与调试有关,默认为 0		00000000
        0x5c DWORD   NumberOfRvaAndSizes;  // 下边数据目录的项数,这个字段自Windows NT 发布以来一直是16	00000010
        0x60 IMAGE_DATA_DIRECTORY DataDirectory[16];  // 数据目录表(数目固定为16,很重要!!!)
        }
    
  • 统计出来的PE头大小为:
    1x2=2 2x9=18 19x4=76 2+18+76=96 --> 96byte
    总大小:96字节 == 60h字节
    Option PE header_第3张图片

  • PE头部信息c代码打印实现

  • 解释
    MajorOperatingSystemVersion : 操作系统主版本号,这里是 0 x 04 \color{red}{0x04} 0x04
    Option PE header_第4张图片Option PE header_第5张图片
    SubSystem:常见的子系统,是一个枚举值Option PE header_第6张图片
    SizeOfStackReserve:要保留的堆栈的大小。只有SizeOfStackCommit被提交,其余部分一次提供一页,直到达到保留大小

    • 重要字段

      M a g i c \color{blue}{Magic} Magic: 表示其是32位PE文件,还是64位PE文件。 0 x 010 B \color{red}{0x010B} 0x010B是32位PE文件,0x020B是64位PE文件;如果为0107H,则表示文件为ROM映像。

      S i z e O f c o d e \color{blue}{SizeOfcode} SizeOfcode:存放总代码(代码段)大小,按照FileAlignment对齐后的大小 0 x 200 \color{red}{0x200} 0x200

      S i z e O f I n i t i a l i z e d D a t a \color{blue}{SizeOfInitializedData} SizeOfInitializedData:已初始化的数据大小,按照FileAlignment对齐 0 x 0400 \color{red}{0x0400} 0x0400

      S i z e O f U n i n i t i a l i z e d D a t a \color{blue}{SizeOfUninitializedData} SizeOfUninitializedData:未初始化的数据大小,按照FileAlignment对齐 0 x 0000 \color{red}{0x0000} 0x0000

      A d d r e s s O f E n t r y P o i n t \color{blue}{AddressOfEntryPoint} AddressOfEntryPoint:程序入口地址–也叫OEP

      • 也是一个偏移地址,是从 程 序 被 加 载 到 内 存 后 在 内 存 中 的 首 地 址 \color{orange}{程序被加载到内存后在内存中的首地址} 的偏移地址。
      • 也就是说PE文件的起始地址,就等于程序加载进入内存后,把程序在内存中的首地址加上OEP的地址就是程序加载进去后跑的第一行代码的地址。
      • 也就是 OEP+ImageBase 的地址,就是一个程序真正的入口地址 0 x 1000 \color{red}{0x1000} 0x1000

      I m a g e B a s e \color{blue}{ImageBase} ImageBase1:内存镜像基址,也就是 程 序 加 载 到 内 存 后 在 内 存 中 的 首 地 址 \color{orange}{程序加载到内存后在内存中的首地址} 0 x 400000 \color{red}{0x400000} 0x400000

      S e c t i o n A l i g n m e n t \color{blue}{SectionAlignment} SectionAlignment:内存对齐大小 0 x 1000 \color{red}{0x1000} 0x1000

      F i l e A l i g n m e n t \color{blue}{FileAlignment} FileAlignment:表示文件(硬盘)中的对齐值 0 x 200 \color{red}{0x200} 0x200

      S i z e O f I m a g e \color{blue}{SizeOfImage} SizeOfImage:加载到内存中所占的大小(PE加载器根据此处值决定申请连续内存空间大小) 0 x 3038 \color{red}{0x3038} 0x3038

      S i z e O f H e a d e r s \color{blue}{SizeOfHeaders} SizeOfHeaders:DOS头+NT头+标准PE头(文件头)+可选PE头+区快表,按照FileAlignment对齐后的大小 0 x 200 \color{red}{0x200} 0x200

      I M A G E _ D A T A _ D I R E C T O R Y D a t a D i r e c t o r y \color{blue}{IMAGE\_DATA\_DIRECTORY DataDirectory} IMAGE_DATA_DIRECTORYDataDirectory

      struct _IMAGE_DATA_DIRECTORY{
      DWORD   VirtualAddress;		// 指向某个数据的相对虚拟地址   RAV  偏移0x00**
      DWORD   Size;		// 某个数据块的大小      偏移0x04**
      };
      //占用16*8 = 128Byte = 80H = E0H(可选PE头默认大小) - 60H(前面所有成员固定占用大小)
      

      VirtualAddress对应关系

      例: #define IMAGE_DIRECTORY_ENTRY_EXPORT      0 //    Export Directory      输出表
      Option PE header_第7张图片

    自认为文件头(file header)和DOS头已经掌握差不多了

    Option PE header_第8张图片
    手动解析PE详见
    有关image官方解释


  1. FileBuffer是磁盘上.exe文件在内存中的一份拷贝,但是FileBuffer无法直接在内存中运行,必须经过PE loader(装载器)装载以后成为ImageBuffer。ImageBuffer是FileBuffer的”拉伸”。即”.exe ① . e x e 首 地 址 ( 基 址 ) 为 0 \color{orchid}{①.exe首地址(基址)为0} .exe0–>FileBuffer ② F i l e B u f f e r 首 地 址 也 为 0 \color{orchid}{②FileBuffer首地址也为0} FileBuffer0–>ImageBuffer ③ I m a g e B u f f e r 首 地 址 为 I m a g e B a s e \color{orchid}{③ImageBuffer首地址为ImageBase} ImageBufferImageBase ④ 而 真 正 的 程 序 入 口 地 址 是 : I m a g e B a s e + A d d r e s s O f E n t r y P o i n t ( O E P ) \color{orchid}{④而真正的程序入口地址是:ImageBase + AddressOfEntryPoint(OEP)} ImageBase+AddressOfEntryPoint(OEP) ↩︎

你可能感兴趣的:(逆向学习,安全)