PE文件结构:学习概览

一、前言

PE是 Portable Executable 的缩写,Windows下所有可执行文件都是PE格式。
例如:exe、dll、sys...

PE格式是微软公司规定好的,大致可分为HeaderSection两部分,
如下图:

PE
注:画图工具为drwa.io

header用于管理pe文件,主要包含了PE文件各部分的属性、大小、起始位置等信息。
section部分是我们编写的代码实际存储的区域,但编译器会按照不同功能将代码分类存储在不同部分。
比如:数据可能存储在.data节,而函数则可能存储在.text节。

二、学习PE文件格式其实就是学习以下四点:

(一):数据结构映射

按照不同结构体和数组的定义对PE文件内部进行划分。
数据结构定义可以参见winnt.h文件,在其中搜索Image Format即可找到相关结构体。

(二):结构体解读:

理解不同结构体内部成员的不同含义
参看微软官方文档:
例如:NT头

(三):PE加载过程:

理解PE文件从硬盘加载到内存的过程:
硬盘文件->加载到内存(FileBuffer)->PE Loader加载并拉伸->ImageBuffer(起始位置ImageBase)

我们要明白PE文件在硬盘中和载入内存后大小可能是不一样的,
如下图:

PE加载

注意:拉伸这块是一个学习难点。

(四):改动PE

改动PE可分为以下四类:
1.空白区添加代码
2.增加节
3.扩大节
4.合并节
目的都是为了把我们自己的代码添加进现有的pe文件中。

三、需要了解的PE结构体

struct _IMAGE_DOS_HEADER
struct _IMAGE_NT_HEADERS
struct _IMAGE_FILE_HEADER
struct _IMAGE_OPTIONAL_HEADER
struct _IMAGE_DATA_DIRECTORY
struct _IMAGE_SECTION_HEADER

FILE头和OPTIONAL头,这两个是初期学习的重点。

四、基础代码

除了要掌握c语言的基础语法,以及深刻理解c语言中的指针外,还要能理解下面代码中的8个c函数:

#define FilePath "C:\\Windows\\System32\\notepad.exe"
FILE* pFile = NULL;
char* buffer;
int nFileLength = 0;
pFile = fopen(FilePath, "rb");  //打开文件
fseek(pFile, 0, SEEK_END);      //文件内部指针指向文件尾
nFileLength = ftell(pFile);    //计算文件长度
rewind(pFile);                  //恢复文件内部指针
buffer = (char*)malloc(nFileLength);  //分配内存
memset(buffer, 0, nFileLength);        //将分配的内存中数据初始化为0 
fread(buffer, 1, nFileLength, pFile);  //将文件读入刚才申请的内存中
fclose(pFile);                  //关闭打开的文件

c函数参考文档

有了以上函数,再结合定义好的数据结构,我们就能尝试对pe文件进行加载与修改了。

五、更详细的PE文件结构图

PE
下载原图

六、参考资料

https://www.kanxue.com/chm.htm?id=16807&pid=node1001252
https://bbs.kanxue.com/thread-278377.htm

posted @ 2025-07-20 11:33  leader4  阅读(24)  评论(0)    收藏  举报