所以每个人都可能知道glibc /lib/libc.so.6可以在shell中执行,就像普通的可执行文件一样,在这种情况下它可以打印出版本信息并退出.这是通过在.so中定义入口点来完成的.对于某些情况,将其用于其他项目可能会很有趣.不幸的是,您可以通过ld的-e选项设置的低级入口点有点太低级:动态加载器不可用,因此您无法调用任何正确的库函数.因此,glibc通过此入口点中的裸系统调用实现write()系统调用.
我现在的问题是,任何人都可以想到一个很好的方法,如何从该入口点引导一个完整的动态链接器,以便可以访问其他.so的函数?
我需要从另一个程序调用一个函数.如果其他程序是库,我可以简单地使用dlopen和dlsym来获取函数的句柄.不幸的是,其他程序是Unix可执行程序,并且将其构建为库不是一种选择.在可执行文件上尝试dlopen()会显示以下错误消息:
dlopen([...]/testprogram, 1): no suitable image found. Did find:
[...]/testprogram: can't map
这并不奇怪,因为dlopen用于库,而不是可执行文件.有没有办法让dlopen和dlsym使用可执行文件?如果没有,是否有另一种方法可以达到同样的目的?
以下是"可执行"共享库的最小示例(假定文件名:)mini.c:
// Interpreter path is different on some systems
//+definitely different for 32-Bit machines
const char my_interp[] __attribute__((section(".interp")))
= "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2";
#include <stdio.h>
#include <stdlib.h>
int entry() {
printf("WooFoo!\n");
exit (0);
}
Run Code Online (Sandbox Code Playgroud)
如果用例如:编译它gcc -fPIC -o mini.so -shared -Wl,-e,entry mini.c."运行"结果.so将如下所示:
confus@confusion:~$ ./mini.so
WooFoo!
Run Code Online (Sandbox Code Playgroud)
我现在的问题是:
如何更改上述程序以将命令行参数传递给.so-file 的调用?更改后的示例shell会话可能如下所示:
confus@confusion:~$ ./mini.so 2 bar
1: WooFoo! bar!
2: WooFoo! bar!
confus@confusion:~$ ./mini.so 3 bla
1: WooFoo! bla!
2: WooFoo! bla!
3: WooFoo! bla!
5: WooFoo! Bar!
Run Code Online (Sandbox Code Playgroud)
在编译时检测 …
这是一个理论问题.我知道也许最好的做法是使用共享库.但我遇到了这个问题,似乎无法在任何地方找到答案.
如何构建代码并用ELF格式编译一个C/C++程序,以便可以加载dlopen()?
例如,如果一个可执行文件包含某个函数的实现,int test()并且我想从我的程序中调用此函数(并且最好得到函数的结果),如果可能的话,我该怎么做呢?
在伪代码中,我可以将其描述如下:
ELF可执行文件来源:
void main() {
int i = test();
printf("Returned: %d", i);//Prints "Returned: 5"
}
int test() {
return 5;
}
Run Code Online (Sandbox Code Playgroud)
外部计划:
// ... Somehow load executable from above
void main() {
int i = test();
printf("Returned: %d", i);//Must print "Returned: 5"
}
Run Code Online (Sandbox Code Playgroud)