鱼C论坛

 找回密码
 立即注册
查看: 3664|回复: 5

[学习笔记] 《解密系列-系统篇》第六讲:PE结构详解6

[复制链接]
发表于 2018-1-19 21:55:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 shuiyu 于 2018-1-19 22:04 编辑

越努力,越幸运。欢迎大家来看我的笔记,不对的请各位大佬指正,谢谢


一、区块描述
(1)PE 文件一般至少都会有两个区块:一个是代码块,另一个是数据块。每一个区块都需要有一个截然不同的名字,这个名字主要是用来表达区块的用途。(通常,区块中的数据在逻辑上是关联的)

(2)例如有一个区块叫.rdata,表明他是一个只读区块。注意:区块在映像中是按起始地址(RVA)来排列的,而不是按字母表顺序。

(3)使用区块名字只是人们为了认识和编程的方便,而对操作系统来说这些是无关紧要的。微软给这些区块取了个有特色的名字,但这不是必须的。当编程从PE 文件中读取需要的内容时,如输入表、输出表,不能以区块名字作为参考,正确的方法是按照数据目录表中的字段来进行定位。

(4)常用的区块名称以及意义(注意这些区块名只用于参考没有实际意义,真正的属性要到字段中定位得到)
1_1.JPG


二、区块的对齐值
(1)PE文件在内存中存放和在磁盘中存放,他们的对齐值一般是不同的。PE 文件头里边的FileAligment 定义了磁盘区块的对齐值。每一个区块从对齐值的倍数的偏移位置开始存放。而区块的实际代码或数据的大小不一定刚好是这么多,所以在多余的地方一般以00h 来填充,这就是区块间的间隙。

(2)例如,在PE文件中,一个典型的对齐值是200h ,这样,每个区块都将从200h 的倍数的文件偏移位置开始,假设第一个区块在400h 处,长度为90h,那么从文件400h 到490h 为这一区块的内容,而由于文件的对齐值是200h,所以为了使这一区块的长度为FileAlignment 的整数倍,490h 到 600h 这一个区间都会被00h 填充,这段空间称为区块间隙,下一个区块的开始地址为600h 。

(3)PE 文件头里边的SectionAligment 定义了内存中区块的对齐值。PE 文件被映射到内存中时,区块总是至少从一个页边界开始。一般在X86 系列的CPU 中,页是按4KB(1000h)来排列的;在IA-64(X64)上,是按8KB(2000h)来排列的。所以在X86 系统中,PE文件区块的内存对齐值一般等于 1000h,每个区块按1000h 的倍数在内存中存放。(同理X64一般为2000h)

三、RVA(相对虚拟地址) 和文件偏移的转换
(1)一个可执行程序加载到内存中,是由windows装载器来分配地址的。RVA 是当PE 文件被装载到内存中后,某个数据位置相对于文件头的偏移量。举个例子,如果 Windows 装载器将一个PE 文件装入到 00400000h 处的内存中,而某个区块中的某个数据被装入 0040xx xxh 处,那么这个数据的 RVA 就是(0040xx xxh - 00400000h )= xx xxh,反过来说,将 RVA 的值加上文件被装载的基地址,就可以找到数据在内存中的实际地址。

(2)在PE文件映射到内存中时,DOS 文件头、PE 文件头和区块表的偏移位置都不会发生变化。而各个区块映射到内存后,其偏移位置就发生了变化(下图的块表(区块表)画错了,块表不会变化的)。RVA 使得文件装入内存后的数据定位变得方便,然而却给我们要定位位于磁盘上的静态PE 文件带来了麻烦。
5.png


(3)磁盘中的对齐值和内存中的对齐值不一定相同,所以会出现两种情况;
如果对齐值相同的话,根据PE_info(就是小甲鱼写的那个根据)得到的那些数据的RVA就是正确的,但是
如果对齐值不相同的话,根据根据得到的RVA就不一定是正确的了,需要我们自己去找了(看下面由讲解。。)

四、如何换算 RVA 和文件偏移呢?
(1)当处理PE 文件时候,任何的 RVA 必须经过到文件偏移的换算,才能用来定位并访问文件中的数据,但换算却无法用一个简单的公式来完成,事实上,唯一可用的方法就是最土最笨的方法:

(2)方法:
步骤一:循环扫描区块表得出每个区块在内存中的起始 RVA(根据IMAGE_SECTION_HEADER 中的VirtualAddress 字段),并根据区块的大小(根据IMAGE_SECTION_HEADER 中的SizeOfRawData 字段)算出区块的结束 RVA(两者相加即可),最后判断目标 RVA 是否落在该区块内。

步骤二:通过步骤一定位了目标 RVA 处于具体的某个区块中后,那么用目标 RVA 减去该区块的起始 RVA ,这样就能得到目标 RVA 相对于起始地址的偏移量 RVA2.

步骤三:在区块表中获取该区块在文件中所处的偏移地址(根据IMAGE_SECTION_HEADER 中的PointerToRawData 字段), 将这个偏移值加上步骤二得到的 RVA2 值,就得到了真正的文件偏移地址。

(3)例子:找到位于66666h的真正的文件偏移地址。
1.首先定位目标 RVA 处于具体的哪个区块?
根据每个区块在内存中的起始 RVA和结束 RVA,判断目标 RVA 是否落在该区块内。
结束RVA如何得到?每个区块在内存中的起始 RVA,加上区块的大小即可得到。然后就一个个区块的找,最后我们发现我们的66666h落在了".reloc"区块。
2.JPG

2.找到目标RVA处于哪个区块后,得到目标 RVA 相对于起始地址的偏移量 RVA2。
我们的目标RVA为:66666h;所在区块的起始RVA为:66000h(在1中已经得到了哦~)
相减得到RVA2,即:RVA2=66666h-66000h=666h

3.获得真正的文件偏移地址。
该区块在文件中所处的偏移地址(在1的图中已经标注出来了),加上RVA2就行了。
所以:真正的文件偏移地址=60E00h+666h=61466h
即下面的就是66666h的真正的文件偏移地址。
3.JPG





谢谢小甲鱼带来的视频教程,感谢!!

本节结束,多谢览阅!
越努力,越幸运。谢谢大家来看我的笔记,不对的请各位大佬指教,谢谢

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-1-20 11:07:37 | 显示全部楼层
支持一下,继续努力
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-3-1 12:23:20 | 显示全部楼层
支持,要继续加油哟。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-3-1 16:26:49 | 显示全部楼层
Helen-00 发表于 2018-3-1 12:23
支持,要继续加油哟。

嗯嗯,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-7-26 17:19:10 | 显示全部楼层
打卡学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-7-30 13:06:26 From FishC Mobile | 显示全部楼层
讲得很清晰。
666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-24 20:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表