可重定位可执行文件和安卓操作系统

19

我已经在Eclipse中编写了一个.c源代码,并使用libcap库获取与网络流量相关的信息。现在,我使用Eclipse中的ndk-build创建了可执行二进制文件。我将创建的二进制文件推送到了我安卓设备(自己的Nexus 5,Lollipop版本且已root)的libs/armeabi文件夹中,并尝试执行该二进制文件。但是,安卓设备报出如下错误:

Error: only position independent executables (PIE) are supported

我不知道什么是PIE,请告诉我如何创建一个位置无关的可执行文件。


已解决,只需在 Android.mk 文件中添加这两行即可。 - Adi Tiwari
2
LOCAL_CFLAGS += -fPIE LOCAL_LDFLAGS += -fPIE -pie - Adi Tiwari
2个回答

23
我不了解PIE,可以告诉我如何创建一个与位置无关的可执行文件吗?
位置无关可执行文件(PIE)允许程序像共享对象一样被重定位。在每次运行程序时,程序可以加载到不同的地址,使得攻击者更难猜测某些程序状态。
你可以通过两种方式之一编译和链接PIE可执行文件。第一种方法是使用-fPIE进行全部编译,并使用-pie进行链接。第二个方法是使用-fPIC进行全部编译,并使用-pie进行链接。
如果你正在构建共享对象和程序,则需要使用-fPIC进行全部编译。将共享对象与-shared链接,将程序与-pie链接。
不能反过来做。也就是说,你不能使用-fPIE进行全部编译并构建共享对象和程序。有关详细信息,请参见GCC手册中的代码生成选项
在Android上要注意一件事:在4.1之前使用PIE进行构建会导致/system/bin/linker出现分段错误。 PIE是在Android 4.1中添加的,并且会崩溃较低版本。
有人告诉我要提供自定义链接/加载器以避免问题,但我目前找不到参考资料。
还可以参见Android 1.5到4.1中的安全增强

Error: only position independent executables (PIE) are supported

是的,这是Lollipop功能。请参见Android 5.0中的安全增强
你可以使用readelf检查程序是否已使用PIE构建:
$ readelf -l my-prog | grep -i "file type"
Elf filetype is DYN (shared object file)

重要的部分是 readelf 报告了 DYN,并且没有报告EXEEXE 表示它缺少 PIE,这应该会触发与安全相关的缺陷。


相关信息,请参见《在Android 4.0(ICS)中是否支持用于主可执行文件的PIE(位置无关可执行文件)?》


感谢@jww提供详细的答案。 - Adi Tiwari
@jww 我已经编译了没有PIE的链接器。你可以从这里获取:http://lifepluslinux.blogspot.com/2015/01/installing-python-on-android-50.html - leet

5

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


1
实际上,使用您提供的解决方案已经修复了 PIE 异常,但我使用的库存在一些问题。因此,总的来说,您的解决方案效果很好! - Salman Khakwani
1
这个答案只解决了PIE错误,但是如果您有第三方库与可执行文件动态链接,它不会被修复(这不是魔法)。 - Koorosh Ghorbani
无法运行。我收到了分段错误的错误提示。 - Majeed Khan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接