如何从终端将共享库作为可执行文件运行?

时间:2019-07-16 23:41:40

标签: linux musl

来自Musl libc常见问题解答

  

问:ldd在哪里?

     

musl的动态链接器内置了ldd功能。只需创建从ld-musl- $ ARCH.so到/ bin / ldd的符号链接。如果动态链接程序以“ ldd”开头,它将检测到并打印适当的DSO信息。

检查ld-musl-$ARCH.so时发现它是与肌肉/usr/local/musl/lib/libc.so的符号链接

那绝对是一个共享库

$ file /usr/local/musl/lib/libc.so
/usr/local/musl/lib/libc.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=068deca2fec0ea2c50ec1e11166d25b3bb057431, not stripped

它实际上是有效的,哈哈。我实际上可以做到这一点:

$ /usr/local/musl/lib/libc.so ./a.out

它将起作用。但是我怎么可能从终端调用共享库?

1 个答案:

答案 0 :(得分:1)

好的,我想我能理解。

因此,基本上,共享库实际上是可执行文件。而且由于musl是libc实现,因此它定义了_start()函数,该函数是程序的真正入口点。 _start()函数将调用主函数。

musl的开发人员做到了这一点,因此,如果您以libc.sold的身份调用ldd,他们将检测到并采取相应措施。

他们可以检测到,因为_start()确实占用了argcargv(然后将它们传递到main()),因此他们可以查看argv[0]是否是“ ld”或“ ldd”。

感谢@that另一个人和@David C. Rankin链接this。那里的答案说,您甚至可以拥有定义main()的共享库。

所以我自己尝试了。

这里是_start.c

void
_start()
{
    asm("mov $60,%rax; mov $0,%rdi; syscall");
}

我在具有gcc 7.4.0的x86_64 ubuntu linux计算机上编译了该代码,

$ gcc -shared -nostdlib _start.c -o libwow.so

然后我叫它:

$ ./libwow.so
$

它当然什么也没做,但是确实可以运行。

我们生活在一个疯狂的世界:D

编辑:

更疯狂。可以使用dlopen(3)将可执行文件作为动态库加载。查看this answer了解更多信息。

结论:

共享库和可执行文件几乎是同一件事(ELF二进制文件)。

除了共享库没有固定的入口点地址,而可执行文件却没有。

共享库也为PIE,而二进制文件默认不是。

我想还有一些其他细微的差别:p

生活在我们中间的可执行文件(叛徒:p)一直都是真正的共享库,而我们却不像gawkntfsck那样。

请查看此Question/Answers,以获取更多信息。