PE文件格式详解

摘要

本文描述了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 headerWORD   e_magic;                     // Magic number:'M','Z'WORD   e_cblp;                      // Bytes on last page of fileWORD   e_cp;                        // Pages in fileWORD   e_crlc;                      // RelocationsWORD   e_cparhdr;                   // Size of header in paragraphsWORD   e_minalloc;                  // Minimum extra paragraphs neededWORD   e_maxalloc;                  // Maximum extra paragraphs neededWORD   e_ss;                        // Initial (relative) SS valueWORD   e_sp;                        // Initial SP valueWORD   e_csum;                      // ChecksumWORD   e_ip;                        // Initial IP valueWORD   e_cs;                        // Initial (relative) CS valueWORD   e_lfarlc;                    // File address of relocation tableWORD   e_ovno;                      // Overlay numberWORD   e_res[4];                    // Reserved wordsWORD   e_oemid;                     // OEM identifier (for e_oeminfo)WORD   e_oeminfo;                   // OEM information; e_oemid specificWORD   e_res2[10];                  // Reserved wordsLONG   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 | ConsoleWORD    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 8typedef struct _IMAGE_SECTION_HEADER {BYTE    Name[IMAGE_SIZEOF_SHORT_NAME]; // 节名称,最多8个字符union {DWORD   PhysicalAddress;DWORD   VirtualSize;} Misc;DWORD   VirtualAddress; // 节内容的起始RVADWORD   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.rhkb.cn/news/120739.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 实现本地一键打包,告别繁琐的studio操作

前言 在实际开发项目中,我们的工程目录往往是多个app在一个工程下的,每次打包都需要手动的用studio点击Build->Generate Signed Bundle or APK->APK 选择app,签名等,甚至有的app签名还不一样,还需要手动的来回切…

NC后端扩展开发

前言 在日常的工作中,会遇到各种各样的需要进行扩展开发的需求,可以使用系统预留的扩展开发机制来实现,避免修改源码。因NC产品已迭代至BIP版本,所以前端扩展方式就再进行不赘述了,本文主要介绍后端扩展开发方式&…

【FreeRTOS】【应用篇】消息队列【下篇】

前言 本篇文章主要对 FreeRTOS 中消息队列的概念和相关函数进行了详解消息队列【下篇】详细剖析了消息队列中发送、接收时队列消息控制块中各种指针的行为,以及几个发送消息和接收消息的函数的运作流程笔者有关于 【FreeRTOS】【应用篇】消息队列【上篇】——队列基…

redis 数据结构(二)

整数集合 整数集合是 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素,并且元素数量不时,就会使用整数集这个数据结构作为底层实现。 整数集合结构设计 整数集合本质上是一块连续内存空间,它的结构定义如下: typed…

nginx使用详解

文章目录 一、前言二、nginx使用详解2.1、nginx特点2.2 静态文件处理2.3 反向代理2.4 负载均衡2.5 高级用法2.5.1 正则表达式匹配2.5.2 重定向 三、总结 一、前言 本文将详细介绍nginx的各个功能使用,主要包括 二、nginx使用详解 2.1、nginx特点 高性能&#xff…

Unity中Shader的面剔除Cull

文章目录 前言一、Unity中Shader的面是否剔除,是由我们自己决定的二、暴露一个属性来控制 剔除模式三、如何区分正反面 前言 Unity中Shader的面剔除 Cull Off | Back | Front 一、Unity中Shader的面是否剔除,是由我们自己决定的 使用 Cull Off | Back |…

Pygame中Trivia游戏解析6-3

3.3 Trivia类的show_question()函数 Trivia类的show_question()函数的作用是显示题目。主要包括显示题目框架、显示题目内容和显示题目选项等三部分。 3.3.1 显示题目的框架 在show_question()函数中,通过以下代码显示题目的框架。 print_text(font1, 210, 5, &q…

【AI】数学基础——数理统计(概念参数估计)

概率论 文章目录 3.6 数理统计概念与定理3.6.1 概率论与数理统计区别3.6.2 基本定理大数定理马尔科夫不等式切比雪夫不等式中心极限定理 3.6.3 统计推断的基本问题 3.7 参数估计3.7.1 频率派点估计法矩阵估计法极大似然估计点估计量的评估 区间估计 3.7.2 贝叶斯派贝叶斯定理条…

Spring Boot 整合 Shiro(后端)

1 Shiro 什么是 Shiro 官网: http://shiro.apache.org/ 是一款主流的 Java 安全框架,不依赖任何容器,可以运行在 Java SE 和 Java EE 项目中,它的主要作用是对访问系统的用户进行身份认证、 授权、会话管理、加密等操作。 …

【ARM CoreLink CCI-400 控制器简介】

文章目录 CCI-400 介绍 CCI-400 介绍 CCI(Cache Coherent Interconnect)是ARM 中 的Cache一致性控制器。 CCI-400 将 Interconnect 和coherency 功能结合到一个模块中。它支持多达两个ACE master 点的interface,例如: Cortex-A…

[Mac软件]Adobe After Effects 2023 v23.5 中文苹果电脑版(支持M1)

After Effects是动画图形和视觉效果的行业标准。由运动设计师、平面设计师和视频编辑用于创建复杂的动画图形和视觉上吸引人的视频。 创建动画图形 使用预设样式为文本和图形添加动画效果,或逐帧调整它们。编辑、添加深度、制作动画或转换为可编辑的路径&#xff…

【Python】pytorch,CUDA是否可用,查看显卡显存剩余容量

CUDA可用,共有 1 个GPU设备可用。 当前使用的GPU设备索引:0 当前使用的GPU设备名称:NVIDIA T1000 GPU显存总量:4.00 GB 已使用的GPU显存:0.00 GB 剩余GPU显存:4.00 GB PyTorch版本:1.10.1cu102 …

【C++】C++面向对象编程三大特性之一——继承

❤️前言 本篇博客主要是关于C面向对象编程中的三大特性之一的继承,希望大家能和我一起共同学习进步! 正文 我们刚刚学习一块全新的知识,首先简单关注一下它的概念和简单的使用方法。 继承的概念及定义 继承的概念 继承的概念:…

HDFS HA 高可用集群搭建详细图文教程

目录 一、高可用(HA)的背景知识 1.1 单点故障 1.2 如何解决单点故障 1.2.1 主备集群 1.2.2 Active、Standby 1.2.3 高可用 1.2.4 集群可用性评判标准(x 个 9) 1.3 HA 系统设计核心问题 1.3.1 脑裂问题 1.3.2 数据状…

从C++98到C++26,经历了什么?

作为一名程序员,2023年最应该关注的话题就是C的标准更新。 C标准遵循3年开发周期,并以发布年份命名。C在临发布的一年前会进入“功能冻结期(feature freeze)”,即版本开发进入半稳定状态,不再添加重大功能及…

【RPC 协议】序列化与反序列化 | lua-cjson | lua-protobuf

文章目录 RPC 协议gRPCJSON-RPC 数据序列化与反序列化lua-cjsonlua-protobuf RPC 协议 在分布式计算,远程过程调用(英语:Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调…

机器学习部分知识点总结

文章目录 基本概念N与NP泛化能力性能度量比较检验 线性回归逻辑回归神经网络 基本概念 N与NP P问题:一个问题可以在多项式(O(n^k) 的时间复杂度内解决 例如:n个数的排序(不超过O(n^2)) NP问题:一个问题的解…

Leetcode 16.07 最大数值

编写一个方法,找出两个数字a和b中最大的那一个。不得使用if-else或其他比较运算符。 示例: 输入: a 1, b 2 输出: 2 我的答案: 为了找出两个数中的较大者,而不使用比较或条件语句,我们可以…

常见的几种排序算法

目录 一、插入排序 1、直接插入排序 1.1、排序方法 1.2、图解分析 1.3、代码实现 2、希尔排序 2.1、排序方法 2.2、图解分析 2.3、代码实现 二、选择排序 1、直接选择排序 1.1、排序方法 1.2、图解分析 1.3、代码实现 2、堆排序 2.1、排序方法 2.2、图解分析 …

视频监控/视频汇聚/视频云存储EasyCVR平台接入国标GB协议后出现断流情况,该如何解决?

视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。安防监控平台EasyCVR既具备传统安防视频监控的能…