好友
阅读权限10
听众
最后登录1970-1-1
|
Kris
发表于 2011-7-25 14:27
本帖最后由 Kris 于 2011-7-25 14:39 编辑
大家都知道,很多程序都带有重定位,特别是DLL文件,总是会出现,这给我们对程序的研究和修改造成了一些麻烦,同时重定位的定义,作用,修改也还有很多童鞋都不会(我也一样=.=都是小菜),就此,我这几天通过查找大量资料并研究,对重定位终于有所理解,所以发表这篇帖子与大家一起分享我对重定位的一些见解,当然,我已经说了,我也是一个刚入门的新手,在这次的分析中,可能会出现错误,希望发现错误的大牛们能及时指正,灰常感谢!
重定位定义:
重定位就是把程序的逻辑地址空间变换成内存中的实际物理地址空间的过程,也就是说在装入时对目标程序中指令和数据的修改过程。他是实现多道程序在内存中同时运行的基础.
这里给出几句代码,来说明重定位的作用
从这几句代码中不难发现,这几句代码的目的地址都是用直接寻址的方式来表示的,在代码的十六进制中,可以看到都是直接使用地址来表示的,当文件运行时,系统会分配一块内存给文件,如果分配的内存与文件镜像基址相同,这些代码则可以正常执行,但是当分配到的内存与文件镜像基址不同的时候,这些指令就会出现错误了,这个时候系统将会获取文件的重定位信息,并把错误指令修正.
比如PUSH 403010这一句是在某个基址为400000的文件中的,当文件运行的时候,系统分配到的内存为500000,那么PUSH 403010这一指令如果是在重定位中,
系统就会在加载时把它修复为PUSH 503010
这样就保证了分配到的内存与基址不同的时候也能正常运行
重定位结构:
struct _IMAGE_BASE_RELOCATION
{
DWORD VirtualAddress; //重定位数据开始的RVA地址
DWORD SizeOfBlock; //重定位块的长度
WORD TypeOffset; //重定位项位数组
} IMAGE_BASE_RELOCATION;
VirtualAddress:
是这一组重定位数据的开始RVA地址.各重定位项的地址加上这个值才是该重定位项完整的RVA地址.
SizeOfBlock:
是重定位结构的大小
TypeOffset:
是一个数组.数组每项大小为两个字节,共16位.它又分为高4位和低12位,高4位代表重定位类型;低12位是重定位地址,它与VirtualAddress相加即是指向PE映像中需要修改的地址数据的指针.
看了基本的重定位知识,大家是不是感到有点迷茫?没关系,下面来示例分析说明一下重定位的作用和结构
首先,要明确一点,EXE通常是不需要重定位的,为证明这一点,
我们来用LordPE看一下本例中的DEDE.EXE,
该EXE是存在重定位的,现在我们将重定位手动删除,首先记录下重定位的RVA地址:001B6000,转换为文件偏移为:001AFC00,重定位大小为:0001B4E4,
我们把1AFC00~1CB0E4(1AFC00+1B4E4)用00填充,并且在LordPE中把重定位的RVA和大小都填0
现在我们再来运行DEDE.EXE,发现该EXE仍然能正常运行.这就证明了该EXE文件并不需要重定位
现在,我们再来研究DLL15.DLL,该DLL为我自己写出来的一个DLL,其代码仅此一句
::MessageBox(NULL,"Yeah,Success!","Test",NULL);
我们和刚才一样,使用LordPE查看其重定位表,并删除其重定位,
该DLL文件的重定位RVA为4000(文件偏移同为4000),大小为10,
也就是说我们需要对4000~4010用00填充,
之后把LordPE里面的重定位信息删掉
接着,我们用OD加载该DLL并运行
发现会出现错误
而我们用OD加载原来的DLL运行,则能正常运行并弹出Message
现在我们再来做1个实验
我们用LordPE的PE编辑器可以看到,
DEDE.EXE的镜像基址为400000,然后把它载入到OD中,发现系统分配的内存空间与EXE的基址相同
DLL15.DLL的镜像基址为400000,然后把它载入到OD中,发现系统分配的内存空间与EXE的基址不同
就此我们就可以得到如下理论:
EXE作为独立的可执行程序,它初始化时系统会给它分配独立的进程内存空间,这个刚分配的内存空间肯定是可以分配一块与EXE的基址相同地址的内存来装载EXE本身,因此通常不需要重定位.而DLL没有独立的进程空间,每次系统分配到的内存地址与基址不一定是相同的,所以DLL总是需要重定位.
接下来我们继续深入解析一下重定位结构IMAGE_BASE_RELOCATION,我们就用DLL15.DLL来分析.
通过前面的实验,已经知道其重定位的偏移量为4000,大小为10,现在我们把它载入到C32Asm中,跳到重定位,可以看到
接下来我们继续载入到LordPE中,发现与我们刚才分析得到的数据是一样的
这就说明了我们的分析的正确的,也说明了,我们在修改程序的过程中,如果碰到修改重定位数据应该对对应的TypeOffset进行修改,以保证程序的正常运行
那么这次对基址重定位的分析就到这里了,我也是一个刚入门的新手,在这次的分析中,可能会出现错误,希望发现错误的大牛们能及时指正,灰常感谢!
附上DLL15.DLL
DLL15.rar
(508 Bytes, 下载次数: 64)
|
免费评分
-
查看全部评分
|