能力值:
(RANK:260 )
|
-
-
2 楼
一般来说,DLL的入口点应该是用RVA基址加上LORDPE里面的入口点地址吧,如图1
入口点的虚拟地址VA(也就是虚拟地址的定义)确实是RVA+BASE,但这个BASE是指模块被 加载后在内存中的基地址,而对DLL来说这个 加载基址不一定与图中LordPE显示的那个值(叫 默认基址,由PE头中相关字段给出)相等,而对EXE来说几乎总是相等。
但是我居然遇到这样一个DLL,跟这个算法不一样啊`如图2
图2看起来没什么问题啊,入口点RVA=001EB2C,加载后的VA是003EEB2C,说明加载的基址是003D0000 还有一个难题我一直不明白,在看雪也问了几次了,就是DLL的重定位问题,让DLL不能加重定位指令怎么办啊~
没读明白你这句话的意思,什么叫“让DLL不能加重定位指令怎么办”???
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
DLL因为加载他的程序不同,DLL文件的基址是会变的,所以需要重定位,不是PE里面显示的基址。OD入口点地址减去PE入口点地址就是新的基址了。SratMain.DLL我接触过,用OC换算文件偏移成内存地址(OC),这个内存地址是错的,新内存地址VA=内存地址(OC)+(新的基址-PE基址)。这样讲应该比较详细了。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
就是经常在给DLL写入命令的时候,只要写入比如,CALL,PUSH **** RETN这种跳转指令的时候总是会出现CPU100%,后来找到个方法就是吧跳转的地址写入重定位表,但是这个每次都写不方便吧,所以来问一下。。
还有个小小问题就是,我能不能把DLL的LORDPE里面显示的那个基址RVA(0040000)改成003D0000呢??改了貌似DLL不能用了,要是要改怎么改呢??
哇哈哈~得到两位的相助,半夜回帖,非常感谢啊`
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
为什么没人理我了~~~
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
我都看懂了,
你把基址改了是没用的,dll之所以能找到入口点,仍然的根据原来的基址做换算得来的,或者说在重定位表里有它的地址(个人猜测),如果你改了基址,dll加载的时候就再也定位不到原来的位置了
不知道我理解得对不对
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
楼上的好像说得没错啊,我去掉了重定位表就不能再载入DLL了~也就是DLL不能找到入口了~但是这种问题怎么解决呢?》
最重要的问题还是
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
只要写入比如,CALL,PUSH **** RETN这种跳转指令的时候总是会出现卡机的现象
~~~~~~~~~~~~~~~~~~~~~~
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
自发自定~期待高哦人帮助~
|
能力值:
(RANK:260 )
|
-
-
9 楼
DLL文件最好还是保留重定位信息比较好,否则遇到默认基址已经被使用的情况时程序就加载不了了;不像EXE,加载器几乎总是把它加载到默认基址上,因为一般不需要重定位。
你说的push + retn,push后面的地址是绝对地址,必须添加到重定位表才能保证程序可以正确执行。
call指令,分不同的情况。
如果是near的call,即机器码0xe8,0xAAAAAAAA,只要目的地址在同一个dll中,就不用重定位,因为这每次指令使用相对地址(0xAAAAAAAA)。而如果要call不同模块中的地址,通常不用near call,而用下面的函数指针的call。
如果是call [BBBBBBBB],机器码是0xff,0x15,0xBBBBBBBB,这里的函数指针0xBBBBBBBB是绝对地址,就必须重定位了。并且0xBBBBBBBB处的值也需要重定位(当然IAT中的指针是加载器自动重定位的,但自定义的指针则需要手动添加重定位信息)。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
明白了,以前只是知道方法,现在知道原因了~哇哈,书呆彭厉害啊~
那有没有方法可以解决这个问题呢?除了写入重定位表就没别的办法了?
|
|
|