首页
社区
课程
招聘
为什么DLL的.reloc块中插入表项后加载时出错???
发表于: 2006-9-9 20:03 4483

为什么DLL的.reloc块中插入表项后加载时出错???

2006-9-9 20:03
4483
我在DLL的.text段插入了一行代码,如下:
    mov [1001E56C],esi
该DLL的默认基址是10000000,但在win2K中被加载到14A000基址中去,
所以要改.reloc块.于是在.reloc块中相应的地方插入了一个表项,
同时修改了列表的长度(长度+2),原位置的列表内容相应后移,
但加载DLL时出错.于是不插入,在.reloc块的末尾添加一个新的列表,
列表只有一项.重新加载没有出错,但用OD查代码处的地址却没有被重定位时
修改.(我肯定插入的表项格式和位置正确,因为我将列表末尾的00项改成相应
的RVA项,加载后用OD查其新值,发觉已被重定位修改成功)
我查看过PE头的.reloc目录项的RVA长度比实际内容长好多.应该不会超出块长.

不知是什么原因, 请问各路高手: .reloc块是否不允许插入新的项吗?如果可以,
该如何办呢?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
2
重定位表的总Size修正了没有?

应该还有简单的解决方法,在这个地址使用之前用代码手动帮其修正重定位后的值应该也可以吧
2006-9-9 20:48
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
理论上应该可以,但应该要写一大段代码(如调用系统的GetProcessInfoA函数等获取基址后对比默认基址,若不同再自己进行修正等),但没有使用重定位表来得简单明了。

我曾经想过借用EIP的值来进行修正,但结果系统不接受EIP作源操作数。

另外我总结出每个重定位列表的表项数必须为偶数,即(列表长度-8)/2的结果不能是奇数。这应该是32位系统的问题吧,奇数项要插入0000来修正。

已经查过PE头的.reloc段的总长,实际是3000B长,RVA中是26B8长。但实际段内的有用数据只得2020B,其余为00。

该DLL修改后用OD查过实际内存,发觉加入的代码的地址已经被修正,但在调用的EXE文件中显式用LoadLibraryA函数加载调用时却中途出现异常:非法访问内存[1612000],提示Shift F7/F8/F9忽略,返回后EAX的值为FFFFFFFF。不知为何,比较前后的DLL,只是插入了一个重定位表项。

插入后则加载出错,但是插入的项起了作用,可以被重定位。另外查过重定位表的最后一项指向的RVA也已经被重定位了,也就是说整个重定位表能被全部执行使用。真是不明白!纳闷!!!
2006-9-10 09:15
0
雪    币: 47147
活跃值: (20380)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
在原重定位表后面追加一个表能行的:
Relocation Block:
    VirtualAddress:  xxxxx
    SizeOfBlock:     xxxxxx

    RVA        Type
    ---------- -----------------
    0x0000xxx HIGHLOW
    0x0000xxx HIGHLOW

如方便将DLL给我,帮你看看。
2006-9-10 11:33
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
非常感谢 fly 大哥和 看雪 坛主的帮忙和建议,刚才问题已经解决了。原因是我误会了fly兄讲的重定位表的总长,以为他是指块表中的RVA总长,所以忽略了。

原来,在PE头中还有个目录索引表,即块表前哪个。里面的size才是关键。修改了后就可以正常加载了。

但还是有点疑惑:为什么size比实际数据短,但实际块中超出的表项指向的RVA却可以被重定位?但又出现访问出错?虽然结果中EAX为负1,但DLL却实际被加载到了内存中去了。而其他块如代码块,我加了代码时只是改了块表的RVA长度而没有改索引表的size却没有出现问题。看来我真是太水皮了,哈哈。。。
2006-9-10 16:47
0
游客
登录 | 注册 方可回帖
返回
//