我需要从另一个程序调用一个函数。如果其他程序是库,我可以简单地使用dlopen和dlsym来获取函数的句柄。不幸的是,其他程序是Unix可执行程序,并且将其构建为库不是一种选择。在可执行文件上尝试dlopen()会出现此错误消息:
dlopen([...]/testprogram, 1): no suitable image found. Did find:
[...]/testprogram: can't map
这并不奇怪,因为dlopen用于库,而不是可执行文件。有没有办法让dlopen和dlsym使用可执行文件?如果没有,是否有其他方法可以达到同样的目的?
答案 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之外,实施这样的功能背后会有许多问题。