【逆向基础】十六、PE文件格式(一)

发布于:2024-11-04 ⋅ 阅读:(167) ⋅ 点赞:(0)

一、简介

PEPortable Executable)文件格式是在Windows操作系统下的一种32位的可移植、可执行文件格式。在学习PE文件格式的过程中,也可以梳理优化进程、内存、DLL等内容,它们是Windows操作系统最核心的部分。值得我们花时间去消化。根据PE正式规范,将PE文件分为一下种类;
在这里插入图片描述

二、PE文件内容映射

1、PE文件内容

下面以windows系统路径“C:\Windows\System32”中的"cmd.exe"为例,开始讲解PE文件格式的基本结构,以十六进制方式查看"cmd.exe"文件,部分内容如下图所示:
cmd.exe文件

2、PE文件内容映射到内存

PE文件内容映射都内存时的情况如下图所示;文件中的内容可分为代码节区(“.text”)、数据节区(“.data”)、资源节区(“.rsrc”)等别分保存在不同位置;各个节区头定义了对应节区在文件或内存中的大小,位置,属性等;
值得注意的是:
(1) 在文件中使用偏移(offset)来表示位置;
(2) 在内存中使用虚拟地址(VA:Virtual Address)来表示位置。
(3) PE头与各节区尾部都存在一个NULL填充(null padding)区域.目的是通过使用“最小基本单位”的概念,让内存或文件中的位置都落在最小单位的倍数上;这样即可以让计算机提高内存中,内存,网络包的处理效率;也可以提高处理文件中数据的效率;
在这里插入图片描述

3、PE文件内容映射到内存后的定位

3.1 前言

在理解如果定位前,我们需要理解如下单词含义
ImageBase:表示基准地址,表示PE文件(DLL文件为主)加载到进程的虚拟内存时的特定位置;
VA:表示虚拟地址(Virtual Address),指的是进程虚拟内存中的绝对地址;
RVA:表示相对虚拟地址(Relative Virtual Adress),指的是从某个基准位置(ImageBase)开始的相对地址;
VA与RVA满足如下关系式: VA = RVA + ImageBase

3.2 机器码定位讲解( RVA to FOA)

PE文件(dll为主)加载到内存时,往往会遇到重定位(Relocaiton)的问题,可能导致加载位置与文件中预定的加载位置不同而定位失败;为了解决这个问题,PE文件头信息中的地址使用的是RVARelative Virtual Adress);这样即使基准位置ImageBase改变,只要相对于基准位置的相对偏移没有变化,就能正常访问到指定信息。

遵循关系式: VA = RVA + ImageBase
遵循关系式:FOA - PointerToRawData = RVA

核心等价关系:文件中 与 内存中的机器码相对于节区起始地址的偏移相等
通俗地说就是某特定代码相对于自己节区起始地址的位置,在映射到内存后是不变的;
请添加图片描述

3.3 机器码定位举例(已上图为依据举例)

举例1:若已知内存中指定机器码的RVA = 1500,求文件中机器码的offset(FOA:file Offset Address).

解:设机器码在文件中偏移为x. 首先查RVA所属内存中的节区为“.text”,因为 1000 < 1500 < 2000;
(其中ImageBase = 01000000); 然后计算机器码相对内存中节区起始地址的偏移:内存_offset = 1500 - 1000 = 500;(“.text”节区在内存起始地址为1000
最后计算机器码相对文件中节区起始地址的偏移:文件_offset = x - 400;
(“.text"节区在文件起始地址为400) 根据等价关系 内存_offset = 文件_offset;求得 `500 = x

  • 400; 最终 x = 900`;

举例2:若已知内存中指定机器码的RVA = 4100,求文件中机器码的offset(FOA:file Offset Address).

解:设机器码在文件中偏移为x.
首先查RVA所属内存中的节区为“.rsrc”,因为 4000 < 4100 < C000;(其中ImageBase = 01000000);
然后计算机器码相对内存中节区起始地址的偏移:内存_offset = 4100 - 4000 = 100;(“.text”节区在内存起始地址为4000
最后计算机器码相对文件中节区起始地址的偏移:文件_offset = x - 2E00;
(“.text"节区在文件起始地址为2E00) 根据等价关系 内存_offset = 文件_offset;求得 100 = x - 2E00; 最终 x = 2F00;

举例3:如下图所示,使用IDA打开cmd.exe文件查看内存中的机器码时,已知机器码的地址是0x14005900,求相同机器码在文件中的地址;

由图可知:设地址为x. 节区“.pdata”在内存中的起始地址是59000;(Virtual address = 59000
节区“.pdata”在文件中的起始地址是3BC00;
RVA = VA - ImagBase = 0x140059000 -0x140000000 = 59000
由于内存_offset = 59000 - 59000 = 0
所以文件_offset = X - 3BC00 = 0; 最后的x = 3BC00

三、小结

熟悉PE文件于内存之间的映射关系,可以帮助我们在逆向过程中,快速定位机器码的位置。是一项非常基础且必不可少的知识点。同样的原理拓展后,我们还可以在逆向过程中快速将动态分析(x32dbg为主)和静态分析(IDA为主)的机器码匹配关联,快速跟踪分析问题。值得我们花时间去瞧瞧哈。


网站公告

今日签到

点亮在社区的每一天
去签到