PE1-什么是pe

PE是什么?

PE即 Portable Executable(可移植的执行体)。它是 Win32环境自身所带的执行体文件格式。它的一些特性继承自 Unix的 Coff 文件格式。“portable executable”(可移植的执行体)意味着此文件格式是跨win32平台的 : 即使Windows运行在非Intel的CPU上,任何win32平台的PE装载器都能识别和使用该文件格式。当然,移植到不同的CPU上PE执行体必然得有一些改变。所有 win32执行体 (除了VxD和16位的Dll)都使用PE文件格式,包括NT的内核模式驱动程序(kernel mode drivers)。研究PE文件格式给了我们洞悉Windows结构的良机

通常一个操作系统或者用户软件都是用二进制组成的, 有一种结构来约定这些二进制代表什么意义
在这里插入图片描述

当我们随便使用一个16进制编辑工具打开一个软件的时候,展示给我们的就是一个PE结构

在这里插入图片描述
将要学习的PE结构


一、PE为什么要分节?

	1、节省硬盘空间.(这个不是决定的,由编译器决定)

硬盘通常都是1TB,2TB等等,而内存大的也就16G,32G。为什么还要节省硬盘空间呢?
在早起的编译器设置里,硬盘是非常昂贵的。通常移动存储设备也非常小(3.5寸软盘等等),为了方便携带,不占用空间,选择了对pe结构进行压缩,在现代编译器里,通常使用内存对齐和硬盘对齐一样为1000h

在这里插入图片描述

	2、一个应用程序多开

在这里插入图片描述
当我们多开的时候,使用了共同的模块或者数据,如果不分节,那么会为每一个进程创建一个完整的pe结构,内存开销会变得无比巨大!



尝试解析一个PE结构的时候,我们可以直接在16进制编辑器里进行查看

学习PE可以做什么?

iat hook,导入表注入等等,pe结构是逆向的重中之重



PE头字段
1、DOC头:

WORD e_magic * “MZ标记” 用于判断是否为可执行文件.
DWORD e_lfanew; *PE头相对于文件的偏移,用于定位PE文件

2、标准PE头:

WORD Machine; *程序运行的CPU型号:0x0 任何处理器 / 0x14C 386及后续处理器
WORD NumberOfSections; *文件中存在的节的总数, 如果要新增节或者合并节 就要修改这个值.
DWORD TimeDateStamp; *时间戳:文件的创建时间(和操作系统的创建时间无关),编译器填写的.
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader; *可选PE头的大小,32位PE文件默认E0h 64位PE文件默认为F0h 大小可以自定义.
WORD Characteristics; *每个位有不同的含义,可执行文件值为10F 即0 1 2 3 8位置1

3、可选PE头:

WORD Magic; *说明文件类型:10B 32位下的PE文件 20B 64位下的PE文件
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode; *所有代码节的和,必须是FileAlignment的整数倍 编译器填的 没用
DWORD SizeOfInitializedData; *已初始化数据大小的和, 必须是FileAlignment的整数倍 编译器填的 没用
DWORD SizeOfUninitializedData; *未初始化数据大小的和, 必须是FileAlignment的整数倍 编译器填的 没用
DWORD AddressOfEntryPoint; *程序入口
DWORD BaseOfCode; *代码开始的基址,编译器填的 没用
DWORD BaseOfData; *数据开始的基址,编译器填的 没用
DWORD ImageBase; *内存镜像基址
DWORD SectionAlignment; *内存对齐
DWORD FileAlignment; *文件对齐
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage; *内存中整个PE文件的映射的尺寸,可以比实际的值大,但必须是SectionAlignment的整数倍
DWORD SizeOfHeaders; *所有头 + 节表按照文件对齐后的大小,否则加载会出错
DWORD CheckSum; *校验和,一些系统文件有要求.用来判断文件是否被修改.
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve; *初始化时保留的堆栈大小
DWORD SizeOfStackCommit; *初始化时实际提交的大小
DWORD SizeOfHeapReserve; *初始化时保留的堆大小
DWORD SizeOfHeapCommit; *初始化时实践提交的大小
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes; *目录项数目

//DOS头
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
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

//32位NT头
typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

//FILE头
typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

//32位NT头
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;
    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;

猜你喜欢

转载自blog.csdn.net/qq_35425243/article/details/82878148
PE