如何加载Dll到指定地址?

bacy001 2011-04-12 02:34:46
Dll 中有一个默认载入地址,一般是:0x10000000

如果加载时,从这个地址开始的内存段能够容纳下此 Dll 文件,那么系统会将此 Dll 加载到 0x10000000

否则系统会将 Dll 加载到进程空间中的其他可用位置!

我现在的问题是,有没有办法能够手动指定一个地址用于加载!

通过修改Dll文件可以做到,但是太麻烦了!请教各位高手!
...全文
376 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
bulerain 2011-04-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lactoferrin 的回复:]
引用 5 楼 bulerain 的回复:
有一个很麻烦的实现,以创建线程的方式加载dll,线程在创建是暂停运行的,然后 通过getthreadcontext得到线程的TEB结构,获得dll入口点地址和加载的基地址,然后virtualallocex ,第二个参数指定你要加载的地址,前提是你指定的地址没有其他程序使用,然后把你想要加载的dll的pe结构映射到virtualallocexe分配后的地址……
[/Quote]


通过getthreadcontext 得到context::Ebx,这个指向peb结构
majia2011 2011-04-14
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lactoferrin 的回复:]

引用 7 楼 bulerain 的回复:

引用 6 楼 lactoferrin 的回复:
引用 5 楼 bulerain 的回复:
有一个很麻烦的实现,以创建线程的方式加载dll,线程在创建是暂停运行的,然后 通过getthreadcontext得到线程的TEB结构,获得dll入口点地址和加载的基地址,然后virtualallocex ,第二个参数指定你要加载的地址,前提是你指定的地址……
[/Quote],
你俩的方法都对,都可以获得,你的方法还要判一下系统,追踪下getthreadcontext其实还是fs
Lactoferrin 2011-04-14
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 bulerain 的回复:]

引用 6 楼 lactoferrin 的回复:
引用 5 楼 bulerain 的回复:
有一个很麻烦的实现,以创建线程的方式加载dll,线程在创建是暂停运行的,然后 通过getthreadcontext得到线程的TEB结构,获得dll入口点地址和加载的基地址,然后virtualallocex ,第二个参数指定你要加载的地址,前提是你指定的地址没有其他程序使用,然后把你想要加载的dll的pe……
[/Quote]
什么意思,要peb直接从fs:[0x30]得到
sunlin7 2011-04-14
  • 打赏
  • 举报
回复
vc6中菜单 projects->settings->link选项卡中下拉选项找到output,里面有Base Address,
vs2008里面projects->properties->Configuration Peroperty->Link->Advanced里面有Base Address,

在Base Address里面填上一个不常用的按dll节对齐大小对齐的地址(建议使用1024整数倍地址),比如0x6000000

也可以直接在Link的命令行选项里面使用/base:"0x6000000"

PS:手工修改PE加载地址,可能需要进行必要的重定向操作,很多情况下很难成功。
另外,也可以用自己手工申请地址,使用RawPeApi加载dll到申请的地址.
哈利路亚1874 2011-04-14
  • 打赏
  • 举报
回复
自己实现加载过程,把dll文件拷贝到你指定的内存地址,然后修正导入表和重定位信息,然后跳转到oep
野男孩 2011-04-14
  • 打赏
  • 举报
回复
连接器中绑定BaseAddress就可以了
bulerain 2011-04-13
  • 打赏
  • 举报
回复
有一个很麻烦的实现,以创建线程的方式加载dll,线程在创建是暂停运行的,然后 通过getthreadcontext得到线程的TEB结构,获得dll入口点地址和加载的基地址,然后virtualallocex ,第二个参数指定你要加载的地址,前提是你指定的地址没有其他程序使用,然后把你想要加载的dll的pe结构映射到virtualallocexe分配后的地址,(实际上就是从内存启动dll),setthreadcontext,设置新的dll入口点地址和virtualallocexe返回的地址,然后恢复线程的执行。

参照PeMemPeLoader0.2的实现

HANDLE hthd = CreateThread(
0,
0,
(LPTHREAD_START_ROUTINE )LoadLibrary("yourdll.dll"),
NULL,
CREATE_SUSPENDED ,/*以线程的方式启动dll,调用ResumeThread 启动dll,默认线程挂起*/
0);


Lactoferrin 2011-04-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 bulerain 的回复:]
有一个很麻烦的实现,以创建线程的方式加载dll,线程在创建是暂停运行的,然后 通过getthreadcontext得到线程的TEB结构,获得dll入口点地址和加载的基地址,然后virtualallocex ,第二个参数指定你要加载的地址,前提是你指定的地址没有其他程序使用,然后把你想要加载的dll的pe结构映射到virtualallocexe分配后的地址,(实际上就是从内存启动dll),setth……
[/Quote]
你这样做,LoadLibrary还没执行,怎么得到加载的基地址?
oyljerry 2011-04-12
  • 打赏
  • 举报
回复
DLL工程属性中可以设定加载的地址,当冲突时,系统会再换一个.
Lactoferrin 2011-04-12
  • 打赏
  • 举报
回复
[Quote=引用楼主 bacy001 的回复:]
Dll 中有一个默认载入地址,一般是:0x10000000

如果加载时,从这个地址开始的内存段能够容纳下此 Dll 文件,那么系统会将此 Dll 加载到 0x10000000

否则系统会将 Dll 加载到进程空间中的其他可用位置!

我现在的问题是,有没有办法能够手动指定一个地址用于加载!

通过修改Dll文件可以做到,但是太麻烦了!请教各位高手!
[/Quote]
你为什么要手动定一个地址用于加载?修改Dll文件并不麻烦,只要它有重定位表,就可以直接修改它的IMAGE_OPTIONAL_HEADER中的BaseAddress
无言猪 2011-04-12
  • 打赏
  • 举报
回复
应该是不能的.比如该地址已经被用了.
  • 打赏
  • 举报
回复
编译的时候有选项可以指定加载dll地址
估计你说的修改dll就是修改这个。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧