【发布时间】:2016-02-13 01:59:00
【问题描述】:
我正在使用 Android r10e NDK 为 Android 构建 Unison(一个文件同步可执行文件),但这并不是一个真正的 Android 问题。
Android > 5.0 (SDK 21) 要求可执行文件与位置无关。所以我 编译时将 -pie 传递给 arm-linux-androideabi-gcc,这样可以:
% hardening-check ./unison
./unison:
Position Independent Executable: yes
...
这在 Android 5.0 设备上运行良好。
Android > 6.0 (SDK 21) 仍然要求可执行文件与位置无关, 但也需要在没有文本重定位的情况下构建可执行文件。所以我 编译时将 -fPIC 传递给 arm-linux-androideabi-gcc,它似乎可以构建 没有文本重定位的二进制文件:
% arm-linux-androideabi-readelf -a ./unison |& grep TEXTREL
(no output is shown)
问题是,我一次只能满足一个要求。如果我使用 -pie 和 -fPIC 一起,生成的可执行文件与位置无关(耶!),但是 还有文本重定位(嘘!):
% hardening-check ./unison
./unison:
Position Independent Executable: yes
...
% arm-linux-androideabi-readelf -a ./unison |& grep TEXTREL
0x00000016 (TEXTREL) 0x0
0x0000001e (FLAGS) TEXTREL BIND_NOW
...Android 6.0 设备拒绝运行它:
% adb push unison /data/local/tmp
% adb shell '/data/local/tmp/unison -version'
WARNING: linker: /data/local/tmp/unison has text relocations. This is wasting memory and prevents security hardening. Please fix.
CANNOT LINK EXECUTABLE: can't protect segments for "/data/local/tmp/unison": Permission denied
让这些标志协同工作所需的特殊调味料是什么?要么, 或者,我错过了什么? PIC 和 PIE 是否互斥?
谢谢!
编辑:
我正在手动完成 OPAM 存储库为 Android 构建 Unison 所经历的相同过程。即:
构建 ocaml 交叉编译器。
下拉 Unison 源。
-
应用补丁:
--- pty.c~ 2010-04-15 19:29:31.000000000 +0200 +++ pty.c 2013-01-16 19:28:56.258812188 +0100 @@ -10,7 +10,7 @@ extern void uerror (char * cmdname, value arg) Noreturn; // openpty -#if defined(__linux) +#if defined(__linux) && !defined(__ANDROID__) #include <pty.h> #define HAS_OPENPTY 1 #endif --- Makefile.OCaml~ 2013-01-16 19:27:10.686807807 +0100 +++ Makefile.OCaml 2013-01-16 19:29:46.814814286 +0100 @@ -136,7 +136,9 @@ # openpty is in the libutil library ifneq ($(OSARCH),solaris) ifneq ($(OSARCH),osx) - CLIBS+=-cclib -lutil + ifneq ($(OSCOMP),android) + CLIBS+=-cclib -lutil + endif endif endif buildexecutable:: -
构建:
% make \ UISTYLE=text \ OCAMLOPT="arm-linux-androideabi-ocamlopt -verbose -ccopt '-fPIC -pie'" \ OSCOMP=android
上述过程构建了一个 PIE 可执行文件,该可执行文件在 Android 5 上运行良好,但在 Android 6 上失败,因为它具有文本重定位。删除上面的“-pie”会构建一个没有文本重定位的二进制文件,但它不是 PIE 可执行文件,因此它不会在 Android 5 或 6 上运行。
【问题讨论】:
-
您能否提供有关如何配置和构建的详细信息,以帮助其他人重现? (构建一个简单的测试应用程序可能不会产生相同的文本重定位。)
-
你解决了这个问题吗?
标签: android gcc android-ndk ocaml