返回列表 发帖

回复: 装入一个exe, 并执行

我看了这个帖子: http://www.thysea.com/lb/cgi-bin/topic.cgi?forum=127&topic=1606
但是由于这个帖子太旧了, 不能回复, 所以只能到这里请教.
太棒了. 这是我寻找已久的主题.
相信作者已经进行了试验, 我有一点不明白, 还请大侠赐教.
为什么必须LoadLibraryEx(), 然后自己搞定引入表?
我知道使用LoadLibrary()装入exe后,执行入口不成功,而且会出错, 但是自己搞定
引入表有什么不同吗?
我自己就是使用了LoadLibrary(),然后找到入口点, 并执行之, 然后就在那个exe调用系统函数的时候出错了. 具体是WinMainCRTStartup()中的GetVersionExA(). 仔细检查发现是存放GetVersionExA的地址根本不在指令引用的内存.

回复: 装入一个exe, 并执行

大体看了下原帖子,有一部分还是冒看懂...
对于楼主的问题:为什么必须LoadLibraryEx(), 然后自己搞定引入表?
我知道使用LoadLibrary()装入exe后,执行入口不成功,而且会出错, 但是自己搞定
引入表有什么不同吗?
LoadLibraryEx()是把其载入内存,这你是知道的,对于导入表中的函数的地址,这是每个windows装载器在装载的时候都必须重新覆盖的.因为不同版本的系统,其提供的动态库的相同API的导出地址是不同的.系统必须用GetProAddress来重新获取其正确地址并进行覆盖.否则一个win2000下编译的程序中所产生的函数导入地址,到了xp上将不能正确使用.我想你所说的GetVersionExA的错误便是如此.
该程序实际的功能便是模拟了该过程,找到导入表的函数地址,然后根据导入函数名和模块名获取在本机上的正确的导入地址,然后修改内存属性,最后重新覆盖了导入表的函数地址,使其能正确实现跳转.在修改完导入表后,找到启动进程的加载地址和入口地址,然后定义一个函数指针,使流程跳转到该文件入口地址运行.这样就似乎以一个线程的方式运行了该进程.

TOP

回复: 装入一个exe, 并执行

楼上的回复我觉得是不对的.
因为这和操作系统的版本没有关系. 问题是如果按照进程装入一个exe, 那么它的基址就是MODULE是0x00400000,而LoadLibrary()装入则不是这个地址. 而exe文件中引用系统函数是间接引用, 就是先把系统函数的地址放入内存地址__imp__XXX, xxx是函数名,然后调用该地址指向的函数. 这样系统装入exe或者DLL的时候, LoadLibrary()会自动修改__imp_xxx的值, 使之指向当前系统函数的地址.
现在是LoadLibrary()已经正确修改了LoadLibrary()装入的exe文件中的__imp_XXX的值, 但是变量__imp_xxx本身的地址是以LoadLibrary()装入的地址作为基址的. 而exe中引用的__imp_xxx却是以0x00400000为基址的, 那么指令中变量__imp_xxx的地址自然就不是LoadLibrary()修改的那个地方, 因而导致出错了.
所以问题不是在系统函数地址装错了, 而是那个间接引用错了. 但是如何改正这个间接引用的错误呢? LoadLibraryEx()有什么不同呢? 即使自己重新设置引入表还是不能解决问题啊.
高手请帮忙啊.

TOP

回复: 装入一个exe, 并执行

我始终认为这个问题是有解决之道的, 因为PE文件,包括exe, 都是可重定位的啊.[br][br]-=-=-=-=- 以下内容由 linghuchong2006年06月11日 11:05am 时添加 -=-=-=-=-

TOP

回复: 装入一个exe, 并执行

请高手指点阿!

TOP

返回列表 回复 发帖