PE文件学习(基础)

DOS 部分

  • 由上往下依次为: IMAGE_ DOS_ HEADER-->DOS Stub

    • IMAGE_ DOS_ HEADER
    • e_magic:DOS签名
    • e_Ifanew:指示NT头偏移(可变) 不一定是00 00 00 E0
    • DOS Stub(大小不固定)
      • 其实是一段汇编代码
      • 一般输出 This program cannot be run in dos mode
      • IMAGE_ DOS_ HEADER大小不固定,原因是DOS Stub大小不固定(由编译器定)
  • NT头: IMAGE_ NT HEADERS (下面介绍)

PE头与各节区的尾部存在一个区域, 称为NULL填充( NULL padding )。 00 00 00 00

NT 头部分

IMAGE_NT_HEADERS

  • 大小为F8
  • 结构如下
    • Signature 50 45 00 00 "PE00 "
    • IMAGE_FILE_HEADER
      • Machine
        • 每个CPU都有唯一的Machine码
        • 兼容32位Intel x86芯片的Machine码为14C)
        • 具体的在winnt.h中有定义
      • NumberOfSections
        • PE文件把代码、数据、资源等依据属性分类到各节区中存储。
        • 节区数量
      • time data stamp
        • 不影响运行
        • 编译器创建此文件时间
      • SizeOfOptionalHeader
        • IMAGE_NT_ HEADER结构体的最后一个成员为IMAGE_OPTIONAL_HEADER32结构体。
        • PE32+格式的文件中使用的是IMAGEOPTIONALHEADER64结构体(两个尺寸不同)
      • Characteristics
        • 该字段用于标识文件的属性,文件是否是可运行的形态、是否为DLL文件等信息(定义在winnt.h中)
          • 0002h:File is executable
          • 0x2000: File is a DLL.

IMAGE_ OPTIONAL_ HEADER32

  • MAGIC:

    • 010B:IMAGE_ OPTIONAL_ HEADER32
    • 020B:IMAGE_ OPTIONAL_ HEADER64
  • AddressOfEntryPoint

    • AddressOfEntryPoint持有EP的RVA值。该值指出程序最先执行的代码起始地址,相当重要。
  • ImageBase

    • 进程虚拟内存的范围是o~FFFFFF ( 32位系统)。PE文件被加载到如此大的内存中时,
      ImageBase指出文件的优先装人地址。
    • EIP初始值:ImageBase+AddressOfEntryPoint
  • SectionAlignment,FileAlignment

    • PE文件的Body部分划分为若干节区,这些节存储着不同类别的数据。FileAlignment指定了节区在磁盘文件中的最小单位,而SectionAlignment则指定了节区在内存中的最小单位(一个文件中,FileAlignment 与SctionAlignment的值可能相同,也可能不同)。磁盘文件或内存的节区大小必定为FileAlignment或SectionAlignment值的整数倍。
  • SizeOflmage

    • 加载PE文件到内存时,SizeOflmage指定 了PE Image在虚拟内存中所占空间的大小。一般而言,文件的大小与加载到内存中的大小是不同的(节区头中定义了各节装载的位置与占有内存的
      大小,后面会讲到)。
  • SizeOfHeader

    • SizeOfHeader用来指出整个PE头的大小。该值也必须是FileAlignment的整数倍。第- -节区所
      在位置与SizeOfHeader距文件开始偏移的量相同。
  • Subsystem

    • 该Subsystem值用来区分系统驱动文件( * .sys)与普通的可执行文件( *.exe, *.dII )。
    • 1 Driver文件 系统驱动(如: ntfs.sys)
      2 GUI文件 窗口应用程序(如: notepad.exe)
      3 CUI文件 控制台应用程序(如: cmd.exe)
  • NumberOfRvaAndSizes

    • NumberOfRvaAndSizes用来指定DataDirectory( IMAGE_ OPTIONAL HEADER32结构体的最
      后一个成员)数组的个数。虽然结构体定义中明确指出了数组个数为IMAGE_NUMBEROF_DIRECTORY_ENTRIES(16),但是PE装载器通过查看NumberOfRvaAndSizes值来识别数组大小,换言之,数组大小也可能不是16。
    • DataDirectory是由IMAGE_ DATA DIRECTORY结构体组成的数组,每一项都有被定义的值
typedef struct _IMAGE_DATA_DIRECTORY {

    DWORD VirtualAddress;

    DWORD Size;

} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
#define IMAGE_DIRECTORY_ENTRY_RESOURCE  2
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
#define IMAGE_DIRECTORY_ENTRY_SECURITY  4
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE  7
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
#define IMAGE_DIRECTORY_ENTRY_TLS  9
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG  10
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
#define IMAGE_DIRECTORY_ENTRY_IAT  12
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR   14

节区头

  • 节区头是由IMAGE SECTION_ HEADER结构体组成的数组,每个结构体对应-一个节区。
  • 以下是IMAGE SECTION_ HEADER比较重要的部分:
    • VirtualSize: 内存中节区所占大小
    • VirtualAddress:内存中节区起始地址(RVA)
    • SizeOfRawData:磁盘文件中节区所占大小
    • PointerToRawData:磁盘文件中节区起始位置
    • Charateristics:节区属性(bit OR)
  • .text /.data/.code为name字段,理论上可以随意填充
posted @ 2020-05-08 15:39  10nnn4R  阅读(440)  评论(0编辑  收藏  举报