【发布时间】:2021-02-15 22:42:24
【问题描述】:
在 SO 上有一个 large number 或 questions 关于如何执行库或动态加载可执行文件。据我所知,所有答案都归结为:将您的可执行文件编译为与位置无关的代码并使用dlopen 加载它。这很好用 --- 在 macOS 上仍然很好用 --- 直到 recent change in glibc,它明确禁用了 dlopening PIE。例如,此更改现在在 ArchLinux 上的当前版本的 glibc (2.30) 中,并且尝试 dlopen 与位置无关的可执行文件会给出错误:“无法动态加载与位置无关的可执行文件”。
很难猜测是什么促成了如此彻底的改变,破坏了如此多的代码和有用的用例。 (关于 Patchwork 和 Bugzilla 的解释对我来说没有多大意义。)但是现在有一个问题:如果您想创建一个同时也是动态库的可执行文件,或者反之亦然,该怎么办?
A solution 是从其中一个 cmets 链接的。在这里复制它以供后代使用:
#include <stdio.h>
#include <unistd.h>
const char service_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux-x86-64.so.2";
extern "C" {
void lib_entry(void)
{
printf("Entry point of the service library\n");
_exit(0);
}
}
使用g++ -shared test-no-pie.cpp -o test-no-pie -Wl,-e,lib_entry 编译会生成一个共享对象(动态库),该对象也可以在 Linux 上执行。
我有两个问题:
- 如果我想传递命令行参数怎么办?如何修改此解决方案使其接受
arc,argv? - 还有其他选择吗?
【问题讨论】:
标签: linux shared-libraries executable glibc dlopen