在可执行文件上使用dlopen()

时间:2011-07-07 22:03:33

标签: unix executable dlopen

我需要从另一个程序调用一个函数。如果其他程序是库,我可以简单地使用dlopen和dlsym来获取函数的句柄。不幸的是,其他程序是Unix可执行程序,并且将其构建为库不是一种选择。在可执行文件上尝试dlopen()会出现此错误消息:

dlopen([...]/testprogram, 1): no suitable image found. Did find: [...]/testprogram: can't map

这并不奇怪,因为dlopen用于库,而不是可执行文件。有没有办法让dlopen和dlsym使用可执行文件?如果没有,是否有其他方法可以达到同样的目的?

4 个答案:

答案 0 :(得分:7)

您无法将可执行文件作为库打开。可执行文件的入口点将尝试重新初始化C库,并接管brk指针。这会破坏你的malloc堆。此外,可执行文件可能会映射到没有重定位的固定地址,如果此地址与已加载的任何地址重叠,则也不可能出于此原因进行映射。

您需要将其他程序重构为库,或者将RPC接口添加到其他程序。

请注意,这不一定适用于PIE可执行文件。但是,除非可执行文件专门用于dlopen()编辑,否则这是不安全的,因为main()将不会运行,因此main()中完成的任何初始化都不会发生。

答案 1 :(得分:6)

在某些ELF系统(尤其是Linux)上,您可以dlopen() PIE可执行文件。使用GCC时,只需使用-fpie-fPIE编译可执行文件,并将其与-pie相关联,然后使用--dynamic-list-rdynamic导出相应的符号(已解释)更详细的this other SO answer

答案 2 :(得分:1)

这里的工具就是这样做,处理ASLR / PIE和非ASLR / PIE。在x86,ARM和MIPS上编译(仅限32位)。编辑Makefile以设置ARCH参数。

http://rtfc.org.uk/cliapi.html

这是我的工具,但它似乎做你想要的。如果它不适合你,请告诉我。

我很欣赏我参加这个派对的时间有点晚了,但是嘿。

答案 3 :(得分:0)

添加通过dlopen加载可执行文件的功能已注册为reject glibc RFE(请求增强)。

详细介绍了RFE和某些特殊情况的可能方法

[http://sourceware.org/bugzilla/show_bug.cgi?id=11754] [1]

除了PIE之外,实施这样的功能背后会有许多问题。