PE文件格式详解

news2024/10/6 11:29:23

摘要

本文描述了Windows系统的PE文件格式。

PE文件格式简介

PE(Portable Executable)文件格式是一种Windows操作系统下的可执行文件格式。PE文件格式是由Microsoft基于COFF(Common Object File Format)格式所定义的,它规定了Windows可执行文件(.exe)和动态链接库(.dll)的结构,包括文件头、节表、导入和导出表、资源表、重定位表等。PE格式被广泛应用于Windows操作系统及Windows软件开发中,它的特点是文件结构清晰、易于扩展、安全性高等。

PE文件格式分为PE32和PE32+,Windows 32位系统采用的是PE32,Windows 64位系统采用的是PE32+。PE32和PE32+之间的区别如下:

1. PE32+将PE32中的32位RVA字段和尺寸相关字段扩展成了64位。

2. 在PE32+中使用了新的数据结构,其中重要的变化是IMAGE_OPTIONAL_HEADER结构的扩展,以包括更多的字段和属性。

3. PE32+中使用了更多的CPU指令集,包括SSE2、SSE3和AVX等指令,以提高程序的性能和处理能力。

本文以PE32文件格式和x86机器模型作为示例进行讲解。

PE文件主要由若干节(Section)构成,节是PE文件格式的核心概念。

PE文件中节与CPU架构中的段(Segment)的概念相对应。加载器将不同内存访问属性的节被加载进内存后,由CPU的LDTR和GDTR指示的段描述表来描述。程序运行时,CPU通过的各种段选择子(如CS、DS、SS、ES、FS、GS等)来选择对应的段(如:代码段.text、数据段.data)的段描述符,通过前端总线(FSB)来访问段内的代码或数据。

COFF文件结构图

Windows系统中的VC编译出来的目标文件格式采用的COFF文件格式,其结构如下:

COFF(Common Object File Format)文件格式起源于UNIX系统,最早是由AT&T Bell Laboratories和Microsoft合作开发出来的。这种文件格式最初用于存储编译后的目标文件和共享库,并被广泛应用于UNIX系统中。COFF文件格式在1985年被POSIX标准所接受,并逐渐成为了一种通用的目标文件格式。

在后来的Windows平台中,微软对COFF进行了一些修改和扩展,并将其用作PE(Portable Executable)文件的基础格式。PE文件包含了Windows中可执行文件和动态链接库的细节信息,并成为了Windows系统中的主要二进制文件格式。在Windows上,COFF和PE同宗同源,联系紧密,可统称为COFF/PE格式。

PE文件结构图

PE文件结构定义

PE文件结构的定义在winnt.h头文件中,winnt.h典型路径为:

C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\winnt.h

DOS头

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number:'M','Z'
    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;

DOS stub

DOS存根程序,一般只打印程序不能在DOS下运行的提示,也可以是具备完整功能的DOS程序。

在Windows上.exe和.dll文件都包含了DOS头和DOS stub。

映像文件头

PE的映像文件头采用了与COFF的映像文件头一致的结构。

typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine; // 例如:intel 386 | 486 | 568,DEC Alpha AXP, IBM Power PC。
    WORD    NumberOfSections; // 节数量
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader; // 可选头尺寸可为0,也可比标准定义更大。
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

PE可选头

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

//
// 镜像数据目录项结构
//
typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

//
// Optional header format.
//
typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //
    WORD    Magic; // 魔法标记:'P', 'E'
    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; // 子系统类型:Windows | Console
    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[16]根据索引值定义了不同的数据内容的起始RVA和尺寸,此数组是理解PE节内容语义的关键数据结构,它直接描述了导入表、导出表、资源等数据在内存中的RVA和尺寸。

数据是按照内存访问属性合并存储在特定的节中的,而不是按照语义分节的,数据语义和节名称没有对应关系。

节头表

PE文件中的代码、数据、资源全部是存储在不同内存访问属性的节中的,类似竹子的多节结构。

节头用于描述一节的名称、节内容的RVA、节大小、特征(是否缓存、代码、数据)等。

节头由定长尺寸的结构体组成,所有节的节头构成一个节头表。

节头表以一个空的节头结构作为结束标记。

//
// Section header format.
//

#define IMAGE_SIZEOF_SHORT_NAME 8

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME]; // 节名称,最多8个字符
    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;

// 节头固定长度为40
#define IMAGE_SIZEOF_SECTION_HEADER 40

节内容

读者可将可节内容理解为于节头(header)对应的节体(body),类似HTML的头和体。

每一个节的内容是链接器根据代码或数据的内存访问属性合并而成的。

每一个节内容的起始地址和尺寸由节头表中的一个节头项描述。

节内的数据语义分界由IMAGE_DATA_DIRECTORY结构定义。

PE文件分析

dumpbin.exe是微软Visual Studio的一个工具,它可以用于检查和显示二进制文件的详细信息。它可以显示一个可执行文件、静态库、动态库或任何其他二进制文件的导出表、导入表、资源表、头文件、符号表和其他详细信息。它可以被用于分析和调试二进制文件,以了解它们内部的结构和内容。

dumpbin.exe的典型路径为:

%VS_INSTALL_DIR%\VC\Tools\MSVC\14.36.32532\bin\Hostx86\x86\dumpbin.exe

以下是一些dumpbin.exe的用法示例:

1. 显示可执行文件的导入表:

dumpbin /imports myapp.exe

 2. 显示静态库的符号表:

dumpbin /symbols mylib.lib

3. 显示动态库的导出表:

dumpbin /exports mydll.dll

4. 显示PE文件的各种头结构:

dumpbin /headers myfile.bin

5. 显示可执行文件的资源表:

dumpbin /resources myapp.exe

6.显示线程局部存储节的汇总信息和原始数据

dumpbin /section:.tls /rawdata myapp.exe

7.显示代码节的反汇编数据

dumpbin /section:.text /disasm myapp.exe

8.显示RVA重定位表

dumpbin /relocations myapp.exe

dumpbin.exe还有许多其他选项和用法,可以通过运行“dumpbin /?”命令来查看完整的用法和选项列表。

参考资料

PE文件结构详解-1

PE文件结构详解-2

PE Format - Win32 apps | Microsoft Learn

PE文件结构详解_大囚长的博客-CSDN博客

PE结构详解_weixin_44870554的博客-CSDN博客

PE文件格式 - 随笔分类 - 不会笑的孩子 - 博客园 (cnblogs.com)

PE结构分析 - Lonely Blog (wuhao13.xin)

DUMPBIN 选项 | Microsoft Learn

总结

PE文件格式是学习Windows系统反病毒、手动查杀木马技术所要求的前置基础知识,需要深刻领会。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/973913.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

16|女性视角:李清照笔下独到的细腻

好诗相伴,千金不换。你好,我是天博。 前面我们说了这一章的主题是“见众生”,见众生就是读诗词里的人性。截止到现在,我们已经感受了杜甫面对人民的悲悯,刘禹锡面对贬谪的耿直,而今天这一讲,我…

智能合约安全,著名的区块链漏洞:双花攻击

智能合约安全,著名的区块链漏洞:双花攻击 介绍: 区块链技术通过提供去中心化和透明的系统彻底改变了各个行业。但是,与任何技术一样,它也不能免受漏洞的影响。一个值得注意的漏洞是双花攻击。在本文中,我们将深入研究…

告别复杂的绘画软件!选择Growly Draw for Mac,让你的创作更轻松

Growly Draw for mac是一款快速绘画应用,让你可以在Mac电脑上轻松创作美丽的绘画作品。这个应用程序并不像Photoshop那样拥有丰富的功能,但它的简约设计使得那些基本的绘画任务变得轻松便捷。 如果你对绘画充满热情,但缺乏专业的绘画技巧&am…

Python调用Jumpserver的Api接口增删改查

引言 Jumpserver是一款强大的堡垒机系统,可以有效管理和控制企业内部服务器的访问权限,提高网络安全性。本文将介绍如何使用Python编程语言,结合Jumpserver提供的API接口,实现对跳板机的管理和操作。 1、什么是Jumpserver&#…

气传导耳机怎么样?市面上热门气传导耳机推荐

​气传导耳机不仅能够提升幸福感还能听到周围环境声,大大提高安全性。如果你在寻找一款高品质的气传导耳机,又不知从何入手时,不要担心,我已经为你精心挑选了四款市面上综合表现很不错的气传导耳机,让你享受更好的音质…

达梦类型转换问题-float转换为varchar

表结构 CREATE TABLE "SYSDBA"."TABLE_2" ( "COLUMN_1" FLOAT, "COLUMN_2" NUMERIC(22,6)) STORAGE(ON "MAIN", CLUSTERBTR) ; 表数据: 查询,将numeric转换为float,再转换为varchar&…

Spring Boot 整合 Redis,使用 RedisTemplate 客户端

文章目录 一、SpringBoot 整合 Redis1.1 整合 Redis 步骤1.1.1 添加依赖1.1.2 yml 配置文件1.1.3 Config 配置文件1.1.4 使用示例 1.2 RedisTemplate 概述1.2.1 RedisTemplate 简介1.2.2 RedisTemplate 功能 二、RedisTemplate API2.1 RedisTemplate 公共 API2.2 String 类型 A…

通讯行业:看完这篇文章,我的认知被刷新了!

在现代社会中,通讯系统已经成为我们生活中不可或缺的一部分,它们支撑着信息传递、数据交流和社交互动。然而,通讯系统的可靠性和连续性依赖于电源的稳定供应。电源中断或波动可能导致通讯中断,给个人、企业和组织带来巨大的不便和…

Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis

功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查看…

港陆证券:服装家纺公司上半年投资并购力度加大

9月1日,嘉曼服饰发布公告,为完善多品牌差异化开展战略,将以自有资金收买暇步士(Hush Puppies)品牌我国内地及香港、澳门区域IP财物。 面对服饰市场的激烈竞争,本年以来一些服饰类A股公司开启了“买买买”形…

西贝餐饮集团贺赞贤:Smartbi及指标体系的应用助力销供产业务协同

“传统的供应链数字化运营,是自下而上的需求驱动,存在效率低下、口径不统一、分析不敏捷等问题。西贝亟需自上而下构建完善科学的指标体系,实现敏捷、灵活、统一的应用。因此借助Smartbi以指标为核心的一站式ABI平台,梳理指标体系…

Spring事务(ACID特性、隔离级别、传播机制、失效场景)

一、事务的ACID特性 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。一致性(Consistency) 事务前后数据的完整性必须保持一致。隔离性(Isola…

数据库概念

定义: 数据库(Database 简称DB)是持久存储有组织/可共享数据/的容器 数据库管理系统(MySQL、Oracle、DB2)是操作/和管理数据库/的软件 分类: 关系(型)数据库 (MySQL、Oracle、SQL Server、SQLite、DB2) 非关系(型)数据库 (Redis…

大模型 Dalle2 学习三部曲(二)Latent Diffusion Models学习

引言 Diffusion model大获成功,但是它的短板也很明显,需要大量的计算资源,并且推理速度比较慢。如何才能提升Diffusion model的计算效率。业界有各种各样的改进,无疑Latent Diffusion Models(潜在扩散模型,…

基于Java+SpringBoot+Vue前后端分离善筹网(众筹)设计和实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

Bootstrap的行、列布局设计(网络系统设计)

目录 00-基础知识01-等宽列布局02-指定某一列的宽度03-根据内容自动改变列的宽度04-五种预定义列宽度 .col、.col-sm-*、.col-md-*、.col-lg-*、.col-xl-*05-不同视口宽度按不同的分列方案划分06-删除列内容的盒模型的外边距07-超过12列怎么办?08-重新排列各列的顺序…

【数据结构初阶】一. 复杂度讲解

相关代码gitee自取: C语言学习日记: 加油努力 (gitee.com) 接上期: 学C的第三十四天【程序环境和预处理】_高高的胖子的博客-CSDN博客 1 . 算法效率 (1). 什么是数据结构: 数据结构(Data Structure)是计算机存储、…

MyBatis Plus 学习笔记

MyBatis Plus 国产的开源框架,基于 MyBatis 核心功能就是简化 MyBatis 的开发,提高效率。 MyBatis Plus 快速上手 Spring Boot(2.3.0) MyBatis Plus(国产的开源框架,并没有接入到 Spring 官方孵化器中) 1、创建 …

Grad-CAM 小陈读paper系列(摘要加引言)

Abstract 我们提出了一种基于卷积神经网络 (CNN) 的模型的决策生成“视觉解释”的技术,使它们更加透明。我们的方法——梯度加权类激活映射(Grad-CAM), 使用任何目标概念的梯度(例如“狗”甚至标题的 logits&#xf…

新品登场!雅特力发布AT32F402与AT32F405高速USB2.0 OTG MCU

因应高速USB市场需求,产品技术不断推陈出新,USB2.0发展带来的高速连接能力,优化消费者的产品使用体验,且由于支持即插即用和热插拔,提高设备易用性,USB接口在各项设备中成为主流通用接口。在USB2.0标准中&a…