PE文件加载过程揭秘(3)

2011年10月09日 星期日 16:24

转载自 cvvd
最终编辑 cvvd

让我想想,这集应该谈什么来着?哦,对了,上次说的重定位数据了,嗯。说到数据的重定位,我们就不得不谈谈系统究竟为什么要对数据进行麻烦的重定位?既然在IMAGE_OPTION_HEADER中有一项ImageBase,指定了程序欲加载的位置,那么程序中用到的地址引用就都可以 以映射基址进行定位,但要知道程序(通常是DLL)有时并不总会按照你预想的位置进行加载,举一个简单的例子来说,当一个DLL欲加载到10 00 00 00地址时,此位置恰巧已经有一个ImageBase指定为10 00 00 00的DLL已经在先前的调用中加载进来,这时第二个DLL就不能在此位置上加载了,其所有的以ImageBase为地址基准数据引用和跳转指令都会因此要求进行重定位。这就是为什么在保护模式下DLL通常要重定位的原因了。

我们可以用如下代码生成一个DLL,如图1。

用PEID打开它,我们会发现一个名为.reloc的节(如图2),


通常程序要重定位的数据RVA就存储在该节里了,我们继续用LoadPE打开它的数据目录(如图3)。


在Relocation项,我们得到了重定位表的RVA,数据上就是.reloc节的起始位置,它的文件偏移在节表中得知是800h,继续用WinHex打开DLL文件定位到800H位置(如图4)。


那对于我们来说应该如何翻译这些信息呢?首先了解一下重定位表的结构定义(如图5)。


即第一项是需要重定位的数据的基RVA,第二项是需要重定位数据的数量,紧接着在它们后面的是一个以WORD为元素的数组,一个WORD的16位数据中高4位为重定位数据类型,后12位是相对于基RVA的偏移,即一个重定位表可以重定位偏移1~FFF大小为4KB(一个内存页)的数据。本次例子中的基RVA为1000H+01Ch(后12数据)为需要重定位的数据RVA,我们可以试着在OD中找到它(如图6),


实际上要定位的就是FF25后面那个对API地址的引用。

好了今天就说这么多,老规矩下集预告:资源数据的加载和读取。

posted @ 2012-07-08 10:52  麦小扣_刘  阅读(452)  评论(0编辑  收藏  举报