为什么我不能在Linux中直接启动共享库?
$ chmod +x libsomelibrary.so
$ ./libsomelibrary.so
Segmentation fault
$ gcc -O2 http://vi-server.org/vi/bin/rundll.c -ldl -o rundll
$ ./rundll ./libsomelibrary.so main
(application starts normally)
如果 libsomelibrary.so 有可用的入口点,为什么我不能启动它?
rundll.c
很简单:
void* d = dlopen(argv[1], RTLD_LAZY);
void* m = dlsym(d, argv[2]);
return ((int(*)(int,char**,char**))m)(argc-2, argv+2, envp);
为什么在尝试加载二进制文件时不在内部使用它?
$ chmod +x libsomelibrary.so
$ ./libsomelibrary.so
Segmentation fault
$ gcc -O2 http://vi-server.org/vi/bin/rundll.c -ldl -o rundll
$ ./rundll ./libsomelibrary.so main
(application starts normally)
Why can't I just start libsomelibrary.so if it has usable entry point?
rundll.c
is trivial:
void* d = dlopen(argv[1], RTLD_LAZY);
void* m = dlsym(d, argv[2]);
return ((int(*)(int,char**,char**))m)(argc-2, argv+2, envp);
Why is it not used internally when attempting to load a binary?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
main
不是内核或动态链接器识别的入口点 - 它由编译可执行文件时链接到可执行文件的启动代码调用(默认情况下,此类启动代码不会链接到共享库) )。ELF 标头包含起始地址。
main
is not the entry point recognised by the kernel or the dynamic linker - it is called by the startup code linked into your executable when you compile it (such startup code isn't linked into shared libraries by default).The ELF header contains the start address.
共享库并非设计为可直接运行。它们被设计为链接到另一个代码库。它可能有一个可用的入口点,但可执行性不仅仅需要有一个可用的入口点。
rundll
实用程序证明了这一点。您的第二个测试表明共享库确实是可执行的,但只有在rundll
完成一些工作之后。如果您对执行库代码之前必须完成哪些操作感到好奇,请查看rundll
的源代码。Shared libraries are not designed to be directly runnable. They are designed to be linked into another codebase. It may have a usable entry point, but being executable entails more than merely having a usable entry point. The
rundll
utility is proof of this. Your second test shows that the shared library is indeed executable, but only afterrundll
does some work. If you are curious as to what all has to be done before the library code can be executed, take a look at the source code forrundll
.您可以在Linux 中启动共享库。
例如,如果您启动
/lib/libc.so.6
,它将打印出其版本号:您的库中肯定缺少某些内容。
You can start shared libraries in Linux.
For example, if you start
/lib/libc.so.6
, it will print out its version number:There must be something missing from your library.