位置无关的可执行文件和 Android

Position Independent Executables and Android

我已经编写了一个 .c 源代码(在 Eclipse 中),它使用 libcap 库来获取与网络流量相关的信息。现在我已经在 Eclipse 中使用 ndk-build 创建了一个可执行二进制文件。我已将 libs/armeabi 文件夹中创建的二进制文件推送到我的 android 的 /data/local/ 文件夹(root nexus 5,Lollipop)并尝试执行二进制文件。但是 android 抛出了这个错误

Error: only position independent executables (PIE) are supported

我对 PIE 一无所知,请告诉我如何创建一个与位置无关的可执行文件。

I don't know anything about PIE, Please tell me how to create a position independent executable.

位置独立可执行文件或 PIE 允许重新定位程序,就像共享对象一样。在程序的每个 运行 处,程序可以加载到不同的地址,使攻击者更难猜测某些程序状态。

您可以通过以下两种方式之一编译和 link PIE 可执行文件。首先,使用 -fPIE 编译所有内容,使用 -pie 编译所有内容 link。第二种是用-fPIC和link用-pie编译所有东西。

如果您同时构建共享对象和程序,则使用 -fPIC 编译所有内容。 Link 与 -shared 的共享对象,link 与 -pie 的程序。

反之则不行。也就是说,您不能使用 -fPIE 编译所有内容并同时构建共享对象和程序。有关详细信息,请参阅 GCC 手册中的 Code Generation Options


在 Android 上需要注意一件事:使用 4.1 之前的 PIE 构建会导致 /system/bin/linker 中出现分段错误。 PIE 是在 Android 4.1 中添加的,它会使较小的版本崩溃。

有人告诉我提供一个自定义 link/loader 来避免这个问题,但我目前找不到参考。

另见 Security Enhancements in Android 1.5 through 4.1


Error: only position independent executables (PIE) are supported

是的,这是 Lollipop 的一项功能。参见 Security Enhancements in Android 5.0


您可以使用 readelf:

检查程序是否使用 PIE 构建
$ readelf -l my-prog | grep -i "file type"
Elf filetype is DYN (shared object file)

重要的部分是 readelf 正在报告 DYN,而不是报告 EXEEXE 表示它缺少 PIE,这应该会触发与安全相关的缺陷。


相关,见Is PIE (Position-independent executable) for main executables supported in Android 4.0 (ICS)?

我知道这是一个老话题,但这种 hacky 方式可能会节省一些人的时间
用十六进制编辑器,找到第17个字节,将值02更改为03,就可以了!